test(cli): dedupe config-guard harness and cover invalid-config gates
This commit is contained in:
@@ -29,10 +29,26 @@ function makeRuntime() {
|
||||
}
|
||||
|
||||
describe("ensureConfigReady", () => {
|
||||
async function runEnsureConfigReady(commandPath: string[]) {
|
||||
async function loadEnsureConfigReady() {
|
||||
vi.resetModules();
|
||||
const { ensureConfigReady } = await import("./config-guard.js");
|
||||
await ensureConfigReady({ runtime: makeRuntime() as never, commandPath });
|
||||
return await import("./config-guard.js");
|
||||
}
|
||||
|
||||
async function runEnsureConfigReady(commandPath: string[]) {
|
||||
const runtime = makeRuntime();
|
||||
const { ensureConfigReady } = await loadEnsureConfigReady();
|
||||
await ensureConfigReady({ runtime: runtime as never, commandPath });
|
||||
return runtime;
|
||||
}
|
||||
|
||||
function setInvalidSnapshot(overrides?: Partial<ReturnType<typeof makeSnapshot>>) {
|
||||
readConfigFileSnapshotMock.mockResolvedValue({
|
||||
...makeSnapshot(),
|
||||
exists: true,
|
||||
valid: false,
|
||||
issues: [{ path: "channels.whatsapp", message: "invalid" }],
|
||||
...overrides,
|
||||
});
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -55,4 +71,33 @@ describe("ensureConfigReady", () => {
|
||||
await runEnsureConfigReady(commandPath);
|
||||
expect(loadAndMaybeMigrateDoctorConfigMock).toHaveBeenCalledTimes(expectedDoctorCalls);
|
||||
});
|
||||
|
||||
it("exits for invalid config on non-allowlisted commands", async () => {
|
||||
setInvalidSnapshot();
|
||||
const runtime = await runEnsureConfigReady(["message"]);
|
||||
|
||||
expect(runtime.error).toHaveBeenCalledWith(expect.stringContaining("Config invalid"));
|
||||
expect(runtime.error).toHaveBeenCalledWith(expect.stringContaining("doctor --fix"));
|
||||
expect(runtime.exit).toHaveBeenCalledWith(1);
|
||||
});
|
||||
|
||||
it("does not exit for invalid config on allowlisted commands", async () => {
|
||||
setInvalidSnapshot();
|
||||
const statusRuntime = await runEnsureConfigReady(["status"]);
|
||||
expect(statusRuntime.exit).not.toHaveBeenCalled();
|
||||
|
||||
const gatewayRuntime = await runEnsureConfigReady(["gateway", "health"]);
|
||||
expect(gatewayRuntime.exit).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("runs doctor migration flow only once per module instance", async () => {
|
||||
const runtimeA = makeRuntime();
|
||||
const runtimeB = makeRuntime();
|
||||
const { ensureConfigReady } = await loadEnsureConfigReady();
|
||||
|
||||
await ensureConfigReady({ runtime: runtimeA as never, commandPath: ["message"] });
|
||||
await ensureConfigReady({ runtime: runtimeB as never, commandPath: ["message"] });
|
||||
|
||||
expect(loadAndMaybeMigrateDoctorConfigMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user