From 6ec76af3a6fb925fffd3c59bff4c7f17931a8941 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 15 Feb 2026 14:41:45 +0000 Subject: [PATCH] refactor(test): share slack slash mocks --- .../monitor/slash.command-arg-menus.test.ts | 40 +----------- src/slack/monitor/slash.policy.test.ts | 40 +----------- src/slack/monitor/slash.test-mocks.ts | 62 +++++++++++++++++++ 3 files changed, 68 insertions(+), 74 deletions(-) create mode 100644 src/slack/monitor/slash.test-mocks.ts diff --git a/src/slack/monitor/slash.command-arg-menus.test.ts b/src/slack/monitor/slash.command-arg-menus.test.ts index ebf40aeca39..d9a2b27fc36 100644 --- a/src/slack/monitor/slash.command-arg-menus.test.ts +++ b/src/slack/monitor/slash.command-arg-menus.test.ts @@ -1,31 +1,8 @@ -import { beforeEach, describe, expect, it, vi } from "vitest"; +import { describe, expect, it, vi } from "vitest"; import { registerSlackMonitorSlashCommands } from "./slash.js"; +import { getDispatchMock } from "./slash.test-mocks.js"; -const dispatchMock = vi.fn(); -const readAllowFromStoreMock = vi.fn(); -const upsertPairingRequestMock = vi.fn(); -const resolveAgentRouteMock = vi.fn(); - -vi.mock("../../auto-reply/reply/provider-dispatcher.js", () => ({ - dispatchReplyWithDispatcher: (...args: unknown[]) => dispatchMock(...args), -})); - -vi.mock("../../pairing/pairing-store.js", () => ({ - readChannelAllowFromStore: (...args: unknown[]) => readAllowFromStoreMock(...args), - upsertChannelPairingRequest: (...args: unknown[]) => upsertPairingRequestMock(...args), -})); - -vi.mock("../../routing/resolve-route.js", () => ({ - resolveAgentRoute: (...args: unknown[]) => resolveAgentRouteMock(...args), -})); - -vi.mock("../../agents/identity.js", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - resolveEffectiveMessagesConfig: () => ({ responsePrefix: "" }), - }; -}); +const dispatchMock = getDispatchMock(); function encodeValue(parts: { command: string; arg: string; value: string; userId: string }) { return [ @@ -85,17 +62,6 @@ function createHarness() { return { commands, actions, postEphemeral, ctx, account }; } -beforeEach(() => { - dispatchMock.mockReset().mockResolvedValue({ counts: { final: 1, tool: 0, block: 0 } }); - readAllowFromStoreMock.mockReset().mockResolvedValue([]); - upsertPairingRequestMock.mockReset().mockResolvedValue({ code: "PAIRCODE", created: true }); - resolveAgentRouteMock.mockReset().mockReturnValue({ - agentId: "main", - sessionKey: "session:1", - accountId: "acct", - }); -}); - describe("Slack native command argument menus", () => { it("shows a button menu when required args are omitted", async () => { const { commands, ctx, account } = createHarness(); diff --git a/src/slack/monitor/slash.policy.test.ts b/src/slack/monitor/slash.policy.test.ts index 8c861f9ac32..c4bf40b7f16 100644 --- a/src/slack/monitor/slash.policy.test.ts +++ b/src/slack/monitor/slash.policy.test.ts @@ -1,31 +1,8 @@ -import { beforeEach, describe, expect, it, vi } from "vitest"; +import { describe, expect, it, vi } from "vitest"; import { registerSlackMonitorSlashCommands } from "./slash.js"; +import { getDispatchMock } from "./slash.test-mocks.js"; -const dispatchMock = vi.fn(); -const readAllowFromStoreMock = vi.fn(); -const upsertPairingRequestMock = vi.fn(); -const resolveAgentRouteMock = vi.fn(); - -vi.mock("../../auto-reply/reply/provider-dispatcher.js", () => ({ - dispatchReplyWithDispatcher: (...args: unknown[]) => dispatchMock(...args), -})); - -vi.mock("../../pairing/pairing-store.js", () => ({ - readChannelAllowFromStore: (...args: unknown[]) => readAllowFromStoreMock(...args), - upsertChannelPairingRequest: (...args: unknown[]) => upsertPairingRequestMock(...args), -})); - -vi.mock("../../routing/resolve-route.js", () => ({ - resolveAgentRoute: (...args: unknown[]) => resolveAgentRouteMock(...args), -})); - -vi.mock("../../agents/identity.js", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - resolveEffectiveMessagesConfig: () => ({ responsePrefix: "" }), - }; -}); +const dispatchMock = getDispatchMock(); function createHarness(overrides?: { groupPolicy?: "open" | "allowlist"; @@ -117,17 +94,6 @@ async function runSlashHandler(params: { return { respond, ack }; } -beforeEach(() => { - dispatchMock.mockReset().mockResolvedValue({ counts: { final: 1, tool: 0, block: 0 } }); - readAllowFromStoreMock.mockReset().mockResolvedValue([]); - upsertPairingRequestMock.mockReset().mockResolvedValue({ code: "PAIRCODE", created: true }); - resolveAgentRouteMock.mockReset().mockReturnValue({ - agentId: "main", - sessionKey: "session:1", - accountId: "acct", - }); -}); - describe("slack slash commands channel policy", () => { it("allows unlisted channels when groupPolicy is open", async () => { const { commands, ctx, account, channelId, channelName } = createHarness({ diff --git a/src/slack/monitor/slash.test-mocks.ts b/src/slack/monitor/slash.test-mocks.ts new file mode 100644 index 00000000000..690e594de31 --- /dev/null +++ b/src/slack/monitor/slash.test-mocks.ts @@ -0,0 +1,62 @@ +import { beforeEach, vi } from "vitest"; + +// Avoid exporting vitest mock types (TS2742 under pnpm + d.ts emit). +// oxlint-disable-next-line typescript/no-explicit-any +type AnyMock = any; + +const hoisted = vi.hoisted(() => ({ + dispatchMock: vi.fn(), + readAllowFromStoreMock: vi.fn(), + upsertPairingRequestMock: vi.fn(), + resolveAgentRouteMock: vi.fn(), +})); + +export function getDispatchMock(): AnyMock { + return hoisted.dispatchMock; +} + +export function getReadAllowFromStoreMock(): AnyMock { + return hoisted.readAllowFromStoreMock; +} + +export function getUpsertPairingRequestMock(): AnyMock { + return hoisted.upsertPairingRequestMock; +} + +export function getResolveAgentRouteMock(): AnyMock { + return hoisted.resolveAgentRouteMock; +} + +vi.mock("../../auto-reply/reply/provider-dispatcher.js", () => ({ + dispatchReplyWithDispatcher: (...args: unknown[]) => hoisted.dispatchMock(...args), +})); + +vi.mock("../../pairing/pairing-store.js", () => ({ + readChannelAllowFromStore: (...args: unknown[]) => hoisted.readAllowFromStoreMock(...args), + upsertChannelPairingRequest: (...args: unknown[]) => hoisted.upsertPairingRequestMock(...args), +})); + +vi.mock("../../routing/resolve-route.js", () => ({ + resolveAgentRoute: (...args: unknown[]) => hoisted.resolveAgentRouteMock(...args), +})); + +vi.mock("../../agents/identity.js", async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + resolveEffectiveMessagesConfig: () => ({ responsePrefix: "" }), + }; +}); + +beforeEach(() => { + hoisted.dispatchMock.mockReset().mockResolvedValue({ counts: { final: 1, tool: 0, block: 0 } }); + hoisted.readAllowFromStoreMock.mockReset().mockResolvedValue([]); + hoisted.upsertPairingRequestMock + .mockReset() + .mockResolvedValue({ code: "PAIRCODE", created: true }); + hoisted.resolveAgentRouteMock.mockReset().mockReturnValue({ + agentId: "main", + sessionKey: "session:1", + accountId: "acct", + }); +});