feat: tests & bootstrap

This commit is contained in:
Anatoly Antonov 2026-04-22 02:26:43 +09:00
parent 4bd927bb4e
commit 79e20ca37c
19 changed files with 706 additions and 23 deletions

120
docs/TESTING.md Normal file
View file

@ -0,0 +1,120 @@
# Testing
End-to-end tests run against the **full chain**:
```
Playwright → leaflet_svelte (Vite :5173)
│ proxies /api → :8000
stratoflights Django (:8000)
│ TAWHIRI_BASE_URL → :8001
fake_tawhiri stub (:8001)
```
The real production flow replaces the stub with
[tawhiri](https://fly.stratonautica.ru/api/v2/) or the Go-based
`predictor-refactored` running on `:8080`. Any service that speaks the
Tawhiri v2 query-string protocol is drop-in compatible.
## One-time setup
**Python deps for stratoflights** (uses sqlite via `DJANGO_ENV=production` to
avoid needing Postgres):
```bash
pip install --user --break-system-packages \
Django djangorestframework djangorestframework-simplejwt drf-spectacular \
requests django-cors-headers Pillow python-dotenv channels daphne
```
**Initialize the Django DB** (sqlite at `stratoflights/db.sqlite3`):
```bash
cd /home/anton/stratoflights
DJANGO_ENV=production python3 manage.py migrate
DJANGO_ENV=production \
DJANGO_SUPERUSER_USERNAME=demo \
DJANGO_SUPERUSER_PASSWORD=demo \
DJANGO_SUPERUSER_EMAIL=demo@demo.demo \
python3 manage.py createsuperuser --noinput
```
**Playwright browsers** (first time only):
```bash
cd /home/anton/leaflet_svelte
npx playwright install chromium
```
## Running tests
```bash
# Start the full stack (Vite, Django, fake predictor).
scripts/run-stack.sh
# Run the Playwright suite.
npm run test:e2e
# Tear down.
scripts/stop-stack.sh
```
Individual files: `npm run test:e2e -- tests/e2e/workspaces.spec.ts`.
UI mode for debugging: `npm run test:e2e:ui`.
## Test organization
| File | Covers |
|------|--------|
| `auth.spec.ts` | Anonymous → login redirect, form login, already-authed visits |
| `smoke.spec.ts` | Page loads, MapLibre canvas mounts, navbar renders |
| `workspaces.spec.ts` | Auto-create, add/remove, prediction render pipeline |
| `settings.spec.ts` | Locale switch updates UI text live |
| `saved-points.spec.ts` | Point editor modal opens |
Fixtures (`tests/e2e/fixtures.ts`) provide `login(context)` / `logout(context)`
helpers that go through `page.context().request` so cookies are shared with
the page.
## Key gotchas
- **Django CSRF is origin-aware.** If Playwright hits `127.0.0.1:5173` but
`CSRF_TRUSTED_ORIGINS` only lists `localhost:5173`, every POST returns 403
with `{"detail": "CSRF Failed: Origin checking failed"}`. `run-stack.sh`
adds both hostnames to `CSRF_TRUSTED_ORIGINS`.
- **Test parallelism is disabled** (`fullyParallel: false`, `workers: 1`)
because fixtures share the Django sqlite DB. If we ever want parallel
workers we need per-worker DBs.
- **The fake tawhiri never fails.** To test the frontend's error path you
need to either stop the fake or point `TAWHIRI_BASE_URL` at an unreachable
host.
- **`window._lsvMap`** is only set in dev builds (`import.meta.env.DEV`), so
the workspace render test won't see the layer names in a production bundle.
## Swapping in the Go predictor
`fake_tawhiri.py` is an expedient stub. To swap in the real Go predictor:
```bash
cd /home/anton/predictor-refactor/predictor-refactored
PREDICTOR_DATA_DIR=/tmp/predictor-data go run ./cmd/api &
# ^ first run downloads ~9 GB of GFS GRIB data; takes 3060 minutes.
# Then restart stratoflights with TAWHIRI_BASE_URL pointing at it:
cd /home/anton/stratoflights
TAWHIRI_BASE_URL=http://127.0.0.1:8080/api/v1/ python3 manage.py runserver
```
## Patched files in stratoflights
To make this stack work we made one tiny change in stratoflights so the
predictor endpoint is configurable:
```python
# stratoflights_api/services/tawhiri.py
class TawhiriClient:
BASE_URL = os.getenv("TAWHIRI_BASE_URL", "https://fly.stratonautica.ru/api/v2/")
```
This is backwards-compatible — the default keeps the existing behavior.