Tests
Automated test suite (pytest). Runs entirely against an in-memory SQLite
database (TestingConfig) — it never touches MySQL, sends mail, or hits the
network, so it's safe to run anywhere.
Running
pip install -r requirements-dev.txt
pytest
Layout
| File | Covers |
|---|---|
test_score.py |
Inspection score calc — correctness and web/API parity (the two hand-mirrored implementations must agree; CLAUDE.md §9 / rule 40). |
test_sla.py |
SLA engine: sla_status / sla_deadline / sla_hours_remaining across every severity tier and boundary. |
test_public_pages.py |
Login-free QR pages (/f/<token>, /f/area/<token>): rule 74 occupant-safety (no leaked checklist names / scores / descriptions), 404s, and the report-a-problem flow. |
test_models.py |
User.display_name, Issue.handler_label / resolved_facility, public-token minting, and the authenticated area-QR route. |
How the fixtures work (conftest.py)
- Required env vars (
SECRET_KEY,DATABASE_URL,DIGEST_SECRET) are set at import top beforeapp/configimport, becauseconfig.pyreads them at import time. - The Flask app is built once per session —
create_app()can't run twice (theapi_bpsub-blueprints are registered on a module-level singleton). - A fresh app context + schema is created per test. The per-test context
matters: Flask-Login caches the current user on
g(bound to the app context), so a shared context would leak an authenticated user between tests. - Factory fixtures (
make_user,make_facility,make_area,make_template,make_inspection,make_issue) build persisted rows; pass only what you care about.login(user)authenticates via the real login route.