From 2da3b45ce78a2451b48fe3208ffaf8e9cc4ec68c Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 3 Apr 2026 16:12:51 +0100 Subject: [PATCH] test: reduce discord component partial mocks --- .../agent-components-helpers.runtime.ts | 5 ++ .../src/monitor/agent-components-helpers.ts | 20 ++++--- .../src/monitor/agent-components.runtime.ts | 6 ++ .../discord/src/monitor/agent-components.ts | 6 +- .../monitor/monitor.agent-components.test.ts | 13 ----- .../src/test-support/component-runtime.ts | 57 ++++++------------- 6 files changed, 42 insertions(+), 65 deletions(-) create mode 100644 extensions/discord/src/monitor/agent-components-helpers.runtime.ts create mode 100644 extensions/discord/src/monitor/agent-components.runtime.ts diff --git a/extensions/discord/src/monitor/agent-components-helpers.runtime.ts b/extensions/discord/src/monitor/agent-components-helpers.runtime.ts new file mode 100644 index 00000000000..91cc2c26125 --- /dev/null +++ b/extensions/discord/src/monitor/agent-components-helpers.runtime.ts @@ -0,0 +1,5 @@ +export { + readStoreAllowFromForDmPolicy, + resolvePinnedMainDmOwnerFromAllowlist, +} from "openclaw/plugin-sdk/security-runtime"; +export { upsertChannelPairingRequest } from "openclaw/plugin-sdk/conversation-runtime"; diff --git a/extensions/discord/src/monitor/agent-components-helpers.ts b/extensions/discord/src/monitor/agent-components-helpers.ts index 73855fd86a2..f6fc34c9548 100644 --- a/extensions/discord/src/monitor/agent-components-helpers.ts +++ b/extensions/discord/src/monitor/agent-components-helpers.ts @@ -15,17 +15,20 @@ import { resolveCommandAuthorizedFromAuthorizers } from "openclaw/plugin-sdk/com import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime"; import type { DiscordAccountConfig } from "openclaw/plugin-sdk/config-runtime"; import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime"; -import { resolveOpenProviderRuntimeGroupPolicy } from "openclaw/plugin-sdk/runtime-group-policy"; -import * as conversationRuntime from "openclaw/plugin-sdk/conversation-runtime"; import { resolveAgentRoute } from "openclaw/plugin-sdk/routing"; import { logVerbose } from "openclaw/plugin-sdk/runtime-env"; -import * as securityRuntime from "openclaw/plugin-sdk/security-runtime"; +import { resolveOpenProviderRuntimeGroupPolicy } from "openclaw/plugin-sdk/runtime-group-policy"; import { logError } from "openclaw/plugin-sdk/text-runtime"; import { parseDiscordComponentCustomId, parseDiscordModalCustomId, } from "../component-custom-id.js"; import type { DiscordComponentEntry, DiscordModalEntry } from "../components.js"; +import { + readStoreAllowFromForDmPolicy, + resolvePinnedMainDmOwnerFromAllowlist, + upsertChannelPairingRequest, +} from "./agent-components-helpers.runtime.js"; import { type DiscordGuildEntryResolved, isDiscordGroupAllowedByPolicy, @@ -138,8 +141,6 @@ export function buildAgentSelectCustomId(componentId: string): string { return `${AGENT_SELECT_KEY}:componentId=${encodeURIComponent(componentId)}`; } -const { resolvePinnedMainDmOwnerFromAllowlist } = securityRuntime; - export function resolveAgentComponentRoute(params: { ctx: AgentComponentContext; rawGuildId: string | undefined; @@ -512,7 +513,7 @@ async function ensureDmComponentAuthorized(params: { return false; } - const storeAllowFrom = await securityRuntime.readStoreAllowFromForDmPolicy({ + const storeAllowFrom = await readStoreAllowFromForDmPolicy({ provider: "discord", accountId: ctx.accountId, dmPolicy, @@ -525,13 +526,14 @@ async function ensureDmComponentAuthorized(params: { if (dmPolicy === "pairing") { const pairingResult = await createChannelPairingChallengeIssuer({ channel: "discord", - upsertPairingRequest: async ({ id, meta }) => - await conversationRuntime.upsertChannelPairingRequest({ + upsertPairingRequest: async ({ id, meta }) => { + return await upsertChannelPairingRequest({ channel: "discord", id, accountId: ctx.accountId, meta, - }), + }); + }, })({ senderId: user.id, senderIdLine: `Your Discord user id: ${user.id}`, diff --git a/extensions/discord/src/monitor/agent-components.runtime.ts b/extensions/discord/src/monitor/agent-components.runtime.ts new file mode 100644 index 00000000000..71567dc23a1 --- /dev/null +++ b/extensions/discord/src/monitor/agent-components.runtime.ts @@ -0,0 +1,6 @@ +export { + buildPluginBindingResolvedText, + parsePluginBindingApprovalCustomId, + recordInboundSession, + resolvePluginConversationBindingApproval, +} from "openclaw/plugin-sdk/conversation-runtime"; diff --git a/extensions/discord/src/monitor/agent-components.ts b/extensions/discord/src/monitor/agent-components.ts index 1411b35928a..d60a7e60dc4 100644 --- a/extensions/discord/src/monitor/agent-components.ts +++ b/extensions/discord/src/monitor/agent-components.ts @@ -86,9 +86,7 @@ import { import { buildDirectLabel, buildGuildLabel } from "./reply-context.js"; import { deliverDiscordReply } from "./reply-delivery.js"; -let conversationRuntimePromise: - | Promise - | undefined; +let conversationRuntimePromise: Promise | undefined; let componentsRuntimePromise: Promise | undefined; let pluginRuntimePromise: Promise | undefined; let replyRuntimePromise: Promise | undefined; @@ -98,7 +96,7 @@ let replyPipelineRuntimePromise: let typingRuntimePromise: Promise | undefined; async function loadConversationRuntime() { - conversationRuntimePromise ??= import("openclaw/plugin-sdk/conversation-runtime"); + conversationRuntimePromise ??= import("./agent-components.runtime.js"); return await conversationRuntimePromise; } diff --git a/extensions/discord/src/monitor/monitor.agent-components.test.ts b/extensions/discord/src/monitor/monitor.agent-components.test.ts index 69158bd6172..310de99ddf0 100644 --- a/extensions/discord/src/monitor/monitor.agent-components.test.ts +++ b/extensions/discord/src/monitor/monitor.agent-components.test.ts @@ -2,9 +2,7 @@ import type { ButtonInteraction, ComponentData, StringSelectMenuInteraction } fr import { ChannelType } from "discord-api-types/v10"; import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime"; import type { DiscordAccountConfig } from "openclaw/plugin-sdk/config-runtime"; -import * as conversationRuntime from "openclaw/plugin-sdk/conversation-runtime"; import { buildAgentSessionKey } from "openclaw/plugin-sdk/routing"; -import * as securityRuntime from "openclaw/plugin-sdk/security-runtime"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { peekSystemEvents, resetSystemEventsForTest } from "../../../../src/infra/system-events.js"; import { expectPairingReplyText } from "../../../../test/helpers/pairing-reply.js"; @@ -100,17 +98,6 @@ describe("agent components", () => { beforeEach(() => { resetDiscordComponentRuntimeMocks(); resetSystemEventsForTest(); - vi.spyOn(securityRuntime, "readStoreAllowFromForDmPolicy").mockImplementation( - async (params) => { - if (params.shouldRead === false || params.dmPolicy === "allowlist") { - return []; - } - return await readAllowFromStoreMock(params.provider, params.accountId); - }, - ); - vi.spyOn(conversationRuntime, "upsertChannelPairingRequest").mockImplementation( - upsertPairingRequestMock, - ); }); it("sends pairing reply when DM sender is not allowlisted", async () => { diff --git a/extensions/discord/src/test-support/component-runtime.ts b/extensions/discord/src/test-support/component-runtime.ts index a0b7b4c8ba5..efb0963670f 100644 --- a/extensions/discord/src/test-support/component-runtime.ts +++ b/extensions/discord/src/test-support/component-runtime.ts @@ -1,11 +1,13 @@ import { vi } from "vitest"; +import { parsePluginBindingApprovalCustomId } from "../../../../src/plugins/conversation-binding.js"; +import { resolvePinnedMainDmOwnerFromAllowlist } from "../../../../src/security/dm-policy-shared.js"; const runtimeMocks = vi.hoisted(() => ({ + buildPluginBindingResolvedTextMock: vi.fn(), readAllowFromStoreMock: vi.fn(), - upsertPairingRequestMock: vi.fn(), recordInboundSessionMock: vi.fn(), resolvePluginConversationBindingApprovalMock: vi.fn(), - buildPluginBindingResolvedTextMock: vi.fn(), + upsertPairingRequestMock: vi.fn(), })); export const readAllowFromStoreMock = runtimeMocks.readAllowFromStoreMock; @@ -15,31 +17,6 @@ export const resolvePluginConversationBindingApprovalMock = runtimeMocks.resolvePluginConversationBindingApprovalMock; export const buildPluginBindingResolvedTextMock = runtimeMocks.buildPluginBindingResolvedTextMock; -async function createConversationRuntimeMock( - importOriginal: () => Promise, -) { - const actual = await importOriginal(); - return { - ...actual, - upsertChannelPairingRequest: (...args: unknown[]) => upsertPairingRequestMock(...args), - resolvePluginConversationBindingApproval: (...args: unknown[]) => - resolvePluginConversationBindingApprovalMock(...args), - buildPluginBindingResolvedText: (...args: unknown[]) => - buildPluginBindingResolvedTextMock(...args), - recordInboundSession: (...args: unknown[]) => recordInboundSessionMock(...args), - }; -} - -async function createAllowFromRuntimeMock( - importOriginal: () => Promise, -): Promise { - const actual = await importOriginal(); - return { - ...actual, - readStoreAllowFromForDmPolicy, - }; -} - async function readStoreAllowFromForDmPolicy(params: { provider: string; accountId: string; @@ -52,22 +29,24 @@ async function readStoreAllowFromForDmPolicy(params: { return await readAllowFromStoreMock(params.provider, params.accountId); } -vi.mock("openclaw/plugin-sdk/security-runtime", (importOriginal) => - createAllowFromRuntimeMock(importOriginal), -); - -vi.mock("openclaw/plugin-sdk/conversation-runtime", createConversationRuntimeMock); -vi.mock("openclaw/plugin-sdk/conversation-runtime.js", createConversationRuntimeMock); -vi.mock("../../../../src/pairing/pairing-store.js", async (importOriginal) => { - const actual = await importOriginal(); +vi.mock("../monitor/agent-components-helpers.runtime.js", () => { return { - ...actual, + readStoreAllowFromForDmPolicy, + resolvePinnedMainDmOwnerFromAllowlist, upsertChannelPairingRequest: (...args: unknown[]) => upsertPairingRequestMock(...args), }; }); -vi.mock("../../../../src/security/dm-policy-shared.js", (importOriginal) => - createAllowFromRuntimeMock(importOriginal), -); + +vi.mock("../monitor/agent-components.runtime.js", () => { + return { + buildPluginBindingResolvedText: (...args: unknown[]) => + buildPluginBindingResolvedTextMock(...args), + parsePluginBindingApprovalCustomId, + recordInboundSession: (...args: unknown[]) => recordInboundSessionMock(...args), + resolvePluginConversationBindingApproval: (...args: unknown[]) => + resolvePluginConversationBindingApprovalMock(...args), + }; +}); export function resetDiscordComponentRuntimeMocks() { readAllowFromStoreMock.mockClear().mockResolvedValue([]);