diff --git a/src/shared/string-normalization.test.ts b/src/shared/string-normalization.test.ts new file mode 100644 index 0000000000..20327f3907 --- /dev/null +++ b/src/shared/string-normalization.test.ts @@ -0,0 +1,25 @@ +import { describe, expect, it } from "vitest"; +import { + normalizeHyphenSlug, + normalizeStringEntries, + normalizeStringEntriesLower, +} from "./string-normalization.js"; + +describe("shared/string-normalization", () => { + it("normalizes mixed allow-list entries", () => { + expect(normalizeStringEntries([" a ", 42, "", " ", "z"])).toEqual(["a", "42", "z"]); + expect(normalizeStringEntries(undefined)).toEqual([]); + }); + + it("normalizes mixed allow-list entries to lowercase", () => { + expect(normalizeStringEntriesLower([" A ", "MiXeD", 7])).toEqual(["a", "mixed", "7"]); + }); + + it("normalizes slug-like labels while preserving supported symbols", () => { + expect(normalizeHyphenSlug(" Team Room ")).toBe("team-room"); + expect(normalizeHyphenSlug(" #My_Channel + Alerts ")).toBe("#my_channel-+-alerts"); + expect(normalizeHyphenSlug("..foo---bar..")).toBe("foo-bar"); + expect(normalizeHyphenSlug(undefined)).toBe(""); + expect(normalizeHyphenSlug(null)).toBe(""); + }); +}); diff --git a/src/slack/monitor/allow-list.test.ts b/src/slack/monitor/allow-list.test.ts new file mode 100644 index 0000000000..dc37f31868 --- /dev/null +++ b/src/slack/monitor/allow-list.test.ts @@ -0,0 +1,56 @@ +import { describe, expect, it } from "vitest"; +import { + normalizeAllowList, + normalizeAllowListLower, + normalizeSlackSlug, + resolveSlackAllowListMatch, + resolveSlackUserAllowed, +} from "./allow-list.js"; + +describe("slack/allow-list", () => { + it("normalizes lists and slugs", () => { + expect(normalizeAllowList([" Alice ", 7, "", " "])).toEqual(["Alice", "7"]); + expect(normalizeAllowListLower([" Alice ", 7])).toEqual(["alice", "7"]); + expect(normalizeSlackSlug(" Team Space ")).toBe("team-space"); + expect(normalizeSlackSlug(" #Ops.Room ")).toBe("#ops.room"); + }); + + it("matches wildcard, id, and prefixed name candidates", () => { + expect(resolveSlackAllowListMatch({ allowList: ["*"], id: "u1", name: "alice" })).toEqual({ + allowed: true, + matchKey: "*", + matchSource: "wildcard", + }); + + expect( + resolveSlackAllowListMatch({ + allowList: ["u1"], + id: "u1", + name: "alice", + }), + ).toEqual({ + allowed: true, + matchKey: "u1", + matchSource: "id", + }); + + expect( + resolveSlackAllowListMatch({ + allowList: ["slack:alice"], + id: "u2", + name: "alice", + }), + ).toEqual({ + allowed: true, + matchKey: "slack:alice", + matchSource: "prefixed-name", + }); + }); + + it("allows all users when allowList is empty and denies unknown entries", () => { + expect(resolveSlackUserAllowed({ allowList: [], userId: "u1", userName: "alice" })).toBe(true); + expect(resolveSlackUserAllowed({ allowList: ["u2"], userId: "u1", userName: "alice" })).toBe( + false, + ); + }); +});