Files
chess/test/README.md
T

7.9 KiB
Executable File

Chess API Test Suite

This directory contains comprehensive test suites for the Chess API server, covering API functionality, database operations, authentication, and real-time updates.

Prerequisites

  • jq - JSON processor
  • curl - HTTP client
  • psql - PostgreSQL client (for database tests)
  • base64 - Base64 encoder (for JWT tests)
  • Stockfish in PATH
  • Compiled bin/chess-server binary (or pass another path to the scripts)
  • A disposable PostgreSQL database named by CHESS_TEST_DSN

CHESS_TEST_DSN must be a libpq-compatible connection string, because the scripts pass it to both chess-server and psql. The test server drops every chess table in that database on start and exit, so never point it at real data.

# One-time setup as a PostgreSQL superuser
psql -U postgres -c "CREATE ROLE chess_test LOGIN PASSWORD 'chess_test'"
psql -U postgres -c "CREATE DATABASE chess_test OWNER chess_test"

export CHESS_TEST_DSN='postgres://chess_test:chess_test@localhost:5432/chess_test?sslmode=disable'

The same variable enables the Go database tests (go test ./...), which create and drop an isolated schema per test and are skipped when it is unset.

Running the test server

From repo root

test/run-test-server.sh

Pass the binary path as the first argument when it is not at bin/chess-server. The server runs with -dev, debug logging, HTTP request logging, and relaxed rate limiting. It drops the test tables on exit, so it's preferred for clean testing. Can be used for all the tests.

Logging can be adjusted without editing the script:

LOG_LEVEL=info LOG_HTTP=false test/run-test-server.sh bin/chess-server

Pre-configured Users

Username Password Email
alice AlicePass123 alice@example.com
bob BobPass456 bob@example.com

Features

  • Automatically initializes database schema
  • Creates three test users
  • Runs on port 8080 (API) and 9090 (Web UI)
  • Development mode with relaxed rate limits
  • Fixed JWT secret for consistent tokens
  • Debug persistence and engine-queue logs by default
  • Graceful shutdown on Ctrl+C

Manual Testing Examples

# Login as alice
curl -X POST http://localhost:8080/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"identifier":"alice","password":"AlicePass123"}'

# Create authenticated game
TOKEN="<jwt-from-login>"
curl -X POST http://localhost:8080/api/games \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"white":{"type":1},"black":{"type":2,"level":10}}'

Test Suite Overview

Test Suite File Coverage
API Functionality test-api.sh Game operations, moves, undo, rate limiting
Database & Auth test-db.sh User registration, login, JWT tokens, persistence
Long-Polling test-longpoll.sh Real-time updates, wait behavior, timeouts
End States test-endstate.sh Checkmate, stalemate, terminal custom positions
Replay test-replay.sh SAN history, PGN export, ETag/304, promotion, FEN validation, cursor-paged listing
Draws & Resignation test-draw.sh Automatic draws, offers (human and computer), resignation and authorization, long-poll wake-up, hand-deleted game row
Test Server run-test-server.sh Pre-populated test environment

1. API Functionality Tests (test-api.sh)

Tests core game mechanics and API endpoints.

Running the test

# Terminal 1: Start server in development mode
test/run-test-server.sh bin/chess-server
# Direct (no cleanup required): bin/chess-server -dev

# Terminal 2: Run API tests
test/test-api.sh

Coverage

  • Game Creation: Human vs Human, Human vs Computer, Computer vs Computer
  • Move Validation: Legal/illegal moves, UCI notation
  • Computer Play: Async engine moves with "cccc" trigger
  • Undo System: Single and multiple move reversal
  • Player Configuration: Dynamic player type changes
  • Rate Limiting: 20 req/s in dev mode
  • Error Handling: Invalid inputs, missing games, wrong content-types
  • Security: Input validation, FEN injection prevention

2. Database & Authentication Tests (test-db.sh)

Tests user management, authentication, and persistence via API integration. Requires Running Server Script

Running the test

# Terminal 1: Start test server with database
# Server is running with -dev and PostgreSQL storage
test/run-test-server.sh bin/chess-server

# Terminal 2: Run API integration tests
test/test-db.sh bin/chess-server

Coverage

  • User Registration: Account creation, password hashing
  • Duplicate Prevention: Username/email uniqueness
  • Authentication: Login with JWT generation
  • Token Validation: JWT parsing and claims verification
  • Password Security: Argon2id hashing, complexity requirements
  • Case Sensitivity: Case-insensitive username/email matching
  • Database Schema: Table creation, constraints, indexes

Test Flow

  1. Re-runs the idempotent schema initialization against CHESS_TEST_DSN
  2. Registers test users (alice, bob, charlie)
  3. Tests authentication endpoints
  4. Validates JWT tokens and claims
  5. Tests duplicate user prevention
  6. Leaves cleanup (dropping tables) to run-test-server.sh

3. Long-Polling Tests (test-longpoll.sh)

Tests real-time game updates via HTTP long-polling.

Running the test

# Terminal 1: Start server with storage
test/run-test-server.sh bin/chess-server
# Direct (table cleanup required): CHESS_DSN="$CHESS_TEST_DSN" bin/chess-server -dev

# Terminal 2: Run long-polling tests
test/test-longpoll.sh

Coverage

  • Basic Long-Polling: Wait for game state changes
  • Multi-Client: Multiple simultaneous waiters
  • Timeout Behavior: 25-second timeout verification
  • Immediate Response: No wait when state already changed
  • Connection Handling: Client disconnect cleanup
  • Game Deletion: Notification on game removal
  • Move Detection: Accurate move count tracking

Test Scenarios

  1. Single Waiter: Client waits, receives update after move
  2. Multiple Waiters: 3 clients wait, all receive notification
  3. Timeout: Verify 25-second timeout with valid response
  4. Skip Wait: Immediate return when moveCount outdated
  5. Disconnection: Proper cleanup on client disconnect

Replay Tests (test-replay.sh)

Exercises the replay API over HTTP with human-vs-human games, so no engine search is involved. Each run registers a fresh account, so it can be repeated against the same server.

# Terminal 1
test/run-test-server.sh bin/chess-server
# Terminal 2
test/test-replay.sh

Covers SAN and results in the history, the PGN attachment (tag order, movetext, ?ply=), ETag/If-None-Match, castling and en passant notation, promotion (a missing piece is rejected, g8=N from the custom position that reported the web-client bug), rejected starting FENs, and cursor paging with status/color filters. API_DELAY (seconds, default 0.06) keeps it under the dev-mode rate limit.

Draw and Resignation Tests (test-draw.sh)

Plays short human-vs-human lines, switching a side to the computer where the computer's answer to a draw offer is tested, so the only engine work is two short evaluations. Each run registers a fresh account and can be repeated against the same server.

test/test-draw.sh

Covers the automatic draws (K+B v K after a capture, a knight shuffle repeated three times, the hundredth quiet ply, a drawn starting position), undo after a draw, resignation (side inference, hot-seat ambiguity, a side claimed by another user), draw offers between humans (standing offer, decline, one offer per move, acceptance waking a long-poll, lapse on the opponent's move), the computer declining early, accepting in a level position and declining when a queen up, and a game whose row is deleted with psql (needs CHESS_TEST_DSN and psql; the server unloads the game and stays healthy).