test(telegram): cover inbound rich message text

This commit is contained in:
Ayaan Zaidi
2026-07-01 11:11:52 -07:00
parent 8c7050423e
commit 404e86f09a
3 changed files with 215 additions and 0 deletions
@@ -98,6 +98,76 @@ describe("resolveTelegramInboundBody", () => {
expect(result?.bodyText).toBe("[unsupported Telegram rich_message received]");
});
it("extracts text from rich-message-only updates", async () => {
const result = await resolveTelegramBody({
msg: {
message_id: 0,
date: 1_700_000_000,
chat: { id: 42, type: "private", first_name: "Pat" },
from: { id: 42, first_name: "Pat" },
rich_message: {
blocks: [
{
type: "paragraph",
text: [{ type: "plain", text: "Forwarded rich text" }],
},
],
},
} as never,
});
expect(result?.rawBody).toBe("Forwarded rich text");
expect(result?.bodyText).toBe("Forwarded rich text");
});
it("preserves whitespace across rich-message inline text spans", async () => {
const result = await resolveTelegramBody({
msg: {
message_id: 0,
date: 1_700_000_000,
chat: { id: 42, type: "private", first_name: "Pat" },
from: { id: 42, first_name: "Pat" },
rich_message: {
blocks: [
{
type: "paragraph",
text: [
{ type: "plain", text: "Forwarded " },
{ type: "bold", text: "rich text" },
],
},
],
},
} as never,
});
expect(result?.rawBody).toBe("Forwarded rich text");
});
it("extracts markdown and html rich-message text", async () => {
const markdownResult = await resolveTelegramBody({
msg: {
message_id: 0,
date: 1_700_000_000,
chat: { id: 42, type: "private", first_name: "Pat" },
from: { id: 42, first_name: "Pat" },
rich_message: { markdown: "Forwarded **markdown**" },
} as never,
});
const htmlResult = await resolveTelegramBody({
msg: {
message_id: 0,
date: 1_700_000_000,
chat: { id: 42, type: "private", first_name: "Pat" },
from: { id: 42, first_name: "Pat" },
rich_message: { html: "<p>Forwarded html</p>" },
} as never,
});
expect(markdownResult?.rawBody).toBe("Forwarded **markdown**");
expect(htmlResult?.rawBody).toBe("Forwarded html");
});
it("keeps rich-message placeholders quiet in requireMention groups", async () => {
const logger = { info: vi.fn() };
const result = await resolveTelegramBody({
@@ -127,6 +197,76 @@ describe("resolveTelegramInboundBody", () => {
expect(result).toBeNull();
});
it("routes rich-message-only updates that match group mention patterns", async () => {
const logger = { info: vi.fn() };
const result = await resolveTelegramBody({
cfg: {
channels: { telegram: {} },
messages: { groupChat: { mentionPatterns: ["\\btelegram\\b"] } },
} as never,
msg: {
message_id: 1,
date: 1_700_000_001,
chat: { id: -1001234567890, type: "supergroup", title: "Test Group" },
from: { id: 42, first_name: "Pat" },
rich_message: {
blocks: [
{
type: "paragraph",
text: [{ type: "plain", text: "telegram please read this" }],
},
],
},
} as never,
isGroup: true,
chatId: -1001234567890,
senderId: "42",
groupConfig: { requireMention: true } as never,
requireMention: true,
logger,
});
expect(logger.info).not.toHaveBeenCalledWith(
{ chatId: -1001234567890, reason: "no-mention" },
"skipping group message",
);
expect(result?.rawBody).toBe("telegram please read this");
expect(result?.effectiveWasMentioned).toBe(true);
});
it("routes rich-message-only updates that mention the bot username", async () => {
const logger = { info: vi.fn() };
const result = await resolveTelegramBody({
msg: {
message_id: 1,
date: 1_700_000_001,
chat: { id: -1001234567890, type: "supergroup", title: "Test Group" },
from: { id: 42, first_name: "Pat" },
rich_message: {
blocks: [
{
type: "paragraph",
text: [{ type: "plain", text: "@bot please read this" }],
},
],
},
} as never,
isGroup: true,
chatId: -1001234567890,
senderId: "42",
groupConfig: { requireMention: true } as never,
requireMention: true,
logger,
});
expect(logger.info).not.toHaveBeenCalledWith(
{ chatId: -1001234567890, reason: "no-mention" },
"skipping group message",
);
expect(result?.rawBody).toBe("@bot please read this");
expect(result?.effectiveWasMentioned).toBe(true);
});
it("renders Telegram text entities before building the agent body", async () => {
const result = await resolveTelegramBody({
msg: {
@@ -525,6 +525,31 @@ describe("describeReplyTarget", () => {
expect(result?.quoteSourceText).toBeUndefined();
});
it("describes rich-message-only reply targets with rich text", () => {
const result = describeReplyTarget({
message_id: 2,
date: 1000,
chat: { id: 1, type: "private" },
reply_to_message: {
message_id: 1,
date: 900,
chat: { id: 1, type: "private" },
rich_message: {
blocks: [
{
type: "paragraph",
text: [{ type: "plain", text: "Forwarded reply text" }],
},
],
},
from: { id: 42, first_name: "Alice", is_bot: false },
},
} as never);
expect(result?.body).toBe("Forwarded reply text");
expect(result?.quoteSourceText).toBeUndefined();
});
it("drops binary reply captions with no safe fallback", () => {
const result = describeReplyTarget({
message_id: 2,
@@ -600,6 +600,56 @@ describe("telegram message cache", () => {
});
});
it("preserves rich-message text in subsequent conversation context", async () => {
const cache = createTelegramMessageCache();
const chat = { id: 7, type: "private", first_name: "Nora" } as const;
await cache.record({
accountId: "default",
chatId: 7,
msg: {
chat,
message_id: 45,
date: 1736380745,
rich_message: {
blocks: [
{
type: "paragraph",
text: [{ type: "plain", text: "Forwarded cache text" }],
},
],
},
from: { id: 1, is_bot: false, first_name: "Nora" },
} as Message,
});
await cache.record({
accountId: "default",
chatId: 7,
msg: {
chat,
message_id: 46,
date: 1736380746,
text: "What did I just send?",
from: { id: 1, is_bot: false, first_name: "Nora" },
} as Message,
});
const context = await buildTelegramConversationContext({
cache,
accountId: "default",
chatId: 7,
messageId: "46",
replyChainNodes: [],
recentLimit: 10,
replyTargetWindowSize: 2,
});
expect(context).toHaveLength(1);
expect(context[0]?.node).toMatchObject({
messageId: "45",
body: "Forwarded cache text",
});
});
it("returns nearby messages around a stale reply target", async () => {
const cache = createTelegramMessageCache();
for (const id of [100, 101, 102, 200, 201]) {