# Testing

**`docs/mvp-test-plan.html` is CLOSED** — it was the MVP's acceptance criterion and finished 143
of 143 passing on 2026-09-03. Renamed from `test-plan.html` on 2026-09-07 (Arfu: "the test plan is
over, it was for MVP only") so nobody mistakes it for the current one. Open it in a browser to read
what was walked: 143 rows across six panels, each with pass/fail state and a note saved in
`localStorage`, plus the known gaps.

**Full-product work does not add rows to it.** There is no manual plan for that phase yet.

> `docs/` is gitignored (`.gitignore:29`), so `mvp-test-plan.html` does **not** ship with the repo.
> Decide before handover whether it should.

```bash
composer test                 # 295 PHPUnit tests in 39 files (~7s)
php vendor/bin/phpunit --filter test_name_fragment
php vendor/bin/phpunit tests/Feature/BookingServiceTest.php

npm run e2e                   # 13 Playwright specs in 6 files
npm run e2e:ui                # interactive runner
npm run e2e:report            # last HTML report
```

## Rules

- **Class-based PHPUnit** (`extends TestCase`, `testX()` methods). **Pest is not adopted** — do
  not add it.
- **Write the test before the fix** when fixing a bug, and **confirm it fails on the old code**.
  An assertion that passes either way is not a regression test.
- **Run the suite before declaring a task done.**
- `tests/Feature/TenancyIsolationTest.php` **must stay green at all times**. Cross-tenant access
  is a test failure, full stop.
- `tests/Unit/Engine*` run **without a database** — that is the point of keeping `app/Flow/*`
  pure, and why they are the fastest signal in the suite.
