Files
clawdbot/src/cli/daemon-cli.coverage.test.ts
2026-01-08 02:29:32 +01:00

149 lines
4.5 KiB
TypeScript

import { Command } from "commander";
import { describe, expect, it, vi } from "vitest";
const callGateway = vi.fn(async () => ({ ok: true }));
const resolveGatewayProgramArguments = vi.fn(async () => ({
programArguments: ["/bin/node", "cli", "gateway-daemon", "--port", "18789"],
}));
const serviceInstall = vi.fn().mockResolvedValue(undefined);
const serviceUninstall = vi.fn().mockResolvedValue(undefined);
const serviceStop = vi.fn().mockResolvedValue(undefined);
const serviceRestart = vi.fn().mockResolvedValue(undefined);
const serviceIsLoaded = vi.fn().mockResolvedValue(false);
const serviceReadCommand = vi.fn().mockResolvedValue(null);
const serviceReadRuntime = vi.fn().mockResolvedValue({ status: "running" });
const findExtraGatewayServices = vi.fn(async () => []);
const inspectPortUsage = vi.fn(async () => ({
port: 18789,
status: "free",
listeners: [],
hints: [],
}));
const runtimeLogs: string[] = [];
const runtimeErrors: string[] = [];
const defaultRuntime = {
log: (msg: string) => runtimeLogs.push(msg),
error: (msg: string) => runtimeErrors.push(msg),
exit: (code: number) => {
throw new Error(`__exit__:${code}`);
},
};
vi.mock("../gateway/call.js", () => ({
callGateway: (opts: unknown) => callGateway(opts),
}));
vi.mock("../daemon/program-args.js", () => ({
resolveGatewayProgramArguments: (opts: unknown) =>
resolveGatewayProgramArguments(opts),
}));
vi.mock("../daemon/service.js", () => ({
resolveGatewayService: () => ({
label: "LaunchAgent",
loadedText: "loaded",
notLoadedText: "not loaded",
install: serviceInstall,
uninstall: serviceUninstall,
stop: serviceStop,
restart: serviceRestart,
isLoaded: serviceIsLoaded,
readCommand: serviceReadCommand,
readRuntime: serviceReadRuntime,
}),
}));
vi.mock("../daemon/legacy.js", () => ({
findLegacyGatewayServices: () => [],
}));
vi.mock("../daemon/inspect.js", () => ({
findExtraGatewayServices: (env: unknown, opts?: unknown) =>
findExtraGatewayServices(env, opts),
}));
vi.mock("../infra/ports.js", () => ({
inspectPortUsage: (port: number) => inspectPortUsage(port),
formatPortDiagnostics: () => ["Port 18789 is already in use."],
}));
vi.mock("../runtime.js", () => ({
defaultRuntime,
}));
vi.mock("./deps.js", () => ({
createDefaultDeps: () => {},
}));
describe("daemon-cli coverage", () => {
it("probes gateway status by default", async () => {
runtimeLogs.length = 0;
runtimeErrors.length = 0;
callGateway.mockClear();
const { registerDaemonCli } = await import("./daemon-cli.js");
const program = new Command();
program.exitOverride();
registerDaemonCli(program);
await program.parseAsync(["daemon", "status"], { from: "user" });
expect(callGateway).toHaveBeenCalledTimes(1);
expect(callGateway).toHaveBeenCalledWith(
expect.objectContaining({ method: "status" }),
);
expect(findExtraGatewayServices).toHaveBeenCalled();
expect(inspectPortUsage).toHaveBeenCalled();
});
it("passes deep scan flag for daemon status", async () => {
findExtraGatewayServices.mockClear();
const { registerDaemonCli } = await import("./daemon-cli.js");
const program = new Command();
program.exitOverride();
registerDaemonCli(program);
await program.parseAsync(["daemon", "status", "--deep"], { from: "user" });
expect(findExtraGatewayServices).toHaveBeenCalledWith(
expect.anything(),
expect.objectContaining({ deep: true }),
);
});
it("installs the daemon when requested", async () => {
serviceIsLoaded.mockResolvedValueOnce(false);
serviceInstall.mockClear();
const { registerDaemonCli } = await import("./daemon-cli.js");
const program = new Command();
program.exitOverride();
registerDaemonCli(program);
await program.parseAsync(["daemon", "install", "--port", "18789"], {
from: "user",
});
expect(serviceInstall).toHaveBeenCalledTimes(1);
});
it("starts and stops the daemon via service helpers", async () => {
serviceRestart.mockClear();
serviceStop.mockClear();
serviceIsLoaded.mockResolvedValue(true);
const { registerDaemonCli } = await import("./daemon-cli.js");
const program = new Command();
program.exitOverride();
registerDaemonCli(program);
await program.parseAsync(["daemon", "start"], { from: "user" });
await program.parseAsync(["daemon", "stop"], { from: "user" });
expect(serviceRestart).toHaveBeenCalledTimes(1);
expect(serviceStop).toHaveBeenCalledTimes(1);
});
});