Files
doodle-store/apps/server/scripts/test-auth-db.mjs
T

91 lines
2.8 KiB
JavaScript

import { randomUUID } from 'node:crypto';
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { parseEnv } from 'node:util';
import { spawnSync } from 'node:child_process';
import pg from 'pg';
// 只使用本机开发库凭据创建独立短期库;绝不在 doodle_dev 中清空或写入测试用户。
const serverRoot = fileURLToPath(new URL('../', import.meta.url));
const local = parseEnv(
readFileSync(new URL('../.env', import.meta.url), 'utf8'),
);
const url = new URL(local.DATABASE_URL);
if (
!['127.0.0.1', 'localhost'].includes(url.hostname) ||
url.pathname !== '/doodle_dev'
)
throw new Error('数据库集成测试只允许本机 doodle_dev 实例创建隔离库');
const database = `doodle_auth_test_${randomUUID().replaceAll('-', '')}`;
const admin = new pg.Pool({
connectionString: url.toString(),
max: 1,
connectionTimeoutMillis: 3000,
});
const testUrl = new URL(url);
testUrl.pathname = `/${database}`;
const env = {
...process.env,
DATABASE_URL: testUrl.toString(),
TEST_DATABASE_URL: testUrl.toString(),
};
let created = false;
function run(args) {
const result = spawnSync('pnpm', args, {
cwd: serverRoot,
env,
encoding: 'utf8',
timeout: 120_000,
});
for (const output of [result.stdout, result.stderr])
if (output)
process.stdout.write(
output
.replaceAll(testUrl.toString(), '[test-database-url]')
.replaceAll(decodeURIComponent(url.password), '[redacted]'),
);
if (result.status !== 0) throw new Error('数据库测试子任务失败');
}
try {
await admin.query(
`CREATE DATABASE "${database}" WITH TEMPLATE template0 ENCODING 'UTF8' LC_COLLATE 'C' LC_CTYPE 'C'`,
);
created = true;
run(['exec', 'prisma', 'migrate', 'deploy']);
run(['exec', 'tsc', '-p', 'tsconfig.test.json']);
run(['exec', 'node', '--test', 'dist-test/test/auth-database.test.js']);
run(['exec', 'node', '--test', 'dist-test/test/category-database.test.js']);
run([
'exec',
'node',
'--test',
'dist-test/test/worksheet-import-database.test.js',
]);
run([
'exec',
'node',
'--test',
'dist-test/test/worksheet-database.test.js',
]);
run([
'exec',
'node',
'--test',
'dist-test/test/content-publication-database.test.js',
]);
run([
'exec',
'node',
'--test',
'dist-test/test/member-site-database.test.js',
]);
} finally {
if (created) {
await admin.query(`DROP DATABASE "${database}"`);
console.log('临时数据库已删除,开发库业务数据未改动。');
}
await admin.end();
}