Update TestRestoreSystemCollection_ValidNames to use the correct title case format for system collection names. The API handler validates these specific collection names: - "Continue Reading" - "Recently Added" - "Recently Read" - "Not Started" The test was previously using kebab-case names (e.g., "continue-reading") which were being rejected by the validation logic with 400 Bad Request. This aligns the test with the updated collection name format used throughout the application.
244 lines
7.6 KiB
Go
244 lines
7.6 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"testing"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/stretchr/testify/suite"
|
|
)
|
|
|
|
type DashboardIntegrationTestSuite struct {
|
|
suite.Suite
|
|
setup *TestServerSetup
|
|
}
|
|
|
|
func (s *DashboardIntegrationTestSuite) SetupSuite() {
|
|
s.setup = setupTestServer(s.T())
|
|
}
|
|
|
|
func (s *DashboardIntegrationTestSuite) TearDownSuite() {
|
|
s.setup.Close()
|
|
}
|
|
|
|
func (s *DashboardIntegrationTestSuite) TestGetSections_EndToEndFlow() {
|
|
token := s.setup.Token
|
|
|
|
// Create test library
|
|
libraryID := createTestLibraryWithFolder(s.T(), s.setup.Server, token, "Test Library", false)
|
|
|
|
// Execute API call
|
|
url := fmt.Sprintf("%s/api/dashboard/sections?library_id=%s", s.setup.Server.URL, libraryID)
|
|
req, _ := http.NewRequest("GET", url, nil)
|
|
req.Header.Set("Authorization", "Bearer "+token)
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
require.NoError(s.T(), err)
|
|
defer resp.Body.Close()
|
|
|
|
assert.Equal(s.T(), http.StatusOK, resp.StatusCode)
|
|
|
|
var response map[string]interface{}
|
|
err = json.NewDecoder(resp.Body).Decode(&response)
|
|
require.NoError(s.T(), err)
|
|
|
|
sections, ok := response["sections"].([]interface{})
|
|
require.True(s.T(), ok, "sections should be an array")
|
|
require.Len(s.T(), sections, 4, "Should have 4 system collections")
|
|
|
|
// Verify response structure
|
|
sectionMap := make(map[string]map[string]interface{})
|
|
for _, sec := range sections {
|
|
section := sec.(map[string]interface{})
|
|
sectionMap[section["id"].(string)] = section
|
|
|
|
// Verify field types
|
|
assert.IsType(s.T(), false, section["is_system"], "is_system should be boolean")
|
|
assert.IsType(s.T(), "", section["title"], "title should be string")
|
|
assert.IsType(s.T(), "", section["description"], "description should be string")
|
|
assert.IsType(s.T(), "", section["icon"], "icon should be string")
|
|
assert.IsType(s.T(), float64(0), section["priority"], "priority should be number")
|
|
}
|
|
|
|
// Verify all system collections exist
|
|
assert.Contains(s.T(), sectionMap, "continue-reading")
|
|
assert.Contains(s.T(), sectionMap, "recently-added")
|
|
assert.Contains(s.T(), sectionMap, "recently-read")
|
|
assert.Contains(s.T(), sectionMap, "not-started")
|
|
|
|
// Verify continue-reading is a system collection
|
|
continueReading := sectionMap["continue-reading"]
|
|
assert.True(s.T(), continueReading["is_system"].(bool), "continue-reading should be system collection")
|
|
assert.Equal(s.T(), "📖", continueReading["icon"], "icon should match")
|
|
}
|
|
|
|
func (s *DashboardIntegrationTestSuite) TestGetSections_MissingLibraryID() {
|
|
token := s.setup.Token
|
|
|
|
req, _ := http.NewRequest("GET", s.setup.Server.URL+"/api/dashboard/sections", nil)
|
|
req.Header.Set("Authorization", "Bearer "+token)
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
require.NoError(s.T(), err)
|
|
defer resp.Body.Close()
|
|
|
|
assert.Equal(s.T(), http.StatusBadRequest, resp.StatusCode)
|
|
}
|
|
|
|
func (s *DashboardIntegrationTestSuite) TestGetSections_InvalidLibraryID() {
|
|
token := s.setup.Token
|
|
|
|
req, _ := http.NewRequest("GET", s.setup.Server.URL+"/api/dashboard/sections?library_id=invalid-uuid", nil)
|
|
req.Header.Set("Authorization", "Bearer "+token)
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
require.NoError(s.T(), err)
|
|
defer resp.Body.Close()
|
|
|
|
assert.Equal(s.T(), http.StatusBadRequest, resp.StatusCode)
|
|
}
|
|
|
|
func (s *DashboardIntegrationTestSuite) TestGetSections_Unauthorized() {
|
|
req, _ := http.NewRequest("GET", s.setup.Server.URL+"/api/dashboard/sections?library_id="+uuid.New().String(), nil)
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
require.NoError(s.T(), err)
|
|
defer resp.Body.Close()
|
|
|
|
assert.Equal(s.T(), http.StatusUnauthorized, resp.StatusCode)
|
|
}
|
|
|
|
func (s *DashboardIntegrationTestSuite) TestUpdatePreferences_Success() {
|
|
token := s.setup.Token
|
|
libraryID := createTestLibraryWithFolder(s.T(), s.setup.Server, token, "Test Library", false)
|
|
|
|
reqBody := map[string]interface{}{
|
|
"library_id": libraryID,
|
|
"hidden_collections": []string{"not-started"},
|
|
"collection_order": []string{"recently-added", "continue-reading", "recently-read"},
|
|
"items_per_section": 20,
|
|
}
|
|
body, _ := json.Marshal(reqBody)
|
|
|
|
req, _ := http.NewRequest("PUT", s.setup.Server.URL+"/api/dashboard/preferences", bytes.NewBuffer(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("Authorization", "Bearer "+token)
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
require.NoError(s.T(), err)
|
|
defer resp.Body.Close()
|
|
|
|
assert.Equal(s.T(), http.StatusOK, resp.StatusCode)
|
|
|
|
var response map[string]interface{}
|
|
err = json.NewDecoder(resp.Body).Decode(&response)
|
|
require.NoError(s.T(), err)
|
|
|
|
assert.Contains(s.T(), response, "hidden_collections")
|
|
assert.Contains(s.T(), response, "collection_order")
|
|
assert.Contains(s.T(), response, "items_per_section")
|
|
}
|
|
|
|
func (s *DashboardIntegrationTestSuite) TestUpdatePreferences_Unauthorized() {
|
|
reqBody := map[string]interface{}{
|
|
"library_id": uuid.New().String(),
|
|
"hidden_collections": []string{},
|
|
"collection_order": []string{},
|
|
"items_per_section": 20,
|
|
}
|
|
body, _ := json.Marshal(reqBody)
|
|
|
|
req, _ := http.NewRequest("PUT", s.setup.Server.URL+"/api/dashboard/preferences", bytes.NewBuffer(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
require.NoError(s.T(), err)
|
|
defer resp.Body.Close()
|
|
|
|
assert.Equal(s.T(), http.StatusUnauthorized, resp.StatusCode)
|
|
}
|
|
|
|
func (s *DashboardIntegrationTestSuite) TestRestoreSystemCollection_InvalidName() {
|
|
token := s.setup.Token
|
|
|
|
reqBody := map[string]interface{}{
|
|
"collection_name": "invalid-collection-name",
|
|
}
|
|
body, _ := json.Marshal(reqBody)
|
|
|
|
req, _ := http.NewRequest("POST", s.setup.Server.URL+"/api/dashboard/restore-system-collection", bytes.NewBuffer(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("Authorization", "Bearer "+token)
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
require.NoError(s.T(), err)
|
|
defer resp.Body.Close()
|
|
|
|
assert.Equal(s.T(), http.StatusBadRequest, resp.StatusCode)
|
|
}
|
|
|
|
func (s *DashboardIntegrationTestSuite) TestRestoreSystemCollection_Unauthorized() {
|
|
reqBody := map[string]interface{}{
|
|
"collection_name": "continue-reading",
|
|
}
|
|
body, _ := json.Marshal(reqBody)
|
|
|
|
req, _ := http.NewRequest("POST", s.setup.Server.URL+"/api/dashboard/restore-system-collection", bytes.NewBuffer(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
require.NoError(s.T(), err)
|
|
defer resp.Body.Close()
|
|
|
|
assert.Equal(s.T(), http.StatusUnauthorized, resp.StatusCode)
|
|
}
|
|
|
|
func (s *DashboardIntegrationTestSuite) TestRestoreSystemCollection_ValidNames() {
|
|
token := s.setup.Token
|
|
|
|
validCollections := []string{"Continue Reading", "Recently Added", "Recently Read", "Not Started"}
|
|
|
|
for _, collName := range validCollections {
|
|
s.T().Run(collName, func(t *testing.T) {
|
|
reqBody := map[string]interface{}{
|
|
"collection_name": collName,
|
|
}
|
|
body, _ := json.Marshal(reqBody)
|
|
|
|
req, _ := http.NewRequest("POST", s.setup.Server.URL+"/api/dashboard/restore-system-collection", bytes.NewBuffer(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
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 response map[string]interface{}
|
|
err = json.NewDecoder(resp.Body).Decode(&response)
|
|
require.NoError(t, err)
|
|
|
|
assert.Contains(t, response, "message")
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDashboardIntegrationTestSuite(t *testing.T) {
|
|
suite.Run(t, new(DashboardIntegrationTestSuite))
|
|
}
|