test: add EDR passenger pricing/config E2E bug-hunt harness

Hermetic E2E harness targeting pricing integrity and backoffice config:
- e2e/ docker Postgres (5544) + prepare.sh/run.sh one-command runner + HTML report
- 6 suites / 23 tests reproducing pricing, FX, wallet, refund, config and auth
  defects (see docs/ISSUES.md); docs/e2e-test-matrix.md documents the matrix
- two-tier harness (slim module boot + direct service instantiation) to work
  around the IAM/RabbitMQ/file-type boot wall
- .env.test.example tracked; loader falls back to it for fresh checkouts

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Muluhabt
2026-07-20 16:22:40 +03:00
parent 5d94e8acf2
commit c4f54a666b
24 changed files with 1938 additions and 2 deletions

76
e2e/README.md Normal file
View File

@@ -0,0 +1,76 @@
# EDR Passenger — Pricing/Config E2E Harness
Hermetic, bug-hunting test harness for the passenger platform. Targets **pricing integrity** and
**backoffice configuration**. Never touches a real database.
## Quick start
```bash
# 1. Bring up the isolated test Postgres (port 5544) and apply all migrations
bash e2e/prepare.sh
# (or: pnpm --filter @edr/passenger-api test:e2e:prepare)
# 2. Run the suites
pnpm --filter @edr/passenger-api test:e2e
# 3. Tear down
pnpm --filter @edr/passenger-api test:e2e:db:down
```
## What's isolated
- `e2e/docker-compose.yml` — Postgres 17 on host port **5544**, container `edr-passenger-e2e-db`,
`tmpfs` data (wiped on `down`). Distinct from any dev/prod DB. Schemas `passenger`, `iam`,
`edr_payment` created by `e2e/init/01-schemas.sql`.
- `apps/edr-passenger-api/.env.test` — points every connection at 5544; brokers/IAM/Fayda OFF.
Loaded by `test/setup/load-env.ts` before the app boots.
## Architecture — why two tiers
The full `AppModule` cannot be booted in-process under jest:
- `@tria-plc/api-common` (pulled via IAM) `require("file-type")`, which is ESM-only → jest's
CommonJS resolver fails. (Worked around with a `moduleNameMapper` stub, but…)
- `@golevelup/nestjs-rabbitmq` + microservice RMQ clients + `onApplicationBootstrap` seeders hang
the boot waiting on a broker that isn't there.
So tests use one of two tiers:
**Tier 1 — slim module harness** (`test/setup/slim-app.ts`). Boots ONLY the pricing/config domain
modules that are free of the IAM/RabbitMQ chain: `fare-engine, currency, currencies, promos,
seat-classes, stations, schedules, segments, system-config`. Two entry points:
- `createServiceHarness()` — resolve services (e.g. `FareEngineService`) for direct method calls.
- `createHttpHarness()` — full HTTP app with the SAME `ValidationPipe` as `src/main.ts`, for
controller/DTO/pipe (client-trust, validation) tests over supertest.
**Tier 2 — direct instantiation** (`test/setup/prisma.ts`). For services behind the wall
(`BookingsService, PaymentsService, WalletService, LoyaltyService, ExcessBaggageService`):
`new TheService(getTestPrisma(), ...mockedCollaborators)` and assert the money logic. Avoids booting
the module graph entirely.
## Fixtures
`test/fixtures/seed-core.ts` — deterministic graph (coach type → LOCAL/INTERNATIONAL seat classes →
3 stations → route with distance-bearing stops → FX rates) with fixed UUIDs in `IDS`. Call
`resetAndSeedCore(prisma)` in `beforeEach`. The repo's `prisma/seed.ts` is disabled (all steps
commented out) and is intentionally NOT used.
## Suites (see `docs/e2e-test-matrix.md` for the full matrix)
Spec files are `test/*.e2e-spec.ts`. Each is tagged with the matrix IDs it covers. 🔴 in a test name
marks a confirmed defect the test documents/reproduces (the assertion encodes the BUGGY behavior;
a passing 🔴 test = the bug is present).
Current suites (all green):
- `pricing-fare-engine.e2e-spec.ts` — baseline + D1/D2/D4 (promo → negative total), C1 (FX fallback)
- `pricing-currency.e2e-spec.ts` — C2/C2b (display↔charge FX divergence), C3 (future rate), C5 (unit divergence)
- `money-integrity.e2e-spec.ts` — F1/F2 (free wallet top-up), G4/G5 (refund never disbursed), E1/E2 (baggage)
- `config-validation.e2e-spec.ts` — H1/H2 (negative fares), H4/H5 (promo bounds/date)
- `auth-gaps.e2e-spec.ts` — J1 (unauthenticated FX writes)
- `critical-repro.e2e-spec.ts` — C-1 (client-controlled booking total), C-4 (payment amount never
validated), C-6 (wallet double-spend via a deterministic race barrier)
`test/app.e2e-spec.ts` is a pre-existing repo test that boots the FULL AppModule; it is excluded via
`testPathIgnorePatterns` because that boot hangs in-process (RabbitMQ connect + ESM `file-type`) — a
harness limitation documented above, not a product bug.
Findings are catalogued in `docs/ISSUES.md`.