From 6c610465eb1ac3801e79d774c4d469df8318914b Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Tue, 10 Feb 2026 13:01:12 -0500 Subject: [PATCH] refactor(tests): Update all test files to use TestServerSetup pattern --- cmd/server/tests/analytics_test.go | 155 ++++++++++--------- cmd/server/tests/book_matching_test.go | 179 +++++++++------------- cmd/server/tests/collections_bulk_test.go | 91 +++++------ cmd/server/tests/conflicts_bulk_test.go | 108 ++++++------- cmd/server/tests/device_cap_test.go | 66 ++++---- cmd/server/tests/device_test.go | 23 ++- cmd/server/tests/goroutine_leak_test.go | 3 +- cmd/server/tests/kobo_test.go | 42 ++--- cmd/server/tests/media_bulk_test.go | 92 +++++------ cmd/server/tests/media_item_isbn_test.go | 55 +++---- cmd/server/tests/opds_test.go | 141 ++++++++--------- cmd/server/tests/queue_test.go | 43 +++--- cmd/server/tests/refresh_token_test.go | 72 ++++----- cmd/server/tests/websocket_test.go | 22 +-- 14 files changed, 484 insertions(+), 608 deletions(-) diff --git a/cmd/server/tests/analytics_test.go b/cmd/server/tests/analytics_test.go index fb5c6f2..2afb1a4 100644 --- a/cmd/server/tests/analytics_test.go +++ b/cmd/server/tests/analytics_test.go @@ -14,10 +14,9 @@ import ( // TestAnalyticsReadingStats tests the reading statistics endpoint func TestAnalyticsReadingStats(t *testing.T) { t.Run("GetReadingStats_WithoutAuth", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - req, _ := http.NewRequest("GET", ts.URL+"/api/analytics/reading-stats", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/analytics/reading-stats", nil) client := &http.Client{} resp, err := client.Do(req) require.NoError(t, err) @@ -27,12 +26,33 @@ func TestAnalyticsReadingStats(t *testing.T) { }) t.Run("GetReadingStats_WithAuth_DefaultDates", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) - req, _ := http.NewRequest("GET", ts.URL+"/api/analytics/reading-stats", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/analytics/reading-stats", nil) + req.Header.Set("Authorization", "Bearer "+token) + client := &http.Client{} + resp, err := client.Do(req) + require.NoError(t, err) + defer resp.Body.Close() + + assert.Equal(t, http.StatusOK, resp.StatusCode) + + var result map[string]interface{} + json.NewDecoder(resp.Body).Decode(&result) + assert.Contains(t, result, "total_books") + assert.Contains(t, result, "total_reading_time") + assert.Contains(t, result, "completion_rate") + assert.Contains(t, result, "daily_reading_minutes") + }) + + t.Run("GetReadingStats_WithAuth_DefaultDates", func(t *testing.T) { + setup := setupTestServer(t) + + token := loginTestUser(t, setup.Server, setup.DB) + + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/analytics/reading-stats", nil) req.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(req) @@ -53,15 +73,14 @@ func TestAnalyticsReadingStats(t *testing.T) { }) t.Run("GetReadingStats_WithCustomDateRange", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) startDate := time.Now().AddDate(0, -2, 0).Format("2006-01-02") endDate := time.Now().Format("2006-01-02") - req, _ := http.NewRequest("GET", ts.URL+"/api/analytics/reading-stats?start_date="+startDate+"&end_date="+endDate, nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/analytics/reading-stats?start_date="+startDate+"&end_date="+endDate, nil) req.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(req) @@ -72,12 +91,11 @@ func TestAnalyticsReadingStats(t *testing.T) { }) t.Run("GetReadingStats_InvalidStartDate", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) - req, _ := http.NewRequest("GET", ts.URL+"/api/analytics/reading-stats?start_date=invalid-date", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/analytics/reading-stats?start_date=invalid-date", nil) req.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(req) @@ -88,12 +106,11 @@ func TestAnalyticsReadingStats(t *testing.T) { }) t.Run("GetReadingStats_InvalidEndDate", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) - req, _ := http.NewRequest("GET", ts.URL+"/api/analytics/reading-stats?end_date=not-a-date", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/analytics/reading-stats?end_date=not-a-date", nil) req.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(req) @@ -104,12 +121,11 @@ func TestAnalyticsReadingStats(t *testing.T) { }) t.Run("GetReadingStats_EmptyHistory", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) - req, _ := http.NewRequest("GET", ts.URL+"/api/analytics/reading-stats", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/analytics/reading-stats", nil) req.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(req) @@ -130,10 +146,9 @@ func TestAnalyticsReadingStats(t *testing.T) { // TestAnalyticsDeviceUsage tests the device usage endpoint func TestAnalyticsDeviceUsage(t *testing.T) { t.Run("GetDeviceUsage_WithoutAuth", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - req, _ := http.NewRequest("GET", ts.URL+"/api/analytics/device-usage", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/analytics/device-usage", nil) client := &http.Client{} resp, err := client.Do(req) require.NoError(t, err) @@ -143,12 +158,11 @@ func TestAnalyticsDeviceUsage(t *testing.T) { }) t.Run("GetDeviceUsage_WithAuth_NoDevices", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) - req, _ := http.NewRequest("GET", ts.URL+"/api/analytics/device-usage", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/analytics/device-usage", nil) req.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(req) @@ -166,10 +180,9 @@ func TestAnalyticsDeviceUsage(t *testing.T) { }) t.Run("GetDeviceUsage_WithAuth_WithDevices", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) // First create a device deviceReq := map[string]interface{}{ @@ -178,7 +191,7 @@ func TestAnalyticsDeviceUsage(t *testing.T) { } deviceBody, _ := json.Marshal(deviceReq) - deviceReqHTTP, _ := http.NewRequest("POST", ts.URL+"/api/devices/register", bytes.NewBuffer(deviceBody)) + deviceReqHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/devices/register", bytes.NewBuffer(deviceBody)) deviceReqHTTP.Header.Set("Content-Type", "application/json") deviceReqHTTP.Header.Set("Authorization", "Bearer "+token) @@ -188,7 +201,7 @@ func TestAnalyticsDeviceUsage(t *testing.T) { resp.Body.Close() // Now get device usage - req, _ := http.NewRequest("GET", ts.URL+"/api/analytics/device-usage", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/analytics/device-usage", nil) req.Header.Set("Authorization", "Bearer "+token) resp, err = client.Do(req) require.NoError(t, err) @@ -206,12 +219,11 @@ func TestAnalyticsDeviceUsage(t *testing.T) { }) t.Run("GetDeviceUsage_ResponseStructure", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) - req, _ := http.NewRequest("GET", ts.URL+"/api/analytics/device-usage", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/analytics/device-usage", nil) req.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(req) @@ -242,10 +254,9 @@ func TestAnalyticsDeviceUsage(t *testing.T) { // TestAnalyticsPopularBooks tests the popular books endpoint func TestAnalyticsPopularBooks(t *testing.T) { t.Run("GetPopularBooks_WithoutAuth", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - req, _ := http.NewRequest("GET", ts.URL+"/api/analytics/popular-books", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/analytics/popular-books", nil) client := &http.Client{} resp, err := client.Do(req) require.NoError(t, err) @@ -255,12 +266,11 @@ func TestAnalyticsPopularBooks(t *testing.T) { }) t.Run("GetPopularBooks_WithAuth_DefaultLimit", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) - req, _ := http.NewRequest("GET", ts.URL+"/api/analytics/popular-books", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/analytics/popular-books", nil) req.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(req) @@ -280,12 +290,11 @@ func TestAnalyticsPopularBooks(t *testing.T) { }) t.Run("GetPopularBooks_WithCustomLimit", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) - req, _ := http.NewRequest("GET", ts.URL+"/api/analytics/popular-books?limit=5", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/analytics/popular-books?limit=5", nil) req.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(req) @@ -302,12 +311,11 @@ func TestAnalyticsPopularBooks(t *testing.T) { }) t.Run("GetPopularBooks_InvalidLimit", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) - req, _ := http.NewRequest("GET", ts.URL+"/api/analytics/popular-books?limit=invalid", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/analytics/popular-books?limit=invalid", nil) req.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(req) @@ -325,13 +333,12 @@ func TestAnalyticsPopularBooks(t *testing.T) { }) t.Run("GetPopularBooks_ResponseStructure", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) // First create a book and some reading history - bookID := createTestMediaItemID(t, ts, token) + bookID := createTestMediaItemID(t, setup.Server, token) // Create reading history for the book historyReq := map[string]interface{}{ @@ -342,7 +349,7 @@ func TestAnalyticsPopularBooks(t *testing.T) { } historyBody, _ := json.Marshal(historyReq) - historyHTTP, _ := http.NewRequest("POST", ts.URL+"/api/media-items/"+bookID+"/progress", bytes.NewBuffer(historyBody)) + historyHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/media-items/"+bookID+"/progress", bytes.NewBuffer(historyBody)) historyHTTP.Header.Set("Content-Type", "application/json") historyHTTP.Header.Set("Authorization", "Bearer "+token) @@ -352,7 +359,7 @@ func TestAnalyticsPopularBooks(t *testing.T) { resp.Body.Close() // Now get popular books - req, _ := http.NewRequest("GET", ts.URL+"/api/analytics/popular-books", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/analytics/popular-books", nil) req.Header.Set("Authorization", "Bearer "+token) resp, err = client.Do(req) require.NoError(t, err) @@ -378,12 +385,11 @@ func TestAnalyticsPopularBooks(t *testing.T) { }) t.Run("GetPopularBooks_NoReadingHistory", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) - req, _ := http.NewRequest("GET", ts.URL+"/api/analytics/popular-books", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/analytics/popular-books", nil) req.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(req) @@ -404,15 +410,14 @@ func TestAnalyticsPopularBooks(t *testing.T) { // TestAnalyticsEdgeCases tests edge cases for analytics endpoints func TestAnalyticsEdgeCases(t *testing.T) { t.Run("ReadingStats_FutureDateRange", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) startDate := time.Now().AddDate(0, 0, 7).Format("2006-01-02") endDate := time.Now().AddDate(0, 0, 14).Format("2006-01-02") - req, _ := http.NewRequest("GET", ts.URL+"/api/analytics/reading-stats?start_date="+startDate+"&end_date="+endDate, nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/analytics/reading-stats?start_date="+startDate+"&end_date="+endDate, nil) req.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(req) @@ -429,12 +434,11 @@ func TestAnalyticsEdgeCases(t *testing.T) { }) t.Run("PopularBooks_LimitZero", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) - req, _ := http.NewRequest("GET", ts.URL+"/api/analytics/popular-books?limit=0", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/analytics/popular-books?limit=0", nil) req.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(req) @@ -452,12 +456,11 @@ func TestAnalyticsEdgeCases(t *testing.T) { }) t.Run("PopularBooks_VeryLargeLimit", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) - req, _ := http.NewRequest("GET", ts.URL+"/api/analytics/popular-books?limit=999999", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/analytics/popular-books?limit=999999", nil) req.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(req) diff --git a/cmd/server/tests/book_matching_test.go b/cmd/server/tests/book_matching_test.go index 3fa0622..07946e2 100644 --- a/cmd/server/tests/book_matching_test.go +++ b/cmd/server/tests/book_matching_test.go @@ -14,15 +14,14 @@ import ( // TestBookMatchingQueryBooks tests the book query endpoint func TestBookMatchingQueryBooks(t *testing.T) { t.Run("QueryBooks_WithoutAuth", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) req := map[string]interface{}{ "title": "Test Book", } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/sync/books/query", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/sync/books/query", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -34,18 +33,17 @@ func TestBookMatchingQueryBooks(t *testing.T) { }) t.Run("QueryBooks_WithAuth_ByTitle", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) - _ = createTestMediaItemID(t, ts, token) + token := loginTestUser(t, setup.Server, setup.DB) + _ = createTestMediaItemID(t, setup.Server, token) req := map[string]interface{}{ "title": "Test Ebook", } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/sync/books/query", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/sync/books/query", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -64,13 +62,12 @@ func TestBookMatchingQueryBooks(t *testing.T) { }) t.Run("QueryBooks_InvalidRequestBody", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) // Send invalid JSON - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/sync/books/query", bytes.NewBuffer([]byte("invalid json"))) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/sync/books/query", bytes.NewBuffer([]byte("invalid json"))) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -83,17 +80,16 @@ func TestBookMatchingQueryBooks(t *testing.T) { }) t.Run("QueryBooks_NoResults", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "title": "NonExistentBookTitleThatDoesNotExist123456789", } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/sync/books/query", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/sync/books/query", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -120,8 +116,7 @@ func TestBookMatchingQueryBooks(t *testing.T) { // TestBookMatchingBulkLink tests bulk linking operations func TestBookMatchingBulkLink(t *testing.T) { t.Run("BulkLinkBooks_WithoutAuth", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) req := map[string]interface{}{ "links": []map[string]interface{}{ @@ -134,7 +129,7 @@ func TestBookMatchingBulkLink(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/sync/bulk-link-books", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/sync/bulk-link-books", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -146,17 +141,16 @@ func TestBookMatchingBulkLink(t *testing.T) { }) t.Run("BulkLinkBooks_WithAuth_EmptyLinks", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "links": []map[string]interface{}{}, } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/sync/bulk-link-books", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/sync/bulk-link-books", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -176,11 +170,10 @@ func TestBookMatchingBulkLink(t *testing.T) { }) t.Run("BulkLinkBooks_InvalidUnlinkedBookID", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) - bookID := createTestMediaItemID(t, ts, token) + token := loginTestUser(t, setup.Server, setup.DB) + bookID := createTestMediaItemID(t, setup.Server, token) req := map[string]interface{}{ "links": []map[string]interface{}{ @@ -193,7 +186,7 @@ func TestBookMatchingBulkLink(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/sync/bulk-link-books", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/sync/bulk-link-books", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -218,10 +211,9 @@ func TestBookMatchingBulkLink(t *testing.T) { }) t.Run("BulkLinkBooks_MultipleLinks", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "links": []map[string]interface{}{ @@ -244,7 +236,7 @@ func TestBookMatchingBulkLink(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/sync/bulk-link-books", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/sync/bulk-link-books", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -267,8 +259,7 @@ func TestBookMatchingBulkLink(t *testing.T) { // TestBookMatchingAutoLink tests automatic linking func TestBookMatchingAutoLink(t *testing.T) { t.Run("AutoLinkBooks_WithoutAuth", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) req := map[string]interface{}{ "confidence_threshold": 0.8, @@ -276,7 +267,7 @@ func TestBookMatchingAutoLink(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/sync/auto-link-books", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/sync/auto-link-books", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -288,15 +279,14 @@ func TestBookMatchingAutoLink(t *testing.T) { }) t.Run("AutoLinkBooks_WithAuth_DefaultThreshold", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{} body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/sync/auto-link-books", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/sync/auto-link-books", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -315,10 +305,9 @@ func TestBookMatchingAutoLink(t *testing.T) { }) t.Run("AutoLinkBooks_CustomThreshold", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "confidence_threshold": 0.95, @@ -326,7 +315,7 @@ func TestBookMatchingAutoLink(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/sync/auto-link-books", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/sync/auto-link-books", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -344,17 +333,16 @@ func TestBookMatchingAutoLink(t *testing.T) { }) t.Run("AutoLinkBooks_NoUnlinkedBooks", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "limit": 5, } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/sync/auto-link-books", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/sync/auto-link-books", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -376,11 +364,10 @@ func TestBookMatchingAutoLink(t *testing.T) { // TestBookMatchingSuggestions tests getting suggestions for unlinked books func TestBookMatchingSuggestions(t *testing.T) { t.Run("GetUnlinkedBookSuggestions_WithoutAuth", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) testID := uuid.New() - httpReq, _ := http.NewRequest("GET", ts.URL+"/api/sync/unlinked-books/"+testID.String()+"/suggestions", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/api/sync/unlinked-books/"+testID.String()+"/suggestions", nil) client := &http.Client{} resp, err := client.Do(httpReq) @@ -391,12 +378,11 @@ func TestBookMatchingSuggestions(t *testing.T) { }) t.Run("GetUnlinkedBookSuggestions_InvalidUUID", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) - httpReq, _ := http.NewRequest("GET", ts.URL+"/api/sync/unlinked-books/invalid-uuid/suggestions", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/api/sync/unlinked-books/invalid-uuid/suggestions", nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -408,13 +394,12 @@ func TestBookMatchingSuggestions(t *testing.T) { }) t.Run("GetUnlinkedBookSuggestions_BookNotFound", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) testID := uuid.New() - httpReq, _ := http.NewRequest("GET", ts.URL+"/api/sync/unlinked-books/"+testID.String()+"/suggestions", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/api/sync/unlinked-books/"+testID.String()+"/suggestions", nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -426,15 +411,14 @@ func TestBookMatchingSuggestions(t *testing.T) { }) t.Run("GetUnlinkedBookSuggestions_ResponseStructure", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) // Create a test device and unlinked book would go here // For now, test with a non-existent ID to check response structure testID := uuid.New() - httpReq, _ := http.NewRequest("GET", ts.URL+"/api/sync/unlinked-books/"+testID.String()+"/suggestions", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/api/sync/unlinked-books/"+testID.String()+"/suggestions", nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -450,11 +434,10 @@ func TestBookMatchingSuggestions(t *testing.T) { // TestBookMatchingDeviceFileAliases tests device file alias operations func TestBookMatchingDeviceFileAliases(t *testing.T) { t.Run("GetDeviceFileAliases_WithoutAuth", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) testID := uuid.New() - httpReq, _ := http.NewRequest("GET", ts.URL+"/api/devices/"+testID.String()+"/file-aliases", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/api/devices/"+testID.String()+"/file-aliases", nil) client := &http.Client{} resp, err := client.Do(httpReq) @@ -465,13 +448,12 @@ func TestBookMatchingDeviceFileAliases(t *testing.T) { }) t.Run("GetDeviceFileAliases_WithAuth", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) testID := uuid.New() - httpReq, _ := http.NewRequest("GET", ts.URL+"/api/devices/"+testID.String()+"/file-aliases", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/api/devices/"+testID.String()+"/file-aliases", nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -490,8 +472,7 @@ func TestBookMatchingDeviceFileAliases(t *testing.T) { }) t.Run("CreateDeviceFileAlias_WithoutAuth", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) deviceID := uuid.New() mediaItemID := uuid.New() @@ -504,7 +485,7 @@ func TestBookMatchingDeviceFileAliases(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/devices/"+deviceID.String()+"/file-aliases", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/devices/"+deviceID.String()+"/file-aliases", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -516,10 +497,9 @@ func TestBookMatchingDeviceFileAliases(t *testing.T) { }) t.Run("CreateDeviceFileAlias_InvalidDeviceID", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) mediaItemID := uuid.New() @@ -531,7 +511,7 @@ func TestBookMatchingDeviceFileAliases(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/devices/invalid-uuid/file-aliases", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/devices/invalid-uuid/file-aliases", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -544,10 +524,9 @@ func TestBookMatchingDeviceFileAliases(t *testing.T) { }) t.Run("CreateDeviceFileAlias_InvalidMediaItemID", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) deviceID := uuid.New() @@ -559,7 +538,7 @@ func TestBookMatchingDeviceFileAliases(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/devices/"+deviceID.String()+"/file-aliases", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/devices/"+deviceID.String()+"/file-aliases", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -572,10 +551,9 @@ func TestBookMatchingDeviceFileAliases(t *testing.T) { }) t.Run("UpdateDeviceFileAlias_InvalidAliasID", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) deviceID := uuid.New() @@ -584,7 +562,7 @@ func TestBookMatchingDeviceFileAliases(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("PUT", ts.URL+"/api/devices/"+deviceID.String()+"/file-aliases/invalid-uuid", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("PUT", setup.Server.URL+"/api/devices/"+deviceID.String()+"/file-aliases/invalid-uuid", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -597,14 +575,13 @@ func TestBookMatchingDeviceFileAliases(t *testing.T) { }) t.Run("DeleteDeviceFileAlias_InvalidAliasID", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) deviceID := uuid.New() - httpReq, _ := http.NewRequest("DELETE", ts.URL+"/api/devices/"+deviceID.String()+"/file-aliases/invalid-uuid", nil) + httpReq, _ := http.NewRequest("DELETE", setup.Server.URL+"/api/devices/"+deviceID.String()+"/file-aliases/invalid-uuid", nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -619,10 +596,9 @@ func TestBookMatchingDeviceFileAliases(t *testing.T) { // TestBookMatchingGetBookMatches tests the book matches endpoint func TestBookMatchingGetBookMatches(t *testing.T) { t.Run("GetBookMatches_WithoutAuth", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - httpReq, _ := http.NewRequest("GET", ts.URL+"/api/books/match?title=Test", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/api/books/match?title=Test", nil) client := &http.Client{} resp, err := client.Do(httpReq) @@ -633,12 +609,11 @@ func TestBookMatchingGetBookMatches(t *testing.T) { }) t.Run("GetBookMatches_WithAuth_ByTitle", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) - httpReq, _ := http.NewRequest("GET", ts.URL+"/api/books/match?title=Test", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/api/books/match?title=Test", nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -656,12 +631,11 @@ func TestBookMatchingGetBookMatches(t *testing.T) { }) t.Run("GetBookMatches_InvalidFileSize", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) - httpReq, _ := http.NewRequest("GET", ts.URL+"/api/books/match?title=Test&file_size=invalid", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/api/books/match?title=Test&file_size=invalid", nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -673,12 +647,11 @@ func TestBookMatchingGetBookMatches(t *testing.T) { }) t.Run("GetBookMatches_MultipleIdentifiers", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) - httpReq, _ := http.NewRequest("GET", ts.URL+"/api/books/match?identifier=id1&identifier=id2&title=Test", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/api/books/match?identifier=id1&identifier=id2&title=Test", nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} diff --git a/cmd/server/tests/collections_bulk_test.go b/cmd/server/tests/collections_bulk_test.go index e007be5..346320f 100644 --- a/cmd/server/tests/collections_bulk_test.go +++ b/cmd/server/tests/collections_bulk_test.go @@ -14,8 +14,7 @@ import ( // TestCollectionsBulkOperations tests bulk collection operations func TestCollectionsBulkOperations(t *testing.T) { t.Run("BulkAddBooks_WithoutAuth", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) req := map[string]interface{}{ "operations": []map[string]interface{}{ @@ -27,7 +26,7 @@ func TestCollectionsBulkOperations(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/collections/bulk-add-books", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/collections/bulk-add-books", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -39,17 +38,16 @@ func TestCollectionsBulkOperations(t *testing.T) { }) t.Run("BulkAddBooks_EmptyOperations", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "operations": []map[string]interface{}{}, } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/collections/bulk-add-books", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/collections/bulk-add-books", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -62,11 +60,10 @@ func TestCollectionsBulkOperations(t *testing.T) { }) t.Run("BulkAddBooks_InvalidCollectionID", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) - bookID := createTestMediaItemID(t, ts, token) + token := loginTestUser(t, setup.Server, setup.DB) + bookID := createTestMediaItemID(t, setup.Server, token) req := map[string]interface{}{ "operations": []map[string]interface{}{ @@ -78,7 +75,7 @@ func TestCollectionsBulkOperations(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/collections/bulk-add-books", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/collections/bulk-add-books", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -105,10 +102,9 @@ func TestCollectionsBulkOperations(t *testing.T) { }) t.Run("BulkAddBooks_InvalidBookID", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) // Create a collection first collectionReq := map[string]interface{}{ @@ -117,7 +113,7 @@ func TestCollectionsBulkOperations(t *testing.T) { } collectionBody, _ := json.Marshal(collectionReq) - collectionHTTP, _ := http.NewRequest("POST", ts.URL+"/api/collections", bytes.NewBuffer(collectionBody)) + collectionHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/collections", bytes.NewBuffer(collectionBody)) collectionHTTP.Header.Set("Content-Type", "application/json") collectionHTTP.Header.Set("Authorization", "Bearer "+token) @@ -141,7 +137,7 @@ func TestCollectionsBulkOperations(t *testing.T) { } addBody, _ := json.Marshal(addReq) - addHTTP, _ := http.NewRequest("POST", ts.URL+"/api/collections/bulk-add-books", bytes.NewBuffer(addBody)) + addHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/collections/bulk-add-books", bytes.NewBuffer(addBody)) addHTTP.Header.Set("Content-Type", "application/json") addHTTP.Header.Set("Authorization", "Bearer "+token) @@ -160,10 +156,9 @@ func TestCollectionsBulkOperations(t *testing.T) { }) t.Run("BulkAddBooks_SingleOperation", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) // Create a collection collectionReq := map[string]interface{}{ @@ -172,7 +167,7 @@ func TestCollectionsBulkOperations(t *testing.T) { } collectionBody, _ := json.Marshal(collectionReq) - collectionHTTP, _ := http.NewRequest("POST", ts.URL+"/api/collections", bytes.NewBuffer(collectionBody)) + collectionHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/collections", bytes.NewBuffer(collectionBody)) collectionHTTP.Header.Set("Content-Type", "application/json") collectionHTTP.Header.Set("Authorization", "Bearer "+token) @@ -186,7 +181,7 @@ func TestCollectionsBulkOperations(t *testing.T) { collectionID := collectionResult["id"].(string) // Create a book - bookID := createTestMediaItemID(t, ts, token) + bookID := createTestMediaItemID(t, setup.Server, token) // Add book to collection addReq := map[string]interface{}{ @@ -199,7 +194,7 @@ func TestCollectionsBulkOperations(t *testing.T) { } addBody, _ := json.Marshal(addReq) - addHTTP, _ := http.NewRequest("POST", ts.URL+"/api/collections/bulk-add-books", bytes.NewBuffer(addBody)) + addHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/collections/bulk-add-books", bytes.NewBuffer(addBody)) addHTTP.Header.Set("Content-Type", "application/json") addHTTP.Header.Set("Authorization", "Bearer "+token) @@ -223,10 +218,9 @@ func TestCollectionsBulkOperations(t *testing.T) { }) t.Run("BulkAddBooks_MultipleBooksSingleCollection", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) // Create a collection collectionReq := map[string]interface{}{ @@ -235,7 +229,7 @@ func TestCollectionsBulkOperations(t *testing.T) { } collectionBody, _ := json.Marshal(collectionReq) - collectionHTTP, _ := http.NewRequest("POST", ts.URL+"/api/collections", bytes.NewBuffer(collectionBody)) + collectionHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/collections", bytes.NewBuffer(collectionBody)) collectionHTTP.Header.Set("Content-Type", "application/json") collectionHTTP.Header.Set("Authorization", "Bearer "+token) @@ -249,9 +243,9 @@ func TestCollectionsBulkOperations(t *testing.T) { collectionID := collectionResult["id"].(string) // Create multiple books - bookID1 := createTestMediaItemID(t, ts, token) - bookID2 := createTestMediaItemID(t, ts, token) - bookID3 := createTestMediaItemID(t, ts, token) + bookID1 := createTestMediaItemID(t, setup.Server, token) + bookID2 := createTestMediaItemID(t, setup.Server, token) + bookID3 := createTestMediaItemID(t, setup.Server, token) // Add all books to collection addReq := map[string]interface{}{ @@ -264,7 +258,7 @@ func TestCollectionsBulkOperations(t *testing.T) { } addBody, _ := json.Marshal(addReq) - addHTTP, _ := http.NewRequest("POST", ts.URL+"/api/collections/bulk-add-books", bytes.NewBuffer(addBody)) + addHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/collections/bulk-add-books", bytes.NewBuffer(addBody)) addHTTP.Header.Set("Content-Type", "application/json") addHTTP.Header.Set("Authorization", "Bearer "+token) @@ -282,10 +276,9 @@ func TestCollectionsBulkOperations(t *testing.T) { }) t.Run("BulkAddBooks_MultipleCollections", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) // Create multiple collections collectionReq := map[string]interface{}{ @@ -294,7 +287,7 @@ func TestCollectionsBulkOperations(t *testing.T) { } collectionBody, _ := json.Marshal(collectionReq) - collectionHTTP, _ := http.NewRequest("POST", ts.URL+"/api/collections", bytes.NewBuffer(collectionBody)) + collectionHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/collections", bytes.NewBuffer(collectionBody)) collectionHTTP.Header.Set("Content-Type", "application/json") collectionHTTP.Header.Set("Authorization", "Bearer "+token) @@ -313,7 +306,7 @@ func TestCollectionsBulkOperations(t *testing.T) { } collectionBody2, _ := json.Marshal(collectionReq2) - collectionHTTP2, _ := http.NewRequest("POST", ts.URL+"/api/collections", bytes.NewBuffer(collectionBody2)) + collectionHTTP2, _ := http.NewRequest("POST", setup.Server.URL+"/api/collections", bytes.NewBuffer(collectionBody2)) collectionHTTP2.Header.Set("Content-Type", "application/json") collectionHTTP2.Header.Set("Authorization", "Bearer "+token) @@ -326,8 +319,8 @@ func TestCollectionsBulkOperations(t *testing.T) { collectionID2 := collectionResult2["id"].(string) // Create books - bookID1 := createTestMediaItemID(t, ts, token) - bookID2 := createTestMediaItemID(t, ts, token) + bookID1 := createTestMediaItemID(t, setup.Server, token) + bookID2 := createTestMediaItemID(t, setup.Server, token) // Add books to multiple collections addReq := map[string]interface{}{ @@ -344,7 +337,7 @@ func TestCollectionsBulkOperations(t *testing.T) { } addBody, _ := json.Marshal(addReq) - addHTTP, _ := http.NewRequest("POST", ts.URL+"/api/collections/bulk-add-books", bytes.NewBuffer(addBody)) + addHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/collections/bulk-add-books", bytes.NewBuffer(addBody)) addHTTP.Header.Set("Content-Type", "application/json") addHTTP.Header.Set("Authorization", "Bearer "+token) @@ -362,10 +355,9 @@ func TestCollectionsBulkOperations(t *testing.T) { }) t.Run("BulkAddBooks_DuplicateBooks", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) // Create a collection collectionReq := map[string]interface{}{ @@ -374,7 +366,7 @@ func TestCollectionsBulkOperations(t *testing.T) { } collectionBody, _ := json.Marshal(collectionReq) - collectionHTTP, _ := http.NewRequest("POST", ts.URL+"/api/collections", bytes.NewBuffer(collectionBody)) + collectionHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/collections", bytes.NewBuffer(collectionBody)) collectionHTTP.Header.Set("Content-Type", "application/json") collectionHTTP.Header.Set("Authorization", "Bearer "+token) @@ -388,7 +380,7 @@ func TestCollectionsBulkOperations(t *testing.T) { collectionID := collectionResult["id"].(string) // Create a book - bookID := createTestMediaItemID(t, ts, token) + bookID := createTestMediaItemID(t, setup.Server, token) // Add book to collection addReq := map[string]interface{}{ @@ -401,7 +393,7 @@ func TestCollectionsBulkOperations(t *testing.T) { } addBody, _ := json.Marshal(addReq) - addHTTP, _ := http.NewRequest("POST", ts.URL+"/api/collections/bulk-add-books", bytes.NewBuffer(addBody)) + addHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/collections/bulk-add-books", bytes.NewBuffer(addBody)) addHTTP.Header.Set("Content-Type", "application/json") addHTTP.Header.Set("Authorization", "Bearer "+token) @@ -411,7 +403,7 @@ func TestCollectionsBulkOperations(t *testing.T) { // Try to add the same book again - create new request with fresh body addBody2, _ := json.Marshal(addReq) - addHTTP2, _ := http.NewRequest("POST", ts.URL+"/api/collections/bulk-add-books", bytes.NewBuffer(addBody2)) + addHTTP2, _ := http.NewRequest("POST", setup.Server.URL+"/api/collections/bulk-add-books", bytes.NewBuffer(addBody2)) addHTTP2.Header.Set("Content-Type", "application/json") addHTTP2.Header.Set("Authorization", "Bearer "+token) @@ -424,13 +416,12 @@ func TestCollectionsBulkOperations(t *testing.T) { }) t.Run("BulkAddBooks_InvalidRequestBody", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) // Send invalid JSON - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/collections/bulk-add-books", bytes.NewBuffer([]byte("invalid json"))) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/collections/bulk-add-books", bytes.NewBuffer([]byte("invalid json"))) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) diff --git a/cmd/server/tests/conflicts_bulk_test.go b/cmd/server/tests/conflicts_bulk_test.go index eb72d96..ad9689e 100644 --- a/cmd/server/tests/conflicts_bulk_test.go +++ b/cmd/server/tests/conflicts_bulk_test.go @@ -14,8 +14,7 @@ import ( // TestConflictsBulkOperations tests bulk conflict resolution operations func TestConflictsBulkOperations(t *testing.T) { t.Run("BulkResolveConflicts_WithoutAuth", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) req := map[string]interface{}{ "conflict_ids": []string{uuid.New().String()}, @@ -23,7 +22,7 @@ func TestConflictsBulkOperations(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/conflicts/bulk-resolve", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/conflicts/bulk-resolve", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -35,10 +34,9 @@ func TestConflictsBulkOperations(t *testing.T) { }) t.Run("BulkResolveConflicts_EmptyConflictIDs", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "conflict_ids": []string{}, @@ -46,7 +44,7 @@ func TestConflictsBulkOperations(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/conflicts/bulk-resolve", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/conflicts/bulk-resolve", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -59,10 +57,9 @@ func TestConflictsBulkOperations(t *testing.T) { }) t.Run("BulkResolveConflicts_InvalidConflictID", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "conflict_ids": []string{"invalid-uuid"}, @@ -70,7 +67,7 @@ func TestConflictsBulkOperations(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/conflicts/bulk-resolve", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/conflicts/bulk-resolve", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -95,10 +92,9 @@ func TestConflictsBulkOperations(t *testing.T) { }) t.Run("BulkResolveConflicts_InvalidStrategy", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "conflict_ids": []string{uuid.New().String()}, @@ -106,7 +102,7 @@ func TestConflictsBulkOperations(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/conflicts/bulk-resolve", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/conflicts/bulk-resolve", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -134,10 +130,9 @@ func TestConflictsBulkOperations(t *testing.T) { }) t.Run("BulkResolveConflicts_MostRecentStrategy", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "conflict_ids": []string{uuid.New().String(), uuid.New().String()}, @@ -145,7 +140,7 @@ func TestConflictsBulkOperations(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/conflicts/bulk-resolve", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/conflicts/bulk-resolve", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -164,10 +159,9 @@ func TestConflictsBulkOperations(t *testing.T) { }) t.Run("BulkResolveConflicts_HighestProgressStrategy", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "conflict_ids": []string{uuid.New().String(), uuid.New().String()}, @@ -175,7 +169,7 @@ func TestConflictsBulkOperations(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/conflicts/bulk-resolve", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/conflicts/bulk-resolve", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -194,10 +188,9 @@ func TestConflictsBulkOperations(t *testing.T) { }) t.Run("BulkResolveConflicts_ManualStrategy_WithoutWinner", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "conflict_ids": []string{uuid.New().String()}, @@ -205,7 +198,7 @@ func TestConflictsBulkOperations(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/conflicts/bulk-resolve", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/conflicts/bulk-resolve", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -223,10 +216,9 @@ func TestConflictsBulkOperations(t *testing.T) { }) t.Run("BulkResolveConflicts_ManualStrategy_WithWinner", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "conflict_ids": []string{uuid.New().String()}, @@ -235,7 +227,7 @@ func TestConflictsBulkOperations(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/conflicts/bulk-resolve", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/conflicts/bulk-resolve", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -248,13 +240,12 @@ func TestConflictsBulkOperations(t *testing.T) { }) t.Run("BulkResolveConflicts_InvalidRequestBody", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) // Send invalid JSON - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/conflicts/bulk-resolve", bytes.NewBuffer([]byte("invalid json"))) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/conflicts/bulk-resolve", bytes.NewBuffer([]byte("invalid json"))) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -270,15 +261,14 @@ func TestConflictsBulkOperations(t *testing.T) { // TestConflictsBulkDismiss tests bulk dismiss operations func TestConflictsBulkDismiss(t *testing.T) { t.Run("BulkDismissConflicts_WithoutAuth", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) req := map[string]interface{}{ "conflict_ids": []string{uuid.New().String()}, } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/conflicts/bulk-dismiss", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/conflicts/bulk-dismiss", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -290,17 +280,16 @@ func TestConflictsBulkDismiss(t *testing.T) { }) t.Run("BulkDismissConflicts_EmptyConflictIDs", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "conflict_ids": []string{}, } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/conflicts/bulk-dismiss", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/conflicts/bulk-dismiss", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -313,17 +302,16 @@ func TestConflictsBulkDismiss(t *testing.T) { }) t.Run("BulkDismissConflicts_InvalidConflictID", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "conflict_ids": []string{"invalid-uuid", uuid.New().String()}, } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/conflicts/bulk-dismiss", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/conflicts/bulk-dismiss", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -348,10 +336,9 @@ func TestConflictsBulkDismiss(t *testing.T) { }) t.Run("BulkDismissConflicts_MultipleConflicts", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "conflict_ids": []string{ @@ -362,7 +349,7 @@ func TestConflictsBulkDismiss(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/conflicts/bulk-dismiss", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/conflicts/bulk-dismiss", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -381,13 +368,12 @@ func TestConflictsBulkDismiss(t *testing.T) { }) t.Run("BulkDismissConflicts_InvalidRequestBody", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) // Send invalid JSON - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/conflicts/bulk-dismiss", bytes.NewBuffer([]byte("invalid json"))) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/conflicts/bulk-dismiss", bytes.NewBuffer([]byte("invalid json"))) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -403,10 +389,9 @@ func TestConflictsBulkDismiss(t *testing.T) { // TestConflictsBulkEdgeCases tests edge cases for bulk operations func TestConflictsBulkEdgeCases(t *testing.T) { t.Run("BulkResolve_NonExistentConflicts", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "conflict_ids": []string{ @@ -418,7 +403,7 @@ func TestConflictsBulkEdgeCases(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/conflicts/bulk-resolve", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/conflicts/bulk-resolve", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -438,10 +423,9 @@ func TestConflictsBulkEdgeCases(t *testing.T) { }) t.Run("BulkDismiss_MixedValidInvalid", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "conflict_ids": []string{ @@ -452,7 +436,7 @@ func TestConflictsBulkEdgeCases(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/conflicts/bulk-dismiss", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/conflicts/bulk-dismiss", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) diff --git a/cmd/server/tests/device_cap_test.go b/cmd/server/tests/device_cap_test.go index 4fa118a..921c1c0 100644 --- a/cmd/server/tests/device_cap_test.go +++ b/cmd/server/tests/device_cap_test.go @@ -16,12 +16,11 @@ import ( // TestUpdateUserMaxDevices tests the admin endpoint for updating user device cap func TestUpdateUserMaxDevices(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) // Create test user with admin role - loginTestUser(t, ts, db) - adminUserID := getTestUserID(t, db) + loginTestUser(t, setup.Server, setup.DB) + adminUserID := getTestUserID(t, setup.DB) adminToken := getAdminToken(t, ts, adminUserID) // Create a test user @@ -66,7 +65,7 @@ func TestUpdateUserMaxDevices(t *testing.T) { } jsonData, _ := json.Marshal(payload) - req, _ := http.NewRequest("PUT", ts.URL+"/api/auth/users/"+userID.String()+"/max-devices", bytes.NewBuffer(jsonData)) + req, _ := http.NewRequest("PUT", setup.Server.URL+"/api/auth/users/"+userID.String()+"/max-devices", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+adminToken) @@ -87,13 +86,12 @@ func TestUpdateUserMaxDevices(t *testing.T) { // TestUpdateUserMaxDevicesValidation tests validation of max_devices parameter func TestUpdateUserMaxDevicesValidation(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) // Create admin user and get token - adminToken := loginTestUser(t, ts, db) + adminToken := loginTestUser(t, setup.Server, setup.DB) createAdminUser(t, ts, adminToken) - adminUserID := getTestUserID(t, db) + adminUserID := getTestUserID(t, setup.DB) adminToken = getAdminToken(t, ts, adminUserID) // Create test user @@ -133,7 +131,7 @@ func TestUpdateUserMaxDevicesValidation(t *testing.T) { } jsonData, _ := json.Marshal(payload) - req, _ := http.NewRequest("PUT", ts.URL+"/api/auth/users/"+userID.String()+"/max-devices", bytes.NewBuffer(jsonData)) + req, _ := http.NewRequest("PUT", setup.Server.URL+"/api/auth/users/"+userID.String()+"/max-devices", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+adminToken) @@ -149,13 +147,12 @@ func TestUpdateUserMaxDevicesValidation(t *testing.T) { // TestUpdateUserMaxDevicesAuth tests authentication requirements func TestUpdateUserMaxDevicesAuth(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) // Create admin user - adminToken := loginTestUser(t, ts, db) + adminToken := loginTestUser(t, setup.Server, setup.DB) createAdminUser(t, ts, adminToken) - adminUserID := getTestUserID(t, db) + adminUserID := getTestUserID(t, setup.DB) adminToken = getAdminToken(t, ts, adminUserID) // Create regular user @@ -167,7 +164,7 @@ func TestUpdateUserMaxDevicesAuth(t *testing.T) { } jsonData, _ := json.Marshal(payload) - req, _ := http.NewRequest("PUT", ts.URL+"/api/auth/users/"+userID.String()+"/max-devices", bytes.NewBuffer(jsonData)) + req, _ := http.NewRequest("PUT", setup.Server.URL+"/api/auth/users/"+userID.String()+"/max-devices", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -190,7 +187,7 @@ func TestUpdateUserMaxDevicesAuth(t *testing.T) { } jsonData, _ := json.Marshal(payload) - req, _ := http.NewRequest("PUT", ts.URL+"/api/auth/users/"+userID.String()+"/max-devices", bytes.NewBuffer(jsonData)) + req, _ := http.NewRequest("PUT", setup.Server.URL+"/api/auth/users/"+userID.String()+"/max-devices", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+regularToken) @@ -205,13 +202,12 @@ func TestUpdateUserMaxDevicesAuth(t *testing.T) { // TestUpdateUserMaxDevicesNonExistentUser tests with non-existent user ID func TestUpdateUserMaxDevicesNonExistentUser(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) // Create admin user - adminToken := loginTestUser(t, ts, db) + adminToken := loginTestUser(t, setup.Server, setup.DB) createAdminUser(t, ts, adminToken) - adminUserID := getTestUserID(t, db) + adminUserID := getTestUserID(t, setup.DB) adminToken = getAdminToken(t, ts, adminUserID) // Use a non-existent user ID @@ -222,7 +218,7 @@ func TestUpdateUserMaxDevicesNonExistentUser(t *testing.T) { } jsonData, _ := json.Marshal(payload) - req, _ := http.NewRequest("PUT", ts.URL+"/api/auth/users/"+nonExistentUserID.String()+"/max-devices", bytes.NewBuffer(jsonData)) + req, _ := http.NewRequest("PUT", setup.Server.URL+"/api/auth/users/"+nonExistentUserID.String()+"/max-devices", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+adminToken) @@ -237,13 +233,12 @@ func TestUpdateUserMaxDevicesNonExistentUser(t *testing.T) { // TestUpdateUserMaxDevicesMissingUserID tests with missing user ID in URL func TestUpdateUserMaxDevicesMissingUserID(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) // Create admin user - adminToken := loginTestUser(t, ts, db) + adminToken := loginTestUser(t, setup.Server, setup.DB) createAdminUser(t, ts, adminToken) - adminUserID := getTestUserID(t, db) + adminUserID := getTestUserID(t, setup.DB) adminToken = getAdminToken(t, ts, adminUserID) payload := map[string]interface{}{ @@ -252,7 +247,7 @@ func TestUpdateUserMaxDevicesMissingUserID(t *testing.T) { jsonData, _ := json.Marshal(payload) // Missing user ID in URL - req, _ := http.NewRequest("PUT", ts.URL+"/api/auth/users//max-devices", bytes.NewBuffer(jsonData)) + req, _ := http.NewRequest("PUT", setup.Server.URL+"/api/auth/users//max-devices", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+adminToken) @@ -266,16 +261,15 @@ func TestUpdateUserMaxDevicesMissingUserID(t *testing.T) { // TestListUsersIncludesMaxDevices tests that List Users returns max_devices field func TestListUsersIncludesMaxDevices(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) // Create admin user - adminToken := loginTestUser(t, ts, db) + adminToken := loginTestUser(t, setup.Server, setup.DB) createAdminUser(t, ts, adminToken) - adminUserID := getTestUserID(t, db) + adminUserID := getTestUserID(t, setup.DB) adminToken = getAdminToken(t, ts, adminUserID) - req, _ := http.NewRequest("GET", ts.URL+"/api/auth/users", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/auth/users", nil) req.Header.Set("Authorization", "Bearer "+adminToken) client := &http.Client{} @@ -310,7 +304,7 @@ func createAdminUser(t *testing.T, ts *httptest.Server, token string) { } jsonData, _ := json.Marshal(createUserPayload) - req, _ := http.NewRequest("POST", ts.URL+"/api/auth/register", bytes.NewBuffer(jsonData)) + req, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/register", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+token) @@ -330,7 +324,7 @@ func createTestUserForMaxDevices(t *testing.T, ts *httptest.Server, adminToken s } jsonData, _ := json.Marshal(createUserPayload) - req, _ := http.NewRequest("POST", ts.URL+"/api/auth/register", bytes.NewBuffer(jsonData)) + req, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/register", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+adminToken) @@ -348,7 +342,7 @@ func createTestUserForMaxDevices(t *testing.T, ts *httptest.Server, adminToken s "password": "Test@Pass123!", } loginData, _ := json.Marshal(loginPayload) - loginReq, _ := http.NewRequest("POST", ts.URL+"/api/auth/login", bytes.NewBuffer(loginData)) + loginReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/login", bytes.NewBuffer(loginData)) loginReq.Header.Set("Content-Type", "application/json") loginResp, err := client.Do(loginReq) @@ -426,7 +420,7 @@ func getAdminToken(t *testing.T, ts *httptest.Server, userID uuid.UUID) string { } jsonData, _ := json.Marshal(loginPayload) - req, _ := http.NewRequest("POST", ts.URL+"/api/auth/login", bytes.NewBuffer(jsonData)) + req, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/login", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -454,7 +448,7 @@ func loginTestUserByCredentials(t *testing.T, ts *httptest.Server, email, passwo } jsonData, _ := json.Marshal(loginPayload) - req, _ := http.NewRequest("POST", ts.URL+"/api/auth/login", bytes.NewBuffer(jsonData)) + req, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/login", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") client := &http.Client{} diff --git a/cmd/server/tests/device_test.go b/cmd/server/tests/device_test.go index 1ef65d9..f90e941 100644 --- a/cmd/server/tests/device_test.go +++ b/cmd/server/tests/device_test.go @@ -16,8 +16,7 @@ import ( ) func TestDeviceRegistrationFlow(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) // Step 1: Initiate device registration regRequest := map[string]interface{}{ @@ -198,11 +197,10 @@ func TestDeleteDevice(t *testing.T) { } func TestDeviceAuthentication(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) // Create a device directly in the database - userID := getTestUserID(t, db) + userID := getTestUserID(t, setup.DB) deviceToken := fmt.Sprintf("dev_%s", uuid.New().String()) _, err := db.CreateDevice(context.Background(), database.CreateDeviceParams{ @@ -230,10 +228,9 @@ func TestDeviceAuthentication(t *testing.T) { } func TestListPendingRegistrations(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := httptest.NewRequest("GET", "/api/devices/pending", nil) req.Header.Set("Authorization", "Bearer "+token) @@ -251,10 +248,9 @@ func TestListPendingRegistrations(t *testing.T) { } func TestApproveDeviceRegistration(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) regRequest := map[string]interface{}{ "device_name": "Test Device for Approval", @@ -290,10 +286,9 @@ func TestApproveDeviceRegistration(t *testing.T) { } func TestRejectDeviceRegistration(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) regRequest := map[string]interface{}{ "device_name": "Test Device for Rejection", diff --git a/cmd/server/tests/goroutine_leak_test.go b/cmd/server/tests/goroutine_leak_test.go index 4535124..a4eff57 100644 --- a/cmd/server/tests/goroutine_leak_test.go +++ b/cmd/server/tests/goroutine_leak_test.go @@ -18,8 +18,7 @@ func TestGoroutineCleanup(t *testing.T) { t.Logf("Initial goroutine count: %d", initialGoroutines) // Start server - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) // Wait for startup time.Sleep(200 * time.Millisecond) diff --git a/cmd/server/tests/kobo_test.go b/cmd/server/tests/kobo_test.go index 106e020..465de7b 100644 --- a/cmd/server/tests/kobo_test.go +++ b/cmd/server/tests/kobo_test.go @@ -19,12 +19,12 @@ func TestKoboInitialization(t *testing.T) { t.Skip("Skipping integration test in short mode") } - ts, db, _ := setupTestServer(t) + setup := setupTestServer(t) defer closeTestServer(t, ts, db) - token := loginTestUser(t, ts, db) - _ = getTestUserID(t, db) - _ = createTestMediaItemID(t, ts, token) + token := loginTestUser(t, setup.Server, setup.DB) + _ = getTestUserID(t, setup.DB) + _ = createTestMediaItemID(t, setup.Server, token) log.Printf("[DEBUG] Kobo test setup: creating device and media") @@ -33,7 +33,7 @@ func TestKoboInitialization(t *testing.T) { deviceSetup := setupDeviceTest(t) koboDevice := deviceSetup.CreateDevice(t, "Test Kobo", "kobo", "kobo-clara-test") - req, _ := http.NewRequest("GET", ts.URL+"/api/sync/kobo/v1/initialization", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/sync/kobo/v1/initialization", nil) req.Header.Set("Authorization", "Bearer "+koboDevice.AuthToken) req.Header.Set("x-kobo-device", fmt.Sprintf(`{"DeviceId":"%s","Model":"Kobo Clara","SerialNumber":"%s"}`, koboDevice.ID.String(), koboDevice.Identifier)) @@ -52,11 +52,11 @@ func TestKoboLibrarySync(t *testing.T) { t.Skip("Skipping integration test in short mode") } - ts, db, _ := setupTestServer(t) + setup := setupTestServer(t) defer closeTestServer(t, ts, db) - token := loginTestUser(t, ts, db) - _ = createTestMediaItemID(t, ts, token) + token := loginTestUser(t, setup.Server, setup.DB) + _ = createTestMediaItemID(t, setup.Server, token) log.Printf("[DEBUG] Kobo test setup: creating device and media") @@ -64,7 +64,7 @@ func TestKoboLibrarySync(t *testing.T) { deviceSetup := setupDeviceTest(t) koboDevice := deviceSetup.CreateDevice(t, "Test Kobo", "kobo", "kobo-clara-test") - req, _ := http.NewRequest("GET", ts.URL+"/api/sync/kobo/v1/initialization", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/sync/kobo/v1/initialization", nil) req.Header.Set("Authorization", "Bearer "+koboDevice.AuthToken) req.Header.Set("x-kobo-device", fmt.Sprintf(`{"DeviceId":"%s","Model":"Kobo Clara","SerialNumber":"%s"}`, koboDevice.ID.String(), koboDevice.Identifier)) @@ -83,11 +83,11 @@ func TestKoboMarkupSync(t *testing.T) { t.Skip("Skipping integration test in short mode") } - ts, db, _ := setupTestServer(t) + setup := setupTestServer(t) defer closeTestServer(t, ts, db) - token := loginTestUser(t, ts, db) - mediaItemID := createTestMediaItemID(t, ts, token) + token := loginTestUser(t, setup.Server, setup.DB) + mediaItemID := createTestMediaItemID(t, setup.Server, token) log.Printf("[DEBUG] Kobo test setup: creating device and media") @@ -130,7 +130,7 @@ func TestKoboMarkupSync(t *testing.T) { } body, _ := json.Marshal(reqBody) - req, _ := http.NewRequest("POST", ts.URL+"/api/sync/kobo/markup", bytes.NewReader(body)) + req, _ := http.NewRequest("POST", setup.Server.URL+"/api/sync/kobo/markup", bytes.NewReader(body)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+koboDevice.AuthToken) req.Header.Set("x-kobo-device", fmt.Sprintf(`{"DeviceId":"%s","Model":"Kobo Clara","SerialNumber":"%s"}`, @@ -153,11 +153,11 @@ func TestKoboBookmarkSync(t *testing.T) { t.Skip("Skipping integration test in short mode") } - ts, db, _ := setupTestServer(t) + setup := setupTestServer(t) defer closeTestServer(t, ts, db) - token := loginTestUser(t, ts, db) - mediaItemID := createTestMediaItemID(t, ts, token) + token := loginTestUser(t, setup.Server, setup.DB) + mediaItemID := createTestMediaItemID(t, setup.Server, token) log.Printf("[DEBUG] Kobo test setup: creating device and media") @@ -186,7 +186,7 @@ func TestKoboBookmarkSync(t *testing.T) { } body, _ := json.Marshal(reqBody) - req, _ := http.NewRequest("POST", ts.URL+"/api/sync/kobo/bookmark", bytes.NewReader(body)) + req, _ := http.NewRequest("POST", setup.Server.URL+"/api/sync/kobo/bookmark", bytes.NewReader(body)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+koboDevice.AuthToken) req.Header.Set("x-kobo-device", fmt.Sprintf(`{"DeviceId":"%s","Model":"Kobo Clara","SerialNumber":"%s"}`, @@ -209,11 +209,11 @@ func TestKoboAnalyticsGettests(t *testing.T) { t.Skip("Skipping integration test in short mode") } - ts, db, _ := setupTestServer(t) + setup := setupTestServer(t) defer closeTestServer(t, ts, db) - token := loginTestUser(t, ts, db) - mediaItemID := createTestMediaItemID(t, ts, token) + token := loginTestUser(t, setup.Server, setup.DB) + mediaItemID := createTestMediaItemID(t, setup.Server, token) log.Printf("[DEBUG] Kobo test setup: creating device and media") @@ -232,7 +232,7 @@ func TestKoboAnalyticsGettests(t *testing.T) { } body, _ := json.Marshal(reqBody) - req, _ := http.NewRequest("POST", ts.URL+"/api/sync/kobo/v1/analytics/gettests", bytes.NewReader(body)) + req, _ := http.NewRequest("POST", setup.Server.URL+"/api/sync/kobo/v1/analytics/gettests", bytes.NewReader(body)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+koboDevice.AuthToken) req.Header.Set("x-kobo-device", fmt.Sprintf(`{"DeviceId":"%s","Model":"Kobo Clara","SerialNumber":"%s"}`, diff --git a/cmd/server/tests/media_bulk_test.go b/cmd/server/tests/media_bulk_test.go index 1cde2a6..175de98 100644 --- a/cmd/server/tests/media_bulk_test.go +++ b/cmd/server/tests/media_bulk_test.go @@ -14,15 +14,14 @@ import ( // TestMediaBulkOperations tests bulk media operations func TestMediaBulkOperations(t *testing.T) { t.Run("BulkDeleteBooks_WithoutAuth", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) req := map[string]interface{}{ "book_ids": []string{uuid.New().String()}, } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/books/bulk-delete", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/books/bulk-delete", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -34,17 +33,16 @@ func TestMediaBulkOperations(t *testing.T) { }) t.Run("BulkDeleteBooks_EmptyBookIDs", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "book_ids": []string{}, } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/books/bulk-delete", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/books/bulk-delete", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -57,17 +55,16 @@ func TestMediaBulkOperations(t *testing.T) { }) t.Run("BulkDeleteBooks_InvalidBookIDs", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "book_ids": []string{"invalid-uuid", "another-invalid"}, } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/books/bulk-delete", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/books/bulk-delete", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -88,14 +85,13 @@ func TestMediaBulkOperations(t *testing.T) { }) t.Run("BulkDeleteBooks_WithValidBooks", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) // Create test books - bookID1 := createTestMediaItemID(t, ts, token) - bookID2 := createTestMediaItemID(t, ts, token) + bookID1 := createTestMediaItemID(t, setup.Server, token) + bookID2 := createTestMediaItemID(t, setup.Server, token) bookID3 := uuid.New().String() req := map[string]interface{}{ @@ -103,7 +99,7 @@ func TestMediaBulkOperations(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/books/bulk-delete", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/books/bulk-delete", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -126,13 +122,12 @@ func TestMediaBulkOperations(t *testing.T) { }) t.Run("BulkDeleteBooks_InvalidRequestBody", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) // Send invalid JSON - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/books/bulk-delete", bytes.NewBuffer([]byte("invalid json"))) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/books/bulk-delete", bytes.NewBuffer([]byte("invalid json"))) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -145,8 +140,7 @@ func TestMediaBulkOperations(t *testing.T) { }) t.Run("BulkUpdateBooks_WithoutAuth", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) req := map[string]interface{}{ "book_ids": []string{uuid.New().String()}, @@ -156,7 +150,7 @@ func TestMediaBulkOperations(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/books/bulk-update", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/books/bulk-update", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -168,10 +162,9 @@ func TestMediaBulkOperations(t *testing.T) { }) t.Run("BulkUpdateBooks_EmptyBookIDs", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "book_ids": []string{}, @@ -181,7 +174,7 @@ func TestMediaBulkOperations(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/books/bulk-update", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/books/bulk-update", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -194,10 +187,9 @@ func TestMediaBulkOperations(t *testing.T) { }) t.Run("BulkUpdateBooks_InvalidBookIDs", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) req := map[string]interface{}{ "book_ids": []string{"invalid-uuid"}, @@ -207,7 +199,7 @@ func TestMediaBulkOperations(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/books/bulk-update", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/books/bulk-update", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -228,14 +220,13 @@ func TestMediaBulkOperations(t *testing.T) { }) t.Run("BulkUpdateBooks_UpdateTags", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) // Create test books - bookID1 := createTestMediaItemID(t, ts, token) - bookID2 := createTestMediaItemID(t, ts, token) + bookID1 := createTestMediaItemID(t, setup.Server, token) + bookID2 := createTestMediaItemID(t, setup.Server, token) req := map[string]interface{}{ "book_ids": []string{bookID1, bookID2}, @@ -245,7 +236,7 @@ func TestMediaBulkOperations(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/books/bulk-update", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/books/bulk-update", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -268,13 +259,12 @@ func TestMediaBulkOperations(t *testing.T) { }) t.Run("BulkUpdateBooks_UpdateReadingStatus", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) // Create test books - bookID1 := createTestMediaItemID(t, ts, token) + bookID1 := createTestMediaItemID(t, setup.Server, token) req := map[string]interface{}{ "book_ids": []string{bookID1}, @@ -284,7 +274,7 @@ func TestMediaBulkOperations(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/books/bulk-update", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/books/bulk-update", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -302,13 +292,12 @@ func TestMediaBulkOperations(t *testing.T) { }) t.Run("BulkUpdateBooks_UpdateMultipleFields", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) // Create test books - bookID1 := createTestMediaItemID(t, ts, token) + bookID1 := createTestMediaItemID(t, setup.Server, token) req := map[string]interface{}{ "book_ids": []string{bookID1}, @@ -320,7 +309,7 @@ func TestMediaBulkOperations(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/books/bulk-update", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/books/bulk-update", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) @@ -338,13 +327,12 @@ func TestMediaBulkOperations(t *testing.T) { }) t.Run("BulkUpdateBooks_InvalidRequestBody", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) // Send invalid JSON - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/books/bulk-update", bytes.NewBuffer([]byte("invalid json"))) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/books/bulk-update", bytes.NewBuffer([]byte("invalid json"))) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) diff --git a/cmd/server/tests/media_item_isbn_test.go b/cmd/server/tests/media_item_isbn_test.go index f5a7aec..c4cee07 100644 --- a/cmd/server/tests/media_item_isbn_test.go +++ b/cmd/server/tests/media_item_isbn_test.go @@ -23,7 +23,7 @@ func createTestLibrary(t *testing.T, ts *httptest.Server, token, name string) st } body, _ := json.Marshal(payload) - req, _ := http.NewRequest("POST", ts.URL+"/api/libraries", bytes.NewBuffer(body)) + req, _ := http.NewRequest("POST", setup.Server.URL+"/api/libraries", bytes.NewBuffer(body)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+token) @@ -42,11 +42,10 @@ func createTestLibrary(t *testing.T, ts *httptest.Server, token, name string) st // TestMediaItemISBNNormalization tests ISBN normalization with media-items endpoint func TestMediaItemISBNNormalization(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) // Create an ebook library first - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) libID := createTestLibrary(t, ts, token, "test-isbn-lib") // Test ISBN normalization cases @@ -109,7 +108,7 @@ func TestMediaItemISBNNormalization(t *testing.T) { } body, _ := json.Marshal(payload) - req, _ := http.NewRequest("POST", ts.URL+"/api/media-items", bytes.NewBuffer(body)) + req, _ := http.NewRequest("POST", setup.Server.URL+"/api/media-items", bytes.NewBuffer(body)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+token) @@ -131,10 +130,9 @@ func TestMediaItemISBNNormalization(t *testing.T) { // TestMediaItemISBNEdgeCases tests ISBN edge cases func TestMediaItemISBNEdgeCases(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) libID := createTestLibrary(t, ts, token, "test-isbn-edge-lib") t.Run("Empty ISBN should be accepted", func(t *testing.T) { @@ -147,7 +145,7 @@ func TestMediaItemISBNEdgeCases(t *testing.T) { } body, _ := json.Marshal(payload) - req, _ := http.NewRequest("POST", ts.URL+"/api/media-items", bytes.NewBuffer(body)) + req, _ := http.NewRequest("POST", setup.Server.URL+"/api/media-items", bytes.NewBuffer(body)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+token) @@ -170,7 +168,7 @@ func TestMediaItemISBNEdgeCases(t *testing.T) { } body, _ := json.Marshal(payload) - req, _ := http.NewRequest("POST", ts.URL+"/api/media-items", bytes.NewBuffer(body)) + req, _ := http.NewRequest("POST", setup.Server.URL+"/api/media-items", bytes.NewBuffer(body)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+token) @@ -197,7 +195,7 @@ func TestMediaItemISBNEdgeCases(t *testing.T) { } body, _ := json.Marshal(payload) - req, _ := http.NewRequest("POST", ts.URL+"/api/media-items", bytes.NewBuffer(body)) + req, _ := http.NewRequest("POST", setup.Server.URL+"/api/media-items", bytes.NewBuffer(body)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+token) @@ -216,10 +214,9 @@ func TestMediaItemISBNEdgeCases(t *testing.T) { // TestMediaItemsPagination tests pagination with media-items endpoint func TestMediaItemsPagination(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) libID := createTestLibrary(t, ts, token, "test-pagination-lib") // Create some test media items @@ -234,7 +231,7 @@ func TestMediaItemsPagination(t *testing.T) { } body, _ := json.Marshal(payload) - req, _ := http.NewRequest("POST", ts.URL+"/api/media-items", bytes.NewBuffer(body)) + req, _ := http.NewRequest("POST", setup.Server.URL+"/api/media-items", bytes.NewBuffer(body)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+token) @@ -245,7 +242,7 @@ func TestMediaItemsPagination(t *testing.T) { } t.Run("Valid pagination parameters", func(t *testing.T) { - req, _ := http.NewRequest("GET", ts.URL+"/api/media-items?library_id="+libID+"&limit=2&offset=0", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/media-items?library_id="+libID+"&limit=2&offset=0", nil) req.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -263,7 +260,7 @@ func TestMediaItemsPagination(t *testing.T) { }) t.Run("Pagination with offset", func(t *testing.T) { - req, _ := http.NewRequest("GET", ts.URL+"/api/media-items?library_id="+libID+"&limit=2&offset=2", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/media-items?library_id="+libID+"&limit=2&offset=2", nil) req.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -281,7 +278,7 @@ func TestMediaItemsPagination(t *testing.T) { }) t.Run("Negative limit should fail", func(t *testing.T) { - req, _ := http.NewRequest("GET", ts.URL+"/api/media-items?library_id="+libID+"&limit=-10&offset=0", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/media-items?library_id="+libID+"&limit=-10&offset=0", nil) req.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -294,7 +291,7 @@ func TestMediaItemsPagination(t *testing.T) { }) t.Run("Negative offset should fail", func(t *testing.T) { - req, _ := http.NewRequest("GET", ts.URL+"/api/media-items?library_id="+libID+"&limit=10&offset=-5", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/media-items?library_id="+libID+"&limit=10&offset=-5", nil) req.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -307,7 +304,7 @@ func TestMediaItemsPagination(t *testing.T) { }) t.Run("Limit exceeds maximum", func(t *testing.T) { - req, _ := http.NewRequest("GET", ts.URL+"/api/media-items?library_id="+libID+"&limit=10000&offset=0", nil) + req, _ := http.NewRequest("GET", setup.Server.URL+"/api/media-items?library_id="+libID+"&limit=10000&offset=0", nil) req.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -323,10 +320,9 @@ func TestMediaItemsPagination(t *testing.T) { // TestMediaItemLibraryRequirement tests that media items require a library func TestMediaItemLibraryRequirement(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) t.Run("Create media-item without library should fail gracefully", func(t *testing.T) { payload := map[string]interface{}{ @@ -338,7 +334,7 @@ func TestMediaItemLibraryRequirement(t *testing.T) { } body, _ := json.Marshal(payload) - req, _ := http.NewRequest("POST", ts.URL+"/api/media-items", bytes.NewBuffer(body)) + req, _ := http.NewRequest("POST", setup.Server.URL+"/api/media-items", bytes.NewBuffer(body)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+token) @@ -364,7 +360,7 @@ func TestMediaItemLibraryRequirement(t *testing.T) { } body, _ := json.Marshal(payload) - req, _ := http.NewRequest("POST", ts.URL+"/api/media-items", bytes.NewBuffer(body)) + req, _ := http.NewRequest("POST", setup.Server.URL+"/api/media-items", bytes.NewBuffer(body)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+token) @@ -386,10 +382,9 @@ func TestMediaItemLibraryRequirement(t *testing.T) { // TestUpdateMediaItemISBN tests updating media-item ISBN func TestUpdateMediaItemISBN(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) libID := createTestLibrary(t, ts, token, "test-update-lib") // First create a media item @@ -403,7 +398,7 @@ func TestUpdateMediaItemISBN(t *testing.T) { } body, _ := json.Marshal(createPayload) - req, _ := http.NewRequest("POST", ts.URL+"/api/media-items", bytes.NewBuffer(body)) + req, _ := http.NewRequest("POST", setup.Server.URL+"/api/media-items", bytes.NewBuffer(body)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+token) @@ -425,7 +420,7 @@ func TestUpdateMediaItemISBN(t *testing.T) { } body, _ := json.Marshal(updatePayload) - req, _ := http.NewRequest("PUT", ts.URL+"/api/media-items/"+mediaItemID, bytes.NewBuffer(body)) + req, _ := http.NewRequest("PUT", setup.Server.URL+"/api/media-items/"+mediaItemID, bytes.NewBuffer(body)) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+token) diff --git a/cmd/server/tests/opds_test.go b/cmd/server/tests/opds_test.go index f2e7d76..0e24eae 100644 --- a/cmd/server/tests/opds_test.go +++ b/cmd/server/tests/opds_test.go @@ -12,11 +12,10 @@ import ( // TestOPDSEndpoints tests OPDS (Open Publication Distribution System) endpoints func TestOPDSEndpoints(t *testing.T) { t.Run("GetDeviceCatalog_WithoutDeviceAuth", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) deviceID := uuid.New() - httpReq, _ := http.NewRequest("GET", ts.URL+"/opds/devices/"+deviceID.String()+"/catalog", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/catalog", nil) client := &http.Client{} resp, err := client.Do(httpReq) @@ -29,10 +28,9 @@ func TestOPDSEndpoints(t *testing.T) { }) t.Run("GetDeviceCatalog_InvalidDeviceID", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - httpReq, _ := http.NewRequest("GET", ts.URL+"/opds/devices/invalid-uuid/catalog", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/invalid-uuid/catalog", nil) client := &http.Client{} resp, err := client.Do(httpReq) @@ -44,15 +42,14 @@ func TestOPDSEndpoints(t *testing.T) { }) t.Run("GetDeviceCatalog_ValidDevice", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) // Note: Device registration requires different endpoint // For now, test with a valid UUID format deviceID := uuid.New() - httpReq, _ := http.NewRequest("GET", ts.URL+"/opds/devices/"+deviceID.String()+"/catalog", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/catalog", nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -65,10 +62,9 @@ func TestOPDSEndpoints(t *testing.T) { }) t.Run("SearchDeviceCatalog_InvalidDeviceID", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - httpReq, _ := http.NewRequest("GET", ts.URL+"/opds/devices/invalid-uuid/search?query=test", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/invalid-uuid/search?query=test", nil) client := &http.Client{} resp, err := client.Do(httpReq) @@ -79,13 +75,12 @@ func TestOPDSEndpoints(t *testing.T) { }) t.Run("SearchDeviceCatalog_ValidDevice", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) deviceID := uuid.New() - httpReq, _ := http.NewRequest("GET", ts.URL+"/opds/devices/"+deviceID.String()+"/search?query=test", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/search?query=test", nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -98,10 +93,9 @@ func TestOPDSEndpoints(t *testing.T) { }) t.Run("GetDeviceNavigation_InvalidDeviceID", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - httpReq, _ := http.NewRequest("GET", ts.URL+"/opds/devices/invalid-uuid/nav", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/invalid-uuid/nav", nil) client := &http.Client{} resp, err := client.Do(httpReq) @@ -112,13 +106,12 @@ func TestOPDSEndpoints(t *testing.T) { }) t.Run("GetDeviceNavigation_ValidDevice", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) deviceID := uuid.New() - httpReq, _ := http.NewRequest("GET", ts.URL+"/opds/devices/"+deviceID.String()+"/nav", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/nav", nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -131,11 +124,10 @@ func TestOPDSEndpoints(t *testing.T) { }) t.Run("DownloadBook_InvalidDeviceID", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) bookID := uuid.New() - httpReq, _ := http.NewRequest("GET", ts.URL+"/opds/devices/invalid-uuid/download/"+bookID.String(), nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/invalid-uuid/download/"+bookID.String(), nil) client := &http.Client{} resp, err := client.Do(httpReq) @@ -146,11 +138,10 @@ func TestOPDSEndpoints(t *testing.T) { }) t.Run("DownloadBook_InvalidBookID", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) deviceID := uuid.New() - httpReq, _ := http.NewRequest("GET", ts.URL+"/opds/devices/"+deviceID.String()+"/download/invalid-uuid", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/download/invalid-uuid", nil) client := &http.Client{} resp, err := client.Do(httpReq) @@ -161,14 +152,13 @@ func TestOPDSEndpoints(t *testing.T) { }) t.Run("DownloadBook_ValidIDs", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) deviceID := uuid.New() - bookID := createTestMediaItemID(t, ts, token) + bookID := createTestMediaItemID(t, setup.Server, token) - httpReq, _ := http.NewRequest("GET", ts.URL+"/opds/devices/"+deviceID.String()+"/download/"+bookID, nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/download/"+bookID, nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -182,11 +172,10 @@ func TestOPDSEndpoints(t *testing.T) { }) t.Run("GetCoverImage_InvalidDeviceID", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) bookID := uuid.New() - httpReq, _ := http.NewRequest("GET", ts.URL+"/opds/devices/invalid-uuid/cover/"+bookID.String(), nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/invalid-uuid/cover/"+bookID.String(), nil) client := &http.Client{} resp, err := client.Do(httpReq) @@ -197,11 +186,10 @@ func TestOPDSEndpoints(t *testing.T) { }) t.Run("GetCoverImage_InvalidBookID", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) deviceID := uuid.New() - httpReq, _ := http.NewRequest("GET", ts.URL+"/opds/devices/"+deviceID.String()+"/cover/invalid-uuid", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/cover/invalid-uuid", nil) client := &http.Client{} resp, err := client.Do(httpReq) @@ -212,14 +200,13 @@ func TestOPDSEndpoints(t *testing.T) { }) t.Run("GetCoverImage_ValidIDs", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) deviceID := uuid.New() - bookID := createTestMediaItemID(t, ts, token) + bookID := createTestMediaItemID(t, setup.Server, token) - httpReq, _ := http.NewRequest("GET", ts.URL+"/opds/devices/"+deviceID.String()+"/cover/"+bookID, nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/cover/"+bookID, nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -232,11 +219,10 @@ func TestOPDSEndpoints(t *testing.T) { }) t.Run("ListFormats_InvalidDeviceID", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) bookID := uuid.New() - httpReq, _ := http.NewRequest("GET", ts.URL+"/opds/devices/invalid-uuid/formats/"+bookID.String(), nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/invalid-uuid/formats/"+bookID.String(), nil) client := &http.Client{} resp, err := client.Do(httpReq) @@ -247,14 +233,13 @@ func TestOPDSEndpoints(t *testing.T) { }) t.Run("ListFormats_ValidDeviceID", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) deviceID := uuid.New() - bookID := createTestMediaItemID(t, ts, token) + bookID := createTestMediaItemID(t, setup.Server, token) - httpReq, _ := http.NewRequest("GET", ts.URL+"/opds/devices/"+deviceID.String()+"/formats/"+bookID, nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/formats/"+bookID, nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -270,15 +255,14 @@ func TestOPDSEndpoints(t *testing.T) { // TestOPDSConversion tests on-the-fly conversion for downloads func TestOPDSConversion(t *testing.T) { t.Run("DownloadKEPUB_FormatParameter", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) deviceID := uuid.New() - bookID := createTestMediaItemID(t, ts, token) + bookID := createTestMediaItemID(t, setup.Server, token) // Request KEPUB format - httpReq, _ := http.NewRequest("GET", ts.URL+"/opds/devices/"+deviceID.String()+"/download/"+bookID+"?format=kepub", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/download/"+bookID+"?format=kepub", nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -292,15 +276,14 @@ func TestOPDSConversion(t *testing.T) { }) t.Run("DownloadEPUB_DefaultFormat", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) deviceID := uuid.New() - bookID := createTestMediaItemID(t, ts, token) + bookID := createTestMediaItemID(t, setup.Server, token) // Request default format (no format parameter) - httpReq, _ := http.NewRequest("GET", ts.URL+"/opds/devices/"+deviceID.String()+"/download/"+bookID, nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/download/"+bookID, nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -313,15 +296,14 @@ func TestOPDSConversion(t *testing.T) { }) t.Run("Download_UnsupportedFormat", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) deviceID := uuid.New() - bookID := createTestMediaItemID(t, ts, token) + bookID := createTestMediaItemID(t, setup.Server, token) // Request unsupported format - httpReq, _ := http.NewRequest("GET", ts.URL+"/opds/devices/"+deviceID.String()+"/download/"+bookID+"?format=pdf", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/download/"+bookID+"?format=pdf", nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -337,13 +319,12 @@ func TestOPDSConversion(t *testing.T) { // TestOPDSEdgeCases tests edge cases for OPDS endpoints func TestOPDSEdgeCases(t *testing.T) { t.Run("Catalog_EmptyLibrary", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) deviceID := uuid.New() - httpReq, _ := http.NewRequest("GET", ts.URL+"/opds/devices/"+deviceID.String()+"/catalog", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/catalog", nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -356,14 +337,13 @@ func TestOPDSEdgeCases(t *testing.T) { }) t.Run("Search_SpecialCharacters", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) deviceID := uuid.New() // Search with special characters - httpReq, _ := http.NewRequest("GET", ts.URL+"/opds/devices/"+deviceID.String()+"/search?query=test%20%26%20more", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/search?query=test%20%26%20more", nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} @@ -376,13 +356,12 @@ func TestOPDSEdgeCases(t *testing.T) { }) t.Run("Search_EmptyQuery", func(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) deviceID := uuid.New() - httpReq, _ := http.NewRequest("GET", ts.URL+"/opds/devices/"+deviceID.String()+"/search?query=", nil) + httpReq, _ := http.NewRequest("GET", setup.Server.URL+"/opds/devices/"+deviceID.String()+"/search?query=", nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} diff --git a/cmd/server/tests/queue_test.go b/cmd/server/tests/queue_test.go index e916473..24392c6 100644 --- a/cmd/server/tests/queue_test.go +++ b/cmd/server/tests/queue_test.go @@ -17,8 +17,7 @@ import ( ) func TestListAllQueueItems_Admin(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) token := loginAdminUser(t, ts, db) @@ -35,12 +34,11 @@ func TestListAllQueueItems_Admin(t *testing.T) { } func TestGetDeviceQueueStats(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) - userID := getTestUserID(t, db) + userID := getTestUserID(t, setup.DB) deviceToken := fmt.Sprintf("dev_%s", uuid.New().String()) device, err := db.CreateDevice(context.Background(), database.CreateDeviceParams{ @@ -72,12 +70,11 @@ func TestGetDeviceQueueStats(t *testing.T) { } func TestListDeviceQueueItems(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) - userID := getTestUserID(t, db) + userID := getTestUserID(t, setup.DB) deviceToken := fmt.Sprintf("dev_%s", uuid.New().String()) device, err := db.CreateDevice(context.Background(), database.CreateDeviceParams{ @@ -109,10 +106,9 @@ func TestListDeviceQueueItems(t *testing.T) { } func TestRetryQueueItem(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) itemID := uuid.New().String() @@ -125,10 +121,9 @@ func TestRetryQueueItem(t *testing.T) { } func TestDeleteQueueItem(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) itemID := uuid.New().String() @@ -141,12 +136,11 @@ func TestDeleteQueueItem(t *testing.T) { } func TestClearDeviceQueue(t *testing.T) { - ts, db, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) - token := loginTestUser(t, ts, db) + token := loginTestUser(t, setup.Server, setup.DB) - userID := getTestUserID(t, db) + userID := getTestUserID(t, setup.DB) deviceToken := fmt.Sprintf("dev_%s", uuid.New().String()) device, err := db.CreateDevice(context.Background(), database.CreateDeviceParams{ @@ -174,8 +168,7 @@ func TestClearDeviceQueue(t *testing.T) { } func TestQueueEndpoints_Unauthorized(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) tests := []struct { name string @@ -230,7 +223,7 @@ func loginAdminUser(t *testing.T, ts *httptest.Server, db *database.Queries) str _, err = db.ListUsers(context.Background()) if err == nil { - return loginTestUser(t, ts, db) + return loginTestUser(t, setup.Server, setup.DB) } loginRequest := map[string]interface{}{ @@ -239,7 +232,7 @@ func loginAdminUser(t *testing.T, ts *httptest.Server, db *database.Queries) str } body, _ := json.Marshal(loginRequest) - req, _ := http.NewRequest("POST", ts.URL+"/api/auth/login", bytes.NewBuffer(body)) + req, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/login", bytes.NewBuffer(body)) req.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -262,7 +255,7 @@ func loginUserWithID(t *testing.T, ts *httptest.Server, db *database.Queries, us } body, _ := json.Marshal(loginRequest) - req, _ := http.NewRequest("POST", ts.URL+"/api/auth/login", bytes.NewBuffer(body)) + req, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/login", bytes.NewBuffer(body)) req.Header.Set("Content-Type", "application/json") client := &http.Client{} diff --git a/cmd/server/tests/refresh_token_test.go b/cmd/server/tests/refresh_token_test.go index b45b75d..a5db17f 100644 --- a/cmd/server/tests/refresh_token_test.go +++ b/cmd/server/tests/refresh_token_test.go @@ -13,13 +13,12 @@ import ( // TestRefreshTokenFlow comprehensive tests for token refresh functionality func TestRefreshTokenFlow(t *testing.T) { t.Run("RefreshToken_MissingToken", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) req := map[string]interface{}{} body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/auth/refresh", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/refresh", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -31,15 +30,14 @@ func TestRefreshTokenFlow(t *testing.T) { }) t.Run("RefreshToken_InvalidTokenFormat", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) req := map[string]interface{}{ "refresh_token": "not-a-valid-jwt-token", } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/auth/refresh", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/refresh", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -51,8 +49,7 @@ func TestRefreshTokenFlow(t *testing.T) { }) t.Run("RefreshToken_ExpiredToken", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) // This would require an expired token - for now test with invalid token req := map[string]interface{}{ @@ -60,7 +57,7 @@ func TestRefreshTokenFlow(t *testing.T) { } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/auth/refresh", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/refresh", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -72,8 +69,7 @@ func TestRefreshTokenFlow(t *testing.T) { }) t.Run("RefreshToken_ValidToken", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) // First, login to get tokens loginReq := map[string]string{ @@ -82,7 +78,7 @@ func TestRefreshTokenFlow(t *testing.T) { } loginBody, _ := json.Marshal(loginReq) - loginHTTP, _ := http.NewRequest("POST", ts.URL+"/api/auth/login", bytes.NewBuffer(loginBody)) + loginHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/login", bytes.NewBuffer(loginBody)) loginHTTP.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -104,7 +100,7 @@ func TestRefreshTokenFlow(t *testing.T) { } refreshBody, _ := json.Marshal(refreshReq) - refreshHTTP, _ := http.NewRequest("POST", ts.URL+"/api/auth/refresh", bytes.NewBuffer(refreshBody)) + refreshHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/refresh", bytes.NewBuffer(refreshBody)) refreshHTTP.Header.Set("Content-Type", "application/json") refreshResp, err := client.Do(refreshHTTP) @@ -126,11 +122,10 @@ func TestRefreshTokenFlow(t *testing.T) { }) t.Run("RefreshToken_InvalidRequestBody", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) // Send invalid JSON - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/auth/refresh", bytes.NewBuffer([]byte("invalid json"))) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/refresh", bytes.NewBuffer([]byte("invalid json"))) httpReq.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -142,15 +137,14 @@ func TestRefreshTokenFlow(t *testing.T) { }) t.Run("RefreshToken_MissingContentType", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) req := map[string]interface{}{ "refresh_token": "some-token", } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/auth/refresh", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/refresh", bytes.NewBuffer(body)) // Don't set Content-Type client := &http.Client{} @@ -166,8 +160,7 @@ func TestRefreshTokenFlow(t *testing.T) { // TestRefreshTokenSecurity tests security aspects of token refresh func TestRefreshTokenSecurity(t *testing.T) { t.Run("RefreshToken_ReuseProtection", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) // Login to get tokens loginReq := map[string]string{ @@ -176,7 +169,7 @@ func TestRefreshTokenSecurity(t *testing.T) { } loginBody, _ := json.Marshal(loginReq) - loginHTTP, _ := http.NewRequest("POST", ts.URL+"/api/auth/login", bytes.NewBuffer(loginBody)) + loginHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/login", bytes.NewBuffer(loginBody)) loginHTTP.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -197,7 +190,7 @@ func TestRefreshTokenSecurity(t *testing.T) { } refreshBody, _ := json.Marshal(refreshReq) - refreshHTTP1, _ := http.NewRequest("POST", ts.URL+"/api/auth/refresh", bytes.NewBuffer(refreshBody)) + refreshHTTP1, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/refresh", bytes.NewBuffer(refreshBody)) refreshHTTP1.Header.Set("Content-Type", "application/json") refreshResp1, err := client.Do(refreshHTTP1) @@ -207,7 +200,7 @@ func TestRefreshTokenSecurity(t *testing.T) { assert.Equal(t, http.StatusOK, refreshResp1.StatusCode) // Try to reuse the same refresh token (should fail if refresh token rotation is enabled) - refreshHTTP2, _ := http.NewRequest("POST", ts.URL+"/api/auth/refresh", bytes.NewBuffer(refreshBody)) + refreshHTTP2, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/refresh", bytes.NewBuffer(refreshBody)) refreshHTTP2.Header.Set("Content-Type", "application/json") refreshResp2, err := client.Do(refreshHTTP2) @@ -220,8 +213,7 @@ func TestRefreshTokenSecurity(t *testing.T) { }) t.Run("RefreshToken_TokenTampering", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) // Login to get a valid token loginReq := map[string]string{ @@ -230,7 +222,7 @@ func TestRefreshTokenSecurity(t *testing.T) { } loginBody, _ := json.Marshal(loginReq) - loginHTTP, _ := http.NewRequest("POST", ts.URL+"/api/auth/login", bytes.NewBuffer(loginBody)) + loginHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/login", bytes.NewBuffer(loginBody)) loginHTTP.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -254,7 +246,7 @@ func TestRefreshTokenSecurity(t *testing.T) { } refreshBody, _ := json.Marshal(refreshReq) - refreshHTTP, _ := http.NewRequest("POST", ts.URL+"/api/auth/refresh", bytes.NewBuffer(refreshBody)) + refreshHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/refresh", bytes.NewBuffer(refreshBody)) refreshHTTP.Header.Set("Content-Type", "application/json") refreshResp, err := client.Do(refreshHTTP) @@ -269,15 +261,14 @@ func TestRefreshTokenSecurity(t *testing.T) { // TestRefreshTokenEdgeCases tests edge cases for token refresh func TestRefreshTokenEdgeCases(t *testing.T) { t.Run("RefreshToken_EmptyStringToken", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) req := map[string]interface{}{ "refresh_token": "", } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/auth/refresh", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/refresh", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -289,15 +280,14 @@ func TestRefreshTokenEdgeCases(t *testing.T) { }) t.Run("RefreshToken_NullToken", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) req := map[string]interface{}{ "refresh_token": nil, } body, _ := json.Marshal(req) - httpReq, _ := http.NewRequest("POST", ts.URL+"/api/auth/refresh", bytes.NewBuffer(body)) + httpReq, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/refresh", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -309,8 +299,7 @@ func TestRefreshTokenEdgeCases(t *testing.T) { }) t.Run("RefreshToken_ResponseStructure", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) // Login to get tokens loginReq := map[string]string{ @@ -319,7 +308,7 @@ func TestRefreshTokenEdgeCases(t *testing.T) { } loginBody, _ := json.Marshal(loginReq) - loginHTTP, _ := http.NewRequest("POST", ts.URL+"/api/auth/login", bytes.NewBuffer(loginBody)) + loginHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/login", bytes.NewBuffer(loginBody)) loginHTTP.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -340,7 +329,7 @@ func TestRefreshTokenEdgeCases(t *testing.T) { } refreshBody, _ := json.Marshal(refreshReq) - refreshHTTP, _ := http.NewRequest("POST", ts.URL+"/api/auth/refresh", bytes.NewBuffer(refreshBody)) + refreshHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/refresh", bytes.NewBuffer(refreshBody)) refreshHTTP.Header.Set("Content-Type", "application/json") refreshResp, err := client.Do(refreshHTTP) @@ -361,8 +350,7 @@ func TestRefreshTokenEdgeCases(t *testing.T) { }) t.Run("RefreshToken_TokenType", func(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) // Login to get tokens loginReq := map[string]string{ @@ -371,7 +359,7 @@ func TestRefreshTokenEdgeCases(t *testing.T) { } loginBody, _ := json.Marshal(loginReq) - loginHTTP, _ := http.NewRequest("POST", ts.URL+"/api/auth/login", bytes.NewBuffer(loginBody)) + loginHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/login", bytes.NewBuffer(loginBody)) loginHTTP.Header.Set("Content-Type", "application/json") client := &http.Client{} @@ -392,7 +380,7 @@ func TestRefreshTokenEdgeCases(t *testing.T) { } refreshBody, _ := json.Marshal(refreshReq) - refreshHTTP, _ := http.NewRequest("POST", ts.URL+"/api/auth/refresh", bytes.NewBuffer(refreshBody)) + refreshHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/auth/refresh", bytes.NewBuffer(refreshBody)) refreshHTTP.Header.Set("Content-Type", "application/json") refreshResp, err := client.Do(refreshHTTP) diff --git a/cmd/server/tests/websocket_test.go b/cmd/server/tests/websocket_test.go index dd7a014..bb0bc9a 100644 --- a/cmd/server/tests/websocket_test.go +++ b/cmd/server/tests/websocket_test.go @@ -21,13 +21,12 @@ import ( func TestWebSocketConnection(t *testing.T) { // Setup test server with WebSocket ts, queries, _ := setupTestServer(t) - defer ts.Close() // Get JWT token for a test user token := loginTestUser(t, ts, queries) // Connect to WebSocket endpoint - wsURL := strings.Replace(ts.URL, "http", "ws", 1) + "/ws/sync?token=" + token + wsURL := strings.Replace(setup.Server.URL, "http", "ws", 1) + "/ws/sync?token=" + token ws, _, err := websocket.DefaultDialer.Dial(wsURL, nil) require.NoError(t, err, "Failed to connect to WebSocket") @@ -52,7 +51,6 @@ func TestWebSocketConnection(t *testing.T) { // TestWebSocketDeviceAuth tests device authentication via WebSocket func TestWebSocketDeviceAuth(t *testing.T) { ts, queries, _ := setupTestServer(t) - defer ts.Close() // Create a test device userID := getTestUserID(t, queries) @@ -72,7 +70,7 @@ func TestWebSocketDeviceAuth(t *testing.T) { require.NoError(t, err) // Connect to WebSocket with device token - wsURL := strings.Replace(ts.URL, "http", "ws", 1) + "/ws/sync?token=device-auth-test" + wsURL := strings.Replace(setup.Server.URL, "http", "ws", 1) + "/ws/sync?token=device-auth-test" req, _ := http.NewRequest("GET", wsURL, nil) req.Header.Set("Authorization", "Bearer test-device-token-"+deviceID.String()) @@ -86,7 +84,6 @@ func TestWebSocketDeviceAuth(t *testing.T) { // TestWebSocketProgressBroadcast tests that progress updates are broadcast to connected clients func TestWebSocketProgressBroadcast(t *testing.T) { ts, queries, _ := setupTestServer(t) - defer ts.Close() // Get JWT token token := loginTestUser(t, ts, queries) @@ -96,7 +93,7 @@ func TestWebSocketProgressBroadcast(t *testing.T) { mediaID := createTestMediaItem(t, queries, userID) // Connect WebSocket client - wsURL := strings.Replace(ts.URL, "http", "ws", 1) + "/ws/sync?token=" + token + wsURL := strings.Replace(setup.Server.URL, "http", "ws", 1) + "/ws/sync?token=" + token ws, _, err := websocket.DefaultDialer.Dial(wsURL, nil) require.NoError(t, err) defer ws.Close() @@ -117,7 +114,7 @@ func TestWebSocketProgressBroadcast(t *testing.T) { } body, _ := json.Marshal(progressReq) - req, _ := http.NewRequest("POST", ts.URL+"/api/progress/"+mediaID, strings.NewReader(string(body))) + req, _ := http.NewRequest("POST", setup.Server.URL+"/api/progress/"+mediaID, strings.NewReader(string(body))) req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+token) @@ -149,11 +146,10 @@ func TestWebSocketProgressBroadcast(t *testing.T) { // TestWebSocketPingPong tests that ping/pong messages work correctly func TestWebSocketPingPong(t *testing.T) { ts, queries, _ := setupTestServer(t) - defer ts.Close() token := loginTestUser(t, ts, queries) - wsURL := strings.Replace(ts.URL, "http", "ws", 1) + "/ws/sync?token=" + token + wsURL := strings.Replace(setup.Server.URL, "http", "ws", 1) + "/ws/sync?token=" + token ws, _, err := websocket.DefaultDialer.Dial(wsURL, nil) require.NoError(t, err) defer ws.Close() @@ -182,14 +178,13 @@ func TestWebSocketPingPong(t *testing.T) { // TestWebSocketConnectionLimit tests that the server handles multiple connections func TestWebSocketConnectionLimit(t *testing.T) { ts, queries, _ := setupTestServer(t) - defer ts.Close() token := loginTestUser(t, ts, queries) // Create multiple connections connections := make([]*websocket.Conn, 5) for i := 0; i < 5; i++ { - wsURL := strings.Replace(ts.URL, "http", "ws", 1) + fmt.Sprintf("/ws/sync?token=%s&conn=%d", token, i) + wsURL := strings.Replace(setup.Server.URL, "http", "ws", 1) + fmt.Sprintf("/ws/sync?token=%s&conn=%d", token, i) ws, _, err := websocket.DefaultDialer.Dial(wsURL, nil) require.NoError(t, err, "Failed to create connection %d", i) connections[i] = ws @@ -207,11 +202,10 @@ func TestWebSocketConnectionLimit(t *testing.T) { // TestWebSocketInvalidToken tests that invalid tokens are rejected func TestWebSocketInvalidToken(t *testing.T) { - ts, _, _ := setupTestServer(t) - defer ts.Close() + setup := setupTestServer(t) // Try to connect with invalid token - wsURL := strings.Replace(ts.URL, "http", "ws", 1) + "/ws/sync?token=invalid-token" + wsURL := strings.Replace(setup.Server.URL, "http", "ws", 1) + "/ws/sync?token=invalid-token" _, _, err := websocket.DefaultDialer.Dial(wsURL, nil) assert.Error(t, err, "Expected error when connecting with invalid token")