import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { jsonResult } from "../../agents/tools/common.js"; import type { OpenClawConfig } from "../../config/config.js"; import { setActivePluginRegistry } from "../../plugins/runtime.js"; import { createChannelTestPluginBase, createTestRegistry, } from "../../test-utils/channel-plugins.js"; import { dispatchChannelMessageAction } from "./message-actions.js"; import type { ChannelPlugin } from "./types.js"; const handleAction = vi.fn(async () => jsonResult({ ok: true })); const emptyRegistry = createTestRegistry([]); const discordPlugin: ChannelPlugin = { ...createChannelTestPluginBase({ id: "discord", label: "Discord", capabilities: { chatTypes: ["direct", "group"] }, config: { listAccountIds: () => ["default"], }, }), actions: { listActions: () => ["kick"], supportsAction: ({ action }) => action === "kick", handleAction, }, }; describe("dispatchChannelMessageAction trusted sender guard", () => { beforeEach(() => { handleAction.mockClear(); setActivePluginRegistry( createTestRegistry([{ pluginId: "discord", source: "test", plugin: discordPlugin }]), ); }); afterEach(() => { setActivePluginRegistry(emptyRegistry); }); it("rejects privileged discord moderation action without trusted sender in tool context", async () => { await expect( dispatchChannelMessageAction({ channel: "discord", action: "kick", cfg: {} as OpenClawConfig, params: { guildId: "g1", userId: "u1" }, toolContext: { currentChannelProvider: "discord" }, }), ).rejects.toThrow("Trusted sender identity is required for discord:kick"); expect(handleAction).not.toHaveBeenCalled(); }); it("allows privileged discord moderation action with trusted sender in tool context", async () => { await dispatchChannelMessageAction({ channel: "discord", action: "kick", cfg: {} as OpenClawConfig, params: { guildId: "g1", userId: "u1" }, requesterSenderId: "trusted-user", toolContext: { currentChannelProvider: "discord" }, }); expect(handleAction).toHaveBeenCalledOnce(); }); it("does not require trusted sender without tool context", async () => { await dispatchChannelMessageAction({ channel: "discord", action: "kick", cfg: {} as OpenClawConfig, params: { guildId: "g1", userId: "u1" }, }); expect(handleAction).toHaveBeenCalledOnce(); }); });