Built with Chinaski

Testing

The test suite’s shape mirrors the product: numbered pre-flight checks, then per-feature files, plus regression suites tied to specific issue numbers, adversarial “exploit” tests for past vulnerabilities, and the separate MCP suite. This page maps the coverage.

The pre-flight files

  • 00-compile.t — the whole application compiles (skips cleanly if Mojolicious/DBI aren’t installed, since it is a smoke check, not a dependency installer).
  • 01-schema.t — the schema itself is what migrations then reproduce; this test validates the schema file.
  • 02-media-sniff.t — media upload sniffing behavior.
  • 03-util.t, 04-webhook.t — utility-layer and webhook-dispatch unit suites.

Per-feature suites

Each API-managed entity gets a suite of its own, usually one per area: pages, posts, blocks (incl. per-type helpers and the block-type palette), snippets, categories, media, documents, nav, redirects, themes, users, audit, drafts_restore, library, health, i18n, settings. Forms and submissions are also their own area (forms.t, submissions.t, submission_values.t), including the file-upload restrictions and quota tests.

Security and adversarial regressions

A dedicated exploit_… family of tests re-creates historically reported exploits as tests, each with a comment describing the vulnerability fixed:

  • Read-only API keys bypassing write gates (#4827) — the session-gate accepted read-scope API keys on mutating routes; the test forces the gate to require write scope for POST/PUT/PATCH/DELETE.
  • API nav privilege escalation — mutating navigation entries (and the admin 404-log intake) with a too-scoped key is rejected.
  • API rate-limit double counting — the per-key rate counter must increment once per HTTP request (a regression previously counted it per auth layer).
  • Documents path traversal — crafted filenames attempting to escape the documents directory.
  • Forms mass-assignment — POSTing values for fields the form never declared is rejected.
  • Theme file dot-placeholder injection — the theme file editor’s path handling blocks crafted paths.
  • A security-regression sweep (exploit_security_regression.t) — a broad adversarial suite.

The naming convention (exploit_issue_tag.t) makes every vulnerability “regression-testable”: each is labeled with a specific issue number so future changes know the fix they must not break.

A whole suite for backup subsystem behaviors

Several separate files cover the backup and restore machinery (backup_*.t): snapshot creation, retention, restore dry-run previews and confirmation, manifest validation, retention, API restores.

Build behavior suites

  • Minimum test: build_helpers run per-language render waves with the Hunni microscopy check (the review-api builds).
  • build_speed_4636/4637/4638: the parallel-build performance test series; a per-build “timings” suite validates per-phase times against fixture tests; incremental builds assert in a mixed-mode test.
  • Build suites measure on a small corpus asserting code paths (fingerprint, minification, link scans, schema) and confirm data races/wall-time conditions (via build_speed_4637-examples — the multiple-speed regression ideas).

Air-gap and platform behaviors

  • Email-when-airgap disabled behaviors (admin_email_airgap.t), SMTP-failure paths (admin_email_smtp.t, form_email_smtp_fail.t) and forced SMTP-hand-rolled CRLF checks (form_email_crlf.t).
  • Turnstile gate: behind turnstile_* settings, verify panels as a separate suite (turnstile_gate.t).
  • Upward-facing ports of URL routing, XML escaping (sitemap/feed safety), and statement-checking in route shadow guards.

The miscellany of suites worth knowing about

  • The migrations suite verifies each migration file’s uniqueness when re-run on a temp DB (idempotency/safe re-run) and cross-checks migration vs schema so schema.sql and migrations can’t drift (migrations_lint.t, migrations_has_table.t, migrations_helpers.t).
  • Installation testing (installer-install.t, installer-bundle.t) covers the offline bundle install path.
  • zz_phase80_verify.t runs late (alphabetically last) as a verify layer crossing multiple areas.

In this section