Hermetic Supabase test guard (global autouse)
Date: 2026-08-05 · Commit: entirely-api 0eb8a99 · Type: decision
Problem class
Host-side pytest runs use the real /opt/unlikely-api/.env. A test that mocks
its own module’s get_client (e.g. supabase_write_service.get_client) still
leaks to production when the exercised code path calls a downstream service that
resolves services.supabase_service.get_client itself. Instance that proved it:
migration-031 status_event_service inserted 2 fake-project rows into prod
project_status_events on 2026-08-05 (deleted same day).
Decision
Replace the narrow per-module conftest stub with a global autouse fixture in
tests/conftest.py that patches at the choke point: supabase_service._client
(the singleton get_client() returns) + create_client as backstop. This covers
all ~60 importers regardless of import style (top-level bind or function-local),
because they bind the function, not the client.
- Per-test overrides unaffected: tests monkeypatch their own module’s
get_clientattribute, which shadows the real function entirely. - The stub records tables touched;
pytest_sessionfinishprints them so unmocked paths stay visible instead of silently no-opping. - Only bypass in tree:
services/status_poller.py(standalone cron, owncreate_client, imported by nothing tests touch).
Audit result (empirical, from the recorder)
3 test cases reached the real client before the guard:
test_supabase_write_service.py×2 →project_status_events(the known leak)test_holding_pool_actions.py::test_shepherd_findings_include_hold_follow_up_due→ real reads onprojectsviapipeline_shepherd(previously unguarded)
Verification
366 passed, 1 skipped in ~9s (--ignore=tests/test_cert_pipeline.py, known
pillow_heif host-side collection failure). project_status_events canary count
0 → 0 across the run.