import { execFileSync } from 'node:child_process' import { createRequire } from 'node:module' import { fileURLToPath } from 'node:url' import pg from 'pg' import { loadEnvFromRepoRoot } from '../dist/loadEnv.js' import { resolveTestDatabaseUrl } from '../dist/testDatabase.js' /** * Legt die Testdatenbank an, falls sie fehlt, und bringt sie auf den aktuellen * Migrationsstand. Wird von `pnpm test` vorgeschaltet. * * Läuft nur in der Entwicklung und in der CI, nie im Betrieb. */ loadEnvFromRepoRoot() const testUrl = resolveTestDatabaseUrl() const dbName = new URL(testUrl).pathname.replace(/^\//, '') const maintenance = new URL(testUrl) maintenance.pathname = '/postgres' const client = new pg.Client({ connectionString: maintenance.toString() }) await client.connect() try { const { rowCount } = await client.query('SELECT 1 FROM pg_database WHERE datname = $1', [dbName]) if (rowCount === 0) { // Bezeichner lassen sich nicht als Parameter binden, deshalb quotiert. await client.query(`CREATE DATABASE "${dbName.replace(/"/g, '""')}"`) console.log(`[test-db] ${dbName} angelegt`) } } finally { await client.end() } const require = createRequire(import.meta.url) const prismaCli = require.resolve('prisma/build/index.js') const testEnv = { ...process.env, DATABASE_URL: testUrl, DIRECT_DATABASE_URL: testUrl } execFileSync(process.execPath, [prismaCli, 'migrate', 'deploy'], { stdio: 'inherit', env: testEnv, }) // Der Auslieferungszustand gehört auch in die Testdatenbank: Freigabestufen und // Änderungsrichtlinie werden von Tests vorausgesetzt. Der Seed ist idempotent. const tsxCli = require.resolve('tsx/cli') execFileSync(process.execPath, [tsxCli, 'prisma/seed.ts'], { stdio: 'inherit', cwd: fileURLToPath(new URL('..', import.meta.url)), env: testEnv, }) console.log(`[test-db] ${dbName} ist auf Stand`)