chore: update mention gating docs and tests
This commit is contained in:
30
src/auto-reply/reply/mentions.test.ts
Normal file
30
src/auto-reply/reply/mentions.test.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
buildMentionRegexes,
|
||||
matchesMentionPatterns,
|
||||
normalizeMentionText,
|
||||
} from "./mentions.js";
|
||||
|
||||
describe("mention helpers", () => {
|
||||
it("builds regexes and skips invalid patterns", () => {
|
||||
const regexes = buildMentionRegexes({
|
||||
routing: {
|
||||
groupChat: { mentionPatterns: ["\\bclawd\\b", "(invalid"] },
|
||||
},
|
||||
});
|
||||
expect(regexes).toHaveLength(1);
|
||||
expect(regexes[0]?.test("clawd")).toBe(true);
|
||||
});
|
||||
|
||||
it("normalizes zero-width characters", () => {
|
||||
expect(normalizeMentionText("cl\u200bawd")).toBe("clawd");
|
||||
});
|
||||
|
||||
it("matches patterns case-insensitively", () => {
|
||||
const regexes = buildMentionRegexes({
|
||||
routing: { groupChat: { mentionPatterns: ["\\bclawd\\b"] } },
|
||||
});
|
||||
expect(matchesMentionPatterns("CLAWD: hi", regexes)).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -139,6 +139,36 @@ describe("monitorIMessageProvider", () => {
|
||||
expect(replyMock).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("allows group messages when requireMention is true but no mentionPatterns exist", async () => {
|
||||
config = {
|
||||
...config,
|
||||
routing: { groupChat: { mentionPatterns: [] }, allowFrom: [] },
|
||||
imessage: { groups: { "*": { requireMention: true } } },
|
||||
};
|
||||
const run = monitorIMessageProvider();
|
||||
await waitForSubscribe();
|
||||
|
||||
notificationHandler?.({
|
||||
method: "message",
|
||||
params: {
|
||||
message: {
|
||||
id: 12,
|
||||
chat_id: 777,
|
||||
sender: "+15550001111",
|
||||
is_from_me: false,
|
||||
text: "hello group",
|
||||
is_group: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await flush();
|
||||
closeResolve?.();
|
||||
await run;
|
||||
|
||||
expect(replyMock).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("prefixes tool and final replies with responsePrefix", async () => {
|
||||
config = {
|
||||
...config,
|
||||
|
||||
@@ -193,6 +193,40 @@ describe("createTelegramBot", () => {
|
||||
expect(replySpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("allows group messages when requireMention is enabled but mentions cannot be detected", async () => {
|
||||
onSpy.mockReset();
|
||||
const replySpy = replyModule.__replySpy as unknown as ReturnType<
|
||||
typeof vi.fn
|
||||
>;
|
||||
replySpy.mockReset();
|
||||
|
||||
loadConfig.mockReturnValue({
|
||||
routing: { groupChat: { mentionPatterns: [] } },
|
||||
telegram: { groups: { "*": { requireMention: true } } },
|
||||
});
|
||||
|
||||
createTelegramBot({ token: "tok" });
|
||||
const handler = onSpy.mock.calls[0][1] as (
|
||||
ctx: Record<string, unknown>,
|
||||
) => Promise<void>;
|
||||
|
||||
await handler({
|
||||
message: {
|
||||
chat: { id: 7, type: "group", title: "Test Group" },
|
||||
text: "hello everyone",
|
||||
date: 1736380800,
|
||||
message_id: 3,
|
||||
from: { id: 9, first_name: "Ada" },
|
||||
},
|
||||
me: {},
|
||||
getFile: async () => ({ download: async () => new Uint8Array() }),
|
||||
});
|
||||
|
||||
expect(replySpy).toHaveBeenCalledTimes(1);
|
||||
const payload = replySpy.mock.calls[0][0];
|
||||
expect(payload.WasMentioned).toBe(false);
|
||||
});
|
||||
|
||||
it("includes reply-to context when a Telegram reply is received", async () => {
|
||||
onSpy.mockReset();
|
||||
sendMessageSpy.mockReset();
|
||||
|
||||
Reference in New Issue
Block a user