Testing
Ezvento maintains a two-tier testing strategy: fast unit tests with Vitest (79 tests) and realistic end-to-end tests with Playwright (47 tests). This page explains how to run them, what they cover, and how the mock infrastructure works.
Unit Tests — Vitest
79 tests covering API routes, library utilities, auth guards, RBAC, and export logic. Configured in
vitest.config.ts.Vitest Configuration
- Environment: jsdom
- Glob:
src/**/*.test.ts,src/**/*.spec.ts - Coverage: v8 provider with text, JSON, and HTML reporters
- Setup file:
src/test/setup.ts - Alias:
@→./src
Test File Inventory
| File | Area |
|---|---|
src/__tests__/api/stores.test.ts | API — Store CRUD, tenant isolation |
src/__tests__/api/products.test.ts | API — Product catalog, variants |
src/__tests__/api/billing.test.ts | API — Invoicing, payments, GST |
src/__tests__/api/tenant-isolation.test.ts | API — Cross-tenant access blocked |
src/__tests__/lib/escpos.test.ts | Lib — ESC/POS thermal printing |
src/__tests__/lib/emails.test.ts | Lib — Email template rendering |
src/__tests__/lib/rbac/role-permissions.test.ts | Lib — RBAC permission matrix |
src/__tests__/lib/export-excel.test.ts | Lib — Excel export generation |
src/__tests__/lib/auth/require.test.ts | Lib — Auth guards, 2FA, PIN |
src/__tests__/lib/auth/platform.test.ts | Lib — Platform-level auth checks |
Shared Factories (src/__tests__/api/helpers.ts)
A central helper file provides mock data factories and request/response utilities used across API tests:
makeDbUser()— constructs a full Prisma user object with nested tenant and roleAssignmentsTENANT_A_DB / TENANT_B_DB / TENANT_A_EMPLOYEE_DB— pre-built mock users for cross-tenant testsTENANT_A_AUTH / TENANT_B_AUTH— Supabase-level auth objects (email + id only)seedStores()— generates store arrays with locationsseedProducts()— generates product arrays with inventoryStockseedInvoices()— generates invoice arrays with customer and itemsseedCustomers()— generates customer arrays with store relationcreateApiRequest()— builds a mockedNextRequestparseResponse()— extracts status + JSON body from a Response
Mock Patterns via globalThis
Because vi.mock() is hoisted, it cannot read variables from the test scope. The codebase uses globalThis as a shared mutable state bridge:
| Global Key | Purpose |
|---|---|
__EZVENTO_TEST_AUTH_USER__ | Mock Supabase auth user returned by createServerSupabaseClient |
__EZVENTO_TEST_PRISMA_DATA__ | Mock Prisma return data for the current test case |
Tests call setAuthUser(user) and setPrismaData(data) before invoking the route handler, and the hoisted mock factories read those globals to return the correct mocked values.