Download src/discord/monitor/native-command.commands-allowfrom.test.ts from Darochin/openskynet: direct link, hf CLI and curl.
- Browser
- Download file 6.88 kB
-
https://huggingface.co/Darochin/openskynet/resolve/main/src/discord/monitor/native-command.commands-allowfrom.test.ts
- Command line
-
hf download hf://Darochin/openskynet/src/discord/monitor/native-command.commands-allowfrom.test.ts
-
curl -L -o native-command.commands-allowfrom.test.ts https://huggingface.co/Darochin/openskynet/resolve/main/src/discord/monitor/native-command.commands-allowfrom.test.ts
6.88 kB
| import { ChannelType } from "discord-api-types/v10"; | |
| import { beforeEach, describe, expect, it, vi } from "vitest"; | |
| import type { NativeCommandSpec } from "../../auto-reply/commands-registry.js"; | |
| import * as dispatcherModule from "../../auto-reply/reply/provider-dispatcher.js"; | |
| import type { OpenClawConfig } from "../../config/config.js"; | |
| import type { DiscordAccountConfig } from "../../config/types.discord.js"; | |
| import * as pluginCommandsModule from "../../plugins/commands.js"; | |
| import { createDiscordNativeCommand } from "./native-command.js"; | |
| import { | |
| createMockCommandInteraction, | |
| type MockCommandInteraction, | |
| } from "./native-command.test-helpers.js"; | |
| import { createNoopThreadBindingManager } from "./thread-bindings.js"; | |
| function createInteraction(params?: { userId?: string }): MockCommandInteraction { | |
| return createMockCommandInteraction({ | |
| userId: params?.userId ?? "123456789012345678", | |
| username: "discord-user", | |
| globalName: "Discord User", | |
| channelType: ChannelType.GuildText, | |
| channelId: "234567890123456789", | |
| guildId: "345678901234567890", | |
| guildName: "Test Guild", | |
| interactionId: "interaction-1", | |
| }); | |
| } | |
| function createConfig(): OpenClawConfig { | |
| return { | |
| commands: { | |
| allowFrom: { | |
| discord: ["user:123456789012345678"], | |
| }, | |
| }, | |
| channels: { | |
| discord: { | |
| groupPolicy: "allowlist", | |
| guilds: { | |
| "345678901234567890": { | |
| channels: { | |
| "234567890123456789": { | |
| allow: true, | |
| requireMention: false, | |
| }, | |
| }, | |
| }, | |
| }, | |
| }, | |
| }, | |
| } as OpenClawConfig; | |
| } | |
| function createCommand(cfg: OpenClawConfig, discordConfig?: DiscordAccountConfig) { | |
| const commandSpec: NativeCommandSpec = { | |
| name: "status", | |
| description: "Status", | |
| acceptsArgs: false, | |
| }; | |
| return createDiscordNativeCommand({ | |
| command: commandSpec, | |
| cfg, | |
| discordConfig: discordConfig ?? cfg.channels?.discord ?? {}, | |
| accountId: "default", | |
| sessionPrefix: "discord:slash", | |
| ephemeralDefault: true, | |
| threadBindings: createNoopThreadBindingManager("default"), | |
| }); | |
| } | |
| function createDispatchSpy() { | |
| return vi.spyOn(dispatcherModule, "dispatchReplyWithDispatcher").mockResolvedValue({ | |
| counts: { | |
| final: 1, | |
| block: 0, | |
| tool: 0, | |
| }, | |
| } as never); | |
| } | |
| async function runGuildSlashCommand(params?: { | |
| userId?: string; | |
| mutateConfig?: (cfg: OpenClawConfig) => void; | |
| runtimeDiscordConfig?: DiscordAccountConfig; | |
| }) { | |
| const cfg = createConfig(); | |
| params?.mutateConfig?.(cfg); | |
| const command = createCommand(cfg, params?.runtimeDiscordConfig); | |
| const interaction = createInteraction({ userId: params?.userId }); | |
| vi.spyOn(pluginCommandsModule, "matchPluginCommand").mockReturnValue(null); | |
| const dispatchSpy = createDispatchSpy(); | |
| await (command as { run: (interaction: unknown) => Promise<void> }).run(interaction as unknown); | |
| return { dispatchSpy, interaction }; | |
| } | |
| function expectNotUnauthorizedReply(interaction: MockCommandInteraction) { | |
| expect(interaction.reply).not.toHaveBeenCalledWith( | |
| expect.objectContaining({ content: "You are not authorized to use this command." }), | |
| ); | |
| } | |
| function expectUnauthorizedReply(interaction: MockCommandInteraction) { | |
| expect(interaction.reply).toHaveBeenCalledWith( | |
| expect.objectContaining({ | |
| content: "You are not authorized to use this command.", | |
| ephemeral: true, | |
| }), | |
| ); | |
| } | |
| describe("Discord native slash commands with commands.allowFrom", () => { | |
| beforeEach(() => { | |
| vi.restoreAllMocks(); | |
| }); | |
| it("authorizes guild slash commands when commands.allowFrom.discord matches the sender", async () => { | |
| const { dispatchSpy, interaction } = await runGuildSlashCommand(); | |
| expect(dispatchSpy).toHaveBeenCalledTimes(1); | |
| expectNotUnauthorizedReply(interaction); | |
| }); | |
| it("authorizes guild slash commands from the global commands.allowFrom list when provider-specific allowFrom is missing", async () => { | |
| const { dispatchSpy, interaction } = await runGuildSlashCommand({ | |
| mutateConfig: (cfg) => { | |
| cfg.commands = { | |
| allowFrom: { | |
| "*": ["user:123456789012345678"], | |
| }, | |
| }; | |
| }, | |
| }); | |
| expect(dispatchSpy).toHaveBeenCalledTimes(1); | |
| expectNotUnauthorizedReply(interaction); | |
| }); | |
| it("authorizes guild slash commands when commands.useAccessGroups is false and commands.allowFrom.discord matches the sender", async () => { | |
| const { dispatchSpy, interaction } = await runGuildSlashCommand({ | |
| mutateConfig: (cfg) => { | |
| cfg.commands = { | |
| ...cfg.commands, | |
| useAccessGroups: false, | |
| }; | |
| }, | |
| }); | |
| expect(dispatchSpy).toHaveBeenCalledTimes(1); | |
| expectNotUnauthorizedReply(interaction); | |
| }); | |
| it("rejects guild slash commands when commands.allowFrom.discord does not match the sender", async () => { | |
| const { dispatchSpy, interaction } = await runGuildSlashCommand({ | |
| userId: "999999999999999999", | |
| }); | |
| expect(dispatchSpy).not.toHaveBeenCalled(); | |
| expectUnauthorizedReply(interaction); | |
| }); | |
| it("rejects guild slash commands when commands.useAccessGroups is false and commands.allowFrom.discord does not match the sender", async () => { | |
| const { dispatchSpy, interaction } = await runGuildSlashCommand({ | |
| userId: "999999999999999999", | |
| mutateConfig: (cfg) => { | |
| cfg.commands = { | |
| ...cfg.commands, | |
| useAccessGroups: false, | |
| }; | |
| }, | |
| }); | |
| expect(dispatchSpy).not.toHaveBeenCalled(); | |
| expectUnauthorizedReply(interaction); | |
| }); | |
| it("uses the root discord maxLinesPerMessage when runtime discordConfig omits it", async () => { | |
| const longReply = Array.from({ length: 20 }, (_value, index) => `Line ${index + 1}`).join("\n"); | |
| const { interaction } = await runGuildSlashCommand({ | |
| mutateConfig: (cfg) => { | |
| cfg.channels = { | |
| ...cfg.channels, | |
| discord: { | |
| ...cfg.channels?.discord, | |
| maxLinesPerMessage: 120, | |
| }, | |
| }; | |
| }, | |
| runtimeDiscordConfig: { | |
| groupPolicy: "allowlist", | |
| guilds: { | |
| "345678901234567890": { | |
| channels: { | |
| "234567890123456789": { | |
| allow: true, | |
| requireMention: false, | |
| }, | |
| }, | |
| }, | |
| }, | |
| }, | |
| }); | |
| const dispatchCall = vi.mocked(dispatcherModule.dispatchReplyWithDispatcher).mock | |
| .calls[0]?.[0] as | |
| | Parameters<typeof dispatcherModule.dispatchReplyWithDispatcher>[0] | |
| | undefined; | |
| await dispatchCall?.dispatcherOptions.deliver({ text: longReply }, { kind: "final" }); | |
| expect(interaction.reply).toHaveBeenCalledWith(expect.objectContaining({ content: longReply })); | |
| expect(interaction.followUp).not.toHaveBeenCalled(); | |
| }); | |
| }); | |