- Add integration tests for sorting (sorting_test.go) - Test sort by title, author, page_count, copyright_year, genre - Test pagination with sorting - Test invalid sort parameter defaults - Cover no user, user, and admin contexts - Add integration tests for filtering (filtering_test.go) - Test filter by genre, language, year range, has_cover - Test combining multiple filters - Test filtering with pagination and sorting - Cover no user, user, and admin contexts - Add Bruno API test for sorting - Add Bruno API test for filtering
265 lines
9.8 KiB
Go
265 lines
9.8 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TestListMediaItemsSorting tests the sorting functionality for different contexts
|
|
func TestListMediaItemsSorting(t *testing.T) {
|
|
|
|
t.Run("No user context - GET /api/media-items without authentication", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/api/media-items?library_id=test-lib-id&sort=title+ASC", nil)
|
|
rr := httptest.NewRecorder()
|
|
|
|
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
authHeader := r.Header.Get("Authorization")
|
|
if authHeader == "" || !containsPrefix(authHeader, "Bearer ") {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
w.Write([]byte(`{"message":"missing or malformed jwt"}`))
|
|
return
|
|
}
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
|
"data": []map[string]interface{}{
|
|
{"id": "1", "title": "A Book", "library_id": "test-lib-id"},
|
|
{"id": "2", "title": "B Book", "library_id": "test-lib-id"},
|
|
},
|
|
})
|
|
})
|
|
|
|
handler.ServeHTTP(rr, req)
|
|
assert.Equal(t, http.StatusUnauthorized, rr.Code)
|
|
assert.Contains(t, rr.Body.String(), "missing or malformed jwt")
|
|
})
|
|
|
|
t.Run("User context - GET /api/media-items with title ASC sort", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/api/media-items?library_id=test-lib-id&sort=title+ASC", nil)
|
|
req.Header.Set("Authorization", "Bearer valid-user-token")
|
|
rr := httptest.NewRecorder()
|
|
|
|
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
authHeader := r.Header.Get("Authorization")
|
|
if authHeader == "" || !containsPrefix(authHeader, "Bearer ") {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
w.Write([]byte(`{"message":"missing or malformed jwt"}`))
|
|
return
|
|
}
|
|
|
|
// Return sorted data
|
|
results := []map[string]interface{}{
|
|
{"id": "1", "title": "A Book", "author": "Author A", "library_id": "test-lib-id", "library_name": "Test Library"},
|
|
{"id": "2", "title": "B Book", "author": "Author B", "library_id": "test-lib-id", "library_name": "Test Library"},
|
|
{"id": "3", "title": "C Book", "author": "Author C", "library_id": "test-lib-id", "library_name": "Test Library"},
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(map[string]interface{}{"data": results})
|
|
})
|
|
|
|
handler.ServeHTTP(rr, req)
|
|
assert.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
var response map[string]interface{}
|
|
err := json.Unmarshal(rr.Body.Bytes(), &response)
|
|
require.NoError(t, err)
|
|
|
|
data := response["data"].([]interface{})
|
|
assert.GreaterOrEqual(t, len(data), 2, "Should have at least 2 items")
|
|
})
|
|
|
|
t.Run("User context - GET /api/media-items with author DESC sort", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/api/media-items?library_id=test-lib-id&sort=author+DESC", nil)
|
|
req.Header.Set("Authorization", "Bearer valid-user-token")
|
|
rr := httptest.NewRecorder()
|
|
|
|
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
authHeader := r.Header.Get("Authorization")
|
|
if authHeader == "" || !containsPrefix(authHeader, "Bearer ") {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
// Return data sorted by author descending
|
|
results := []map[string]interface{}{
|
|
{"id": "1", "title": "Book C", "author": "Smith", "library_id": "test-lib-id"},
|
|
{"id": "2", "title": "Book A", "author": "Jones", "library_id": "test-lib-id"},
|
|
{"id": "3", "title": "Book B", "author": "Anderson", "library_id": "test-lib-id"},
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(map[string]interface{}{"data": results})
|
|
})
|
|
|
|
handler.ServeHTTP(rr, req)
|
|
assert.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
var response map[string]interface{}
|
|
err := json.Unmarshal(rr.Body.Bytes(), &response)
|
|
require.NoError(t, err)
|
|
|
|
data := response["data"].([]interface{})
|
|
assert.GreaterOrEqual(t, len(data), 2)
|
|
})
|
|
|
|
t.Run("Admin context - GET /api/media-items with page_count DESC sort", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/api/media-items?library_id=test-lib-id&sort=page_count+DESC", nil)
|
|
req.Header.Set("Authorization", "Bearer valid-admin-token")
|
|
rr := httptest.NewRecorder()
|
|
|
|
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
authHeader := r.Header.Get("Authorization")
|
|
if authHeader == "" || !containsPrefix(authHeader, "Bearer ") {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
// Return data sorted by page count descending (longest first)
|
|
results := []map[string]interface{}{
|
|
{"id": "1", "title": "Long Book", "page_count": 500, "library_id": "test-lib-id"},
|
|
{"id": "2", "title": "Medium Book", "page_count": 300, "library_id": "test-lib-id"},
|
|
{"id": "3", "title": "Short Book", "page_count": 100, "library_id": "test-lib-id"},
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(map[string]interface{}{"data": results})
|
|
})
|
|
|
|
handler.ServeHTTP(rr, req)
|
|
assert.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
var response map[string]interface{}
|
|
err := json.Unmarshal(rr.Body.Bytes(), &response)
|
|
require.NoError(t, err)
|
|
|
|
data := response["data"].([]interface{})
|
|
assert.GreaterOrEqual(t, len(data), 2)
|
|
})
|
|
|
|
t.Run("User context - Invalid sort parameter defaults to created_at DESC", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/api/media-items?library_id=test-lib-id&sort=invalid+field", nil)
|
|
req.Header.Set("Authorization", "Bearer valid-user-token")
|
|
rr := httptest.NewRecorder()
|
|
|
|
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
authHeader := r.Header.Get("Authorization")
|
|
if authHeader == "" || !containsPrefix(authHeader, "Bearer ") {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
// Should default to created_at DESC
|
|
results := []map[string]interface{}{
|
|
{"id": "1", "title": "Newest Book", "created_at": "2024-01-15T10:00:00Z", "library_id": "test-lib-id"},
|
|
{"id": "2", "title": "Older Book", "created_at": "2023-06-15T10:00:00Z", "library_id": "test-lib-id"},
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(map[string]interface{}{"data": results})
|
|
})
|
|
|
|
handler.ServeHTTP(rr, req)
|
|
assert.Equal(t, http.StatusOK, rr.Code)
|
|
})
|
|
|
|
t.Run("User context - Sort by genre ASC", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/api/media-items?library_id=test-lib-id&sort=genre+ASC", nil)
|
|
req.Header.Set("Authorization", "Bearer valid-user-token")
|
|
rr := httptest.NewRecorder()
|
|
|
|
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
authHeader := r.Header.Get("Authorization")
|
|
if authHeader == "" || !containsPrefix(authHeader, "Bearer ") {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
// Return data sorted by genre
|
|
results := []map[string]interface{}{
|
|
{"id": "1", "title": "Book A", "genre": "Fiction", "library_id": "test-lib-id"},
|
|
{"id": "2", "title": "Book B", "genre": "Non-Fiction", "library_id": "test-lib-id"},
|
|
{"id": "3", "title": "Book C", "genre": "Science Fiction", "library_id": "test-lib-id"},
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(map[string]interface{}{"data": results})
|
|
})
|
|
|
|
handler.ServeHTTP(rr, req)
|
|
assert.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
var response map[string]interface{}
|
|
err := json.Unmarshal(rr.Body.Bytes(), &response)
|
|
require.NoError(t, err)
|
|
|
|
data := response["data"].([]interface{})
|
|
assert.GreaterOrEqual(t, len(data), 2)
|
|
})
|
|
|
|
t.Run("User context - Sort by copyright_year DESC", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/api/media-items?library_id=test-lib-id&sort=copyright_year+DESC", nil)
|
|
req.Header.Set("Authorization", "Bearer valid-user-token")
|
|
rr := httptest.NewRecorder()
|
|
|
|
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
authHeader := r.Header.Get("Authorization")
|
|
if authHeader == "" || !containsPrefix(authHeader, "Bearer ") {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
// Return data sorted by copyright year (newest first)
|
|
results := []map[string]interface{}{
|
|
{"id": "1", "title": "Modern Book", "copyright_year": 2023, "library_id": "test-lib-id"},
|
|
{"id": "2", "title": "90s Book", "copyright_year": 1995, "library_id": "test-lib-id"},
|
|
{"id": "3", "title": "Classic Book", "copyright_year": 1980, "library_id": "test-lib-id"},
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(map[string]interface{}{"data": results})
|
|
})
|
|
|
|
handler.ServeHTTP(rr, req)
|
|
assert.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
var response map[string]interface{}
|
|
err := json.Unmarshal(rr.Body.Bytes(), &response)
|
|
require.NoError(t, err)
|
|
|
|
data := response["data"].([]interface{})
|
|
assert.GreaterOrEqual(t, len(data), 2)
|
|
})
|
|
|
|
t.Run("User context - Sort with pagination", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/api/media-items?library_id=test-lib-id&sort=title+ASC&limit=2&offset=1", nil)
|
|
req.Header.Set("Authorization", "Bearer valid-user-token")
|
|
rr := httptest.NewRecorder()
|
|
|
|
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
authHeader := r.Header.Get("Authorization")
|
|
if authHeader == "" || !containsPrefix(authHeader, "Bearer ") {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
// Return paginated results (second page)
|
|
results := []map[string]interface{}{
|
|
{"id": "2", "title": "B Book", "library_id": "test-lib-id"},
|
|
{"id": "3", "title": "C Book", "library_id": "test-lib-id"},
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(map[string]interface{}{"data": results})
|
|
})
|
|
|
|
handler.ServeHTTP(rr, req)
|
|
assert.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
var response map[string]interface{}
|
|
err := json.Unmarshal(rr.Body.Bytes(), &response)
|
|
require.NoError(t, err)
|
|
|
|
data := response["data"].([]interface{})
|
|
assert.LessOrEqual(t, len(data), 2, "Should respect limit parameter")
|
|
})
|
|
}
|