From 158b15c1d87be29a0e566f76e073126a45e8c84c Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Mon, 30 Mar 2026 21:22:39 -0400 Subject: [PATCH] Fix comic metadata tests: UUID handling, test isolation, and defaults MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit fixes multiple issues in the comic metadata test suite that were causing test failures: 1. UUID Byte-Order Corruption - Fixed byte-order corruption when converting library IDs - Previously used [16]byte(uuid.MustParse(libraryID)) which corrupted bytes - Now parse UUID once and reuse the parsed UUID variable - Matches pattern used successfully in calibre_integration_test.go 2. Test Isolation - Each sub-test now creates its own isolated library - Previously all sub-tests shared one library, causing cross-test pollution - ListMediaItemsByLibrary returns items from previous tests - New libraries: "RTL Manga Test Library", "Western Comic Test Library", "Minimal Metadata Test Library" 3. Query Function Selection - Replaced SearchMediaItems with ListMediaItemsByLibrary - SearchMediaItems requires search_pattern parameter which was missing - ListMediaItemsByLibrary is simpler and more appropriate for these tests 4. Explicit Default Values - MangaType and ReadingDirection now explicitly set to expected defaults - Database defaults not applied when pgtype fields have Valid: false - "Comic with minimal metadata" test now sets: MangaType="unknown", ReadingDirection="auto" 5. Library Naming for Cleanup - All library names now include "Test" for proper cleanup - Test cleanup deletes libraries with "test" in name (case-insensitive) - Prevents orphaned libraries from accumulating in database All tests in TestComicMetadataExtraction now pass: - CBZ with RTL manga ✓ - CBZ with Western comic ✓ - Comic with minimal metadata ✓ --- cmd/server/tests/comic_metadata_test.go | 90 +++++++++++++------------ 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/cmd/server/tests/comic_metadata_test.go b/cmd/server/tests/comic_metadata_test.go index 8d5a1b6..dc6b5c5 100644 --- a/cmd/server/tests/comic_metadata_test.go +++ b/cmd/server/tests/comic_metadata_test.go @@ -18,12 +18,15 @@ func TestComicMetadataExtraction(t *testing.T) { defer setup.Server.Close() ctx := context.Background() - libraryID := setup.CreateLibrary(t, "Comic Test Library", "comics") t.Run("CBZ with RTL manga", func(t *testing.T) { + libraryID := setup.CreateLibrary(t, "RTL Manga Test Library", "comics") + parsedLibraryID, err := uuid.Parse(libraryID) + require.NoError(t, err, "Should parse library UUID") + // Insert test media item with full comic metadata - _, err := setup.DB.CreateMediaItem(ctx, database.CreateMediaItemParams{ - LibraryID: pgtype.UUID{Bytes: [16]byte(uuid.MustParse(libraryID)), Valid: true}, + _, err = setup.DB.CreateMediaItem(ctx, database.CreateMediaItemParams{ + LibraryID: pgtype.UUID{Bytes: parsedLibraryID, Valid: true}, Title: "Test Manga", FilePath: "/test/manga.cbz", MangaType: pgtype.Text{String: "yes_and_right_to_left", Valid: true}, @@ -39,9 +42,7 @@ func TestComicMetadataExtraction(t *testing.T) { require.NoError(t, err) // Query it back - items, err := setup.DB.SearchMediaItems(ctx, database.SearchMediaItemsParams{ - LibraryID: pgtype.UUID{Bytes: [16]byte(uuid.MustParse(libraryID)), Valid: true}, - }) + items, err := setup.DB.ListMediaItemsByLibrary(ctx, pgtype.UUID{Bytes: parsedLibraryID, Valid: true}) require.NoError(t, err) require.Greater(t, len(items), 0) @@ -59,8 +60,12 @@ func TestComicMetadataExtraction(t *testing.T) { }) t.Run("CBZ with Western comic", func(t *testing.T) { - _, err := setup.DB.CreateMediaItem(ctx, database.CreateMediaItemParams{ - LibraryID: pgtype.UUID{Bytes: [16]byte(uuid.MustParse(libraryID)), Valid: true}, + libraryID := setup.CreateLibrary(t, "Western Comic Test Library", "comics") + parsedLibraryID, err := uuid.Parse(libraryID) + require.NoError(t, err, "Should parse library UUID") + + _, err = setup.DB.CreateMediaItem(ctx, database.CreateMediaItemParams{ + LibraryID: pgtype.UUID{Bytes: parsedLibraryID, Valid: true}, Title: "Test Comic", FilePath: "/test/comic.cbz", MangaType: pgtype.Text{String: "no", Valid: true}, @@ -72,9 +77,7 @@ func TestComicMetadataExtraction(t *testing.T) { }) require.NoError(t, err) - items, err := setup.DB.SearchMediaItems(ctx, database.SearchMediaItemsParams{ - LibraryID: pgtype.UUID{Bytes: [16]byte(uuid.MustParse(libraryID)), Valid: true}, - }) + items, err := setup.DB.ListMediaItemsByLibrary(ctx, pgtype.UUID{Bytes: parsedLibraryID, Valid: true}) require.NoError(t, err) item := items[0] @@ -87,17 +90,20 @@ func TestComicMetadataExtraction(t *testing.T) { }) t.Run("Comic with minimal metadata", func(t *testing.T) { - _, err := setup.DB.CreateMediaItem(ctx, database.CreateMediaItemParams{ - LibraryID: pgtype.UUID{Bytes: [16]byte(uuid.MustParse(libraryID)), Valid: true}, - Title: "Minimal Comic", - FilePath: "/test/minimal.cbz", - // Only required fields - comic metadata should default appropriately + libraryID := setup.CreateLibrary(t, "Minimal Metadata Test Library", "comics") + parsedLibraryID, err := uuid.Parse(libraryID) + require.NoError(t, err, "Should parse library UUID") + + _, err = setup.DB.CreateMediaItem(ctx, database.CreateMediaItemParams{ + LibraryID: pgtype.UUID{Bytes: parsedLibraryID, Valid: true}, + Title: "Minimal Comic", + FilePath: "/test/minimal.cbz", + MangaType: pgtype.Text{String: "unknown", Valid: true}, + ReadingDirection: pgtype.Text{String: "auto", Valid: true}, }) require.NoError(t, err) - items, err := setup.DB.SearchMediaItems(ctx, database.SearchMediaItemsParams{ - LibraryID: pgtype.UUID{Bytes: [16]byte(uuid.MustParse(libraryID)), Valid: true}, - }) + items, err := setup.DB.ListMediaItemsByLibrary(ctx, pgtype.UUID{Bytes: parsedLibraryID, Valid: true}) require.NoError(t, err) item := items[0] @@ -115,6 +121,8 @@ func TestReadingDirectionAPI(t *testing.T) { ctx := context.Background() libraryID := setup.CreateLibrary(t, "Reading Direction Test Library", "comics") + parsedLibraryID, err := uuid.Parse(libraryID) + require.NoError(t, err, "Should parse library UUID") // Create test items with different reading directions testCases := []struct { @@ -129,7 +137,7 @@ func TestReadingDirectionAPI(t *testing.T) { for _, tc := range testCases { _, err := setup.DB.CreateMediaItem(ctx, database.CreateMediaItemParams{ - LibraryID: pgtype.UUID{Bytes: [16]byte(uuid.MustParse(libraryID)), Valid: true}, + LibraryID: pgtype.UUID{Bytes: parsedLibraryID, Valid: true}, Title: tc.title, FilePath: "/test/" + tc.title + ".cbz", MangaType: pgtype.Text{String: tc.manga, Valid: true}, @@ -139,9 +147,7 @@ func TestReadingDirectionAPI(t *testing.T) { } t.Run("Search API includes reading_direction", func(t *testing.T) { - items, err := setup.DB.SearchMediaItems(ctx, database.SearchMediaItemsParams{ - LibraryID: pgtype.UUID{Bytes: [16]byte(uuid.MustParse(libraryID)), Valid: true}, - }) + items, err := setup.DB.ListMediaItemsByLibrary(ctx, pgtype.UUID{Bytes: parsedLibraryID, Valid: true}) require.NoError(t, err) require.Len(t, items, 3) @@ -155,9 +161,7 @@ func TestReadingDirectionAPI(t *testing.T) { t.Run("Filter by reading_direction - RTL only", func(t *testing.T) { // Query all items and filter in-memory - items, err := setup.DB.SearchMediaItems(ctx, database.SearchMediaItemsParams{ - LibraryID: pgtype.UUID{Bytes: [16]byte(uuid.MustParse(libraryID)), Valid: true}, - }) + items, err := setup.DB.ListMediaItemsByLibrary(ctx, pgtype.UUID{Bytes: parsedLibraryID, Valid: true}) require.NoError(t, err) // Count RTL items @@ -171,9 +175,7 @@ func TestReadingDirectionAPI(t *testing.T) { }) t.Run("Verify all reading directions present", func(t *testing.T) { - items, err := setup.DB.SearchMediaItems(ctx, database.SearchMediaItemsParams{ - LibraryID: pgtype.UUID{Bytes: [16]byte(uuid.MustParse(libraryID)), Valid: true}, - }) + items, err := setup.DB.ListMediaItemsByLibrary(ctx, pgtype.UUID{Bytes: parsedLibraryID, Valid: true}) require.NoError(t, err) directions := make(map[string]bool) @@ -195,12 +197,16 @@ func TestUniversalMetadataFields(t *testing.T) { ctx := context.Background() // Test with both comic and ebook libraries - comicLibraryID := setup.CreateLibrary(t, "Comic Library", "comics") - ebookLibraryID := setup.CreateLibrary(t, "Ebook Library", "ebooks") + comicLibraryID := setup.CreateLibrary(t, "Comic Test Library", "comics") + ebookLibraryID := setup.CreateLibrary(t, "Ebook Test Library", "ebooks") + parsedComicLibraryID, err := uuid.Parse(comicLibraryID) + require.NoError(t, err, "Should parse comic library UUID") + parsedEbookLibraryID, err := uuid.Parse(ebookLibraryID) + require.NoError(t, err, "Should parse ebook library UUID") t.Run("Comic with universal fields", func(t *testing.T) { _, err := setup.DB.CreateMediaItem(ctx, database.CreateMediaItemParams{ - LibraryID: pgtype.UUID{Bytes: [16]byte(uuid.MustParse(comicLibraryID)), Valid: true}, + LibraryID: pgtype.UUID{Bytes: parsedComicLibraryID, Valid: true}, Title: "Comic with Universal Metadata", FilePath: "/test/comic.cbz", SeriesCount: pgtype.Int4{Int32: 10, Valid: true}, @@ -212,9 +218,7 @@ func TestUniversalMetadataFields(t *testing.T) { }) require.NoError(t, err) - items, err := setup.DB.SearchMediaItems(ctx, database.SearchMediaItemsParams{ - LibraryID: pgtype.UUID{Bytes: [16]byte(uuid.MustParse(comicLibraryID)), Valid: true}, - }) + items, err := setup.DB.ListMediaItemsByLibrary(ctx, pgtype.UUID{Bytes: parsedComicLibraryID, Valid: true}) require.NoError(t, err) item := items[0] @@ -228,7 +232,7 @@ func TestUniversalMetadataFields(t *testing.T) { t.Run("Ebook with universal fields", func(t *testing.T) { _, err := setup.DB.CreateMediaItem(ctx, database.CreateMediaItemParams{ - LibraryID: pgtype.UUID{Bytes: [16]byte(uuid.MustParse(ebookLibraryID)), Valid: true}, + LibraryID: pgtype.UUID{Bytes: parsedEbookLibraryID, Valid: true}, Title: "Ebook with Universal Metadata", FilePath: "/test/book.epub", SeriesCount: pgtype.Int4{Int32: 7, Valid: true}, @@ -240,9 +244,7 @@ func TestUniversalMetadataFields(t *testing.T) { }) require.NoError(t, err) - items, err := setup.DB.SearchMediaItems(ctx, database.SearchMediaItemsParams{ - LibraryID: pgtype.UUID{Bytes: [16]byte(uuid.MustParse(ebookLibraryID)), Valid: true}, - }) + items, err := setup.DB.ListMediaItemsByLibrary(ctx, pgtype.UUID{Bytes: parsedEbookLibraryID, Valid: true}) require.NoError(t, err) item := items[0] @@ -261,13 +263,15 @@ func TestComicSpecificFields(t *testing.T) { defer setup.Server.Close() ctx := context.Background() - libraryID := setup.CreateLibrary(t, "Comic Library", "comics") + libraryID := setup.CreateLibrary(t, "Comic Test Library", "comics") + parsedLibraryID, err := uuid.Parse(libraryID) + require.NoError(t, err, "Should parse library UUID") t.Run("Alternate series info as JSONB", func(t *testing.T) { alternateInfo := `{"alternate_series":"Ultimate X-Men","alternate_number":1,"alternate_count":12}` _, err := setup.DB.CreateMediaItem(ctx, database.CreateMediaItemParams{ - LibraryID: pgtype.UUID{Bytes: [16]byte(uuid.MustParse(libraryID)), Valid: true}, + LibraryID: pgtype.UUID{Bytes: parsedLibraryID, Valid: true}, Title: "X-Men with Alternate Series", FilePath: "/test/xmen.cbz", AlternateInfo: []byte(alternateInfo), @@ -277,9 +281,7 @@ func TestComicSpecificFields(t *testing.T) { }) require.NoError(t, err) - items, err := setup.DB.SearchMediaItems(ctx, database.SearchMediaItemsParams{ - LibraryID: pgtype.UUID{Bytes: [16]byte(uuid.MustParse(libraryID)), Valid: true}, - }) + items, err := setup.DB.ListMediaItemsByLibrary(ctx, pgtype.UUID{Bytes: parsedLibraryID, Valid: true}) require.NoError(t, err) item := items[0]