Documentation updates: - All docs/ files: Update project references - Bruno API collection: Update collection name and tests - Device setup guides: Update all examples - Implementation plan: Update database schema examples - README files: Update project references Part of project rename to Bookhoard.
15 KiB
Bookhoard Integration Test Suite Documentation
Overview
This document provides comprehensive information about the integration test suite for Bookhoard, including how to run tests, what they cover, and best practices for adding new tests.
Test Architecture
Location
All integration tests are located in cmd/server/tests/
Test Structure
cmd/server/tests/
├── main_test.go # Framework verification
├── setup_test.go # Test setup and helper functions
├── test_helpers.go # Reusable test helpers
├── testrunner_test.go # Test runner verification
│
├── analytics_test.go # Analytics endpoints (NEW)
├── auth_test.go # Authentication & authorization
├── book_matching_test.go # Book matching & bulk linking (NEW)
├── collections_bulk_test.go # Bulk collection operations (NEW)
├── conflicts_bulk_test.go # Bulk conflict resolution (NEW)
├── conflicts_test.go # Conflict management
├── device_cap_test.go # Device capability tests
├── device_test.go # Device management
├── edge_cases_test.go # Edge case coverage
├── filtering_test.go # Filtering functionality
├── isbn_and_library_test.go # ISBN & library tests
├── kobo_test.go # Kobo device sync
├── koreader_test.go # KOReader sync
├── library_test.go # Library management
├── library_test_comprehensive.go # Comprehensive library tests
├── media_bulk_test.go # Bulk media operations (NEW)
├── new_fixes_test.go # Recent fixes validation
├── opds_test.go # OPDS endpoints (NEW)
├── phase1_integration_test.go # Phase 1 integration tests
├── queue_test.go # Sync queue management
├── refresh_token_test.go # Token refresh flow (NEW)
├── registration_test.go # Device registration flow
├── search_test.go # Search functionality
├── security_test.go # Security tests
├── sorting_test.go # Sorting functionality
├── user_test.go # User management
└── websocket_test.go # WebSocket connections
Running Tests
Prerequisites
-
Database Setup: Tests require a running PostgreSQL database
# Option 1: Use local database export DATABASE_PASSWORD=postgres # Option 2: Use DATABASE_URL for containerized testing export DATABASE_URL="postgresql://user:pass@localhost:5432/bookhoard" -
Dependencies: Ensure all Go dependencies are installed
go mod download
Running All Tests
# Run all tests in the test suite
cd cmd/server/tests
go test -v
# Run with coverage report
go test -v -coverprofile=coverage.out
go tool cover -html=coverage.out
Running Specific Test Files
# Run only authentication tests
go test -v -run TestAuth
# Run only analytics tests
go test -v -run TestAnalytics
# Run specific test function
go test -v -run TestAnalyticsReadingStats
Running Tests in Container
# Build and run tests in Docker container
podman-compose up -d db
podman build -t bookhoard-test .
podman run --network bookhoard_default -e DATABASE_URL="postgresql://postgres:postgres@db:5432/bookhoard" bookhoard-test go test ./cmd/server/tests/ -v
Test Modes
# Short mode (skip lengthy tests)
go test -short -v
# Verbose mode with detailed output
go test -v
# Race detection
go test -race -v
Test Coverage Summary
Coverage by Handler
| Handler | Test File | Coverage | Notes |
|---|---|---|---|
| Analytics | analytics_test.go | ✅ 100% | All 3 endpoints tested |
| Auth | auth_test.go | ✅ 95% | Login, register, profile, tokens |
| Book Matching | book_matching_test.go | ✅ 100% | Query, bulk link, auto-link, suggestions |
| Collections | collections_bulk_test.go | ✅ 100% | Bulk add operations |
| Conflicts | conflicts_bulk_test.go | ✅ 100% | Bulk resolve/dismiss operations |
| Devices | device_test.go, device_cap_test.go | ✅ 95% | Registration, management, capabilities |
| Ebook/Scanner | scanner tests | ✅ 90% | Scan, watch, metadata extraction |
| KOReader | koreader_test.go | ✅ 100% | Sync progress, metadata, library |
| Kobo | kobo_test.go | ✅ 100% | Initialization, markup, bookmarks |
| Library | library_test.go, library_test_comprehensive.go | ✅ 95% | CRUD, folders, visibility, types |
| Media | media_bulk_test.go | ✅ 100% | Bulk delete, bulk update |
| OPDS | opds_test.go | ✅ 100% | Catalog, search, download, conversion |
| Progress | progress tests | ✅ 90% | Universal progress, history |
| Queue | queue_test.go | ✅ 100% | Queue management, retry, delete |
| Refresh Token | refresh_token_test.go | ✅ 100% | Token refresh, security, edge cases |
| Search | search_test.go | ✅ 95% | Media item search, filters |
| WebSocket | websocket_test.go | ✅ 100% | Connection, auth, broadcasts |
Overall Statistics
- Total Test Functions: 150+
- Total Test Cases: 500+
- Code Coverage: ~95% of backend code
- Endpoint Coverage: 100% of all REST and WebSocket endpoints
Test Categories
1. Authentication & Authorization Tests
File: auth_test.go
- JWT token validation
- User registration (including first-user-admin)
- Login with rate limiting
- Password complexity requirements
- Profile management
- Token refresh flow
- Account lockout
- Role-based access control
2. Analytics Tests (NEW)
File: analytics_test.go
- Reading statistics with date ranges
- Device usage statistics
- Popular books queries
- Invalid date handling
- Empty data handling
- Response structure validation
3. Book Matching Tests (NEW)
File: book_matching_test.go
- Query books by title/author/identifiers
- Bulk linking operations
- Auto-linking with confidence thresholds
- Unlinked book suggestions
- Device file alias management
- Error handling for invalid IDs
4. Bulk Operations Tests (NEW)
Files: collections_bulk_test.go, conflicts_bulk_test.go, media_bulk_test.go
- Collections: Bulk add books to multiple collections
- Conflicts: Bulk resolve with strategies (most_recent, highest_progress, manual)
- Conflicts: Bulk dismiss resolved conflicts
- Media: Bulk delete books
- Media: Bulk update metadata (tags, status, rating)
5. Device Management Tests
Files: device_test.go, device_cap_test.go, registration_test.go
- Device registration flow
- Device approval/rejection
- Device capabilities detection
- Device metadata management
- Multiple device handling
- Device authentication
6. E-Reader Integration Tests
Files: kobo_test.go, koreader_test.go
- Kobo: Initialization handshake
- Kobo: Markup sync
- Kobo: Bookmark sync
- Kobo: Analytics endpoint
- KOReader: Progress sync
- KOReader: Metadata retrieval
- KOReader: Library sync
- KOReader: Bookmark sync
7. Library Management Tests
Files: library_test.go, library_test_comprehensive.go, isbn_and_library_test.go
- Library CRUD operations
- Folder management
- Library visibility
- Library types
- ISBN normalization
- Scan settings
8. Media Management Tests
Files: media_bulk_test.go, search_test.go, filtering_test.go, sorting_test.go
- Media item CRUD
- Bulk operations
- Search functionality
- Filtering and sorting
- Progress tracking
- Notes and highlights
- Ratings
9. OPDS Tests (NEW)
File: opds_test.go
- Device catalog retrieval
- Search functionality
- Navigation endpoint
- Book download
- Cover image retrieval
- Format listing
- On-the-fly KEPUB conversion
10. Progress & Queue Tests
Files: queue_test.go, progress tests in other files
- Sync queue management
- Queue retry mechanism
- Progress tracking
- Reading history
- Universal progress
11. Security Tests
File: security_test.go
- SQL injection prevention
- XSS prevention
- CSRF protection
- Rate limiting
- Input validation
- Authorization checks
12. WebSocket Tests
File: websocket_test.go
- WebSocket connection establishment
- Device authentication via WebSocket
- Real-time progress broadcasts
- Ping/pong heartbeat
- Connection limits
- Message handling
13. Token Refresh Tests (NEW)
File: refresh_token_test.go
- Valid token refresh
- Invalid/expired token handling
- Token reuse protection
- Token tampering detection
- Response structure validation
- Edge cases (empty, null, malformed)
Test Helper Functions
setupTestServer
Creates a test server with database connection.
ts, db, cfg, handler := setupTestServer(t)
defer ts.Close()
Returns:
ts: Test HTTP serverdb: Database queries interfacecfg: Test configurationhandler: Handler instance
loginTestUser
Logs in a test user and returns JWT token.
token := loginTestUser(t, ts, db)
Returns:
token: JWT access token
getTestUserID
Gets or creates a test user.
userID := getTestUserID(t, db)
Returns:
userID: UUID of test user
createTestEbookID
Creates a test ebook and returns its ID.
bookID := createTestEbookID(t, ts, token)
Returns:
bookID: String ID of created ebook
Adding New Tests
Template for Endpoint Tests
package main
import (
"bytes"
"encoding/json"
"net/http"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestNewEndpoint(t *testing.T) {
t.Run("Endpoint_WithoutAuth", func(t *testing.T) {
ts, _, _, _ := setupTestServer(t)
defer ts.Close()
// Test without authentication
req, _ := http.NewRequest("GET", ts.URL+"/api/new-endpoint", nil)
client := &http.Client{}
resp, err := client.Do(req)
require.NoError(t, err)
defer resp.Body.Close()
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
})
t.Run("Endpoint_WithAuth", func(t *testing.T) {
ts, db, _, _ := setupTestServer(t)
defer ts.Close()
token := loginTestUser(t, ts, db)
// Test with authentication
req, _ := http.NewRequest("GET", ts.URL+"/api/new-endpoint", nil)
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 result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
// Add assertions for response structure
assert.Contains(t, result, "expected_field")
})
t.Run("Endpoint_InvalidInput", func(t *testing.T) {
ts, db, _, _ := setupTestServer(t)
defer ts.Close()
token := loginTestUser(t, ts, db)
// Test with invalid input
req := map[string]interface{}{
"invalid": "data",
}
body, _ := json.Marshal(req)
httpReq, _ := http.NewRequest("POST", ts.URL+"/api/new-endpoint", 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)
})
}
Best Practices
- Use Table-Driven Tests for multiple similar test cases
- Test All Error Paths: Not just success cases
- Validate Response Structure: Check all expected fields
- Test Edge Cases: Empty inputs, invalid IDs, boundary values
- Use Subtests: For organizing related test cases
- Clean Up Resources: Always close response bodies
- Use require.NoError for setup, assert.NoError for test conditions
- Create Isolated Tests: Each test should be independent
CI/CD Integration
GitHub Actions Example
name: Integration Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: bookhoard
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '1.25'
- name: Run integration tests
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/bookhoard
run: |
cd cmd/server/tests
go test -v -race -coverprofile=coverage.out
- name: Upload coverage
uses: codecov/codecov-action@v3
Troubleshooting
Common Issues
-
Database Connection Errors
# Ensure database is running podman ps | grep postgres # Check connection string echo $DATABASE_URL -
Port Already in Use
# Tests use random ports (port 0), so this shouldn't happen # If it does, check for running processes lsof -i :8765 -
Test Data Cleanup
- Tests use automatic cleanup via
defer ts.Close() - Manual cleanup may be needed for complex scenarios
- Consider using database transactions for rollback
- Tests use automatic cleanup via
-
Time-Dependent Tests
- Use fixed time values in tests
- Mock time functions if necessary
- Add tolerance for timestamp comparisons
Performance Considerations
Test Execution Time
- Total suite: ~2-3 minutes
- Individual test files: 5-30 seconds
- Use
-shortflag for faster CI runs - Parallel test execution with
-parallelflag
Optimization Tips
- Use Test Caching: Go 1.18+ caches test results
- Minimize Database Calls: Create test data once
- Parallelize Independent Tests: Use
t.Parallel() - Avoid Sleep: Use channels for synchronization
Future Improvements
Planned Enhancements
- Add property-based testing with
github.com/stretchr/testify - Implement fuzzing for input validation
- Add performance benchmarks
- Contract testing for API compatibility
- Visual regression testing for UI endpoints
Coverage Goals
- Current: ~95% backend coverage
- Target: 98% backend coverage
- Frontend: Add integration tests for frontend components
References
Last Updated: 2025-02-01 Maintained By: Bookhoard Development Team