central/tests
Matt Johnson c317c9ab01 fix(csrf): replace fastapi-csrf-protect with session-bound CSRF
Fixes CSRF race condition where every GET rotated the CSRF token,
causing POST failures when users had multiple tabs or slow connections.

Changes:
- Remove fastapi-csrf-protect dependency
- Add session-bound CSRF tokens stored in config.sessions table
- Add pre-auth CSRF for unauthenticated routes (/login, /setup/operator)
- Add csrf.py module for pre-auth token generation/validation
- Update routes to use new CSRF token handling
- Add migration 013 to add csrf_token column to sessions

The session-bound approach ensures CSRF tokens remain stable for the
duration of a session, eliminating the race condition.

Note: Route tests (test_wizard.py, test_adapters.py, etc.) need
refactoring to mock get_settings() instead of CsrfProtect dependency.
Core auth/CSRF handler tests pass (74 tests).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-18 03:16:37 +00:00
..
__init__.py scaffold: initial repository structure 2026-05-15 19:16:24 +00:00
conftest.py feat(gui): add auth core, setup gate, and first-run operator creation 2026-05-17 05:30:49 +00:00
README.md chore: normalize line endings to LF 2026-05-16 22:26:12 +00:00
test_adapters.py feat(gui): Leaflet region picker (1b-5) (#19) 2026-05-17 16:53:27 -06:00
test_api_keys.py feat(gui): add API keys management routes (#23) 2026-05-17 18:46:39 -06:00
test_archive_multi_stream.py fix(archive): subscribe to all event streams 2026-05-17 19:29:38 +00:00
test_audit.py feat(gui): add auth core, setup gate, and first-run operator creation 2026-05-17 05:30:49 +00:00
test_auth.py fix(csrf): replace fastapi-csrf-protect with session-bound CSRF 2026-05-18 03:16:37 +00:00
test_bootstrap_config.py chore: housekeeping - orphan branch + three stale tests (#22) 2026-05-17 18:14:58 -06:00
test_config_source.py chore: normalize line endings to LF 2026-05-16 22:26:12 +00:00
test_config_store.py chore: normalize line endings to LF 2026-05-16 22:26:12 +00:00
test_crypto.py chore: normalize line endings to LF 2026-05-16 22:26:12 +00:00
test_csrf_handler.py fix(csrf): replace fastapi-csrf-protect with session-bound CSRF 2026-05-18 03:16:37 +00:00
test_csrf_race_condition.py fix(csrf): replace fastapi-csrf-protect with session-bound CSRF 2026-05-18 03:16:37 +00:00
test_dashboard.py fix(gui): dashboard polls card + CSRF exception handler 2026-05-17 22:34:13 +00:00
test_events_adapter_column.py docs: add test database setup, restore geom to test fixture 2026-05-17 18:26:48 +00:00
test_firms.py feat(schema): add adapter column to events, drop source 2026-05-17 16:09:59 +00:00
test_gui_scaffold.py fix(tests): update tests for lazy app loading and 302 redirect 2026-05-17 06:14:25 +00:00
test_models.py chore: housekeeping - orphan branch + three stale tests (#22) 2026-05-17 18:14:58 -06:00
test_nws_normalization.py chore: housekeeping - orphan branch + three stale tests (#22) 2026-05-17 18:14:58 -06:00
test_region_picker.py feat(gui): Leaflet region picker (1b-5) (#19) 2026-05-17 16:53:27 -06:00
test_session_auth.py fix(csrf): replace fastapi-csrf-protect with session-bound CSRF 2026-05-18 03:16:37 +00:00
test_setup_gate.py feat(gui): implement first-run setup wizard (1b-8) 2026-05-17 19:06:23 -06:00
test_streams.py feat(gui): add streams view (1b-6) (#21) 2026-05-17 18:04:23 -06:00
test_supervisor_hotreload.py chore: normalize line endings to LF 2026-05-16 22:26:12 +00:00
test_supervisor_integration.py fix(tests): update supervisor integration tests for config_store (#20) 2026-05-17 17:29:51 -06:00
test_usgs_quake.py chore: normalize line endings to LF 2026-05-16 22:26:12 +00:00
test_wizard.py fix(gui): handle revisiting /setup/operator after operator created 2026-05-17 20:08:50 -06:00

Central Tests

Test Database

Some tests (notably test_config_store.py) require a real PostgreSQL database. By default, tests connect to:

postgresql://central_test:testpass@localhost/central_test

If your test database uses different credentials, set the CENTRAL_TEST_DB_DSN environment variable:

export CENTRAL_TEST_DB_DSN="postgresql://myuser:mypass@localhost/mydb"
uv run pytest tests/test_config_store.py