Update test_inventory.md to reflect PC1 checkpoint reality

Was written 2026-08-19 and badly stale by the time the full PC1
checkpoint validation ran 2026-08-20: said 38 backend tests (actually
68), said zero integration/endpoint tests exist (4 real integration
test files landed since), and said nothing had merged for Godot smoke
tests (4 real ones did).

Verified for real, fresh clone of main, commit 927f9bd: migrations +
68/68 pytest + all 4 Godot smoke tests + both platform exports (Linux
ELF64 + Windows PE32+, confirmed valid via file) all clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
claude-checkpoint-tooling
2026-08-20 00:47:18 +00:00
parent 927f9bd95e
commit afc2211d70
+58 -49
View File
@@ -7,72 +7,81 @@ to know what "run the tests" actually checked.
Run everything below in one shot with `scripts/run_checkpoint_tests.py`. Run everything below in one shot with `scripts/run_checkpoint_tests.py`.
Last verified against `main`: 2026-08-19 (commit `1c75367`). 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) ## Backend — `backend/tests/` (pytest)
Run: `cd backend && python -m pytest -v` (needs `DATABASE_URL` pointed at a Run: `cd backend && python -m pytest -v` (needs `DATABASE_URL` pointed at a
reachable Postgres — see the runner script; most of these tests don't reachable Postgres — see the runner script).
actually touch the DB, but the app's import chain requires a valid URL to
construct).
**Current total: 38 tests, all passing on a clean `main` checkout.** **Current total: 68 tests, all passing on a clean `main` checkout.**
| File | Tests | What it covers | | File | Tests | What it covers |
|---|---|---| |---|---|---|
| `test_auth_age_gate.py` | 10 | `calculate_age()` date-math correctness (exact boundary, leap years, birthday-not-yet-this-year) + `RegisterRequest` date-of-birth validation (parametrized valid/invalid date rejection). Backs the 18+ registration gate (PR #23). | | `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_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 these are, honestly:** pure unit tests of standalone functions **What changed since the last inventory (2026-08-19):** that version said
(`calculate_age`, the glTF parser, Pydantic validators). None of them spin "no integration/endpoint tests at all" — that gap is closed.
up the FastAPI app or hit a real endpoint — they run in ~1s and don't `test_auth_endpoints.py`, `test_refresh_endpoint.py`,
actually need Postgres reachable at all (the import chain just needs a `test_refresh_token_jti.py`, and `test_auth_expired_token.py` all hit the
syntactically valid `DATABASE_URL`, nothing connects during collection). 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 — nothing enforces filling **Known coverage gaps** (real gaps, not placeholders):
these yet): - `/worlds` (POST) and `/assets/*` have no endpoint tests yet — `GET /worlds`
- No integration/endpoint tests at all — `/register`, `/login`, `/refresh`, is covered indirectly via the Godot smoke tests below, but there's no
`/worlds`, `/assets/*` have zero tests that actually call them through pytest coverage for either.
the FastAPI app (e.g. via `httpx.AsyncClient` + `ASGITransport`) against a - No tests for the moderation schema/migration — it exists
real (or test) database. Everything currently shipped works because it (`0003_add_moderation_tables_and_user_roles`) and the migration itself
was manually verified at merge time (checkpoint review), not because a runs clean, but nothing in `backend/tests/` exercises the models or any
test asserts it. moderation endpoint (there isn't one yet).
- No tests for the RS256 auth upgrade (key generation, refresh-token
issuance/persistence) — PR #30, pending review as of this writing,
manually verified (correct key usage, all 38 existing tests still pass)
but not covered by an automated test of its own yet.
- No tests for the moderation schema/migration (in progress as of this
writing) beyond "the migration runs."
## Godot client — `scripts/smoke_test_*.gd` ## Godot client — `scripts/smoke_test_*.gd`
**Nothing merged into `main` yet as of this writing** — `sandbox_probe/test_script.gd` **4 real smoke tests merged on `main`.** Each needs a live backend —
is the only Godot script on `main` right now, and it's **not a real `AGP_API_BASE_URL` env var, falling back to the
test** (a leftover manual probe, returns a hardcoded string, asserts `application/agp/api_base_url` project setting (default
nothing). Don't count it toward coverage; delete or repurpose it if anyone `http://127.0.0.1:8000`) if unset.
actually needs a sandbox probe again.
`scripts/smoke_test_api.gd` (PC1, PR #29, pending review as of this writing) Run: `godot --headless --path . --import` once (builds the class cache —
will be the first real one once merged — `ApiClient` autoload's skip this and every `class_name`-declared class falsely errors as
`health_check()` against a **live backend** (set `AGP_API_BASE_URL` to point undeclared), then for each file below: `godot --headless --path . --script
at one), verified by hand end-to-end before opening the PR: exercises the res://scripts/<name>.gd` — **no `--quit`**, it kills these before their
real HTTP request path (`HTTPRequest` node lifecycle, JSON parse, the awaited HTTP calls finish.
result-dictionary contract), not just that the script compiles. Exits 1 on
failure, so it's CI/script-friendly.
Run (once merged): `godot --headless --path . --import` once (builds the | File | What it covers |
class cache — skip this and every `class_name`-declared class falsely |---|---|
errors as undeclared), then for each `scripts/smoke_test_*.gd`: | `smoke_test_api.gd` | `ApiClient.health_check()` against a live backend — the HTTP request path itself (`HTTPRequest` node lifecycle, JSON parse, result-dictionary contract). |
`godot --headless --path . --script res://scripts/<name>.gd` | `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 once it lands:** only `health_check()` is exercised end-to-end. **Known gap:** `get_me()` (`GET /auth/me`) is implemented in
`login`, `register`, `get_worlds`, `get_me` are implemented (see `scripts/api_client.gd` but has no smoke coverage yet.
`scripts/api_client.gd`) but have no smoke coverage yet — each would need a
real user/world fixture in the target backend to test against meaningfully. ## 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 ## What "full coverage" should eventually mean here
Not defined precisely yet — the honest target as of 2026-08-19 is just Not defined precisely yet — the honest target is "close the /worlds POST
"more than pure-function unit tests." As real integration/endpoint tests get and /assets/* gaps next, and add get_me() smoke coverage" rather than a
added, update the tables above rather than letting this doc drift stale; number. As real integration/endpoint tests get added, update the tables
a wrong inventory is worse than no inventory. above rather than letting this doc drift stale; a wrong inventory is worse
than no inventory.