| 1 |
# MNW Server Tests |
| 2 |
|
| 3 |
## Prerequisites |
| 4 |
|
| 5 |
- PostgreSQL running locally (default: `postgres://localhost/postgres`) |
| 6 |
- Set `TEST_DATABASE_URL` if using a non-default admin connection |
| 7 |
|
| 8 |
## Test Types |
| 9 |
|
| 10 |
### Unit Tests (`cargo test --lib`) |
| 11 |
|
| 12 |
Pure logic: pricing, validation, formatting, enums, error handling, CSRF, RSS, file scanning, import parsing. No database required. |
| 13 |
|
| 14 |
### Integration Tests (`cargo test --test integration`) |
| 15 |
|
| 16 |
Workflow modules under `tests/workflows/`. Each test gets an isolated PostgreSQL database cloned from a shared template (migrations applied once, then reused across runs while migration-current). Run with `--test-threads=8`; full parallelism overwhelms PostgreSQL. |
| 17 |
|
| 18 |
**Harness features:** |
| 19 |
- In-process Axum app (no network, uses `tower::ServiceExt::oneshot`) |
| 20 |
- Cookie-aware HTTP client with automatic CSRF token management |
| 21 |
- Mock Stripe (`MockPaymentProvider`), captures checkout sessions, supports webhook signing |
| 22 |
- Mock email (`MockEmailTransport`), captures all sent emails for assertion |
| 23 |
- Mock S3 (`InMemoryStorage`), in-memory file storage |
| 24 |
- Direct SQL helpers for test setup (`grant_creator`, `grant_tier`, `connect_stripe`, etc.) |
| 25 |
|
| 26 |
**Harness constructors:** |
| 27 |
- `TestHarness::new()`: DB only (fastest, for auth/CRUD tests) |
| 28 |
- `with_storage()`: adds in-memory S3 |
| 29 |
- `with_mocks()`: mock Stripe + email (for payment flow tests) |
| 30 |
- `with_stripe()`: real Stripe SDK with test keys |
| 31 |
- `with_admin()`: pre-created admin user |
| 32 |
- `with_storage_and_scanner()`: file scanning pipeline |
| 33 |
- `with_git_repos(path)`: git repository support |
| 34 |
- `with_admin_storage_and_scanner()`: admin user + in-memory S3 + scanner |
| 35 |
- `with_synckit_storage()`: SyncKit in-memory bucket (OTA tests) |
| 36 |
- `with_creator_tier_checkout()`: mock Stripe + a configured Everything-tier price |
| 37 |
- `with_postmark()`: Postmark webhook tokens configured |
| 38 |
|
| 39 |
Anything not covered by a constructor goes through `TestHarness::build(BuildOptions { .. })` |
| 40 |
directly; add a documented `BuildOptions` field rather than a constructor per calling test. |
| 41 |
|
| 42 |
**Seeding:** `harness/seed.rs` provides `seed_user` and `seed_project` for the |
| 43 |
`db_*_layer.rs` contract tests, which run against a bare `TestDb` with no router |
| 44 |
and so cannot use `signup`. Prefer the harness methods (`signup`, `create_creator`, |
| 45 |
`create_creator_with_item`) anywhere a session or HTTP flow is in play. |
| 46 |
|
| 47 |
### Seal Tests |
| 48 |
|
| 49 |
Ratchets over the repo itself, each its own binary. No database. |
| 50 |
|
| 51 |
- `assumptions.rs`: the business assumptions TOML parses, validates, and still resolves every marker in the site-docs corpus. |
| 52 |
- `migration_hygiene.rs`: new migrations use `CONCURRENTLY` / `IF NOT EXISTS` and opt out of the per-migration transaction correctly. |
| 53 |
- `frontend_globals.rs`: the `window.*` global count only goes down. |
| 54 |
- `bases_mirror.rs`: every file in `static/bases/` hashes to its own filename, and the directory's README table lists exactly those files. |
| 55 |
- `test_hygiene.rs`: test-suite conventions: doc headers, `#[ignore]` reasons, and `HIGH_WATER` counts for loose status assertions, `test_` prefixes, and oversized modules. |
| 56 |
- `workflows/enum_drift.rs`: every domain enum's variants match its Postgres `CHECK` list (needs a DB; runs inside the integration binary). |
| 57 |
|
| 58 |
### Load Tests (`cargo test --test load -- --ignored --nocapture`) |
| 59 |
|
| 60 |
Multi-scenario virtual user simulation. Requires `--ignored` flag. Configurable via env vars: |
| 61 |
- `LOAD_VUS`: virtual users (default: 20) |
| 62 |
- `LOAD_DURATION_SECS`: duration (default: 30) |
| 63 |
- `LOAD_RAMP_SECS`: ramp-up (default: 5) |
| 64 |
- `LOAD_MIX`: scenario shares, e.g. `anon:25,buyer:15,creator:10,dash:50`. Must sum to 100. |
| 65 |
- `QUASI_SCREENS`: which screens serve from the description layer (`*` for all). |
| 66 |
- `LOAD_MT_LATENCY_MS`: how long the stub Multithreaded sleeps before answering (default: 0). |
| 67 |
- `LOAD_MT_MEMBERSHIPS`: rows the stub answers with (default: 8). |
| 68 |
- `LOAD_PROBE_MS`: blocking-pool probe interval (default: 50). |
| 69 |
|
| 70 |
The report carries two things beyond the endpoint table: |
| 71 |
|
| 72 |
- **`Rej`**, 4xx other than 429. Read it first. A rejected request is fast, so a |
| 73 |
route quietly answering 403 or 404 wins a latency comparison it never ran. |
| 74 |
- **Blocking-pool dispatch delay.** How long a fresh `spawn_blocking` waits to |
| 75 |
start, sampled through the run. The description layer's whole runtime cost is |
| 76 |
that quasi's router is sync, so every described request holds a pool thread; |
| 77 |
this is whether that pool still has headroom. `RuntimeMetrics` would say it |
| 78 |
directly but is behind `tokio_unstable`, which this tree does not build with. |
| 79 |
Read it with the `POST /join/step/account` mean, which is argon2 and the same |
| 80 |
fact from the other end. |
| 81 |
|
| 82 |
For comparing the description layer against Askama, use |
| 83 |
`scripts/load-conversion-ab.sh` rather than driving `QUASI_SCREENS` by hand: it |
| 84 |
runs the alternating-pairs protocol (Askama / described / described / Askama) at |
| 85 |
one fixed mix, so the four runs stay comparable. |
| 86 |
|
| 87 |
### Health Tests (`cargo test --test health`) |
| 88 |
|
| 89 |
External HTTP tests against a running server at `http://localhost:3000`. Skips gracefully if server is not running. |
| 90 |
|
| 91 |
## Running |
| 92 |
|
| 93 |
```bash |
| 94 |
# Unit tests only (fast, no DB) |
| 95 |
cargo test --lib |
| 96 |
|
| 97 |
# Integration tests (requires PostgreSQL) |
| 98 |
cargo test --test integration |
| 99 |
|
| 100 |
# Specific workflow |
| 101 |
cargo test --test integration sandbox |
| 102 |
|
| 103 |
# All tests |
| 104 |
cargo test |
| 105 |
``` |
| 106 |
|
| 107 |
## Fixtures |
| 108 |
|
| 109 |
Test media files in `tests/fixtures/`: `.mp3`, `.mp4`, `.flac`, `.webm`, `.ogg`, `.wav`, `.m4a` |
| 110 |
|