Testing
Brand Protect has three layers of tests: the Python unit suite, the Rails suite, and a control-plane end-to-end smoke test.
Python (services/tests/)
Section titled “Python (services/tests/)”-
26 test files + a shared
conftest.py(notably astub_dnstwistfixture that replacesdnstwist.runso discovery tests are hermetic). -
Run from
services/:Terminal window .venv/bin/pytest -q -
Baseline: 557 passed, 1 skipped, 23 warnings. The single skip is the PDF debug-artifact test, which is skipped when
services/tmp/isn’t writable (e.g. root-owned after a container run). -
Known flaky:
test_scoring.py::TestThreats::test_urlhaus_*hit the live URLhaus API (unmocked) and can fail on restricted networks. Pre-existing, unrelated to feature work.
Coverage includes orchestration (stage ordering, parallelism, resume, cancellation, failure isolation), domain generation, RDAP/WHOIS fallback, fingerprinting, identity matching, scoring and threats, AI settings, PDF report correctness, WebSocket/Redis messaging, and the audit MCP server.
Rails (rails_web/test/)
Section titled “Rails (rails_web/test/)”-
Minitest with fixtures (
fixtures :all) and parallelized execution. -
SessionTestHelper#sign_in_assigns a user into controller tests. -
The largest file is
test/controllers/v1/internal_api(547 lines) — the Python→Rails surface. -
Run:
Terminal window cd rails_web && bin/rails test -
Baseline: 117 runs / 390 assertions / 0 failures.
-
TEST_DATABASE_URLis pinned for tests;test.rbsetsmaintain_test_schema = false.
End-to-end (e2e/scan_e2e_test.py)
Section titled “End-to-end (e2e/scan_e2e_test.py)”A control-plane smoke test — it does not run a real scan (no dnstwist, Playwright, or threat feeds). It verifies, against a live Rails + Python pair:
- Liveness: Rails
/upand Python/health. - A learned-weights round trip:
PUTthenGET /v1/scoring/weights— proves auth + persistence. - Publishing scan status and findings on the
brand_protect_cable:*channels. - Polling
GET /v1/scans/:id/audit_datauntil a finding and a final status appear. - The analyst-feedback path (labels surface in
/v1/scoring/feedback_samples).
Run it in CI via the e2e-scan job (see CI/CD).