4.0 KiB
Parity — discourse
The recipe-maintainer corpus has no recipe-info/discourse/tests/ directory — discourse was not
in their parity suite (verified absent: /srv/recipe-maintainer/recipe-info/discourse does not
exist). So there is no upstream test to port and parity is genuinely N/A (no silent omission —
there is simply no corpus). Per plan §4.1 this file still documents the Phase-2 health baseline +
recipe-specific tests beyond, and P2's "non-ports documented" requirement is satisfied by this note.
Parity ports
None — no recipe-info/discourse/tests/*.py exists upstream to port. (Not a deliberate omission of a
test that exists; the upstream corpus is absent. Same disposition as ghost / mattermost-lts.)
Recipe-specific tests (Phase-2 P3, ≥2 beyond a bare health check)
Discourse is a forum/discussion platform: a Rails app whose primary object is a topic (a thread
of posts), with a public JSON surface (/site.json, /t/<id>.json, /posts.json) and an Admin API.
Defining behaviors exercised against the live per-run deploy:
| cc-ci file | what's verified | rationale |
|---|---|---|
functional/test_create_topic.py::test_create_topic_roundtrip |
Bootstraps an admin + API key via Rails in the app container (_discourse.mint_admin), POSTs /posts.json to create a NEW topic with a unique marker in title + body, then GETs /t/<topic_id>.json and asserts the title (Discourse title_prettify-aware) and the unique body marker round-tripped in the first post's cooked. |
§4.3 "create the app's primary object — a topic — and read it back". Non-vacuous: the marker is unique per run, so a stale/echoed response can't pass; a wedged DB/Rails/posting path fails here even though /srv/status returns 200. |
functional/test_site_basic.py::test_site_json_has_discourse_config |
GETs /site.json and asserts a Discourse-specific config structure (e.g. a categories list), not a bare 200. |
Proves Rails is serving its real site config JSON (a distinctive Discourse structure), distinguishing "the forum backend is up + emitting its API" from "a static/error page at /". |
functional/test_health_check.py::test_discourse_srv_status_ok |
GETs /srv/status and asserts the Discourse readiness signal (Rails serving). |
Baseline readiness (parity-aligned health check). |
Two recipe-specific functional tests (create-topic round-trip + site.json config) + the health check = the ≥2 floor met, with a real create-an-object + read-it-back as the characteristic-behavior test.
Backup data-integrity (P4) — AUTHORED, non-vacuous
ops.py + the lifecycle overlays (test_backup.py / test_restore.py) seed a deterministic
ci_marker row into the PostgreSQL discourse DB (the recipe's real state store), via the db
service. The recipe's backupbot db pre-hook (/pg_backup.sh backup, added in PR head 3758522) dumps
the DB into the backed-up postgresql_data/backup.sql; the backupbot.restore.* post-hook reimports
it — so the seeded marker rides backup→restore the way a real topic's row would. pre_restore drops
the marker table (divergence so a passing restore can't be a no-op); test_restore.py:: test_restore_returns_state asserts the value returns post-restore. The published recipe had a pg_dump
backup but no restore hook (silent data loss — same class as immich/mattermost-lts/ghost); cc-ci's
P4 overlay caught it, fixed via recipe-PR recipe-maintainers/discourse#1.
A BACKUP_VERIFY probe (recipe_meta.py) re-runs the backup if backup.sql is gzip-invalid/empty
(the chaos-upgrade db-cycle race truncates the dump) — a read-only check that weakens no assertion;
the restore re-read stays the real P4 gate.
Playwright (P6)
Not authored. Discourse's core API surface is exercised over HTTP/JSON above (create-topic round-trip is the characteristic flow); a Playwright login + topic-compose flow would be a future hardening (advisory, not a P3 blocker — the create-an-object behavior is already proven via the Admin API).