Files
aurum/backend/tests
technosexual b045d378f0 fix(security): stop granting every origin credentialed access to the API (#5)
`AURUM_CORS_ORIGINS` defaults to `*`, and the middleware was configured with
`allow_credentials=True`. Starlette does not answer that combination with a
literal `*` — it echoes back whatever `Origin` the caller sent and adds
`Access-Control-Allow-Credentials: true`, so any page open in the same
browser can call the instance, with the user's Basic Auth attached, and read
the response:

    GET /api/accounts   Origin: https://evil.example
    -> Access-Control-Allow-Origin: https://evil.example
       Access-Control-Allow-Credentials: true

That undercuts the README's advice that leaving Basic Auth off is fine while
the instance is only reachable from localhost: reachable-from-localhost
includes every website the user visits.

Nothing in the shipped setup is cross-origin. Compose serves the UI and the
API from the same nginx, and the Vite dev server proxies `/api`
(frontend/vite.config.ts), so neither deployment nor development needs CORS
at all. The default is therefore empty — no cross-origin access — and the
middleware is only installed when origins are configured deliberately.

An explicit `*` is still honoured for a genuinely public read-only setup, but
never together with credentials, which is what the spec intends `*` to mean
anyway.
2026-08-30 18:11:09 +03:00
..

Backend tests

Real integration tests against a real Postgres database — a dedicated aurum_test database created fresh, migrated, and dropped again on every run. They never touch the real aurum database or its data: the app's lifespan startup (which seeds against the real DB) is never triggered, and every route's DB dependency is overridden to point at aurum_test instead.

Running

The stack must already be up (docker compose up -d). Test dependencies aren't baked into the production image, so install them once per container lifetime, then run pytest inside the running backend container — it's the only place with network access to Postgres:

docker compose exec backend pip install -r requirements-dev.txt
docker compose exec backend pytest -v

Re-run just pytest -v for subsequent runs; the pip install only needs repeating after a container restart/rebuild.

Adding a test

  • Use the client fixture (an httpx.AsyncClient wired to the app) to hit the API the same way the frontend does — prefer this over reaching into services/models directly, so tests keep verifying the actual contract.
  • account_id and categories fixtures give you the same default account/categories a real fresh install seeds.
  • Every table is truncated and reseeded before each test (see conftest.py::_clean_database), so tests don't need to worry about leftover state or guess at IDs from a previous test.