Files
politics-tracking/docs/contributing/testing.md
T
Simon DiesenreiterandClaude Opus 5.5 9da5a1dc48 Politrack: track Austrian politicians from public sources
Initial import of Politrack, a self-hosted service that tracks Austrian
politicians from federal to municipal level - roles, votes, money flows,
statements, meetings, social media and legal proceedings - with every claim
linked to its sources.

- backend: FastAPI + Postgres/pgvector; adapter framework (fetch -> parse ->
  load -> enrich) with robots.txt/TDM-aware fetching, a raw-response archive
  for reparsing, and a claim/evidence model with corroboration
- sources: Parliament, Wikidata, EU Parliament/Commission, Council of
  Ministers, Rechnungshof party reports and donations, procurement, RTR media
  transparency, political ad libraries, WKStA, news feeds, Wikipedia edits,
  Bluesky, Mastodon, public Telegram channels, YouTube and X (official API)
- web: Next.js frontend in German and English with typed API client
- mcp: MCP server for AI agents and RAG
- docs: architecture, data model, sources, legal notes, Unraid deployment and
  contributor guides; Docker Compose setup for Unraid

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 19:47:14 +01:00

51 lines
2.2 KiB
Markdown

# Testing
```bash
cd backend
pytest # everything below except the DB smoke test
pytest tests/test_golden.py -k parlament # one adapter's golden tests
UPDATE_GOLDEN=1 pytest tests/test_golden.py # regenerate expected outputs (review the diff!)
```
| suite | what it covers | needs |
|---|---|---|
| `tests/test_core.py` | framework invariants: request identity, secret redaction, registry consistency, record serialisation, OpenAPI→TS generator, shared helpers | nothing |
| `tests/test_parsers.py` | parsing helpers (vote texts, CSV layouts of the Rechnungshof, dates, normalisation) | nothing |
| `tests/test_extraction.py` | roll-call lists, immunity reports, event/legal/office-title detection | nothing |
| `tests/test_golden.py` | every captured fixture replayed through `adapter.parse()` and compared with `<case>.expected.json` | nothing |
Parsers are pure, so none of these needs a database or network.
## Golden fixtures
```
tests/fixtures/<adapter name>/<case>.request.json {url, kind, meta, content_type, body_file}
tests/fixtures/<adapter name>/<case>.<ext> the captured body
tests/fixtures/<adapter name>/<case>.expected.json parse() output (records as JSON)
```
Capture with `politrack fixture <adapter> <url> <case> --kind <kind> --meta '{"…": …}'`. A fixture
without `.expected.json` creates it on the first run and is skipped until you have reviewed it.
When a source changes its format: capture a new case next to the old one (keep the old one if the
publisher still serves old documents in that format), fix the parser, bump `parser_version`.
## Against a real database
The quickest end-to-end check uses the compose stack:
```bash
docker compose up -d db && docker compose run --rm migrate
docker compose run --rm api politrack run parlament.persons --max-requests 20 -p periods='["XXVIII"]'
docker compose run --rm api politrack enrich
docker compose run --rm api politrack status
curl -s localhost:8000/api/v1/stats
```
`--max-requests` keeps test runs polite. Each run is recorded in the `run` table (stats, errors) and
shown by `politrack status` and `/api/v1/admin/runs`.
## Frontend
`npm run typecheck` (strict TypeScript against the generated API types) and `npm run build`.