mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-10 07:32:44 +00:00
test: speed up slack slash monitor tests
This commit is contained in:
@@ -252,15 +252,7 @@ describe("Slack native command argument menus", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function createPolicyHarness(overrides?: {
|
function createPolicyHarness() {
|
||||||
groupPolicy?: "open" | "allowlist";
|
|
||||||
channelsConfig?: Record<string, { allow?: boolean; requireMention?: boolean }>;
|
|
||||||
channelId?: string;
|
|
||||||
channelName?: string;
|
|
||||||
allowFrom?: string[];
|
|
||||||
useAccessGroups?: boolean;
|
|
||||||
resolveChannelName?: () => Promise<{ name?: string; type?: string }>;
|
|
||||||
}) {
|
|
||||||
const commands = new Map<unknown, (args: unknown) => Promise<void>>();
|
const commands = new Map<unknown, (args: unknown) => Promise<void>>();
|
||||||
const postEphemeral = vi.fn().mockResolvedValue({ ok: true });
|
const postEphemeral = vi.fn().mockResolvedValue({ ok: true });
|
||||||
const app = {
|
const app = {
|
||||||
@@ -270,24 +262,21 @@ function createPolicyHarness(overrides?: {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const channelId = overrides?.channelId ?? "C_UNLISTED";
|
|
||||||
const channelName = overrides?.channelName ?? "unlisted";
|
|
||||||
|
|
||||||
const ctx = {
|
const ctx = {
|
||||||
cfg: { commands: { native: false } },
|
cfg: { commands: { native: false } },
|
||||||
runtime: {},
|
runtime: {},
|
||||||
botToken: "bot-token",
|
botToken: "bot-token",
|
||||||
botUserId: "bot",
|
botUserId: "bot",
|
||||||
teamId: "T1",
|
teamId: "T1",
|
||||||
allowFrom: overrides?.allowFrom ?? ["*"],
|
allowFrom: ["*"],
|
||||||
dmEnabled: true,
|
dmEnabled: true,
|
||||||
dmPolicy: "open",
|
dmPolicy: "open",
|
||||||
groupDmEnabled: false,
|
groupDmEnabled: false,
|
||||||
groupDmChannels: [],
|
groupDmChannels: [],
|
||||||
defaultRequireMention: true,
|
defaultRequireMention: true,
|
||||||
groupPolicy: overrides?.groupPolicy ?? "open",
|
groupPolicy: "open",
|
||||||
useAccessGroups: overrides?.useAccessGroups ?? true,
|
useAccessGroups: true,
|
||||||
channelsConfig: overrides?.channelsConfig,
|
channelsConfig: undefined,
|
||||||
slashCommand: {
|
slashCommand: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
name: "openclaw",
|
name: "openclaw",
|
||||||
@@ -297,14 +286,21 @@ function createPolicyHarness(overrides?: {
|
|||||||
textLimit: 4000,
|
textLimit: 4000,
|
||||||
app,
|
app,
|
||||||
isChannelAllowed: () => true,
|
isChannelAllowed: () => true,
|
||||||
resolveChannelName:
|
resolveChannelName: async () => ({ name: "unlisted", type: "channel" }),
|
||||||
overrides?.resolveChannelName ?? (async () => ({ name: channelName, type: "channel" })),
|
|
||||||
resolveUserName: async () => ({ name: "Ada" }),
|
resolveUserName: async () => ({ name: "Ada" }),
|
||||||
} as unknown;
|
} as Record<string, unknown>;
|
||||||
|
|
||||||
const account = { accountId: "acct", config: { commands: { native: false } } } as unknown;
|
const account = { accountId: "acct", config: { commands: { native: false } } } as unknown;
|
||||||
|
|
||||||
return { commands, ctx, account, postEphemeral, channelId, channelName };
|
return { commands, ctx, account, postEphemeral };
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetPolicyHarness(harness: ReturnType<typeof createPolicyHarness>) {
|
||||||
|
harness.ctx.allowFrom = ["*"];
|
||||||
|
harness.ctx.groupPolicy = "open";
|
||||||
|
harness.ctx.useAccessGroups = true;
|
||||||
|
harness.ctx.channelsConfig = undefined;
|
||||||
|
harness.ctx.resolveChannelName = async () => ({ name: "unlisted", type: "channel" });
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runSlashHandler(params: {
|
async function runSlashHandler(params: {
|
||||||
@@ -343,20 +339,28 @@ async function runSlashHandler(params: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe("slack slash commands channel policy", () => {
|
describe("slack slash commands channel policy", () => {
|
||||||
|
let harness: ReturnType<typeof createPolicyHarness>;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
harness = createPolicyHarness();
|
||||||
|
await registerCommands(harness.ctx, harness.account);
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
harness.postEphemeral.mockClear();
|
||||||
|
resetPolicyHarness(harness);
|
||||||
|
});
|
||||||
|
|
||||||
it("allows unlisted channels when groupPolicy is open", async () => {
|
it("allows unlisted channels when groupPolicy is open", async () => {
|
||||||
const { commands, ctx, account, channelId, channelName } = createPolicyHarness({
|
harness.ctx.groupPolicy = "open";
|
||||||
groupPolicy: "open",
|
harness.ctx.channelsConfig = { C_LISTED: { requireMention: true } };
|
||||||
channelsConfig: { C_LISTED: { requireMention: true } },
|
harness.ctx.resolveChannelName = async () => ({ name: "unlisted", type: "channel" });
|
||||||
channelId: "C_UNLISTED",
|
|
||||||
channelName: "unlisted",
|
|
||||||
});
|
|
||||||
await registerCommands(ctx, account);
|
|
||||||
|
|
||||||
const { respond } = await runSlashHandler({
|
const { respond } = await runSlashHandler({
|
||||||
commands,
|
commands: harness.commands,
|
||||||
command: {
|
command: {
|
||||||
channel_id: channelId,
|
channel_id: "C_UNLISTED",
|
||||||
channel_name: channelName,
|
channel_name: "unlisted",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -367,19 +371,15 @@ describe("slack slash commands channel policy", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("blocks explicitly denied channels when groupPolicy is open", async () => {
|
it("blocks explicitly denied channels when groupPolicy is open", async () => {
|
||||||
const { commands, ctx, account, channelId, channelName } = createPolicyHarness({
|
harness.ctx.groupPolicy = "open";
|
||||||
groupPolicy: "open",
|
harness.ctx.channelsConfig = { C_DENIED: { allow: false } };
|
||||||
channelsConfig: { C_DENIED: { allow: false } },
|
harness.ctx.resolveChannelName = async () => ({ name: "denied", type: "channel" });
|
||||||
channelId: "C_DENIED",
|
|
||||||
channelName: "denied",
|
|
||||||
});
|
|
||||||
await registerCommands(ctx, account);
|
|
||||||
|
|
||||||
const { respond } = await runSlashHandler({
|
const { respond } = await runSlashHandler({
|
||||||
commands,
|
commands: harness.commands,
|
||||||
command: {
|
command: {
|
||||||
channel_id: channelId,
|
channel_id: "C_DENIED",
|
||||||
channel_name: channelName,
|
channel_name: "denied",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -391,19 +391,15 @@ describe("slack slash commands channel policy", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("blocks unlisted channels when groupPolicy is allowlist", async () => {
|
it("blocks unlisted channels when groupPolicy is allowlist", async () => {
|
||||||
const { commands, ctx, account, channelId, channelName } = createPolicyHarness({
|
harness.ctx.groupPolicy = "allowlist";
|
||||||
groupPolicy: "allowlist",
|
harness.ctx.channelsConfig = { C_LISTED: { requireMention: true } };
|
||||||
channelsConfig: { C_LISTED: { requireMention: true } },
|
harness.ctx.resolveChannelName = async () => ({ name: "unlisted", type: "channel" });
|
||||||
channelId: "C_UNLISTED",
|
|
||||||
channelName: "unlisted",
|
|
||||||
});
|
|
||||||
await registerCommands(ctx, account);
|
|
||||||
|
|
||||||
const { respond } = await runSlashHandler({
|
const { respond } = await runSlashHandler({
|
||||||
commands,
|
commands: harness.commands,
|
||||||
command: {
|
command: {
|
||||||
channel_id: channelId,
|
channel_id: "C_UNLISTED",
|
||||||
channel_name: channelName,
|
channel_name: "unlisted",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -416,41 +412,24 @@ describe("slack slash commands channel policy", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("slack slash commands access groups", () => {
|
describe("slack slash commands access groups", () => {
|
||||||
it("fails closed when channel type lookup returns empty for channels", async () => {
|
let harness: ReturnType<typeof createPolicyHarness>;
|
||||||
const { commands, ctx, account, channelId, channelName } = createPolicyHarness({
|
|
||||||
allowFrom: [],
|
|
||||||
channelId: "C_UNKNOWN",
|
|
||||||
channelName: "unknown",
|
|
||||||
resolveChannelName: async () => ({}),
|
|
||||||
});
|
|
||||||
await registerCommands(ctx, account);
|
|
||||||
|
|
||||||
const { respond } = await runSlashHandler({
|
beforeAll(async () => {
|
||||||
commands,
|
harness = createPolicyHarness();
|
||||||
command: {
|
await registerCommands(harness.ctx, harness.account);
|
||||||
channel_id: channelId,
|
});
|
||||||
channel_name: channelName,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(dispatchMock).not.toHaveBeenCalled();
|
beforeEach(() => {
|
||||||
expect(respond).toHaveBeenCalledWith({
|
harness.postEphemeral.mockClear();
|
||||||
text: "You are not authorized to use this command.",
|
resetPolicyHarness(harness);
|
||||||
response_type: "ephemeral",
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("still treats D-prefixed channel ids as DMs when lookup fails", async () => {
|
it("still treats D-prefixed channel ids as DMs when lookup fails", async () => {
|
||||||
const { commands, ctx, account } = createPolicyHarness({
|
harness.ctx.allowFrom = [];
|
||||||
allowFrom: [],
|
harness.ctx.resolveChannelName = async () => ({});
|
||||||
channelId: "D123",
|
|
||||||
channelName: "notdirectmessage",
|
|
||||||
resolveChannelName: async () => ({}),
|
|
||||||
});
|
|
||||||
await registerCommands(ctx, account);
|
|
||||||
|
|
||||||
const { respond } = await runSlashHandler({
|
const { respond } = await runSlashHandler({
|
||||||
commands,
|
commands: harness.commands,
|
||||||
command: {
|
command: {
|
||||||
channel_id: "D123",
|
channel_id: "D123",
|
||||||
channel_name: "notdirectmessage",
|
channel_name: "notdirectmessage",
|
||||||
@@ -468,16 +447,11 @@ describe("slack slash commands access groups", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("computes CommandAuthorized for DM slash commands when dmPolicy is open", async () => {
|
it("computes CommandAuthorized for DM slash commands when dmPolicy is open", async () => {
|
||||||
const { commands, ctx, account } = createPolicyHarness({
|
harness.ctx.allowFrom = ["U_OWNER"];
|
||||||
allowFrom: ["U_OWNER"],
|
harness.ctx.resolveChannelName = async () => ({ name: "directmessage", type: "im" });
|
||||||
channelId: "D999",
|
|
||||||
channelName: "directmessage",
|
|
||||||
resolveChannelName: async () => ({ name: "directmessage", type: "im" }),
|
|
||||||
});
|
|
||||||
await registerCommands(ctx, account);
|
|
||||||
|
|
||||||
await runSlashHandler({
|
await runSlashHandler({
|
||||||
commands,
|
commands: harness.commands,
|
||||||
command: {
|
command: {
|
||||||
user_id: "U_ATTACKER",
|
user_id: "U_ATTACKER",
|
||||||
user_name: "Mallory",
|
user_name: "Mallory",
|
||||||
@@ -494,19 +468,14 @@ describe("slack slash commands access groups", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("enforces access-group gating when lookup fails for private channels", async () => {
|
it("enforces access-group gating when lookup fails for private channels", async () => {
|
||||||
const { commands, ctx, account, channelId, channelName } = createPolicyHarness({
|
harness.ctx.allowFrom = [];
|
||||||
allowFrom: [],
|
harness.ctx.resolveChannelName = async () => ({});
|
||||||
channelId: "G123",
|
|
||||||
channelName: "private",
|
|
||||||
resolveChannelName: async () => ({}),
|
|
||||||
});
|
|
||||||
await registerCommands(ctx, account);
|
|
||||||
|
|
||||||
const { respond } = await runSlashHandler({
|
const { respond } = await runSlashHandler({
|
||||||
commands,
|
commands: harness.commands,
|
||||||
command: {
|
command: {
|
||||||
channel_id: channelId,
|
channel_id: "G123",
|
||||||
channel_name: channelName,
|
channel_name: "private",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user