| import { describe, expect, it } from "vitest"; |
| import { resolveChannelGroupPolicy } from "../../../src/config/group-policy.js"; |
| import { |
| resolveIrcGroupAccessGate, |
| resolveIrcGroupMatch, |
| resolveIrcGroupSenderAllowed, |
| resolveIrcMentionGate, |
| resolveIrcRequireMention, |
| } from "./policy.js"; |
|
|
| describe("irc policy", () => { |
| it("matches direct and wildcard group entries", () => { |
| const direct = resolveIrcGroupMatch({ |
| groups: { |
| "#ops": { requireMention: false }, |
| }, |
| target: "#ops", |
| }); |
| expect(direct.allowed).toBe(true); |
| expect(resolveIrcRequireMention({ groupConfig: direct.groupConfig })).toBe(false); |
|
|
| const wildcard = resolveIrcGroupMatch({ |
| groups: { |
| "*": { requireMention: true }, |
| }, |
| target: "#random", |
| }); |
| expect(wildcard.allowed).toBe(true); |
| expect(resolveIrcRequireMention({ wildcardConfig: wildcard.wildcardConfig })).toBe(true); |
| }); |
|
|
| it("enforces allowlist by default in groups", () => { |
| const message = { |
| messageId: "m1", |
| target: "#ops", |
| senderNick: "alice", |
| senderUser: "ident", |
| senderHost: "example.org", |
| text: "hi", |
| timestamp: Date.now(), |
| isGroup: true, |
| }; |
|
|
| expect( |
| resolveIrcGroupSenderAllowed({ |
| groupPolicy: "allowlist", |
| message, |
| outerAllowFrom: [], |
| innerAllowFrom: [], |
| }), |
| ).toBe(false); |
|
|
| expect( |
| resolveIrcGroupSenderAllowed({ |
| groupPolicy: "allowlist", |
| message, |
| outerAllowFrom: ["alice!ident@example.org"], |
| innerAllowFrom: [], |
| }), |
| ).toBe(true); |
| expect( |
| resolveIrcGroupSenderAllowed({ |
| groupPolicy: "allowlist", |
| message, |
| outerAllowFrom: ["alice"], |
| innerAllowFrom: [], |
| }), |
| ).toBe(false); |
| expect( |
| resolveIrcGroupSenderAllowed({ |
| groupPolicy: "allowlist", |
| message, |
| outerAllowFrom: ["alice"], |
| innerAllowFrom: [], |
| allowNameMatching: true, |
| }), |
| ).toBe(true); |
| }); |
|
|
| it('allows unconfigured channels when groupPolicy is "open"', () => { |
| const groupMatch = resolveIrcGroupMatch({ |
| groups: undefined, |
| target: "#random", |
| }); |
| const gate = resolveIrcGroupAccessGate({ |
| groupPolicy: "open", |
| groupMatch, |
| }); |
| expect(gate.allowed).toBe(true); |
| expect(gate.reason).toBe("open"); |
| }); |
|
|
| it("honors explicit group disable even in open mode", () => { |
| const groupMatch = resolveIrcGroupMatch({ |
| groups: { |
| "#ops": { enabled: false }, |
| }, |
| target: "#ops", |
| }); |
| const gate = resolveIrcGroupAccessGate({ |
| groupPolicy: "open", |
| groupMatch, |
| }); |
| expect(gate.allowed).toBe(false); |
| expect(gate.reason).toBe("disabled"); |
| }); |
|
|
| it("allows authorized control commands without mention", () => { |
| const gate = resolveIrcMentionGate({ |
| isGroup: true, |
| requireMention: true, |
| wasMentioned: false, |
| hasControlCommand: true, |
| allowTextCommands: true, |
| commandAuthorized: true, |
| }); |
| expect(gate.shouldSkip).toBe(false); |
| }); |
|
|
| it("keeps case-insensitive group matching aligned with shared channel policy resolution", () => { |
| const groups = { |
| "#Ops": { requireMention: false }, |
| "#Hidden": { enabled: false }, |
| "*": { requireMention: true }, |
| }; |
|
|
| const inboundDirect = resolveIrcGroupMatch({ groups, target: "#ops" }); |
| const sharedDirect = resolveChannelGroupPolicy({ |
| cfg: { channels: { irc: { groups } } }, |
| channel: "irc", |
| groupId: "#ops", |
| groupIdCaseInsensitive: true, |
| }); |
| expect(sharedDirect.allowed).toBe(inboundDirect.allowed); |
| expect(sharedDirect.groupConfig?.requireMention).toBe( |
| inboundDirect.groupConfig?.requireMention, |
| ); |
|
|
| const inboundDisabled = resolveIrcGroupMatch({ groups, target: "#hidden" }); |
| const sharedDisabled = resolveChannelGroupPolicy({ |
| cfg: { channels: { irc: { groups } } }, |
| channel: "irc", |
| groupId: "#hidden", |
| groupIdCaseInsensitive: true, |
| }); |
| expect(sharedDisabled.allowed).toBe(inboundDisabled.allowed); |
| expect(inboundDisabled.groupConfig?.enabled).toBe(false); |
| }); |
| }); |
|
|