Testing and CI Contracts
Use the starter's test tiers, real infrastructure suite, Playwright flow, coverage ratchet, and build gates without weakening their guarantees.
Verified against starter commit
b16b416.
The test suite is organized by what it may mock. That rule matters more than the folder names: a mocked database test cannot prove a unique constraint, and a route test that mocks its auth guard cannot prove authentication happens before data access.
| Tier | Purpose | May mock |
|---|---|---|
| Unit | pure rules and architecture scans | nothing |
| API route | HTTP status, envelope, auth ordering | services/models, never guards |
| Service | orchestration, retries, costs, compensation | models and external SDKs |
| Component | browser-visible behavior | fetch |
| Database | constraints, locks, real timestamps | nothing |
| End to end | signed-in browser through local infrastructure | nothing |
Every route needs an auth-gate test proving the data function was not called before 401/403. Every credit or money mutation needs a replay test proving two identical requests produce one effect.
Commands
pnpm test:fast
pnpm test:run
pnpm test:cov
pnpm test:db
pnpm exec playwright install chromium
pnpm test:e2etest:fast is the hermetic pre-commit pass. test:run executes the configured Vitest projects. test:cov applies the coverage ratchet to services, models, API routes, shared server code, and Admin data code.
Without either TEST_DATABASE_URL or TEST_REDIS_URL, Vitest omits the infrastructure project before collection. PostgreSQL and Redis tests opt in independently; a Redis-only run does not initialize Better Auth or PostgreSQL. CI requires both URLs and fails when infrastructure is absent. The PostgreSQL test database name must contain test because the harness truncates its tables. Keep test URLs out of production deployment settings.
The Playwright suite uses a disposable stack on port 3100. It signs in through the visible Better Auth form and exercises tenant credits, direct Garage upload/delete, and the five-credit image workflow from idempotent replay through the durable worker to a signed private result. External targets require explicit credentials and E2E_ALLOW_MUTATIONS=1 before destructive tests run.
CI runs lint, migrations against PostgreSQL 16, Redis-backed tests, coverage, all application builds, and the browser suite. Do not lower a coverage threshold or replace a real-infrastructure test with a mock to turn a release green; change the product or add the missing test.
Ready to merge means: the lowest tier that can prove each invariant contains the test, auth and replay checks exist where required, real infrastructure is green, and a production build succeeds.