python3 -m venv venv
venv/bin/pip install -r requirements-dev.txt
Use a dev config (never edit the real config.toml) with static auth:
[auth]
mode = "static"
[auth.static]
username = "admin"
password = "admin"
email = "dev@example.invalid"
role = "admin"
PPSQ_CONFIG=/tmp/dev-config.toml PPSQ_ALLOW_INSECURE=1 venv/bin/python wsgi.py
PPSQ_CONFIG points at your dev file so nothing touches the real config.PPSQ_ALLOW_INSECURE=1 allows an http:// PPS base_url.PPSQ_ALLOW_INSECURE_AUTH=1).[pps] base_url at a mock server, or a throwaway PPS folder.venv/bin/python -m pytest # ~57 tests, < 1s
tests/conftest.py guarantees isolation: a session-scoped autouse fixture sets
PPSQ_CONFIG to a temp copy of config.example.toml before any app import, and
ConfigStore refuses to open the default config.toml under pytest. No test starts a
worker thread — they call queue._process(job) synchronously with a FakePPS that records
every call.
Suites:
| File | Covers |
|---|---|
test_config_store.py |
round-trip (comments preserved), atomic write/perms/backup, redaction, validation, restart-vs-live, client rebuild, migration, isolation guard |
test_auth.py |
is_allowed/safe_next (pure), static login, CSRF, admin gate |
test_oidc.py |
OIDC callback allow/deny/role/demotion (monkeypatched token) |
test_report_release.py |
pipeline: no-deletedfolder rule, lazy refind, fallback, destinations |
test_paging.py |
cursor from raw batch, has_more boundary, _clamp_limit |
test_prefs.py |
override/default/fallback/isolation |
test_jobs_visibility.py |
user attribution, targetfolder validation, per-user scoping |
See AGENTS.md for the module map and the invariants you must not break. In short:
wsgi.py constructs everything; app.py is a factory with no import-time side effects.ConfigStore snapshots (one per request, one per job).pipeline.py — add a step there, not in worker.py.static/app.js, static/admin.js); no build step.@step("name") in pipeline.py + add to ALLOWED_STEPS.config.example.toml (with a comment) → read from snapshot → if
admin-editable, add to ADMIN_EDITABLE + validation in config_store.py.PrefSpec in prefs.py PREF_SPECS.Match surrounding style: from __future__ import annotations, pps.* logger names,
%-style logging, _-prefixed privates.