# Testing

Integration tests are the primary safety net. The full suite lives in the `tests/` workspace and is organised by domain. Tests run against **real Postgres, Redis, and SQS** (or a local stub for SQS via `QueueTestProxy`). There are no mocked databases — if you're tempted to mock one, see the precedent in `tests/utils/TestUtils.ts` first.

## How to run a single test

Per the root CLAUDE.md, tests are executed with `ts-mocha` from inside the `tests/` folder. The canonical command:

```bash
cd tests
ts-mocha --bail --exit --timeout=500000 api/098.RateLimiter.ts
```

Key flags:

- `--bail` — stop at the first failing test
- `--exit` — force Mocha to exit after the suite (otherwise dangling Redis/DB connections prevent exit)
- `--timeout=500000` — long timeout because many tests do multi-step state-transition checks (500 s)

To run a whole domain:

```bash
cd tests
ts-mocha --bail --exit --timeout=500000 api/0*.ts
```

## Domain Layout

```
tests/
├── api/             — Auth, accounts, media, Shopify, moderation   (~85 files)
├── auth/            — Auth core + security controls                  (2 files)
├── cloud-api/       — Rooms, connections, media-server msgs        (~69 files)
├── fabricator/      — Orders, shipping, inventory, DHL            (~111 files)
├── social/          — Friends, blocks, notifications, presence     (~26 files)
├── scan-yourself/   — iOS scan handoff + auth                       (2 files)
├── kb/              — Knowledge-base ingestion + query              (6 files)
├── utils/           — Shared test helpers (TestUtils, accounts, cloud, queue proxy)
├── survey/          — Test orchestration + reporting
├── allowed_apps.json — App key allow-list for tests
└── products.json   — Product seed data for Fabricator tests
```

Approximate test counts come from the file listings as of this rebuild; actual counts drift as tests are added.

## The Survey Runner

Running `yarn test:survey` (or `yarn test:survey:full`, `yarn test:parallel`, `yarn test:review`) at the repo root invokes the orchestration tools in [tests/survey/](../tests/survey). These are a higher-level layer on top of ts-mocha that:

- Walks the test domains in [`config.ts`](../tests/survey/config.ts)
- Decides which tests to run (changed files only vs. everything)
- Runs them sequentially or in parallel
- Collects results and generates HTML / JSON reports
- Provides a CLI review UI for past runs

```mermaid
flowchart LR
    CFG["survey/config.ts<br/>(categories, patterns,<br/>timeouts)"] --> RUN["test-runner.ts"]
    RUN -->|per domain| MOCHA["ts-mocha<br/>child process"]
    MOCHA -->|per test| RESULT["TestResult<br/>(pass/fail/time)"]
    RESULT --> STATE["SurveyState<br/>(persisted to .out/)"]
    STATE --> REPORT["report-generator.ts"]
    REPORT --> HTML["HTML + JSON reports"]
    STATE --> REVIEW["review-tool.ts<br/>(CLI review UI)"]

    subgraph Parallel["Parallel variant"]
        PARRUN["parallel-runner.ts"] -->|N workers| MOCHAP["ts-mocha × N"]
        MOCHAP --> RESULT
    end
```

The survey state is persisted to `tests/.out/` (or similar) so you can resume a partial run. `review-tool.ts` lets you re-examine failures interactively after the fact.

## Test Helpers

The shared helpers in `tests/utils/` save a lot of boilerplate:

| File | What it provides |
|------|------------------|
| [`TestUtils.ts`](../tests/utils/TestUtils.ts) | Spins up the API / Cloud servers in-process for integration testing. |
| [`TestUtils.Accounts.ts`](../tests/utils/TestUtils.Accounts.ts) | Helpers for creating test accounts with preset access policies. |
| [`TestUtils.Cloud.ts`](../tests/utils/TestUtils.Cloud.ts) | Cloud-specific helpers (rooms, users, sessions). |
| [`QueueTestProxy.ts`](../tests/utils/QueueTestProxy.ts) | Stubs/inspects SQS queue interactions so tests don't hit live AWS. |

## Writing a new test

- Drop it under the correct domain folder, numbered (e.g. `api/112.MyNewThing.ts`). Numbers are for rough grouping — files are globbed, not listed.
- Use `ts-mocha` + `chai` + `chai-http` — that's the house style across every existing test.
- Create accounts via the helpers in `TestUtils.Accounts`; don't hand-roll account INSERTs.
- If you need to assert on queue messages, use `QueueTestProxy`.
- If your test needs a particular access policy, attach it via `TestUtils.Accounts` rather than modifying the DB directly.

## Before pushing

The repo root README is explicit: **make sure all tests pass before pushing an update.** For large changes, running `yarn test:survey:full` is the fastest way to get a cross-domain signal.
