# Test Inventory What automated coverage actually exists, what it actually verifies, and what doesn't have coverage yet. Keep this current as tests are added — it's the thing a Package Checkpoint review (see `docs/testing/README.md`) reads first to know what "run the tests" actually checked. Run everything below in one shot with `scripts/run_checkpoint_tests.py`. Last verified against `main`: 2026-08-20 (commit `927f9bd`) — full PC1 checkpoint run, fresh clone, migrations + pytest + all 4 Godot smoke tests + both platform exports, all clean. ## Backend — `backend/tests/` (pytest) Run: `cd backend && python -m pytest -v` (needs `DATABASE_URL` pointed at a reachable Postgres — see the runner script). **Current total: 68 tests, all passing on a clean `main` checkout.** | File | Tests | What it covers | |---|---|---| | `test_auth_age_gate.py` | 17 | `calculate_age()` date-math correctness (exact boundary, leap years, birthday-not-yet-this-year) + `RegisterRequest` date-of-birth validation. Backs the 18+ registration gate (PR #23). | | `test_gltf_metadata.py` | 21 | glTF/GLB binary + JSON parsing: magic-byte detection, chunk-padding handling, mesh/animation/texture-reference metadata extraction, malformed-input rejection. Backs the asset-import pipeline (PR #27). | | `test_auth_endpoints.py` | 11 | Real integration tests against the FastAPI app via `TestClient`: register, login, duplicate username/email, wrong password, JWT shape. Hits a real Postgres, not mocked (PR #35). | | `test_refresh_endpoint.py` | 8 | `POST /auth/refresh` end-to-end: valid token exchange, distinct access tokens per call (jti-based), invalid/missing token rejection, login-issued tokens also work (PR #37). | | `test_refresh_token_jti.py` | 6 | Refresh-token `jti` uniqueness and the `refresh_tokens.token` column length/type (PR #33's RS256 upgrade). | | `test_auth_expired_token.py` | 5 | Expired-token rejection on two distinct paths: an access JWT with a past `exp` claim, and a refresh token whose persisted `expires_at` is in the past (PR #38). | **What changed since the last inventory (2026-08-19):** that version said "no integration/endpoint tests at all" — that gap is closed. `test_auth_endpoints.py`, `test_refresh_endpoint.py`, `test_refresh_token_jti.py`, and `test_auth_expired_token.py` all hit the real FastAPI app against a real Postgres, not mocks. The suite is also re-runnable without manual cleanup now — `backend/tests/conftest.py` has a session-scoped autouse fixture that truncates all app tables once before the suite runs. **Known coverage gaps** (real gaps, not placeholders): - `/worlds` (POST) and `/assets/*` have no endpoint tests yet — `GET /worlds` is covered indirectly via the Godot smoke tests below, but there's no pytest coverage for either. - No tests for the moderation schema/migration — it exists (`0003_add_moderation_tables_and_user_roles`) and the migration itself runs clean, but nothing in `backend/tests/` exercises the models or any moderation endpoint (there isn't one yet). ## Godot client — `scripts/smoke_test_*.gd` **4 real smoke tests merged on `main`.** Each needs a live backend — `AGP_API_BASE_URL` env var, falling back to the `application/agp/api_base_url` project setting (default `http://127.0.0.1:8000`) if unset. Run: `godot --headless --path . --import` once (builds the class cache — skip this and every `class_name`-declared class falsely errors as undeclared), then for each file below: `godot --headless --path . --script res://scripts/.gd` — **no `--quit`**, it kills these before their awaited HTTP calls finish. | File | What it covers | |---|---| | `smoke_test_api.gd` | `ApiClient.health_check()` against a live backend — the HTTP request path itself (`HTTPRequest` node lifecycle, JSON parse, result-dictionary contract). | | `smoke_test_auth.gd` | 6 real scenarios end-to-end: register, duplicate username, under-18 rejection, correct login, wrong password, non-existent user. | | `smoke_test_e2e.gd` | Full loop: health check → register → login → fetch worlds list, 4/4 steps. | | `smoke_test_world_list.gd` | Instantiates the real `world_list.tscn` scene (not just the API layer) — registers a user, adds the scene to the tree, confirms it reaches a real end state (cards, empty-list, or error) and actually renders world cards when data exists. | **Known gap:** `get_me()` (`GET /auth/me`) is implemented in `scripts/api_client.gd` but has no smoke coverage yet. ## Client export `scripts/build.sh` produces real Linux (`agp-game.x86_64`) and Windows (`agp-game.exe`) binaries via `--export-release`. Verified 2026-08-20: both exports complete clean from a fresh checkout and produce valid binaries (confirmed via `file` — real ELF64/PE32+, not empty or truncated). Neither export is exercised by an automated GUI test (headless Godot can't drive a window) — actually launching and clicking through the exported binary is a manual step, see the checkpoint playtest instructions. ## What "full coverage" should eventually mean here Not defined precisely yet — the honest target is "close the /worlds POST and /assets/* gaps next, and add get_me() smoke coverage" rather than a number. As real integration/endpoint tests get added, update the tables above rather than letting this doc drift stale; a wrong inventory is worse than no inventory.