mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-11 00:14:34 +00:00
158 lines
4.3 KiB
TypeScript
158 lines
4.3 KiB
TypeScript
import { PermissionFlagsBits } from "discord-api-types/v10";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
import type { DiscordActionConfig } from "../../config/config.js";
|
|
import { handleDiscordModerationAction } from "./discord-actions-moderation.js";
|
|
|
|
const discordSendMocks = vi.hoisted(() => ({
|
|
banMemberDiscord: vi.fn(async () => ({ ok: true })),
|
|
kickMemberDiscord: vi.fn(async () => ({ ok: true })),
|
|
timeoutMemberDiscord: vi.fn(async () => ({ id: "user-1" })),
|
|
hasAnyGuildPermissionDiscord: vi.fn(async () => false),
|
|
}));
|
|
|
|
const { banMemberDiscord, kickMemberDiscord, timeoutMemberDiscord, hasAnyGuildPermissionDiscord } =
|
|
discordSendMocks;
|
|
|
|
vi.mock("../../discord/send.js", () => ({
|
|
...discordSendMocks,
|
|
}));
|
|
|
|
const enableAllActions = (_key: keyof DiscordActionConfig, _defaultValue = true) => true;
|
|
|
|
describe("discord moderation sender authorization", () => {
|
|
it("rejects ban when sender lacks BAN_MEMBERS", async () => {
|
|
hasAnyGuildPermissionDiscord.mockResolvedValueOnce(false);
|
|
|
|
await expect(
|
|
handleDiscordModerationAction(
|
|
"ban",
|
|
{
|
|
guildId: "guild-1",
|
|
userId: "user-1",
|
|
senderUserId: "sender-1",
|
|
},
|
|
enableAllActions,
|
|
),
|
|
).rejects.toThrow("required permissions");
|
|
|
|
expect(hasAnyGuildPermissionDiscord).toHaveBeenCalledWith(
|
|
"guild-1",
|
|
"sender-1",
|
|
[PermissionFlagsBits.BanMembers],
|
|
undefined,
|
|
);
|
|
expect(banMemberDiscord).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("rejects kick when sender lacks KICK_MEMBERS", async () => {
|
|
hasAnyGuildPermissionDiscord.mockResolvedValueOnce(false);
|
|
|
|
await expect(
|
|
handleDiscordModerationAction(
|
|
"kick",
|
|
{
|
|
guildId: "guild-1",
|
|
userId: "user-1",
|
|
senderUserId: "sender-1",
|
|
},
|
|
enableAllActions,
|
|
),
|
|
).rejects.toThrow("required permissions");
|
|
|
|
expect(hasAnyGuildPermissionDiscord).toHaveBeenCalledWith(
|
|
"guild-1",
|
|
"sender-1",
|
|
[PermissionFlagsBits.KickMembers],
|
|
undefined,
|
|
);
|
|
expect(kickMemberDiscord).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("rejects timeout when sender lacks MODERATE_MEMBERS", async () => {
|
|
hasAnyGuildPermissionDiscord.mockResolvedValueOnce(false);
|
|
|
|
await expect(
|
|
handleDiscordModerationAction(
|
|
"timeout",
|
|
{
|
|
guildId: "guild-1",
|
|
userId: "user-1",
|
|
senderUserId: "sender-1",
|
|
durationMinutes: 60,
|
|
},
|
|
enableAllActions,
|
|
),
|
|
).rejects.toThrow("required permissions");
|
|
|
|
expect(hasAnyGuildPermissionDiscord).toHaveBeenCalledWith(
|
|
"guild-1",
|
|
"sender-1",
|
|
[PermissionFlagsBits.ModerateMembers],
|
|
undefined,
|
|
);
|
|
expect(timeoutMemberDiscord).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("executes moderation action when sender has required permission", async () => {
|
|
hasAnyGuildPermissionDiscord.mockResolvedValueOnce(true);
|
|
kickMemberDiscord.mockResolvedValueOnce({ ok: true });
|
|
|
|
await handleDiscordModerationAction(
|
|
"kick",
|
|
{
|
|
guildId: "guild-1",
|
|
userId: "user-1",
|
|
senderUserId: "sender-1",
|
|
reason: "rule violation",
|
|
},
|
|
enableAllActions,
|
|
);
|
|
|
|
expect(hasAnyGuildPermissionDiscord).toHaveBeenCalledWith(
|
|
"guild-1",
|
|
"sender-1",
|
|
[PermissionFlagsBits.KickMembers],
|
|
undefined,
|
|
);
|
|
expect(kickMemberDiscord).toHaveBeenCalledWith({
|
|
guildId: "guild-1",
|
|
userId: "user-1",
|
|
reason: "rule violation",
|
|
});
|
|
});
|
|
|
|
it("forwards accountId into permission check and moderation execution", async () => {
|
|
hasAnyGuildPermissionDiscord.mockResolvedValueOnce(true);
|
|
timeoutMemberDiscord.mockResolvedValueOnce({ id: "user-1" });
|
|
|
|
await handleDiscordModerationAction(
|
|
"timeout",
|
|
{
|
|
guildId: "guild-1",
|
|
userId: "user-1",
|
|
senderUserId: "sender-1",
|
|
accountId: "ops",
|
|
durationMinutes: 5,
|
|
},
|
|
enableAllActions,
|
|
);
|
|
|
|
expect(hasAnyGuildPermissionDiscord).toHaveBeenCalledWith(
|
|
"guild-1",
|
|
"sender-1",
|
|
[PermissionFlagsBits.ModerateMembers],
|
|
{ accountId: "ops" },
|
|
);
|
|
expect(timeoutMemberDiscord).toHaveBeenCalledWith(
|
|
{
|
|
guildId: "guild-1",
|
|
userId: "user-1",
|
|
durationMinutes: 5,
|
|
until: undefined,
|
|
reason: undefined,
|
|
},
|
|
{ accountId: "ops" },
|
|
);
|
|
});
|
|
});
|