






















@@ -12,10 +12,92 @@ const resolvePluginConversationBindingApprovalMock = vi.hoisted(() => vi.fn());
1212const buildPluginBindingResolvedTextMock = vi.hoisted(() => vi.fn(() => "Binding updated."));
13131414let registerSlackInteractionEvents: typeof import("./interactions.js").registerSlackInteractionEvents;
15-let enqueueSystemEventSpy: ReturnType<typeof vi.spyOn>;
16-let dispatchPluginInteractiveHandlerSpy: ReturnType<typeof vi.spyOn>;
17-let resolvePluginConversationBindingApprovalSpy: ReturnType<typeof vi.spyOn>;
18-let buildPluginBindingResolvedTextSpy: ReturnType<typeof vi.spyOn>;
15+16+vi.mock("openclaw/plugin-sdk/infra-runtime", () => ({
17+enqueueSystemEvent: (...args: unknown[]) => enqueueSystemEventMock(...args),
18+}));
19+20+vi.mock("../../interactive-dispatch.js", () => ({
21+dispatchSlackPluginInteractiveHandler: (params: {
22+data: string;
23+interactionId: string;
24+ctx: {
25+interaction?: Record<string, unknown>;
26+} & Record<string, unknown>;
27+respond: unknown;
28+}) =>
29+(dispatchPluginInteractiveHandlerMock as (arg: unknown) => Promise<unknown>)({
30+channel: "slack",
31+data: params.data,
32+dedupeId: params.interactionId,
33+invoke: async ({
34+ registration,
35+ namespace,
36+ payload,
37+}: {
38+registration: { handler: (ctx: unknown) => unknown };
39+namespace: string;
40+payload: string;
41+}) =>
42+registration.handler({
43+ ...params.ctx,
44+channel: "slack",
45+interaction: {
46+ ...params.ctx.interaction,
47+data: params.data,
48+ namespace,
49+ payload,
50+},
51+respond: params.respond,
52+requestConversationBinding: vi.fn(),
53+detachConversationBinding: vi.fn(),
54+getCurrentConversationBinding: vi.fn(),
55+}),
56+}),
57+}));
58+59+vi.mock("../conversation.runtime.js", () => {
60+const parsePluginBindingApprovalCustomId = (value: string) => {
61+const prefix = "pluginbind:";
62+const trimmed = value.trim();
63+if (!trimmed.startsWith(prefix)) {
64+return null;
65+}
66+const body = trimmed.slice(prefix.length);
67+const separator = body.lastIndexOf(":");
68+if (separator <= 0 || separator === body.length - 1) {
69+return null;
70+}
71+const decisionCode = body.slice(separator + 1).trim();
72+const decision =
73+decisionCode === "o"
74+ ? "allow-once"
75+ : decisionCode === "a"
76+ ? "allow-always"
77+ : decisionCode === "d"
78+ ? "deny"
79+ : null;
80+if (!decision) {
81+return null;
82+}
83+return {
84+approvalId: decodeURIComponent(body.slice(0, separator).trim()),
85+ decision,
86+};
87+};
88+89+return {
90+buildPluginBindingResolvedText: (...args: unknown[]) =>
91+(buildPluginBindingResolvedTextMock as (...innerArgs: unknown[]) => string)(...args),
92+ parsePluginBindingApprovalCustomId,
93+resolvePluginConversationBindingApproval: (...args: unknown[]) =>
94+(
95+resolvePluginConversationBindingApprovalMock as (
96+ ...innerArgs: unknown[]
97+) => Promise<unknown>
98+)(...args),
99+};
100+});
1910120102type RegisteredHandler = (args: {
21103ack: () => Promise<void>;
@@ -167,49 +249,10 @@ function createContext(overrides?: {
167249168250describe("registerSlackInteractionEvents", () => {
169251beforeAll(async () => {
170-const channelRuntime = await import("openclaw/plugin-sdk/infra-runtime");
171-const pluginRuntime = await import("openclaw/plugin-sdk/plugin-runtime");
172-const conversationBinding = await import("../../../../../src/plugins/conversation-binding.js");
173-enqueueSystemEventSpy = vi
174-.spyOn(channelRuntime, "enqueueSystemEvent")
175-.mockImplementation(((...args: Parameters<typeof channelRuntime.enqueueSystemEvent>) =>
176-(enqueueSystemEventMock as (...innerArgs: unknown[]) => boolean)(
177- ...args,
178-)) as typeof channelRuntime.enqueueSystemEvent);
179-dispatchPluginInteractiveHandlerSpy = vi
180-.spyOn(pluginRuntime, "dispatchPluginInteractiveHandler")
181-.mockImplementation(((
182- ...args: Parameters<typeof pluginRuntime.dispatchPluginInteractiveHandler>
183-) =>
184-(dispatchPluginInteractiveHandlerMock as (...innerArgs: unknown[]) => Promise<unknown>)(
185- ...args,
186-)) as typeof pluginRuntime.dispatchPluginInteractiveHandler);
187-resolvePluginConversationBindingApprovalSpy = vi
188-.spyOn(conversationBinding, "resolvePluginConversationBindingApproval")
189-.mockImplementation(((
190- ...args: Parameters<typeof conversationBinding.resolvePluginConversationBindingApproval>
191-) =>
192-(
193-resolvePluginConversationBindingApprovalMock as (
194- ...innerArgs: unknown[]
195-) => Promise<unknown>
196-)(...args)) as typeof conversationBinding.resolvePluginConversationBindingApproval);
197-buildPluginBindingResolvedTextSpy = vi
198-.spyOn(conversationBinding, "buildPluginBindingResolvedText")
199-.mockImplementation(((
200- ...args: Parameters<typeof conversationBinding.buildPluginBindingResolvedText>
201-) =>
202-(buildPluginBindingResolvedTextMock as (...innerArgs: unknown[]) => string)(
203- ...args,
204-)) as typeof conversationBinding.buildPluginBindingResolvedText);
205252({ registerSlackInteractionEvents } = await import("./interactions.js"));
206253});
207254208255beforeEach(() => {
209-enqueueSystemEventSpy.mockClear();
210-dispatchPluginInteractiveHandlerSpy.mockClear();
211-resolvePluginConversationBindingApprovalSpy.mockClear();
212-buildPluginBindingResolvedTextSpy.mockClear();
213256enqueueSystemEventMock.mockClear();
214257dispatchPluginInteractiveHandlerMock.mockClear();
215258resolvePluginConversationBindingApprovalMock.mockClear();
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。