200 lines
7.7 KiB
Markdown
200 lines
7.7 KiB
Markdown
# Backend API Test Guide
|
|
|
|
This directory contains the backend API test suite. The tests use pytest, FastAPI's `TestClient`, and an isolated in-memory SQLite database. The goal is to cover the business-critical API behaviour without relying on MySQL, SMTP, or a running browser.
|
|
|
|
## How To Run
|
|
|
|
From `backend/`:
|
|
|
|
```bash
|
|
pytest
|
|
pytest --cov=app --cov-report=term-missing
|
|
```
|
|
|
|
From the project root with Docker Compose running:
|
|
|
|
```bash
|
|
docker compose exec api pytest
|
|
docker compose exec api pytest --cov=app --cov-report=term-missing
|
|
```
|
|
|
|
## Shared Fixtures
|
|
|
|
### `conftest.py`
|
|
|
|
Sets up the test harness used by every module.
|
|
|
|
What it does:
|
|
- Provides safe default environment variables before the app imports settings.
|
|
- Creates an in-memory SQLite database and overrides FastAPI's `get_db` dependency.
|
|
- Recreates all tables for every test so tests cannot leak state into each other.
|
|
- Patches SQLite primary-key handling for models that use `BigInteger` ids in production.
|
|
- Provides `client` for unauthenticated requests and `auth_client` for administrator/operator requests.
|
|
- Provides reusable PPR payload and factory fixtures.
|
|
|
|
Why it exists:
|
|
- Keeps API tests fast, deterministic, and independent from Docker MySQL data.
|
|
- Lets tests exercise the real FastAPI routes, schemas, CRUD calls, and dependency overrides.
|
|
|
|
## Test Modules
|
|
|
|
### `test_app_health.py`
|
|
|
|
Covers the simplest application-level endpoints.
|
|
|
|
What it tests:
|
|
- `/` returns API metadata.
|
|
- `/health` reports a healthy application and database connection.
|
|
|
|
Why it matters:
|
|
- These tests catch broken app imports, router setup problems, and database dependency regressions early.
|
|
|
|
### `test_auth_api.py`
|
|
|
|
Covers authentication and admin user-management routes.
|
|
|
|
What it tests:
|
|
- Login rejects invalid credentials.
|
|
- Login returns a bearer token for a valid user.
|
|
- Admin users can create, list, update, and change passwords for users.
|
|
- Duplicate users and missing users return the expected errors.
|
|
|
|
Why it matters:
|
|
- Auth is the gatekeeper for most operational endpoints.
|
|
- The admin user flow is also a good end-to-end check of password hashing, token creation, CRUD, and journal side effects.
|
|
|
|
### `test_pprs_api.py`
|
|
|
|
Covers the core PPR lifecycle.
|
|
|
|
What it tests:
|
|
- PPR routes require authentication where appropriate.
|
|
- Authenticated users can create, read, update, patch, acknowledge, status-update, soft-delete, and audit PPRs.
|
|
- List filters work for status, dates, skip, and limit.
|
|
- Public PPR creation sends email and generates secure edit tokens.
|
|
- Public edit and cancel token flows work and reject invalid or processed requests.
|
|
- Activation creates an arrival and pending departure.
|
|
- Missing PPRs return 404.
|
|
- Invalid payloads return validation errors.
|
|
|
|
Why it matters:
|
|
- PPRs are the central workflow in the system.
|
|
- These tests protect the operational state transitions that drive tower/admin views and audit history.
|
|
|
|
### `test_public_api.py`
|
|
|
|
Covers public read-only board and lookup endpoints.
|
|
|
|
What it tests:
|
|
- Public arrivals and departures start empty.
|
|
- Today's PPRs, local flights, arrivals, and departures appear on public boards.
|
|
- Old or cancelled records are excluded.
|
|
- Public airport and aircraft lookups return seeded records.
|
|
- Short or invalid lookup queries return empty lists.
|
|
|
|
Why it matters:
|
|
- Public boards and lookup helpers are user-facing and unauthenticated.
|
|
- These tests check that the public API exposes useful operational information without requiring login.
|
|
|
|
### `test_flight_strip_apis.py`
|
|
|
|
Covers authenticated flight-strip style CRUD endpoints.
|
|
|
|
What it tests:
|
|
- Arrival lifecycle: create, list/filter, read, update, land, cancel, and not-found paths.
|
|
- Landing an arrival promotes a linked pending departure.
|
|
- Departure lifecycle: create, list/filter, update, takeoff/departure status, cancel, and not-found paths.
|
|
- Local flight lifecycle: create, list/filter, update, depart, land, special lists, cancel, and not-found paths.
|
|
- Overflight lifecycle: create, active/today lists, list/filter, update, mark inactive/QSY, cancel, and not-found paths.
|
|
- Movement records are created for real takeoff, landing, touch-and-go, and overflight events where relevant.
|
|
|
|
Why it matters:
|
|
- These endpoints represent day-to-day tower strip operations.
|
|
- They also exercise important CRUD side effects: status timestamps, movements, linked departures, and journal entries.
|
|
|
|
### `test_circuits_api.py`
|
|
|
|
Covers circuit/touch-and-go records.
|
|
|
|
What it tests:
|
|
- Circuits can be recorded for local flights.
|
|
- Circuits can be recorded for arrivals.
|
|
- Circuit list, lookup-by-flight, lookup-by-arrival, update, and delete work.
|
|
- Invalid circuit creation requests are rejected when neither or both parent ids are supplied.
|
|
- Missing circuits return 404.
|
|
- Recording a circuit creates a touch-and-go movement.
|
|
|
|
Why it matters:
|
|
- Circuit traffic is a distinct operational pattern and feeds movement logging.
|
|
- The parent-id validation prevents ambiguous audit/movement records.
|
|
|
|
### `test_movements_api.py`
|
|
|
|
Covers movement listing, context lookup, and bulk paper-strip logging.
|
|
|
|
What it tests:
|
|
- Movement list filters and single-record reads.
|
|
- Bulk movement context suggests matching PPRs and existing movements.
|
|
- Bulk logging can create and update PPR-linked arrivals.
|
|
- Bulk logging can create unmatched arrival and departure records.
|
|
- Bulk logging handles local flight strips with takeoff, landing, duration, and circuits.
|
|
- Bulk logging handles overflight strips and updates existing overflight records.
|
|
- Invalid bulk-log requests return helpful 400 errors.
|
|
|
|
Why it matters:
|
|
- Bulk movement logging is one of the densest workflows in the API.
|
|
- These tests protect the behaviour that translates paper-strip data into PPR, arrival, departure, local flight, overflight, movement, and journal records.
|
|
|
|
### `test_drone_requests_api.py`
|
|
|
|
Covers drone flight request workflows.
|
|
|
|
What it tests:
|
|
- Public drone request creation generates references/tokens and sends confirmation email.
|
|
- Public edit and cancel token flows work.
|
|
- Processed drone requests cannot be edited or cancelled publicly.
|
|
- Authenticated users can list, read, update, status-update, comment on, and audit drone requests.
|
|
- Missing records and invalid payloads return expected errors.
|
|
|
|
Why it matters:
|
|
- Drone requests are a newer workflow with public and authenticated surfaces.
|
|
- The tests protect email notification, public token, status, comment, and journal behaviour.
|
|
|
|
### `test_public_book_api.py`
|
|
|
|
Covers the optional public booking portal.
|
|
|
|
What it tests:
|
|
- Public booking rejects requests when disabled.
|
|
- Public local flight booking creates a public-submitted local flight.
|
|
- Public circuit recording creates a circuit and touch-and-go movement.
|
|
- Public departure and arrival booking create public-submitted records with pilot emails.
|
|
- Invalid public booking payloads return validation errors.
|
|
|
|
Why it matters:
|
|
- Public booking is controlled by configuration and should be safe to disable.
|
|
- When enabled, it creates operational records without authentication, so validation and submitted-via metadata matter.
|
|
|
|
### `test_journal_api.py`
|
|
|
|
Covers generic audit/journal endpoints.
|
|
|
|
What it tests:
|
|
- Journal search filters by date, entity type, entity id, and user.
|
|
- Invalid entity types are rejected.
|
|
- User journal and entity journal endpoints return entries and summary counts.
|
|
|
|
Why it matters:
|
|
- The journal is the audit trail across PPRs, flights, users, drone requests, and movements.
|
|
- These tests make sure audit entries remain queryable as the system grows.
|
|
|
|
## Current Scope
|
|
|
|
The suite intentionally focuses on API behaviour, local WebSocket broadcast behaviour, and database side effects. It does not deeply test:
|
|
- Full browser WebSocket lifecycle.
|
|
- Real SMTP delivery.
|
|
- Browser UI behaviour.
|
|
- Every branch of low-level validators or helper functions.
|
|
|
|
Those areas are better handled with focused unit tests or E2E tests later.
|