Testing
An orientation to how the Pasar Seken code repo is tested: the Vitest runner, the four-layer test pyramid, coverage targets, sandbox end-to-end tests, and the pre-push gate. For engineers writing or running tests.
Where this lives​
This page is a projection, not the source of truth. The canonical testing plan lives in the brain and is synced into the pasarseken code repo as a CLAUDE.md detail doc at docs/claude/testing.md (deployed by the brain's deploy.sh). Treat that copy as authoritative, and read it for the full per-file assertion tables and mock reference. Do not add or change test facts here without updating the brain first.
Test runner​
Tests run on Vitest. Domain and application tests live in src/__tests__/.
pnpm vitest run # run the whole suite
pnpm vitest run src/__tests__/domain # run one layer only
The original DDD plan used Deno's built-in Deno.test under supabase/functions/server/tests/. Tests now live in src/__tests__/ and run on Vitest against the NestJS backend. If you find a reference to the old Deno path, it is stale.
The test pyramid​
Four layers, from fast and pure at the base to slow and real at the top. Each layer has its own folder under src/__tests__/ and its own run cadence.
| Layer | Location | Scope | Runs |
|---|---|---|---|
| Unit | src/__tests__/domain | Pure functions, zero I/O | Every save |
| Use case | src/__tests__/application | In-memory repository fakes, no network | Every commit |
| Integration | src/__tests__/infrastructure | Staging PostgreSQL via Drizzle, no external APIs | Every PR |
| E2E | src/__tests__/e2e | Real Xendit and Biteship sandboxes, staging database | Pre-deploy only |
Unit and use-case tests must pass on every commit. Integration tests run on every PR. E2E tests run on the develop branch only and must pass before the change is merged into main.
Coverage targets​
The domain core and the money-critical use cases are held to full coverage. Everything else has a lower floor. The full per-file table lives in the canonical doc.
| Area | Target |
|---|---|
Domain core: Money, OrderStatus (all 14 states), Order, Listing, Phase 1 fees | 100% |
ShippingQuoteSigner (C-2) | 100% branches |
ConfirmPaymentUseCase, including the PAYMENT_REVIEW path | 100% branches |
CreateOrderUseCase, CheckoutFacade | 90%+ |
| All other use cases | 80%+ |
| Infrastructure repositories | 70%+ (integration) |
| Route handlers | 0% unit (covered by E2E) |
Sandbox E2E (Xendit and Biteship)​
End-to-end tests exercise the full order lifecycle against real payment and shipping sandboxes, never production. They are run manually before a production deploy, and in CI only on the develop branch.
They require sandbox credentials (see Environment Variables for the full list):
XENDIT_SECRET_KEY(sandbox)BITESHIP_API_KEY(sandbox)SHIPPING_QUOTE_SIGNING_KEY(test-only)- Staging database
DATABASE_URL
Flows covered end to end include checkout, payment review (C-4), dispute, return (Phase 4), return rejection (M-4), and promotion or boost. Because these call the real sandboxes rather than mocks, they are the slowest layer and are kept few in number.
The pnpm preflight gate​
pnpm preflight is the pre-push gate. It runs typecheck, lint, brand-check, and tests in one command, and it must pass before every push:
pnpm preflight
Branch flow is feature to develop to main, never push straight to main. See Local Setup for the full development workflow and Deployment for the release process.
Mobile tests​
The Flutter app has its own suite: flutter test for unit and widget tests, and flutter test integration_test/ for integration tests on a device or simulator. See Flutter for details.