@@ -29,14 +29,14 @@ import (
2929// session for the supplied tier. Mirrors setupPauseFixture but exposes the
3030// app + db + jwt + teamID for arbitrary cross-cutting tests.
3131type authedFixture struct {
32- app interface {
32+ app interface {
3333 Test (req * http.Request , msTimeout ... int ) (* http.Response , error )
3434 }
35- db * sql.DB
36- jwt string
37- teamID string
38- userID string
39- teamUUID uuid.UUID
35+ db * sql.DB
36+ jwt string
37+ teamID string
38+ userID string
39+ teamUUID uuid.UUID
4040}
4141
4242func setupAuthedFixture (t * testing.T , planTier string ) authedFixture {
@@ -1486,3 +1486,22 @@ func TestResourceList_AllFieldsPresent(t *testing.T) {
14861486// ───────────────────────────────────────────────────────────────────────────
14871487var _ = fmt .Sprintf
14881488var _ = uuid .Nil
1489+
1490+ // TestResourceDelete_Idempotent_DoubleDelete — bug-bash #4/#12: a repeated
1491+ // DELETE on an already-deleted resource returns 200 already_deleted and does NOT
1492+ // re-run the soft-delete + backend deprovision.
1493+ func TestResourceDelete_Idempotent_DoubleDelete (t * testing.T ) {
1494+ fix := setupAuthedFixture (t , "hobby" )
1495+ _ , tok := insertResourceCov (t , fix .db , fix .teamID , "redis" , "hobby" )
1496+
1497+ r1 := authedDelete (t , fix , "/api/v1/resources/" + tok )
1498+ _ = r1 .Body .Close ()
1499+ require .Equal (t , http .StatusOK , r1 .StatusCode )
1500+
1501+ r2 := authedDelete (t , fix , "/api/v1/resources/" + tok )
1502+ defer r2 .Body .Close ()
1503+ require .Equal (t , http .StatusOK , r2 .StatusCode , "second DELETE must be idempotent 200" )
1504+ var body map [string ]any
1505+ require .NoError (t , json .NewDecoder (r2 .Body ).Decode (& body ))
1506+ assert .Equal (t , true , body ["already_deleted" ], "repeat DELETE must report already_deleted" )
1507+ }
0 commit comments