71 lines
2.3 KiB
TypeScript
71 lines
2.3 KiB
TypeScript
import { randomBytes } from 'node:crypto';
|
|
import { readFile, readdir } from 'node:fs/promises';
|
|
import { join } from 'node:path';
|
|
import { Client } from 'pg';
|
|
import { PGlite } from '@electric-sql/pglite';
|
|
import { PGLiteSocketServer } from '@electric-sql/pglite-socket';
|
|
|
|
export const legacyOrganizationId = '00000000-0000-4000-8000-000000000001';
|
|
export async function testDatabase() {
|
|
let connectionUrl: string;
|
|
let execute: (sql: string) => Promise<unknown>;
|
|
let close: () => Promise<void>;
|
|
if (process.env.TEST_DATABASE_URL) {
|
|
// CI supplies a disposable PostgreSQL administrator URL, never a production URL.
|
|
const administrator = new Client({
|
|
connectionString: process.env.TEST_DATABASE_URL,
|
|
});
|
|
await administrator.connect();
|
|
const name = 'mani_test_' + randomBytes(8).toString('hex');
|
|
await administrator.query(`CREATE DATABASE "${name}"`);
|
|
const url = new URL(process.env.TEST_DATABASE_URL);
|
|
url.pathname = '/' + name;
|
|
connectionUrl = url.toString();
|
|
const client = new Client({ connectionString: connectionUrl });
|
|
await client.connect();
|
|
execute = (sql) => client.query(sql);
|
|
close = async () => {
|
|
await client.end();
|
|
await administrator.query(`DROP DATABASE "${name}" WITH (FORCE)`);
|
|
await administrator.end();
|
|
};
|
|
} else {
|
|
const pg = await PGlite.create();
|
|
const server = new PGLiteSocketServer({
|
|
db: pg,
|
|
port: 0,
|
|
host: '127.0.0.1',
|
|
maxConnections: 1,
|
|
});
|
|
await server.start();
|
|
connectionUrl = `postgresql://postgres:postgres@${server.getServerConn()}/postgres`;
|
|
execute = (sql) => pg.exec(sql);
|
|
close = async () => {
|
|
await server.stop();
|
|
await pg.close();
|
|
};
|
|
}
|
|
try {
|
|
const migrations = (await readdir('prisma/migrations'))
|
|
.filter((path) => /^\d/.test(path))
|
|
.sort();
|
|
for (const path of migrations) {
|
|
await execute(
|
|
await readFile(
|
|
join('prisma/migrations', path, 'migration.sql'),
|
|
'utf8',
|
|
),
|
|
);
|
|
if (path === '202609080001_create_organizations') {
|
|
await execute(
|
|
`INSERT INTO organizations (id, name, updated_at) VALUES ('${legacyOrganizationId}', 'Existing organization', NOW())`,
|
|
);
|
|
}
|
|
}
|
|
return { connectionUrl, close, execute };
|
|
} catch (error) {
|
|
await close();
|
|
throw error;
|
|
}
|
|
}
|