package main import ( "bytes" "encoding/json" "net/http" "testing" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // TestMediaBulkOperations tests bulk media operations func TestMediaBulkOperations(t *testing.T) { t.Run("BulkDeleteBooks_WithoutAuth", func(t *testing.T) { ts, _, _ := setupTestServer(t) defer ts.Close() 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.Header.Set("Content-Type", "application/json") client := &http.Client{} resp, err := client.Do(httpReq) require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, http.StatusUnauthorized, resp.StatusCode) }) t.Run("BulkDeleteBooks_EmptyBookIDs", func(t *testing.T) { ts, db, _ := setupTestServer(t) defer ts.Close() token := loginTestUser(t, ts, 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.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(httpReq) require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, http.StatusBadRequest, resp.StatusCode) }) t.Run("BulkDeleteBooks_InvalidBookIDs", func(t *testing.T) { ts, db, _ := setupTestServer(t) defer ts.Close() token := loginTestUser(t, ts, 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.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(httpReq) 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, "results") assert.Contains(t, result, "total") assert.Contains(t, result, "deleted") assert.Contains(t, result, "failed") }) t.Run("BulkDeleteBooks_WithValidBooks", func(t *testing.T) { ts, db, _ := setupTestServer(t) defer ts.Close() token := loginTestUser(t, ts, db) // Create test books bookID1 := createTestEbookID(t, ts, token) bookID2 := createTestEbookID(t, ts, token) bookID3 := uuid.New().String() req := map[string]interface{}{ "book_ids": []string{bookID1, bookID2, bookID3}, } body, _ := json.Marshal(req) httpReq, _ := http.NewRequest("POST", ts.URL+"/api/books/bulk-delete", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(httpReq) 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, "results") assert.Equal(t, 3, result["total"]) assert.True(t, result["deleted"].(float64) >= 2) // At least the valid ones }) t.Run("BulkDeleteBooks_InvalidRequestBody", func(t *testing.T) { ts, db, _ := setupTestServer(t) defer ts.Close() token := loginTestUser(t, ts, db) // Send invalid JSON httpReq, _ := http.NewRequest("POST", ts.URL+"/api/books/bulk-delete", bytes.NewBuffer([]byte("invalid json"))) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(httpReq) require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, http.StatusBadRequest, resp.StatusCode) }) t.Run("BulkUpdateBooks_WithoutAuth", func(t *testing.T) { ts, _, _ := setupTestServer(t) defer ts.Close() req := map[string]interface{}{ "book_ids": []string{uuid.New().String()}, "updates": map[string]interface{}{ "tags": []string{"test"}, }, } body, _ := json.Marshal(req) httpReq, _ := http.NewRequest("POST", ts.URL+"/api/books/bulk-update", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") client := &http.Client{} resp, err := client.Do(httpReq) require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, http.StatusUnauthorized, resp.StatusCode) }) t.Run("BulkUpdateBooks_EmptyBookIDs", func(t *testing.T) { ts, db, _ := setupTestServer(t) defer ts.Close() token := loginTestUser(t, ts, db) req := map[string]interface{}{ "book_ids": []string{}, "updates": map[string]interface{}{ "tags": []string{"test"}, }, } body, _ := json.Marshal(req) httpReq, _ := http.NewRequest("POST", ts.URL+"/api/books/bulk-update", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(httpReq) require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, http.StatusBadRequest, resp.StatusCode) }) t.Run("BulkUpdateBooks_InvalidBookIDs", func(t *testing.T) { ts, db, _ := setupTestServer(t) defer ts.Close() token := loginTestUser(t, ts, db) req := map[string]interface{}{ "book_ids": []string{"invalid-uuid"}, "updates": map[string]interface{}{ "tags": []string{"fiction", "test"}, }, } body, _ := json.Marshal(req) httpReq, _ := http.NewRequest("POST", ts.URL+"/api/books/bulk-update", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(httpReq) 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, "results") assert.Contains(t, result, "total") assert.Contains(t, result, "updated") assert.Contains(t, result, "failed") }) t.Run("BulkUpdateBooks_UpdateTags", func(t *testing.T) { ts, db, _ := setupTestServer(t) defer ts.Close() token := loginTestUser(t, ts, db) // Create test books bookID1 := createTestEbookID(t, ts, token) bookID2 := createTestEbookID(t, ts, token) req := map[string]interface{}{ "book_ids": []string{bookID1, bookID2}, "updates": map[string]interface{}{ "tags": []string{"fiction", "science-fiction", "test"}, }, } body, _ := json.Marshal(req) httpReq, _ := http.NewRequest("POST", ts.URL+"/api/books/bulk-update", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(httpReq) 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, "results") assert.Equal(t, 2, result["total"]) assert.True(t, result["updated"].(float64) > 0) }) t.Run("BulkUpdateBooks_UpdateReadingStatus", func(t *testing.T) { ts, db, _ := setupTestServer(t) defer ts.Close() token := loginTestUser(t, ts, db) // Create test books bookID1 := createTestEbookID(t, ts, token) req := map[string]interface{}{ "book_ids": []string{bookID1}, "updates": map[string]interface{}{ "reading_status": "reading", }, } body, _ := json.Marshal(req) httpReq, _ := http.NewRequest("POST", ts.URL+"/api/books/bulk-update", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(httpReq) 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, "results") }) t.Run("BulkUpdateBooks_UpdateMultipleFields", func(t *testing.T) { ts, db, _ := setupTestServer(t) defer ts.Close() token := loginTestUser(t, ts, db) // Create test books bookID1 := createTestEbookID(t, ts, token) req := map[string]interface{}{ "book_ids": []string{bookID1}, "updates": map[string]interface{}{ "tags": []string{"test", "bulk-update"}, "reading_status": "to-read", "rating": 4, }, } body, _ := json.Marshal(req) httpReq, _ := http.NewRequest("POST", ts.URL+"/api/books/bulk-update", bytes.NewBuffer(body)) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(httpReq) 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, "results") }) t.Run("BulkUpdateBooks_InvalidRequestBody", func(t *testing.T) { ts, db, _ := setupTestServer(t) defer ts.Close() token := loginTestUser(t, ts, db) // Send invalid JSON httpReq, _ := http.NewRequest("POST", ts.URL+"/api/books/bulk-update", bytes.NewBuffer([]byte("invalid json"))) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(httpReq) require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, http.StatusBadRequest, resp.StatusCode) }) }