test(channels): add slack group-mention and onboarding helper coverage

This commit is contained in:
Peter Steinberger
2026-02-18 16:31:27 +00:00
parent f3b75730de
commit 4605dfd2ae
2 changed files with 124 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
import { describe, expect, it } from "vitest";
import { resolveSlackGroupRequireMention, resolveSlackGroupToolPolicy } from "./group-mentions.js";
const cfg = {
channels: {
slack: {
botToken: "xoxb-test",
appToken: "xapp-test",
channels: {
alerts: {
requireMention: false,
tools: { allow: ["message.send"] },
toolsBySender: {
"user:alice": { allow: ["sessions.list"] },
},
},
"*": {
requireMention: true,
tools: { deny: ["exec"] },
},
},
},
},
// oxlint-disable-next-line typescript/no-explicit-any
} as any;
describe("group mentions (slack)", () => {
it("uses matched channel requireMention and wildcard fallback", () => {
expect(resolveSlackGroupRequireMention({ cfg, groupChannel: "#alerts" })).toBe(false);
expect(resolveSlackGroupRequireMention({ cfg, groupChannel: "#missing" })).toBe(true);
});
it("resolves sender override, then channel tools, then wildcard tools", () => {
const senderOverride = resolveSlackGroupToolPolicy({
cfg,
groupChannel: "#alerts",
senderId: "user:alice",
});
expect(senderOverride).toEqual({ allow: ["sessions.list"] });
const channelTools = resolveSlackGroupToolPolicy({
cfg,
groupChannel: "#alerts",
senderId: "user:bob",
});
expect(channelTools).toEqual({ allow: ["message.send"] });
const wildcardTools = resolveSlackGroupToolPolicy({
cfg,
groupChannel: "#missing",
senderId: "user:bob",
});
expect(wildcardTools).toEqual({ deny: ["exec"] });
});
});

View File

@@ -0,0 +1,69 @@
import { describe, expect, it, vi } from "vitest";
import { promptResolvedAllowFrom } from "./helpers.js";
function createPrompter(inputs: string[]) {
return {
text: vi.fn(async () => inputs.shift() ?? ""),
note: vi.fn(async () => undefined),
};
}
describe("promptResolvedAllowFrom", () => {
it("re-prompts without token until all ids are parseable", async () => {
const prompter = createPrompter(["@alice", "123"]);
const resolveEntries = vi.fn();
const result = await promptResolvedAllowFrom({
// oxlint-disable-next-line typescript/no-explicit-any
prompter: prompter as any,
existing: ["111"],
token: "",
message: "msg",
placeholder: "placeholder",
label: "allowlist",
parseInputs: (value) =>
value
.split(",")
.map((part) => part.trim())
.filter(Boolean),
parseId: (value) => (/^\d+$/.test(value.trim()) ? value.trim() : null),
invalidWithoutTokenNote: "ids only",
// oxlint-disable-next-line typescript/no-explicit-any
resolveEntries: resolveEntries as any,
});
expect(result).toEqual(["111", "123"]);
expect(prompter.note).toHaveBeenCalledWith("ids only", "allowlist");
expect(resolveEntries).not.toHaveBeenCalled();
});
it("re-prompts when token resolution returns unresolved entries", async () => {
const prompter = createPrompter(["alice", "bob"]);
const resolveEntries = vi
.fn()
.mockResolvedValueOnce([{ input: "alice", resolved: false }])
.mockResolvedValueOnce([{ input: "bob", resolved: true, id: "U123" }]);
const result = await promptResolvedAllowFrom({
// oxlint-disable-next-line typescript/no-explicit-any
prompter: prompter as any,
existing: [],
token: "xoxb-test",
message: "msg",
placeholder: "placeholder",
label: "allowlist",
parseInputs: (value) =>
value
.split(",")
.map((part) => part.trim())
.filter(Boolean),
parseId: () => null,
invalidWithoutTokenNote: "ids only",
resolveEntries,
});
expect(result).toEqual(["U123"]);
expect(prompter.note).toHaveBeenCalledWith("Could not resolve: alice", "allowlist");
expect(resolveEntries).toHaveBeenCalledTimes(2);
});
});