From cfb516b6664cf3f909966ea874774397c3ec46a5 Mon Sep 17 00:00:00 2001 From: Shakker Date: Mon, 11 May 2026 17:36:12 +0100 Subject: [PATCH] test: verify cli and daemon call shapes --- src/cli/gateway-cli.coverage.test.ts | 5 ++++- src/cli/route.test.ts | 20 ++++++++++++-------- src/cli/system-cli.test.ts | 25 ++++++++++++++++--------- src/daemon/schtasks.stop.test.ts | 4 ++-- src/daemon/systemd.test.ts | 11 +++++++---- 5 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/cli/gateway-cli.coverage.test.ts b/src/cli/gateway-cli.coverage.test.ts index 54e56f8f21a..cf5246b9429 100644 --- a/src/cli/gateway-cli.coverage.test.ts +++ b/src/cli/gateway-cli.coverage.test.ts @@ -428,7 +428,10 @@ describe("gateway-cli coverage", () => { startGatewayServer.mockRejectedValueOnce(new Error("nope")); await expectGatewayExit(["gateway", "--token", "test-token", "--allow-unconfigured"]); - expect(startGatewayServer).toHaveBeenCalledWith(19001, expect.anything()); + expect(startGatewayServer).toHaveBeenCalledTimes(1); + const startCall = startGatewayServer.mock.calls[0]; + expect(startCall?.[0]).toBe(19001); + expect(typeof startCall?.[1]).toBe("object"); }); }); }); diff --git a/src/cli/route.test.ts b/src/cli/route.test.ts index d7de234f08e..d2a94233190 100644 --- a/src/cli/route.test.ts +++ b/src/cli/route.test.ts @@ -86,10 +86,12 @@ describe("tryRouteCli", () => { it("does not pass suppressDoctorStdout for routed non-json commands", async () => { await expect(tryRouteCli(["node", "openclaw", "status"])).resolves.toBe(true); - expect(ensureConfigReadyMock).toHaveBeenCalledWith({ - runtime: expect.any(Object), - commandPath: ["status"], - }); + expect(ensureConfigReadyMock).toHaveBeenCalledTimes(1); + const configReadyCall = ensureConfigReadyMock.mock.calls[0]?.[0] as + | { runtime?: unknown; commandPath?: unknown } + | undefined; + expect(typeof configReadyCall?.runtime).toBe("object"); + expect(configReadyCall?.commandPath).toEqual(["status"]); expect(ensurePluginRegistryLoadedMock).toHaveBeenCalledWith({ scope: "channels", }); @@ -157,10 +159,12 @@ describe("tryRouteCli", () => { ["status"], ["node", "openclaw", "--log-level", "debug", "status"], ); - expect(ensureConfigReadyMock).toHaveBeenCalledWith({ - runtime: expect.any(Object), - commandPath: ["status"], - }); + expect(ensureConfigReadyMock).toHaveBeenCalledTimes(1); + const configReadyCall = ensureConfigReadyMock.mock.calls[0]?.[0] as + | { runtime?: unknown; commandPath?: unknown } + | undefined; + expect(typeof configReadyCall?.runtime).toBe("object"); + expect(configReadyCall?.commandPath).toEqual(["status"]); expect(ensurePluginRegistryLoadedMock).toHaveBeenCalledWith({ scope: "channels", }); diff --git a/src/cli/system-cli.test.ts b/src/cli/system-cli.test.ts index 22b7e44a6b3..c67fc8508ce 100644 --- a/src/cli/system-cli.test.ts +++ b/src/cli/system-cli.test.ts @@ -78,12 +78,15 @@ describe("system-cli", () => { ]); expect(callGatewayFromCli).toHaveBeenCalledTimes(1); - expect(callGatewayFromCli).toHaveBeenCalledWith( - "wake", - expect.any(Object), - { mode: "next-heartbeat", text: "ping", sessionKey: "agent:main:telegram:dm:42" }, - { expectFinal: false }, - ); + const [method, gatewayOptions, params, requestOptions] = callGatewayFromCli.mock.calls[0] ?? []; + expect(method).toBe("wake"); + expect(typeof gatewayOptions).toBe("object"); + expect(params).toEqual({ + mode: "next-heartbeat", + text: "ping", + sessionKey: "agent:main:telegram:dm:42", + }); + expect(requestOptions).toEqual({ expectFinal: false }); }); it("omits sessionKey from payload when --session-key not provided", async () => { @@ -120,9 +123,13 @@ describe("system-cli", () => { await runCli(args); - expect(callGatewayFromCli).toHaveBeenCalledWith(method, expect.any(Object), params, { - expectFinal: false, - }); + expect(callGatewayFromCli).toHaveBeenCalledTimes(1); + const [calledMethod, gatewayOptions, calledParams, requestOptions] = + callGatewayFromCli.mock.calls[0] ?? []; + expect(calledMethod).toBe(method); + expect(typeof gatewayOptions).toBe("object"); + expect(calledParams).toEqual(params); + expect(requestOptions).toEqual({ expectFinal: false }); expect(runtimeLogs).toEqual([JSON.stringify({ method }, null, 2)]); }); }); diff --git a/src/daemon/schtasks.stop.test.ts b/src/daemon/schtasks.stop.test.ts index 176f8ab9145..767f0a62712 100644 --- a/src/daemon/schtasks.stop.test.ts +++ b/src/daemon/schtasks.stop.test.ts @@ -129,7 +129,7 @@ describe("Scheduled Task stop/restart cleanup", () => { pushSuccessfulSchtasksResponses(3); findVerifiedGatewayListenerPidsOnPortSync.mockReturnValue([4242]); inspectPortUsage.mockResolvedValueOnce(busyPortUsage(4242)); - for (let i = 0; i < 20; i += 1) { + for (let i = 0; i < 19; i += 1) { inspectPortUsage.mockResolvedValueOnce(busyPortUsage(4242)); } inspectPortUsage @@ -140,7 +140,7 @@ describe("Scheduled Task stop/restart cleanup", () => { if (process.platform !== "win32") { expect(killProcessTree).toHaveBeenNthCalledWith(1, 4242, { graceMs: 300 }); - expect(killProcessTree).toHaveBeenNthCalledWith(2, expect.any(Number), { graceMs: 300 }); + expect(killProcessTree).toHaveBeenNthCalledWith(2, 5252, { graceMs: 300 }); } else { expect(killProcessTree).not.toHaveBeenCalled(); } diff --git a/src/daemon/systemd.test.ts b/src/daemon/systemd.test.ts index 1304650887c..1f01a7c4406 100644 --- a/src/daemon/systemd.test.ts +++ b/src/daemon/systemd.test.ts @@ -1195,10 +1195,13 @@ describe("systemd service install and uninstall", () => { const { write, stdout } = createWritableStreamMock(); await uninstallSystemdService({ env, stdout }); - await expect(fs.access(unitPath)).rejects.toSatisfy((error) => { - expect((error as NodeJS.ErrnoException).code).toBe("ENOENT"); - return true; - }); + let accessError: NodeJS.ErrnoException | undefined; + try { + await fs.access(unitPath); + } catch (error) { + accessError = error as NodeJS.ErrnoException; + } + expect(accessError?.code).toBe("ENOENT"); expect(requireFirstWrite(write)).toContain("Removed systemd service"); expect(execFileMock).toHaveBeenCalledTimes(2); });