TestUnifiedSearch: Search for 'zzzznonexistent' instead of 'test' which matches leftover test data from other tests. Fixes false 200 instead of 404. TestWebSocketProgressBroadcast: Update to new progress endpoint /api/media-items/:id/progress with correct PUT body format matching ProgressService (percentage, epubcfi). Use book_id instead of media_item_id to match WebSocket broadcast payload field names.
107 lines
3.8 KiB
Go
107 lines
3.8 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestUnifiedSearch(t *testing.T) {
|
|
setup := setupDeviceTest(t)
|
|
defer setup.Server.Close()
|
|
|
|
libraryID := setup.CreateLibrary(t, "Test Search Library", "ebooks")
|
|
_ = setup.CreateDevice(t, "Test Search Device", "koreader", "search-test-123")
|
|
|
|
client := &http.Client{}
|
|
|
|
// Add folder to library (required before adding media items)
|
|
folderReq := map[string]interface{}{
|
|
"folder_path": "/app/uploads",
|
|
}
|
|
folderBody, _ := json.Marshal(folderReq)
|
|
folderHTTP, _ := http.NewRequest("POST", setup.Server.URL+"/api/libraries/"+libraryID+"/folders", bytes.NewBuffer(folderBody))
|
|
folderHTTP.Header.Set("Content-Type", "application/json")
|
|
folderHTTP.Header.Set("Authorization", "Bearer "+setup.UserToken)
|
|
folderResp, err := client.Do(folderHTTP)
|
|
require.NoError(t, err)
|
|
_ = folderResp.Body.Close()
|
|
require.Equal(t, http.StatusCreated, folderResp.StatusCode)
|
|
|
|
// Helper to create book with fields
|
|
createBook := func(title, author, genre string, year int, hasCover bool) {
|
|
bookReq := map[string]interface{}{
|
|
"library_id": libraryID,
|
|
"title": title,
|
|
"author": author,
|
|
"genre": genre,
|
|
"copyright_year": year,
|
|
"file_path": "/tmp/test.epub",
|
|
"file_size": 1024,
|
|
"mime_type": "application/epub+zip",
|
|
}
|
|
if hasCover {
|
|
bookReq["cover_image_path"] = "/tmp/cover.jpg"
|
|
}
|
|
body, _ := json.Marshal(bookReq)
|
|
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 "+setup.UserToken)
|
|
resp, err := client.Do(req)
|
|
require.NoError(t, err)
|
|
defer func(Body io.ReadCloser) {
|
|
_ = Body.Close()
|
|
}(resp.Body)
|
|
require.Equal(t, http.StatusCreated, resp.StatusCode)
|
|
}
|
|
|
|
// Create test books with various fields for filtering
|
|
createBook("Foundation and Empire", "asimov", "scifi", 1951, true)
|
|
createBook("The Martian", "weir", "scifi", 2010, true)
|
|
createBook("I, Robot", "asimov", "fiction", 1950, false)
|
|
|
|
t.Run("Fuzzy author filter", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/api/media-items/search?library_id="+libraryID+"&q=%22Foundation%20and%20Empire%22", nil)
|
|
req.Header.Set("Authorization", "Bearer "+setup.UserToken)
|
|
rec := httptest.NewRecorder()
|
|
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
|
|
|
assert.Equal(t, http.StatusOK, rec.Code, "Should exact match quoted query")
|
|
})
|
|
|
|
t.Run("Combined search + filters", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/api/media-items/search?library_id="+libraryID+"&q=foundation&author_filter=asimov", nil)
|
|
req.Header.Set("Authorization", "Bearer "+setup.UserToken)
|
|
rec := httptest.NewRecorder()
|
|
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
|
|
|
assert.Equal(t, http.StatusOK, rec.Code, "Should combine search and filters")
|
|
})
|
|
|
|
t.Run("Boolean filter (exact)", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/api/media-items/search?library_id="+libraryID+"&has_cover=true", nil)
|
|
req.Header.Set("Authorization", "Bearer "+setup.UserToken)
|
|
rec := httptest.NewRecorder()
|
|
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
|
|
|
assert.Equal(t, http.StatusOK, rec.Code, "Should filter by has_cover")
|
|
})
|
|
|
|
t.Run("Missing library_id searches all libraries", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/api/media-items/search?q=zzzznonexistent", nil)
|
|
req.Header.Set("Authorization", "Bearer "+setup.UserToken)
|
|
rec := httptest.NewRecorder()
|
|
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
|
|
|
// library_id is optional - searches all libraries when omitted
|
|
// Returns 404 when no results match
|
|
assert.Equal(t, http.StatusNotFound, rec.Code, "Should return 404 when no results match")
|
|
})
|
|
}
|