105 lines
5.1 KiB
JavaScript
105 lines
5.1 KiB
JavaScript
import fs from 'node:fs/promises';
|
|
import os from 'node:os';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { spawnSync } from 'node:child_process';
|
|
import { randomUUID } from 'node:crypto';
|
|
import assert from 'node:assert/strict';
|
|
import pg from 'pg';
|
|
|
|
const sourceUrl = process.env.OPEN_REQUEST_DATABASE_URL;
|
|
if (!sourceUrl) throw new Error('OPEN_REQUEST_DATABASE_URL must point to a disposable fixture instance.');
|
|
const target = '20261022000000_add_open_requests';
|
|
const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
const prismaRoot = path.join(packageRoot, 'prisma');
|
|
const temp = await fs.mkdtemp(path.join(os.tmpdir(), 'open-request-migration-'));
|
|
const schema = `open_request_upgrade_${Date.now()}`;
|
|
const url = new URL(sourceUrl);
|
|
url.searchParams.set('schema', schema);
|
|
const client = new pg.Client({ connectionString: sourceUrl });
|
|
const deploy = (config) => {
|
|
const result = spawnSync('pnpm', ['exec', 'prisma', 'migrate', 'deploy', '--config', config], {
|
|
cwd: packageRoot,
|
|
env: { ...process.env, GATEWAY_DATABASE_URL: url.href },
|
|
encoding: 'utf8',
|
|
});
|
|
if (result.status !== 0)
|
|
throw new Error(`Migration deploy failed (exit ${result.status}); datasource output suppressed.`);
|
|
};
|
|
try {
|
|
await fs.copyFile(path.join(prismaRoot, 'gateway.prisma'), path.join(temp, 'gateway.prisma'));
|
|
await fs.cp(path.join(prismaRoot, 'gateway-migrations'), path.join(temp, 'gateway-migrations'), {
|
|
recursive: true,
|
|
});
|
|
await fs.rm(path.join(temp, 'gateway-migrations', target), { recursive: true });
|
|
// Keep config inside this package so Prisma's config import resolves normally.
|
|
const config = path.join(packageRoot, `.open-request-migration-${process.pid}.config.mjs`);
|
|
const configText = `export default { schema: ${JSON.stringify(path.join(temp, 'gateway.prisma'))}, migrations: { path: ${JSON.stringify(path.join(temp, 'gateway-migrations'))} }, datasource: { url: process.env.GATEWAY_DATABASE_URL } };\n`;
|
|
await fs.writeFile(config, configText);
|
|
try {
|
|
deploy(config);
|
|
} finally {
|
|
await fs.rm(config);
|
|
}
|
|
await client.connect();
|
|
await client.query(`SET search_path TO "${schema}", public`);
|
|
const userId = randomUUID(),
|
|
profileName = 'opening-upgrade:default';
|
|
await client.query(
|
|
'INSERT INTO app_user(id,login_id,display_name,password_hash,password_salt,updated_at) VALUES($1,$2,$2,$3,$3,NOW())',
|
|
[userId, 'fixture-user', 'fixture-only']
|
|
);
|
|
await client.query(
|
|
'INSERT INTO gateway_profile(profile_name,profile,instance_key,scenario,api_port,status,updated_at) VALUES($1,$2,$3,$3,15995,$4,NOW())',
|
|
[profileName, 'opening-upgrade', 'default', 'STOPPED']
|
|
);
|
|
deploy(path.join(packageRoot, 'prisma.gateway.config.ts'));
|
|
const after = await client.query('SELECT COUNT(*)::int AS count FROM _prisma_migrations');
|
|
deploy(path.join(packageRoot, 'prisma.gateway.config.ts'));
|
|
assert.deepEqual((await client.query('SELECT COUNT(*)::int AS count FROM _prisma_migrations')).rows, after.rows);
|
|
assert.equal((await client.query('SELECT id FROM app_user WHERE id=$1', [userId])).rowCount, 1);
|
|
const requestId = randomUUID();
|
|
await client.query(
|
|
`INSERT INTO gateway_open_request(id,profile_name,requested_by,install,announcement,season_key,expires_at,preopen_at,open_at,updated_at)
|
|
VALUES($1,$2,$3,'{}','{}','fixture',NOW()+INTERVAL '1 day',NOW()+INTERVAL '2 days',NOW()+INTERVAL '3 days',NOW())`,
|
|
[requestId, profileName, userId]
|
|
);
|
|
await client.query('INSERT INTO gateway_open_endorsement(request_id,user_id) VALUES($1,$2)', [requestId, userId]);
|
|
await assert.rejects(
|
|
() =>
|
|
client.query('INSERT INTO gateway_open_endorsement(request_id,user_id) VALUES($1,$2)', [requestId, userId]),
|
|
{ code: '23505' }
|
|
);
|
|
await assert.rejects(
|
|
() =>
|
|
client.query(
|
|
`INSERT INTO gateway_open_request(id,profile_name,requested_by,install,announcement,season_key,expires_at,preopen_at,open_at,updated_at)
|
|
SELECT $1,profile_name,requested_by,install,announcement,season_key,expires_at,preopen_at,open_at,NOW() FROM gateway_open_request WHERE id=$2`,
|
|
[randomUUID(), requestId]
|
|
),
|
|
{ code: '23505' }
|
|
);
|
|
await assert.rejects(
|
|
() => client.query("UPDATE gateway_open_request SET status='RESERVED' WHERE id=$1", [requestId]),
|
|
{ code: '23514' }
|
|
);
|
|
await assert.rejects(
|
|
() => client.query('UPDATE gateway_open_request SET open_at=preopen_at WHERE id=$1', [requestId]),
|
|
{ code: '23514' }
|
|
);
|
|
await assert.rejects(
|
|
() =>
|
|
client.query('INSERT INTO gateway_open_endorsement(request_id,user_id) VALUES($1,$2)', [
|
|
randomUUID(),
|
|
userId,
|
|
]),
|
|
{ code: '23503' }
|
|
);
|
|
console.log(
|
|
`Opening migration: predecessor upgrade, preserved rows, repeated deploy no-op, unique/FK/CHECK constraints passed (${schema}).`
|
|
);
|
|
} finally {
|
|
await client.end();
|
|
await fs.rm(temp, { recursive: true, force: true });
|
|
}
|