# Testing Test infrastructure and manual recipes for the Africa Alert PWA. Owned by the `tester` rein. ## Status - No test framework installed yet — bootstrap is the tester's first sprint. - Target stack: Vitest (client + server) + Supertest (server) + Playwright (E2E, when needed). ## When you add a new feature 1. Producer writes the feature. 2. Producer hands off to `tester` with a one-line description of the happy path and at least one adversarial path. 3. `tester` writes unit + integration tests, runs them, and reports coverage to the orchestrator. 4. `code-reviewer` audits the tests for circular assertions and demands real-run evidence for the user path. ## Manual recipes (for things that don't auto-test credibly) ### Paynow webhook idempotency 1. Initiate a payment via the UI or `POST /api/payments/initiate` with a small amount. 2. Capture the returned `payment_id`. 3. `curl -X POST http://localhost:3001/api/payments/webhook -d '{ "payment_id": "", "status": "paid" }'` — twice in a row. 4. Verify the database has exactly one row in `payments` for that `student_fee_id` and `student_fees.status = 'paid'`. Two POSTs, one state change. ### Sync engine round-trip 1. Set `SUPABASE_URL` to a local stub (e.g. `http://localhost:4000/rest/v1/`) and `SUPABASE_KEY` to anything truthy. 2. `POST /api/sync/force`. 3. Inspect `sync_logs` — every table should be `success` or `skipped` (offline), no `failed` for a clean round. 4. `GET /api/sync/status` → `lastSync` updated, `totalPending` decreased. ### Offline PWA 1. `npm run dev` in `client/` and `server/`. 2. Open the app, log in, navigate to a couple of pages (warms the service worker cache). 3. DevTools → Application → Service Workers → confirm `sw.js` is `activated`. 4. DevTools → Network → Offline. 5. Reload. The shell should still render; cached pages should still open; the dashboard fetch may fail with a clear offline banner (this is fine — the design point is "no white screen of death"). ## CI (planned) GitHub Actions workflow at `.github/workflows/test.yml` (when the user adds it): - Matrix: Node 20.x - Steps: install (client + server), `npm test` in each, build client. ## Test data isolation - Use `data/school.test.db` for integration tests, never the real `data/school.db`. - Each test or describe block gets a fresh DB file (or in-memory `:memory:`). - Don't mock the DB schema — copy the relevant `CREATE TABLE` block from `server/src/database/init.js`.