Files
ppr-ng/backend/tests
2026-06-20 04:09:38 -04:00
..
2026-06-20 04:01:24 -04:00
2026-06-20 04:09:38 -04:00
2026-06-20 04:09:38 -04:00
2026-06-20 04:01:24 -04:00
2026-06-20 04:01:24 -04:00
2026-06-20 04:01:24 -04:00
2026-06-20 04:01:24 -04:00
2026-06-20 04:01:24 -04:00
2026-06-20 04:01:24 -04:00

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/:

pytest
pytest --cov=app --cov-report=term-missing

From the project root with Docker Compose running:

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.