Files
HiveGrid-Wireframes/hivegrid-cloud/scripts/verify-db-migrate-status.test.mjs
T

187 lines
6.9 KiB
JavaScript

import { EventEmitter } from "node:events";
import assert from "node:assert/strict";
import { describe, it } from "vitest";
import {
buildMigrateStatusCommand,
formatMigrateStatusResult,
redactSecrets,
verifyDbMigrateStatus,
} from "./verify-db-migrate-status.mjs";
function createSpawnStub({ exitCode = 0, stdout = "", stderr = "", error = null } = {}) {
const calls = [];
const spawnImpl = (command, args, options) => {
calls.push({ command, args, options });
if (error?.throwSync) {
throw error.value;
}
const child = new EventEmitter();
child.stdout = new EventEmitter();
child.stderr = new EventEmitter();
queueMicrotask(() => {
if (stdout) {
child.stdout.emit("data", Buffer.from(stdout));
}
if (stderr) {
child.stderr.emit("data", Buffer.from(stderr));
}
if (error) {
child.emit("error", error.value ?? error);
} else {
child.emit("close", exitCode);
}
});
return child;
};
return { spawnImpl, calls };
}
const SECRET_URL = "postgresql://ci_user:super-secret@db.example.test:5432/toolctrl";
describe("verify-db-migrate-status", () => {
it("constructs the package-owned Prisma migrate status command", () => {
const command = buildMigrateStatusCommand();
assert.equal(command.command, "pnpm");
assert.deepEqual(command.args, ["--filter", "@toolctrl/db", "prisma:migrate:status"]);
assert.equal(command.display, "pnpm --filter @toolctrl/db prisma:migrate:status");
});
it("passes when Prisma migrate status exits successfully", async () => {
const { spawnImpl, calls } = createSpawnStub({ stdout: "Database schema is up to date\n", exitCode: 0 });
const result = await verifyDbMigrateStatus({
env: { DATABASE_URL: SECRET_URL, PATH: "/bin" },
spawnImpl,
cwd: "/repo",
});
const output = formatMigrateStatusResult(result);
assert.equal(result.ok, true);
assert.equal(result.phase, "prisma:migrate:status");
assert.equal(result.exitCode, 0);
assert.equal(calls.length, 1);
assert.equal(calls[0].command, "pnpm");
assert.deepEqual(calls[0].args, ["--filter", "@toolctrl/db", "prisma:migrate:status"]);
assert.equal(calls[0].options.cwd, "/repo");
assert.equal(calls[0].options.env.CI, "1");
assert.equal(calls[0].options.env.DATABASE_URL, SECRET_URL);
assert.match(output, /^PASS database migrate status verification/);
assert.match(output, /phase: prisma:migrate:status/);
assert.match(output, /command: pnpm --filter @toolctrl\/db prisma:migrate:status/);
assert.match(output, /exitCode: 0/);
});
it("fails before spawning when DATABASE_URL is missing", async () => {
const { spawnImpl, calls } = createSpawnStub();
const result = await verifyDbMigrateStatus({ env: { PATH: "/bin" }, spawnImpl });
const output = formatMigrateStatusResult(result);
assert.equal(result.ok, false);
assert.equal(result.phase, "preflight");
assert.equal(calls.length, 0);
assert.match(output, /^FAIL database migrate status verification/);
assert.match(output, /status: missing DATABASE_URL/);
assert.match(output, /DATABASE_URL is required/);
});
it("fails with sanitized output when Prisma migrate status exits non-zero", async () => {
const { spawnImpl } = createSpawnStub({
exitCode: 1,
stdout: `Connecting with DATABASE_URL=${SECRET_URL}\n`,
stderr: `Migration failed for ${SECRET_URL}\n`,
});
const result = await verifyDbMigrateStatus({ env: { DATABASE_URL: SECRET_URL }, spawnImpl });
const output = formatMigrateStatusResult(result);
assert.equal(result.ok, false);
assert.equal(result.exitCode, 1);
assert.equal(result.status, "prisma migrate status failed");
assert.match(output, /^FAIL database migrate status verification/);
assert.match(output, /exitCode: 1/);
assert.doesNotMatch(output, /super-secret/);
assert.doesNotMatch(output, new RegExp(SECRET_URL.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")));
assert.match(output, /<redacted:DATABASE_URL>/);
});
it("passes unreachable database failures only when explicitly allowed", async () => {
const { spawnImpl } = createSpawnStub({
exitCode: 1,
stderr: "Error: P1001: Can't reach database server at `db.internal:5432`\n",
});
const result = await verifyDbMigrateStatus({
env: {
DATABASE_URL: SECRET_URL,
DB_MIGRATE_STATUS_ALLOW_UNREACHABLE: "1",
},
spawnImpl,
});
const output = formatMigrateStatusResult(result);
assert.equal(result.ok, true);
assert.equal(result.exitCode, 1);
assert.equal(result.status, "database unreachable; skipped by DB_MIGRATE_STATUS_ALLOW_UNREACHABLE");
assert.match(output, /^PASS database migrate status verification/);
});
it("still fails unreachable database errors without the explicit allow flag", async () => {
const { spawnImpl } = createSpawnStub({
exitCode: 1,
stderr: "Error: P1001: Can't reach database server at `db.internal:5432`\n",
});
const result = await verifyDbMigrateStatus({ env: { DATABASE_URL: SECRET_URL }, spawnImpl });
assert.equal(result.ok, false);
assert.equal(result.status, "prisma migrate status failed");
});
it("fails with spawn diagnostics when command execution errors", async () => {
const { spawnImpl } = createSpawnStub({ error: { value: new Error(`spawn failed for ${SECRET_URL}`) } });
const result = await verifyDbMigrateStatus({ env: { DATABASE_URL: SECRET_URL }, spawnImpl });
const output = formatMigrateStatusResult(result);
assert.equal(result.ok, false);
assert.equal(result.phase, "spawn");
assert.equal(result.exitCode, null);
assert.match(output, /status: spawn error/);
assert.match(output, /error: spawn failed for <redacted:DATABASE_URL>/);
assert.doesNotMatch(output, /super-secret/);
});
it("redacts literal DATABASE_URL values and generic URL credentials", () => {
const output = redactSecrets(
`DATABASE_URL=${SECRET_URL}\njson={"DATABASE_URL":"${SECRET_URL}"}\nother=mysql://user:password@localhost:3306/app`,
{ DATABASE_URL: SECRET_URL },
);
assert.doesNotMatch(output, /super-secret/);
assert.doesNotMatch(output, /password/);
assert.doesNotMatch(output, /ci_user/);
assert.match(output, /DATABASE_URL=<redacted:DATABASE_URL>/);
assert.match(output, /mysql:\/\/<redacted>@localhost/);
});
it("captures synchronous spawn failures as sanitized failures", async () => {
const { spawnImpl } = createSpawnStub({ error: { throwSync: true, value: new Error(`ENOENT ${SECRET_URL}`) } });
const result = await verifyDbMigrateStatus({ env: { DATABASE_URL: SECRET_URL }, spawnImpl });
const output = formatMigrateStatusResult(result);
assert.equal(result.ok, false);
assert.equal(result.phase, "spawn");
assert.match(output, /ENOENT <redacted:DATABASE_URL>/);
assert.doesNotMatch(output, /super-secret/);
});
});