From 8f535285d2516509516721c71542ceadccbd8d80 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 14 Feb 2026 22:11:48 +0000 Subject: [PATCH] refactor(test): share command handler params --- src/auto-reply/reply/commands-approve.test.ts | 53 +++---------------- src/auto-reply/reply/commands-parsing.test.ts | 45 ++-------------- src/auto-reply/reply/commands.test-harness.ts | 46 ++++++++++++++++ 3 files changed, 56 insertions(+), 88 deletions(-) create mode 100644 src/auto-reply/reply/commands.test-harness.ts diff --git a/src/auto-reply/reply/commands-approve.test.ts b/src/auto-reply/reply/commands-approve.test.ts index 3ffce93c8b6..cfb1f3cb7f0 100644 --- a/src/auto-reply/reply/commands-approve.test.ts +++ b/src/auto-reply/reply/commands-approve.test.ts @@ -1,52 +1,13 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; import type { OpenClawConfig } from "../../config/config.js"; -import type { MsgContext } from "../templating.js"; import { callGateway } from "../../gateway/call.js"; -import { buildCommandContext, handleCommands } from "./commands.js"; -import { parseInlineDirectives } from "./directive-handling.js"; +import { handleCommands } from "./commands.js"; +import { buildCommandTestParams } from "./commands.test-harness.js"; vi.mock("../../gateway/call.js", () => ({ callGateway: vi.fn(), })); -function buildParams(commandBody: string, cfg: OpenClawConfig, ctxOverrides?: Partial) { - const ctx = { - Body: commandBody, - CommandBody: commandBody, - CommandSource: "text", - CommandAuthorized: true, - Provider: "whatsapp", - Surface: "whatsapp", - ...ctxOverrides, - } as MsgContext; - - const command = buildCommandContext({ - ctx, - cfg, - isGroup: false, - triggerBodyNormalized: commandBody.trim().toLowerCase(), - commandAuthorized: true, - }); - - return { - ctx, - cfg, - command, - directives: parseInlineDirectives(commandBody), - elevated: { enabled: true, allowed: true, failures: [] }, - sessionKey: "agent:main:main", - workspaceDir: "/tmp", - defaultGroupActivation: () => "mention", - resolvedVerboseLevel: "off" as const, - resolvedReasoningLevel: "off" as const, - resolveDefaultThinkingLevel: async () => undefined, - provider: "whatsapp", - model: "test-model", - contextTokens: 0, - isGroup: false, - }; -} - describe("/approve command", () => { beforeEach(() => { vi.clearAllMocks(); @@ -57,7 +18,7 @@ describe("/approve command", () => { commands: { text: true }, channels: { whatsapp: { allowFrom: ["*"] } }, } as OpenClawConfig; - const params = buildParams("/approve", cfg); + const params = buildCommandTestParams("/approve", cfg); const result = await handleCommands(params); expect(result.shouldContinue).toBe(false); expect(result.reply?.text).toContain("Usage: /approve"); @@ -68,7 +29,7 @@ describe("/approve command", () => { commands: { text: true }, channels: { whatsapp: { allowFrom: ["*"] } }, } as OpenClawConfig; - const params = buildParams("/approve abc allow-once", cfg, { SenderId: "123" }); + const params = buildCommandTestParams("/approve abc allow-once", cfg, { SenderId: "123" }); const mockCallGateway = vi.mocked(callGateway); mockCallGateway.mockResolvedValueOnce({ ok: true }); @@ -88,7 +49,7 @@ describe("/approve command", () => { const cfg = { commands: { text: true }, } as OpenClawConfig; - const params = buildParams("/approve abc allow-once", cfg, { + const params = buildCommandTestParams("/approve abc allow-once", cfg, { Provider: "webchat", Surface: "webchat", GatewayClientScopes: ["operator.write"], @@ -107,7 +68,7 @@ describe("/approve command", () => { const cfg = { commands: { text: true }, } as OpenClawConfig; - const params = buildParams("/approve abc allow-once", cfg, { + const params = buildCommandTestParams("/approve abc allow-once", cfg, { Provider: "webchat", Surface: "webchat", GatewayClientScopes: ["operator.approvals"], @@ -131,7 +92,7 @@ describe("/approve command", () => { const cfg = { commands: { text: true }, } as OpenClawConfig; - const params = buildParams("/approve abc allow-once", cfg, { + const params = buildCommandTestParams("/approve abc allow-once", cfg, { Provider: "webchat", Surface: "webchat", GatewayClientScopes: ["operator.admin"], diff --git a/src/auto-reply/reply/commands-parsing.test.ts b/src/auto-reply/reply/commands-parsing.test.ts index 908cf7ca43c..47309f93217 100644 --- a/src/auto-reply/reply/commands-parsing.test.ts +++ b/src/auto-reply/reply/commands-parsing.test.ts @@ -1,49 +1,10 @@ import { describe, expect, it } from "vitest"; import type { OpenClawConfig } from "../../config/config.js"; -import type { MsgContext } from "../templating.js"; import { extractMessageText } from "./commands-subagents.js"; -import { buildCommandContext, handleCommands } from "./commands.js"; +import { handleCommands } from "./commands.js"; +import { buildCommandTestParams } from "./commands.test-harness.js"; import { parseConfigCommand } from "./config-commands.js"; import { parseDebugCommand } from "./debug-commands.js"; -import { parseInlineDirectives } from "./directive-handling.js"; - -function buildParams(commandBody: string, cfg: OpenClawConfig, ctxOverrides?: Partial) { - const ctx = { - Body: commandBody, - CommandBody: commandBody, - CommandSource: "text", - CommandAuthorized: true, - Provider: "whatsapp", - Surface: "whatsapp", - ...ctxOverrides, - } as MsgContext; - - const command = buildCommandContext({ - ctx, - cfg, - isGroup: false, - triggerBodyNormalized: commandBody.trim().toLowerCase(), - commandAuthorized: true, - }); - - return { - ctx, - cfg, - command, - directives: parseInlineDirectives(commandBody), - elevated: { enabled: true, allowed: true, failures: [] }, - sessionKey: "agent:main:main", - workspaceDir: "/tmp", - defaultGroupActivation: () => "mention", - resolvedVerboseLevel: "off" as const, - resolvedReasoningLevel: "off" as const, - resolveDefaultThinkingLevel: async () => undefined, - provider: "whatsapp", - model: "test-model", - contextTokens: 0, - isGroup: false, - }; -} describe("parseConfigCommand", () => { it("parses show/unset", () => { @@ -116,7 +77,7 @@ describe("handleCommands /config configWrites gating", () => { commands: { config: true, text: true }, channels: { whatsapp: { allowFrom: ["*"], configWrites: false } }, } as OpenClawConfig; - const params = buildParams('/config set messages.ackReaction=":)"', cfg); + const params = buildCommandTestParams('/config set messages.ackReaction=":)"', cfg); const result = await handleCommands(params); expect(result.shouldContinue).toBe(false); expect(result.reply?.text).toContain("Config writes are disabled"); diff --git a/src/auto-reply/reply/commands.test-harness.ts b/src/auto-reply/reply/commands.test-harness.ts new file mode 100644 index 00000000000..12b598c19a7 --- /dev/null +++ b/src/auto-reply/reply/commands.test-harness.ts @@ -0,0 +1,46 @@ +import type { OpenClawConfig } from "../../config/config.js"; +import type { MsgContext } from "../templating.js"; +import { buildCommandContext } from "./commands.js"; +import { parseInlineDirectives } from "./directive-handling.js"; + +export function buildCommandTestParams( + commandBody: string, + cfg: OpenClawConfig, + ctxOverrides?: Partial, +) { + const ctx = { + Body: commandBody, + CommandBody: commandBody, + CommandSource: "text", + CommandAuthorized: true, + Provider: "whatsapp", + Surface: "whatsapp", + ...ctxOverrides, + } as MsgContext; + + const command = buildCommandContext({ + ctx, + cfg, + isGroup: false, + triggerBodyNormalized: commandBody.trim().toLowerCase(), + commandAuthorized: true, + }); + + return { + ctx, + cfg, + command, + directives: parseInlineDirectives(commandBody), + elevated: { enabled: true, allowed: true, failures: [] }, + sessionKey: "agent:main:main", + workspaceDir: "/tmp", + defaultGroupActivation: () => "mention", + resolvedVerboseLevel: "off" as const, + resolvedReasoningLevel: "off" as const, + resolveDefaultThinkingLevel: async () => undefined, + provider: "whatsapp", + model: "test-model", + contextTokens: 0, + isGroup: false, + }; +}