import { readFileSync, existsSync } from "node:fs"; import { resolve } from "node:path"; import { defineConfig } from "vitest/config"; import swc from "unplugin-swc"; /** * These are integration tests, not unit tests — they need DATABASE_URL, * JWT_SIGNING_SECRET, EDEN_SUPERADMIN_EMAIL/PASSWORD, etc. from the repo * root `.env` (gitignored, never read by vitest automatically the way * Next/Vite's client env loading does). Parsed by hand here (no `dotenv` * dependency needed) and passed through `test.env` so it reaches the * worker process(es) vitest actually runs specs in. */ function loadRootEnv(): Record { const envPath = resolve(__dirname, "../../.env"); if (!existsSync(envPath)) return {}; const out: Record = {}; for (const line of readFileSync(envPath, "utf8").split("\n")) { const trimmed = line.trim(); if (!trimmed || trimmed.startsWith("#")) continue; const eq = trimmed.indexOf("="); if (eq === -1) continue; out[trimmed.slice(0, eq).trim()] = trimmed.slice(eq + 1).trim(); } return out; } /** * Integration test config (eden-qa). Every spec under test/ boots a real, * fully-wired Nest app (Test.createTestingModule + AppModule) against a * real Postgres — no mocked DB layer, per the eden-qa persona's rule. * Timeout is generous (15s default) because some tests hit the DB several * times in sequence and hash passwords with Argon2id (intentionally slow). */ export default defineConfig({ // NestJS's DI resolves constructor parameter types from // `design:paramtypes` metadata emitted by the TS decorator-metadata // transform. Vite's default esbuild transform does NOT implement // `emitDecoratorMetadata` (esbuild is a single-file transformer with no // type checker to resolve types from) — every @Injectable()/@Controller // class would silently receive `undefined` for its dependencies instead // of a real instance. Using SWC (which does implement it, matching // `tsc`'s behavior) here is the standard fix for testing Nest apps with // Vitest — see https://docs.nestjs.com/recipes/swc#vitest. plugins: [swc.vite()], test: { environment: "node", include: ["test/**/*.spec.ts"], testTimeout: 15000, hookTimeout: 15000, // Integration tests share one real Postgres connection pool + one // seeded super_admin account; running spec files in parallel worker // processes risks session/role-cleanup races between files (e.g. two // files both minting/deleting similarly-named throwaway roles). Runs // sequentially, file by file — still fully real, just not concurrent. fileParallelism: false, globals: false, env: { ...loadRootEnv(), ...process.env }, }, });