// Pure helper for integration tests. Requires TEST_DATABASE_URL pointing at // a throwaway Postgres. Returns a pg Pool with the full schema applied. // Tests that need this should `skip` (not fail) when TEST_DATABASE_URL is unset. import { Pool } from 'pg'; import { readdirSync, readFileSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; import { dirname, join } from 'node:path'; const __dirname = dirname(fileURLToPath(import.meta.url)); const migrationsDir = join(__dirname, '..', '..', 'src', 'db', 'migrations'); const schemaFile = join(__dirname, '..', '..', 'src', 'db', 'schema.sql'); const patches = [ 'schema_patch_ampp.sql', 'schema_patch_editor.sql', 'schema_patch_groups_tokens.sql', ]; export function isTestDbConfigured() { return !!process.env.TEST_DATABASE_URL; } export async function setupTestDb() { if (!process.env.TEST_DATABASE_URL) { throw new Error('TEST_DATABASE_URL not set'); } const pool = new Pool({ connectionString: process.env.TEST_DATABASE_URL }); // Wipe and recreate the public schema so each test run starts clean. await pool.query('DROP SCHEMA IF EXISTS public CASCADE'); await pool.query('CREATE SCHEMA public'); await pool.query('GRANT ALL ON SCHEMA public TO PUBLIC'); // Base schema, then patches, then migrations in order. await pool.query(readFileSync(schemaFile, 'utf8')); for (const p of patches) { await pool.query(readFileSync(join(__dirname, '..', '..', 'src', 'db', p), 'utf8')); } const migrations = readdirSync(migrationsDir).filter(f => f.endsWith('.sql')).sort(); for (const f of migrations) { await pool.query(readFileSync(join(migrationsDir, f), 'utf8')); } return pool; }