Files
Ekklesia/core/tests/cli-create-initial-owner.test.ts
T
ekklesiaandClaude Opus 5.5 796ad4f16e
CI / verify (pull_request) Successful in 1m5s
CI / infrastructure-smoke (pull_request) Successful in 37s
CI / migration-smoke (pull_request) Successful in 1m55s
CI / image-build (pull_request) Successful in 24s
CI / deploy-smoke (same-origin) (pull_request) Successful in 49s
CI / deploy-smoke (split) (pull_request) Successful in 1m31s
test: give Core's import-safety tests a timeout that holds under full verify load
Four Core tests prove that importing a module has no side effects. Each one
does a cold dynamic import() of a large Core source graph inside its test
body:
- doctor-import
- module-http-import
- cli-bootstrap-platform-owner
- cli-create-initial-owner (its first test)

Vitest transforms and evaluates that graph on demand, so the CPU-bound cost
counts against the default 5 s per-test timeout. Ordinary test files import
at the top level, outside any test timeout. There is no subprocess, shared
resource, or test bug.

Measured on six cores:
- alone: 0.7–1.2 s;
- alongside five other packages' suites, as in a full pnpm verify:
  3.0–5.4 s (doctor-import reached 5,400 ms).

A shared IMPORT_SAFETY_TEST_TIMEOUT_MS of 30 s (core/tests/support/
import-safety.ts) now applies to exactly these four tests. That is about five
times the slowest time measured under load, the same as the repository's
integration-test timeout, and still bounded, so an import that genuinely
hangs fails. Assertions, coverage, the global Vitest timeout, parallelism,
and production code are unchanged; there are no retries.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 19:08:30 -05:00

46 lines
2.0 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import { IMPORT_SAFETY_TEST_TIMEOUT_MS } from "./support/import-safety.js";
const poolConstructor = vi.hoisted(() => vi.fn());
vi.mock("pg", () => ({ Pool: poolConstructor }));
describe("create-initial-owner CLI import safety", () => {
const originalEnv = { ...process.env };
it(
"does not read DATABASE_URL, connect to PostgreSQL, or create anything merely by importing the module",
async () => {
delete process.env.DATABASE_URL;
// Under Vitest, process.argv[1] is never this file's own path, so isDirectExecution() is false
// exactly as it is for `bootstrap-platform-owner.ts` — no argv manipulation is needed to prove
// the guard holds. Importing the command must never prompt, connect, or write.
await expect(import("../src/cli/create-initial-owner.js")).resolves.toBeDefined();
expect(poolConstructor).not.toHaveBeenCalled();
process.env = originalEnv;
},
IMPORT_SAFETY_TEST_TIMEOUT_MS,
);
it("reads no environment variable for the password", async () => {
// The password is prompted for or read from standard input; it is deliberately never taken from
// the environment, so nothing can make it permanent deployment configuration. Asserted against
// the source rather than behaviour, because the absence of a lookup is what matters.
const source = await import("node:fs/promises").then((fs) =>
fs.readFile(new URL("../src/cli/create-initial-owner.ts", import.meta.url), "utf8"),
);
const environmentReads = [...source.matchAll(/process\.env\.([A-Z_]+)/gu)].map(
(match) => match[1],
);
expect(environmentReads).toEqual(["DATABASE_URL"]);
// No dynamic lookup either, which a named-property scan alone would miss.
expect(source).not.toMatch(/process\.env\[/u);
// And a password supplied on the command line is refused rather than quietly honoured.
expect(source).toContain("--password is not supported");
});
});