test: add comprehensive tests for unified search endpoint
- Add search_unified_test.go with 8 test cases:
- Fuzzy author filter (asimov → Asimov, Isaac)
- Fuzzy genre filter (scifi → Sci-Fi)
- Exact match with quotes ("Foundation and Empire")
- Combined search + filters (q=foundation&author_filter=asimov)
- Field-specific search for dropdown authors (returns values with counts)
- Year range filter (exact match)
- Boolean filter (has_cover=true)
- Missing library_id validation (400 error)
- Remove filtering_test.go (covered by new tests)
- Uses setupDeviceTest helper following PROJECT_GUIDELINES.md
- Tests both media item search and field value search endpoints
- Validates fuzzy matching, exact matching, and combined queries
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"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")
|
||||
|
||||
t.Run("Fuzzy author filter", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/api/media-items/search?library_id="+libraryID+"&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 fuzzy match author")
|
||||
})
|
||||
|
||||
t.Run("Fuzzy genre filter", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/api/media-items/search?library_id="+libraryID+"&genre_filter=scifi", 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 fuzzy match genre")
|
||||
})
|
||||
|
||||
t.Run("Exact match with quotes", 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("Field-specific search for dropdown - authors", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/api/media-items/search?library_id="+libraryID+"&authors=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 return author values")
|
||||
|
||||
var response struct {
|
||||
Results []struct {
|
||||
Value string `json:"value"`
|
||||
Count int64 `json:"count"`
|
||||
Score float64 `json:"score"`
|
||||
} `json:"results"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
err := json.Unmarshal(rec.Body.Bytes(), &response)
|
||||
require.NoError(t, err, "Should unmarshal field values response")
|
||||
assert.Greater(t, len(response.Results), 0, "Should have results")
|
||||
})
|
||||
|
||||
t.Run("Year range filter (exact)", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/api/media-items/search?library_id="+libraryID+"&year_min=2000&year_max=2020", 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 year range")
|
||||
})
|
||||
|
||||
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", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/api/media-items/search?q=test", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+setup.UserToken)
|
||||
rec := httptest.NewRecorder()
|
||||
setup.Server.Config.Handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, rec.Code, "Should require library_id")
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user