From 7a8749739ae1bf4e4dc0a6fd0a68299912cb8d5d Mon Sep 17 00:00:00 2001 From: RXWatcher <14085001+RXWatcher@users.noreply.github.com> Date: Tue, 26 May 2026 19:59:38 +0200 Subject: [PATCH] test(audiobooks): tighten delete tests with cascade + unreachability checks Final review flagged two small gaps in the delete tests: - TestCollection_Delete_Owner_204 now seeds a book and asserts the items table is empty after delete (proves FK CASCADE works). - TestPlaylist_Delete_Owner_FiresRemovedEvent now also asserts the post-delete GET returns 404 (symmetry with the collection test). Co-Authored-By: Claude Opus 4.7 (1M context) --- internal/audiobooks/abs/collections_handler_test.go | 11 ++++++++++- internal/audiobooks/abs/playlists_handler_test.go | 5 +++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/internal/audiobooks/abs/collections_handler_test.go b/internal/audiobooks/abs/collections_handler_test.go index 09b4a2c6..ed746256 100644 --- a/internal/audiobooks/abs/collections_handler_test.go +++ b/internal/audiobooks/abs/collections_handler_test.go @@ -433,9 +433,13 @@ func TestCollection_Patch_NonOwner_404(t *testing.T) { } func TestCollection_Delete_Owner_204(t *testing.T) { - hb := newCollectionsHarness(t) + hb := newCollectionsHarness(t, "book-1") id := createCollectionForUser(t, hb, "1", "", `{"name":"x"}`) + // Seed an item so the cascade-delete is exercised. + _ = dispatchABSWithParams(http.MethodPost, "/api/collections/"+id+"/book/book-1", + map[string]string{"id": id, "bookId": "book-1"}, nil, "1", "", hb.H.handleAddCollectionBook) + rec := dispatchABSWithParams(http.MethodDelete, "/api/collections/"+id, map[string]string{"id": id}, nil, "1", "", hb.H.handleDeleteCollection) if rec.Code != http.StatusNoContent { t.Fatalf("status = %d, want 204; body=%s", rec.Code, rec.Body.String()) @@ -445,6 +449,11 @@ func TestCollection_Delete_Owner_204(t *testing.T) { if rec2.Code != http.StatusNotFound { t.Errorf("post-delete GET status = %d, want 404", rec2.Code) } + // Cascade: items table must be empty for the deleted collection. + items, _ := hb.Coll.ListCollectionItems(context.Background(), id) + if len(items) != 0 { + t.Errorf("items len = %d, want 0 (cascade did not drop child rows)", len(items)) + } } func TestCollection_Delete_NonOwner_404(t *testing.T) { diff --git a/internal/audiobooks/abs/playlists_handler_test.go b/internal/audiobooks/abs/playlists_handler_test.go index 227dd7d8..f14b46ad 100644 --- a/internal/audiobooks/abs/playlists_handler_test.go +++ b/internal/audiobooks/abs/playlists_handler_test.go @@ -370,6 +370,11 @@ func TestPlaylist_Delete_Owner_FiresRemovedEvent(t *testing.T) { if evts[len(evts)-1].Event != "playlist_removed" { t.Errorf("event = %q, want playlist_removed", evts[len(evts)-1].Event) } + // Post-delete GET must 404 (symmetry with collection delete test). + rec2 := dispatchABSWithParams(http.MethodGet, "/api/playlists/"+id, map[string]string{"id": id}, nil, "7", "", hb.H.handleGetPlaylist) + if rec2.Code != http.StatusNotFound { + t.Errorf("post-delete GET status = %d, want 404", rec2.Code) + } } func TestPlaylist_Delete_NonOwner_404(t *testing.T) {