Files
bookhoard/docs/TESTING.md
T
john-okeefe ff96ffa92d Update documentation and API tests: Bookmann → Bookhoard
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.
2026-02-01 16:20:56 -05:00

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

  1. 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"
    
  2. 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 server
  • db: Database queries interface
  • cfg: Test configuration
  • handler: 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

  1. Use Table-Driven Tests for multiple similar test cases
  2. Test All Error Paths: Not just success cases
  3. Validate Response Structure: Check all expected fields
  4. Test Edge Cases: Empty inputs, invalid IDs, boundary values
  5. Use Subtests: For organizing related test cases
  6. Clean Up Resources: Always close response bodies
  7. Use require.NoError for setup, assert.NoError for test conditions
  8. 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

  1. Database Connection Errors

    # Ensure database is running
    podman ps | grep postgres
    
    # Check connection string
    echo $DATABASE_URL
    
  2. 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
    
  3. 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
  4. 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 -short flag for faster CI runs
  • Parallel test execution with -parallel flag

Optimization Tips

  1. Use Test Caching: Go 1.18+ caches test results
  2. Minimize Database Calls: Create test data once
  3. Parallelize Independent Tests: Use t.Parallel()
  4. 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