












@@ -4,9 +4,11 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
4455const sendMessageTelegramMock = vi.fn();
66const pinMessageTelegramMock = vi.fn();
7+const sendPollTelegramMock = vi.fn();
7889vi.mock("./send.js", () => ({
910pinMessageTelegram: (...args: unknown[]) => pinMessageTelegramMock(...args),
11+sendPollTelegram: (...args: unknown[]) => sendPollTelegramMock(...args),
1012sendMessageTelegram: (...args: unknown[]) => sendMessageTelegramMock(...args),
1113}));
1214@@ -57,6 +59,7 @@ function callOptionsFromEnd(
5759describe("telegramOutbound", () => {
5860beforeEach(() => {
5961pinMessageTelegramMock.mockReset();
62+sendPollTelegramMock.mockReset();
6063sendMessageTelegramMock.mockReset();
6164});
6265@@ -381,6 +384,98 @@ describe("telegramOutbound", () => {
381384expect(options.textMode).toBeUndefined();
382385});
383386387+it("normalizes legacy durable group retry targets before Telegram sends", async () => {
388+sendMessageTelegramMock.mockResolvedValueOnce({
389+messageId: "tg-group-retry",
390+chatId: "-1001234567890",
391+});
392+393+await telegramOutbound.sendText!({
394+cfg: {} as never,
395+to: "group:-1001234567890",
396+text: "retry reminder",
397+deps: { sendTelegram: sendMessageTelegramMock },
398+});
399+400+lastCallOptions(sendMessageTelegramMock, "-1001234567890", "retry reminder");
401+});
402+403+it("keeps numeric durable retry targets unchanged", async () => {
404+sendMessageTelegramMock.mockResolvedValueOnce({
405+messageId: "tg-direct-retry",
406+chatId: "123456789",
407+});
408+409+await telegramOutbound.sendText!({
410+cfg: {} as never,
411+to: "123456789",
412+text: "retry direct",
413+deps: { sendTelegram: sendMessageTelegramMock },
414+});
415+416+lastCallOptions(sendMessageTelegramMock, "123456789", "retry direct");
417+});
418+419+it("normalizes legacy durable group retry targets with topic suffixes", async () => {
420+sendMessageTelegramMock.mockResolvedValueOnce({
421+messageId: "tg-topic-retry",
422+chatId: "-1001234567890",
423+});
424+425+await telegramOutbound.sendPayload!({
426+cfg: {} as never,
427+to: "group:-1001234567890:topic:77",
428+text: "",
429+payload: { text: "topic retry" },
430+deps: { sendTelegram: sendMessageTelegramMock },
431+});
432+433+lastCallOptions(sendMessageTelegramMock, "-1001234567890:topic:77", "topic retry");
434+});
435+436+it("does not make non-numeric legacy group targets look valid", async () => {
437+sendMessageTelegramMock.mockResolvedValueOnce({
438+messageId: "tg-invalid-retry",
439+chatId: "group:not-a-number",
440+});
441+442+await telegramOutbound.sendText!({
443+cfg: {} as never,
444+to: "group:not-a-number",
445+text: "bad retry target",
446+deps: { sendTelegram: sendMessageTelegramMock },
447+});
448+449+lastCallOptions(sendMessageTelegramMock, "group:not-a-number", "bad retry target");
450+});
451+452+it("normalizes legacy durable group retry topic targets before Telegram polls", async () => {
453+sendPollTelegramMock.mockResolvedValueOnce({
454+messageId: "tg-poll-retry",
455+chatId: "-1001234567890",
456+});
457+458+await telegramOutbound.sendPoll?.({
459+cfg: {} as never,
460+to: "group:-1001234567890:topic:77",
461+poll: { question: "Retry?", options: ["Yes", "No"] },
462+accountId: "ops",
463+});
464+465+expect(sendPollTelegramMock).toHaveBeenCalledWith(
466+"-1001234567890:topic:77",
467+{ question: "Retry?", options: ["Yes", "No"] },
468+{
469+cfg: {},
470+accountId: "ops",
471+messageThreadId: undefined,
472+silent: undefined,
473+isAnonymous: undefined,
474+gatewayClientScopes: undefined,
475+},
476+);
477+});
478+384479it("forwards audioAsVoice payload media to Telegram voice sends", async () => {
385480sendMessageTelegramMock.mockResolvedValueOnce({ messageId: "tg-voice", chatId: "12345" });
386481@@ -507,4 +602,42 @@ describe("telegramOutbound", () => {
507602expect(options.notify).toBe(true);
508603expect(options.verbose).toBe(false);
509604});
605+606+it("normalizes legacy durable group retry targets before Telegram pinning", async () => {
607+pinMessageTelegramMock.mockResolvedValueOnce({
608+ok: true,
609+messageId: "tg-group-retry",
610+chatId: "-1001234567890",
611+});
612+613+await telegramOutbound.pinDeliveredMessage?.({
614+cfg: {} as never,
615+target: { channel: "telegram", to: "group:-1001234567890", accountId: "ops" },
616+messageId: "tg-group-retry",
617+pin: { enabled: true, notify: false },
618+});
619+620+const options = callOptionsAt(pinMessageTelegramMock, 0, "-1001234567890", "tg-group-retry");
621+expect(options.accountId).toBe("ops");
622+expect(options.notify).toBe(false);
623+});
624+625+it("normalizes legacy durable group retry topic targets before Telegram pinning", async () => {
626+pinMessageTelegramMock.mockResolvedValueOnce({
627+ok: true,
628+messageId: "tg-topic-retry",
629+chatId: "-1001234567890",
630+});
631+632+await telegramOutbound.pinDeliveredMessage?.({
633+cfg: {} as never,
634+target: { channel: "telegram", to: "group:-1001234567890:topic:77", accountId: "ops" },
635+messageId: "tg-topic-retry",
636+pin: { enabled: true, notify: false },
637+});
638+639+const options = callOptionsAt(pinMessageTelegramMock, 0, "-1001234567890", "tg-topic-retry");
640+expect(options.accountId).toBe("ops");
641+expect(options.notify).toBe(false);
642+});
510643});
此內容由慣性聚合(RSS閱讀器)自動聚合整理,僅供閱讀參考。 原文來自 — 版權歸原作者所有。