102 lines
4.4 KiB
TypeScript
102 lines
4.4 KiB
TypeScript
import { spawn } from 'node:child_process';
|
|
import fs from 'node:fs/promises';
|
|
import os from 'node:os';
|
|
import path from 'node:path';
|
|
|
|
import { createGamePostgresConnector } from '@sammo-ts/infra';
|
|
import { describe, expect, it } from 'vitest';
|
|
|
|
const databaseUrl = process.env.PROFILE_SEED_CLI_DATABASE_URL;
|
|
const describeDatabase = describe.runIf(Boolean(databaseUrl));
|
|
const workspaceRoot = path.resolve(process.cwd(), '../..');
|
|
|
|
const runSeedCli = async (requestFile: string): Promise<{ code: number | null; output: string }> =>
|
|
new Promise((resolve) => {
|
|
const child = spawn(process.execPath, [path.join(workspaceRoot, 'app/gateway-api/dist/index.js')], {
|
|
cwd: workspaceRoot,
|
|
env: {
|
|
...process.env,
|
|
DATABASE_URL: databaseUrl,
|
|
GATEWAY_ROLE: 'profile-seed',
|
|
PROFILE_SEED_REQUEST_FILE: requestFile,
|
|
},
|
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
});
|
|
let output = '';
|
|
child.stdout.on('data', (chunk) => {
|
|
output += chunk.toString();
|
|
});
|
|
child.stderr.on('data', (chunk) => {
|
|
output += chunk.toString();
|
|
});
|
|
child.on('close', (code) => resolve({ code, output }));
|
|
});
|
|
|
|
describeDatabase('selected workspace profile seed CLI', () => {
|
|
it('seeds through the built gateway artifact with the serialized operation identity', async () => {
|
|
if (!databaseUrl) {
|
|
throw new Error('PROFILE_SEED_CLI_DATABASE_URL is required.');
|
|
}
|
|
const tempDirectory = await fs.mkdtemp(path.join(os.tmpdir(), 'profile-seed-cli-test-'));
|
|
const requestFile = path.join(tempDirectory, 'request.json');
|
|
const connector = createGamePostgresConnector({ url: databaseUrl });
|
|
try {
|
|
await fs.writeFile(
|
|
requestFile,
|
|
JSON.stringify({
|
|
scenarioId: 1010,
|
|
tickSeconds: 60,
|
|
now: '2036-03-03T00:00:00.000Z',
|
|
installOptions: {
|
|
serverId: 'selected-cli-seed',
|
|
installOperationId: 'selected-cli-operation',
|
|
installCommitSha: 'selected-cli-commit',
|
|
},
|
|
adminUser: {
|
|
id: 'selected-cli-admin',
|
|
username: 'selected-cli-admin',
|
|
displayName: '선택 CLI 관리자',
|
|
},
|
|
}),
|
|
{ encoding: 'utf8', mode: 0o600 }
|
|
);
|
|
|
|
const result = await runSeedCli(requestFile);
|
|
expect(result, result.output).toMatchObject({ code: 0 });
|
|
await connector.connect();
|
|
const world = await connector.prisma.worldState.findFirstOrThrow();
|
|
expect(world).toMatchObject({
|
|
scenarioCode: '1010',
|
|
meta: {
|
|
installOperationId: 'selected-cli-operation',
|
|
installCommitSha: 'selected-cli-commit',
|
|
},
|
|
});
|
|
const adminGeneral = await connector.prisma.general.findFirstOrThrow({
|
|
where: { userId: 'selected-cli-admin' },
|
|
});
|
|
expect(adminGeneral).toMatchObject({ meta: { createdBy: 'admin-seed' } });
|
|
const history = await connector.prisma.gameHistory.findUniqueOrThrow({
|
|
where: { serverId: 'selected-cli-seed' },
|
|
});
|
|
|
|
const retry = await runSeedCli(requestFile);
|
|
expect(retry, retry.output).toMatchObject({ code: 0 });
|
|
await expect(connector.prisma.worldState.findFirstOrThrow()).resolves.toEqual(world);
|
|
await expect(
|
|
connector.prisma.general.findFirstOrThrow({ where: { userId: 'selected-cli-admin' } })
|
|
).resolves.toEqual(adminGeneral);
|
|
await expect(
|
|
connector.prisma.gameHistory.findUniqueOrThrow({ where: { serverId: 'selected-cli-seed' } })
|
|
).resolves.toEqual(history);
|
|
await expect(
|
|
connector.prisma.gameHistory.count({ where: { serverId: 'selected-cli-seed' } })
|
|
).resolves.toBe(1);
|
|
} finally {
|
|
await connector.prisma.gameHistory.deleteMany({ where: { serverId: 'selected-cli-seed' } });
|
|
await connector.disconnect();
|
|
await fs.rm(tempDirectory, { recursive: true, force: true });
|
|
}
|
|
});
|
|
});
|