Files

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 before app/config import, because config.py reads them at import time.
  • The Flask app is built once per sessioncreate_app() can't run twice (the api_bp sub-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.