Skip to content

Commit 809e491

Browse files
test(coverage): resource RotateCredentials update_failed arm
RotateCredentials persist-error arm (UpdateConnectionURL fails after a decryptable URL rotate) via faultdb + rfEncryptURL seed helper. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 79e54d3 commit 809e491

1 file changed

Lines changed: 37 additions & 0 deletions

File tree

internal/handlers/resource_final_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"github.com/stretchr/testify/require"
2121

2222
"instant.dev/internal/config"
23+
"instant.dev/internal/crypto"
2324
"instant.dev/internal/handlers"
2425
"instant.dev/internal/middleware"
2526
"instant.dev/internal/plans"
@@ -93,6 +94,17 @@ func rfErr(t *testing.T, resp *http.Response) string {
9394
return ""
9495
}
9596

97+
// rfEncryptURL encrypts a connection URL with the test AES key so a seeded
98+
// resource's stored URL decrypts cleanly in the handler.
99+
func rfEncryptURL(t *testing.T, plain string) string {
100+
t.Helper()
101+
key, err := crypto.ParseAESKey(testhelpers.TestAESKeyHex)
102+
require.NoError(t, err)
103+
enc, err := crypto.Encrypt(key, plain)
104+
require.NoError(t, err)
105+
return enc
106+
}
107+
96108
// Pause: GetResourceByToken errors → fetch_failed (resource.go:567). failAfter=0.
97109
func TestResourceFinal_Pause_LookupError_503(t *testing.T) {
98110
seedDB, clean := testhelpers.SetupTestDB(t)
@@ -180,3 +192,28 @@ func TestResourceFinal_Rotate_LookupError_503(t *testing.T) {
180192
require.Equal(t, http.StatusServiceUnavailable, resp.StatusCode)
181193
assert.Equal(t, "fetch_failed", rfErr(t, resp))
182194
}
195+
196+
// RotateCredentials: UpdateConnectionURL errors → update_failed
197+
// (resource.go:499). The resource must have a DECRYPTABLE connection_url so the
198+
// rotate reaches the persist step; seed it with a real encrypted URL. resource
199+
// lookup(1) succeeds, the postgres ALTER ROLE is a no-op (nil customer DB), the
200+
// UpdateConnectionURL UPDATE(2) errors. failAfter=1.
201+
func TestResourceFinal_Rotate_UpdateFailed_503(t *testing.T) {
202+
seedDB, clean := testhelpers.SetupTestDB(t)
203+
defer clean()
204+
teamID := testhelpers.MustCreateTeamDB(t, seedDB, "pro")
205+
// Encrypt a real postgres URL with the test AES key so decrypt + url-parse
206+
// succeed and the handler reaches UpdateConnectionURL.
207+
enc := rfEncryptURL(t, "postgres://usr:pw@host:5432/db_x")
208+
var token string
209+
require.NoError(t, seedDB.QueryRowContext(context.Background(),
210+
`INSERT INTO resources (team_id, resource_type, tier, status, connection_url)
211+
VALUES ($1::uuid, 'postgres', 'pro', 'active', $2) RETURNING token::text`,
212+
teamID, enc).Scan(&token))
213+
214+
app := resourceFaultApp(t, openFaultDB(t, 1), teamID)
215+
resp := rfPost(t, app, "/r/"+token+"/rotate")
216+
defer resp.Body.Close()
217+
require.Equal(t, http.StatusServiceUnavailable, resp.StatusCode)
218+
assert.Equal(t, "update_failed", rfErr(t, resp))
219+
}

0 commit comments

Comments
 (0)