mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
60 lines
2.0 KiB
TypeScript
60 lines
2.0 KiB
TypeScript
/**
|
|
* Vitest globalSetup — boots ONE Postgres testcontainer for the whole
|
|
* integration run, applies migrations, and exposes the connection URL
|
|
* via process.env.DATABASE_URL. The teardown returned at the end stops
|
|
* the container after all test files have finished.
|
|
*
|
|
* Why globalSetup instead of beforeAll/afterAll per file:
|
|
* - The application's Prisma singleton in `src/lib/db.ts` is built at
|
|
* module load time using the current `process.env.DATABASE_URL`. If
|
|
* the container is rotated between test files, the singleton keeps
|
|
* pointing at the dead container and queries fail. Booting once,
|
|
* keeping the URL stable, and truncating between tests is both
|
|
* faster and safer.
|
|
* - Truncate-between-tests still gives per-test isolation; see
|
|
* `setup.ts -> truncateAllTables`.
|
|
*/
|
|
import { execSync } from "node:child_process";
|
|
import { dirname, resolve } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
import type { TestProject } from "vitest/node";
|
|
import {
|
|
PostgreSqlContainer,
|
|
type StartedPostgreSqlContainer,
|
|
} from "@testcontainers/postgresql";
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = dirname(__filename);
|
|
const PROJECT_ROOT = resolve(__dirname, "..", "..");
|
|
|
|
let container: StartedPostgreSqlContainer | null = null;
|
|
|
|
export default async function setup(
|
|
project: TestProject,
|
|
): Promise<() => Promise<void>> {
|
|
container = await new PostgreSqlContainer("postgres:16-alpine")
|
|
.withDatabase("healthlog_test")
|
|
.withUsername("healthlog")
|
|
.withPassword("healthlog")
|
|
.start();
|
|
|
|
const url = container.getConnectionUri() + "?schema=public&pgbouncer=false";
|
|
process.env.DATABASE_URL = url;
|
|
project.provide("integrationDatabaseUrl", url);
|
|
|
|
// The explicit child environment keeps Prisma CLI on the same container.
|
|
execSync("pnpm db:migrate:deploy", {
|
|
cwd: PROJECT_ROOT,
|
|
stdio: "inherit",
|
|
env: { ...process.env, DATABASE_URL: url },
|
|
});
|
|
|
|
return async () => {
|
|
if (container) {
|
|
await container.stop({ remove: true });
|
|
container = null;
|
|
}
|
|
};
|
|
}
|