Spaces:
Paused
Paused
| import { describe, expect, it } from "vitest"; | |
| import { | |
| buildSlackSlashCommandMatcher, | |
| isSlackChannelAllowedByPolicy, | |
| resolveSlackThreadTs, | |
| } from "./monitor.js"; | |
| describe("slack groupPolicy gating", () => { | |
| it("allows when policy is open", () => { | |
| expect( | |
| isSlackChannelAllowedByPolicy({ | |
| groupPolicy: "open", | |
| channelAllowlistConfigured: false, | |
| channelAllowed: false, | |
| }), | |
| ).toBe(true); | |
| }); | |
| it("blocks when policy is disabled", () => { | |
| expect( | |
| isSlackChannelAllowedByPolicy({ | |
| groupPolicy: "disabled", | |
| channelAllowlistConfigured: true, | |
| channelAllowed: true, | |
| }), | |
| ).toBe(false); | |
| }); | |
| it("blocks allowlist when no channel allowlist configured", () => { | |
| expect( | |
| isSlackChannelAllowedByPolicy({ | |
| groupPolicy: "allowlist", | |
| channelAllowlistConfigured: false, | |
| channelAllowed: true, | |
| }), | |
| ).toBe(false); | |
| }); | |
| it("allows allowlist when channel is allowed", () => { | |
| expect( | |
| isSlackChannelAllowedByPolicy({ | |
| groupPolicy: "allowlist", | |
| channelAllowlistConfigured: true, | |
| channelAllowed: true, | |
| }), | |
| ).toBe(true); | |
| }); | |
| it("blocks allowlist when channel is not allowed", () => { | |
| expect( | |
| isSlackChannelAllowedByPolicy({ | |
| groupPolicy: "allowlist", | |
| channelAllowlistConfigured: true, | |
| channelAllowed: false, | |
| }), | |
| ).toBe(false); | |
| }); | |
| }); | |
| describe("resolveSlackThreadTs", () => { | |
| const threadTs = "1234567890.123456"; | |
| const messageTs = "9999999999.999999"; | |
| describe("replyToMode=off", () => { | |
| it("returns incomingThreadTs when in a thread", () => { | |
| expect( | |
| resolveSlackThreadTs({ | |
| replyToMode: "off", | |
| incomingThreadTs: threadTs, | |
| messageTs, | |
| hasReplied: false, | |
| }), | |
| ).toBe(threadTs); | |
| }); | |
| it("returns incomingThreadTs even after replies (stays in thread)", () => { | |
| expect( | |
| resolveSlackThreadTs({ | |
| replyToMode: "off", | |
| incomingThreadTs: threadTs, | |
| messageTs, | |
| hasReplied: true, | |
| }), | |
| ).toBe(threadTs); | |
| }); | |
| it("returns undefined when not in a thread", () => { | |
| expect( | |
| resolveSlackThreadTs({ | |
| replyToMode: "off", | |
| incomingThreadTs: undefined, | |
| messageTs, | |
| hasReplied: false, | |
| }), | |
| ).toBeUndefined(); | |
| }); | |
| }); | |
| describe("replyToMode=first", () => { | |
| it("returns incomingThreadTs when in a thread (always stays threaded)", () => { | |
| expect( | |
| resolveSlackThreadTs({ | |
| replyToMode: "first", | |
| incomingThreadTs: threadTs, | |
| messageTs, | |
| hasReplied: false, | |
| }), | |
| ).toBe(threadTs); | |
| }); | |
| it("returns messageTs for first reply when not in a thread", () => { | |
| expect( | |
| resolveSlackThreadTs({ | |
| replyToMode: "first", | |
| incomingThreadTs: undefined, | |
| messageTs, | |
| hasReplied: false, | |
| }), | |
| ).toBe(messageTs); | |
| }); | |
| it("returns undefined for subsequent replies when not in a thread (goes to main channel)", () => { | |
| expect( | |
| resolveSlackThreadTs({ | |
| replyToMode: "first", | |
| incomingThreadTs: undefined, | |
| messageTs, | |
| hasReplied: true, | |
| }), | |
| ).toBeUndefined(); | |
| }); | |
| }); | |
| describe("replyToMode=all", () => { | |
| it("returns incomingThreadTs when in a thread", () => { | |
| expect( | |
| resolveSlackThreadTs({ | |
| replyToMode: "all", | |
| incomingThreadTs: threadTs, | |
| messageTs, | |
| hasReplied: false, | |
| }), | |
| ).toBe(threadTs); | |
| }); | |
| it("returns messageTs when not in a thread (starts thread)", () => { | |
| expect( | |
| resolveSlackThreadTs({ | |
| replyToMode: "all", | |
| incomingThreadTs: undefined, | |
| messageTs, | |
| hasReplied: true, | |
| }), | |
| ).toBe(messageTs); | |
| }); | |
| }); | |
| }); | |
| describe("buildSlackSlashCommandMatcher", () => { | |
| it("matches with or without a leading slash", () => { | |
| const matcher = buildSlackSlashCommandMatcher("openclaw"); | |
| expect(matcher.test("openclaw")).toBe(true); | |
| expect(matcher.test("/openclaw")).toBe(true); | |
| }); | |
| it("does not match similar names", () => { | |
| const matcher = buildSlackSlashCommandMatcher("openclaw"); | |
| expect(matcher.test("/openclaw-bot")).toBe(false); | |
| expect(matcher.test("openclaw-bot")).toBe(false); | |
| }); | |
| }); | |