# Tests

Plain Node scripts — no npm install, no dependencies, no config. Every path
resolves from `__dirname`, so this folder works on any machine the project is
copied to (Windows or Linux).

```bash
cd tests
node run-all.js         # summary
node run-all.js -v      # full output from every suite
node test-roles.js      # or run one directly
```

## What each suite covers

| File | Checks |
|---|---|
| `test-structure.js` | HTML: balanced markup, every `getElementById` target exists, every inline handler resolves to a real function |
| `test-network.js` | Club pyramid, downline rollup arithmetic, card-block allocation, repeat-guest matching, new-club creation |
| `test-roles.js` | Downline visibility is admin/manager only; role change forces scope back; all club × scope combinations render |
| `test-api.js` | API layer: demo fallback, debounce, scan error cases, hydration refills arrays in place, server refusals respected |
| `test-pwa.js` | manifest validity, icons are real PNGs at declared sizes, service worker parses, duplicate-check is never cached |
| `test-migrations.js` | Laravel migrations: structure, every `create` has a matching `dropIfExists` |
| `test-php-structure.js` | Laravel app code: balanced braces, `<?php` opener, **case-sensitive** PSR-4 paths |
| `test-feature-audit.js` | Every feature claimed in `PROJECT_NOTES.md` is actually present in the code |

`harness.js` is the shared DOM mock that loads the dashboard's script blocks
into Node. It concatenates all inline `<script>` blocks in document order, the
way a browser would.

## What these do NOT cover

**Nothing here proves the Laravel API works.** The PHP checks are *structural
only* — braces, file paths, migration symmetry. No PHP has ever been executed
against this project.

`test-api.js` tests the front-end against a **mocked** backend. That proves the
client handles the contract correctly. It proves nothing about whether the
server implements that contract — field names, status codes and response shapes
are all still unverified.

## Once PHP is installed

These become possible and are worth doing in order:

```bash
php -l $(find api -name '*.php')      # lint every file — never run yet
php artisan migrate                   # first real test of the schema
php artisan db:seed
php artisan serve
curl localhost:8000/api/login-options
```

Then a Pest/PHPUnit feature suite is the thing that would actually make the
backend trustworthy — particularly:

- `BranchScope` really hides other clubs' rows (try to read across, expect empty)
- A coach cannot roll up, even with a forged `X-Branch-Id` header
- `POST /guests` returns 409 for a known person and 201 with `acknowledge_repeat`
- The duplicate lookup finds a match by name+DOB when the phone differs
- Two concurrent scans of one card produce one row, not two
- Recharge amount comes from `price_history`, not from the request body
