From dc9e67d2d4728ff1ff6fcd91c8cd07ffb3172a06 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Mon, 1 Jun 2026 06:13:26 +0200 Subject: [PATCH] refactor: share tools catalog test helpers --- .../server-methods/tools-catalog.test.ts | 90 +++++++++---------- 1 file changed, 43 insertions(+), 47 deletions(-) diff --git a/src/gateway/server-methods/tools-catalog.test.ts b/src/gateway/server-methods/tools-catalog.test.ts index 0ed0750f6a0..eafd8fc1294 100644 --- a/src/gateway/server-methods/tools-catalog.test.ts +++ b/src/gateway/server-methods/tools-catalog.test.ts @@ -6,10 +6,6 @@ import { } from "../../plugins/tools.js"; import { toolsCatalogHandlers } from "./tools-catalog.js"; -vi.mock("../../config/config.js", () => ({ - getRuntimeConfig: vi.fn(() => ({})), -})); - vi.mock("../../agents/agent-scope.js", () => ({ listAgentIds: vi.fn(() => ["main"]), resolveDefaultAgentId: vi.fn(() => "main"), @@ -17,6 +13,10 @@ vi.mock("../../agents/agent-scope.js", () => ({ resolveAgentDir: vi.fn(() => "/tmp/agents/main/agent"), })); +vi.mock("../../config/config.js", () => ({ + getRuntimeConfig: vi.fn(() => ({})), +})); + const pluginToolMetaState = new Map(); vi.mock("../../plugins/tools.js", () => ({ @@ -36,6 +36,27 @@ vi.mock("../../plugins/tools.js", () => ({ })); type RespondCall = [boolean, unknown?, { code: number; message: string }?]; +type CatalogTool = { + id: string; + source: "core" | "plugin"; + label?: string; + description?: string; + pluginId?: string; + optional?: boolean; + risk?: unknown; + tags?: unknown; + defaultProfiles?: unknown[]; +}; +type CatalogGroup = { + id?: string; + source: "core" | "plugin"; + pluginId?: string; + tools: CatalogTool[]; +}; +type CatalogPayload = { + agentId?: string; + groups: CatalogGroup[]; +}; function createInvokeParams(params: Record) { const respond = vi.fn(); @@ -69,6 +90,19 @@ function respondCall(respond: ReturnType): RespondCall { return call; } +function expectInvalidRequest(respond: ReturnType, message: string) { + const call = respondCall(respond); + expect(call[0]).toBe(false); + expect(call[2]?.code).toBe(ErrorCodes.INVALID_REQUEST); + expect(call[2]?.message).toContain(message); +} + +function expectCatalogPayload(respond: ReturnType): CatalogPayload { + const call = respondCall(respond); + expect(call[0]).toBe(true); + return call[1] as CatalogPayload; +} + describe("tools.catalog handler", () => { beforeEach(() => { pluginToolMetaState.clear(); @@ -79,34 +113,19 @@ describe("tools.catalog handler", () => { it("rejects invalid params", async () => { const { respond, invoke } = createInvokeParams({ extra: true }); await invoke(); - const call = respondCall(respond); - expect(call[0]).toBe(false); - expect(call[2]?.code).toBe(ErrorCodes.INVALID_REQUEST); - expect(call[2]?.message).toContain("invalid tools.catalog params"); + expectInvalidRequest(respond, "invalid tools.catalog params"); }); it("rejects unknown agent ids", async () => { const { respond, invoke } = createInvokeParams({ agentId: "unknown-agent" }); await invoke(); - const call = respondCall(respond); - expect(call[0]).toBe(false); - expect(call[2]?.code).toBe(ErrorCodes.INVALID_REQUEST); - expect(call[2]?.message).toContain("unknown agent id"); + expectInvalidRequest(respond, "unknown agent id"); }); it("returns core groups including tts and excludes plugins when includePlugins=false", async () => { const { respond, invoke } = createInvokeParams({ includePlugins: false }); await invoke(); - const call = respondCall(respond); - expect(call[0]).toBe(true); - const payload = call[1] as { - agentId: string; - groups: Array<{ - id: string; - source: "core" | "plugin"; - tools: Array<{ id: string; source: "core" | "plugin" }>; - }>; - }; + const payload = expectCatalogPayload(respond); expect(payload.agentId).toBe("main"); const groups = payload.groups ?? []; expect(groups.some((group) => group.source === "plugin")).toBe(false); @@ -117,20 +136,7 @@ describe("tools.catalog handler", () => { it("includes plugin groups with plugin metadata", async () => { const { respond, invoke } = createInvokeParams({}); await invoke(); - const call = respondCall(respond); - expect(call[0]).toBe(true); - const payload = call[1] as { - groups: Array<{ - source: "core" | "plugin"; - pluginId?: string; - tools: Array<{ - id: string; - source: "core" | "plugin"; - pluginId?: string; - optional?: boolean; - }>; - }>; - }; + const payload = expectCatalogPayload(respond); const pluginGroups = payload.groups.filter((group) => group.source === "plugin"); expect(pluginGroups.length).toBeGreaterThan(0); const voiceCall = pluginGroups @@ -152,17 +158,7 @@ describe("tools.catalog handler", () => { it("summarizes plugin tool descriptions the same way as the effective inventory", async () => { const { respond, invoke } = createInvokeParams({}); await invoke(); - const call = respondCall(respond); - expect(call[0]).toBe(true); - const payload = call[1] as { - groups: Array<{ - source: "core" | "plugin"; - tools: Array<{ - id: string; - description: string; - }>; - }>; - }; + const payload = expectCatalogPayload(respond); const matrixRoom = payload.groups .filter((group) => group.source === "plugin") .flatMap((group) => group.tools)