Files
JQC_multi_tenant/tests

Tests

The first automated tests for JQC. Kept deliberately small and targeted at the places where a bug is catastrophic and non-obvious — the money path (Stripe webhooks), the SLA state machine, and the multi-tenant routing invariant.

Running

pip install -r requirements-dev.txt
pytest

No MySQL, Redis, or Stripe account is required. tests/conftest.py sets throwaway SECRET_KEY / DATABASE_URL (in-memory SQLite) at import time so the app package imports cleanly, and every test either exercises pure functions or uses the in-memory engine.

What's covered

File Scope Infra needed
test_sla.py SLA thresholds + ok/at_risk/breached/None boundaries none
test_billing_webhooks.py _ts_to_dt, status normalization, handle_event dispatch + error-swallowing none
test_tenant_routing.py Routing is inert with no tenant; resolved g.tenant_engine wins in-memory SQLite

Not yet covered (needs a live control DB + ≥2 tenant DBs)

These are the highest-value integration tests to add next. They require a throwaway MySQL control DB plus two provisioned tenant DBs, so they live outside this fast unit suite for now:

  1. Cross-tenant isolation — resolve tenant A, write a row, resolve tenant B, assert the row is invisible. Proves RoutingSession never leaks across tenants. This is the single most important test the project can have.
  2. Webhook handlers end-to-end_on_payment_failed sets past_due_since and subscription_status='past_due'; _on_payment_succeeded clears the dunning columns. Assert against a real Tenant row.
  3. bootstrap_tenant vs upgrade_tenant — a freshly bootstrapped tenant DB ends stamped at chain head with the full schema (the logic scripts/scratch_bootstrap_test.py proves manually today).
  4. Billing gate state machine — trial-expired redirects to /billing/subscribe; cancelled redirects to /billing/suspended.