Files
edr-platform/e2e
Nathnael 6469c7fa52 test(e2e): cover every onboarding route across portal and backoffice
Five journeys, one file each, every one of them crossing from the portal into
the backoffice and cross-checking the database rather than the screen:

- ethiopian     eTrade verified, Fayda, approved, contract wizard reachable —
                including the dead end a TIN with no trade licence is for an
                ordinary company
- investor      foreign investment licence: nothing on file at eTrade, typed
                registration, passport identity, per-role licence still owed,
                and the backoffice's manual-entry badge and banner
- cooperative   no foreign option, no freight-forwarder role, the co-operative
                document set, no licence cards, its own badge and banner
- switch_back   settings → switch to eTrade → registration cleared, company
                pending, wizard reopened on the company step → re-run through
                eTrade → the flag is gone from the backoffice
- guards        the refused combinations, and the mid-wizard un-tick that has
                to clear the typed registration

Replaces the old onboarding.cy.ts (removed a commit earlier by accident of a
staged deletion): it drove a wizard shape that no longer exists — Fayda before
the company step, a "Personnel" step — so it could only ever have been red.

Notes for whoever edits these next. Attach files to the FIRST empty dropzone,
never by index — SmartFileInput removes the input once a file is on it. Resolve
the company from the database after any cross-origin hop, never from module
state: Cypress re-evaluates the spec bundle and Date.now() with it, which is
what latestJourney's run-stamp cutoff is for. And the deliberate eTrade 400 is
ignored as an uncaught exception — the portal handles that outcome on screen
but leaves the rejected request unhandled at the promise level.
2026-08-18 11:38:37 +00:00
..

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

# 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.