From 16e5fa1db945e158ebca919346307559bae5e125 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 17 Jan 2026 23:41:39 +0000 Subject: [PATCH] test: cover daemon install helpers --- src/commands/daemon-install-helpers.test.ts | 104 ++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 src/commands/daemon-install-helpers.test.ts diff --git a/src/commands/daemon-install-helpers.test.ts b/src/commands/daemon-install-helpers.test.ts new file mode 100644 index 000000000..a5b51e225 --- /dev/null +++ b/src/commands/daemon-install-helpers.test.ts @@ -0,0 +1,104 @@ +import { afterEach, describe, expect, it, vi } from "vitest"; + +const mocks = vi.hoisted(() => ({ + resolvePreferredNodePath: vi.fn(), + resolveGatewayProgramArguments: vi.fn(), + resolveSystemNodeInfo: vi.fn(), + renderSystemNodeWarning: vi.fn(), + buildServiceEnvironment: vi.fn(), +})); + +vi.mock("../daemon/runtime-paths.js", () => ({ + resolvePreferredNodePath: mocks.resolvePreferredNodePath, + resolveSystemNodeInfo: mocks.resolveSystemNodeInfo, + renderSystemNodeWarning: mocks.renderSystemNodeWarning, +})); + +vi.mock("../daemon/program-args.js", () => ({ + resolveGatewayProgramArguments: mocks.resolveGatewayProgramArguments, +})); + +vi.mock("../daemon/service-env.js", () => ({ + buildServiceEnvironment: mocks.buildServiceEnvironment, +})); + +import { + buildGatewayInstallPlan, + gatewayInstallErrorHint, + resolveGatewayDevMode, +} from "./daemon-install-helpers.js"; + +afterEach(() => { + vi.resetAllMocks(); +}); + +describe("resolveGatewayDevMode", () => { + it("detects dev mode for src ts entrypoints", () => { + expect( + resolveGatewayDevMode(["node", "/Users/me/clawdbot/src/cli/index.ts"]), + ).toBe(true); + expect(resolveGatewayDevMode(["node", "/Users/me/clawdbot/dist/cli/index.js"])).toBe(false); + }); +}); + +describe("buildGatewayInstallPlan", () => { + it("uses provided nodePath and returns plan", async () => { + mocks.resolvePreferredNodePath.mockResolvedValue("/opt/node"); + mocks.resolveGatewayProgramArguments.mockResolvedValue({ + programArguments: ["node", "gateway"], + workingDirectory: "/Users/me", + }); + mocks.resolveSystemNodeInfo.mockResolvedValue({ + path: "/opt/node", + version: "22.0.0", + supported: true, + }); + mocks.renderSystemNodeWarning.mockReturnValue(undefined); + mocks.buildServiceEnvironment.mockReturnValue({ CLAWDBOT_PORT: "3000" }); + + const plan = await buildGatewayInstallPlan({ + env: {}, + port: 3000, + runtime: "node", + nodePath: "/custom/node", + }); + + expect(plan.programArguments).toEqual(["node", "gateway"]); + expect(plan.workingDirectory).toBe("/Users/me"); + expect(plan.environment).toEqual({ CLAWDBOT_PORT: "3000" }); + expect(mocks.resolvePreferredNodePath).not.toHaveBeenCalled(); + }); + + it("emits warnings when renderSystemNodeWarning returns one", async () => { + const warn = vi.fn(); + mocks.resolvePreferredNodePath.mockResolvedValue("/opt/node"); + mocks.resolveGatewayProgramArguments.mockResolvedValue({ + programArguments: ["node", "gateway"], + workingDirectory: undefined, + }); + mocks.resolveSystemNodeInfo.mockResolvedValue({ + path: "/opt/node", + version: "18.0.0", + supported: false, + }); + mocks.renderSystemNodeWarning.mockReturnValue("Node too old"); + mocks.buildServiceEnvironment.mockReturnValue({}); + + await buildGatewayInstallPlan({ + env: {}, + port: 3000, + runtime: "node", + warn, + }); + + expect(warn).toHaveBeenCalledWith("Node too old", "Gateway runtime"); + expect(mocks.resolvePreferredNodePath).toHaveBeenCalled(); + }); +}); + +describe("gatewayInstallErrorHint", () => { + it("returns platform-specific hints", () => { + expect(gatewayInstallErrorHint("win32")).toContain("Run as administrator"); + expect(gatewayInstallErrorHint("linux")).toContain("clawdbot daemon install"); + }); +});