


























@@ -114,7 +114,7 @@ function expectRecordFields(record: unknown, expected: Record<string, unknown>)
114114}
115115116116function mockCallArg(mock: ReturnType<typeof vi.fn>, callIndex: number, argIndex: number) {
117-const call = mock.mock.calls[callIndex];
117+const call = mock.mock.calls.at(callIndex);
118118if (!call) {
119119throw new Error(`Expected mock call ${callIndex}`);
120120}
@@ -229,7 +229,7 @@ describe("deliverReplies", () => {
229229230230expect(runtime.error).toHaveBeenCalledTimes(1);
231231expect(sendMessage).toHaveBeenCalledTimes(1);
232-expect(sendMessage.mock.calls[0]?.[1]).toBe("hello");
232+expect(sendMessage.mock.calls.at(0)?.[1]).toBe("hello");
233233});
234234235235it("mirrors delivered replies once after successful sends", async () => {
@@ -276,8 +276,8 @@ describe("deliverReplies", () => {
276276 bot,
277277});
278278279-expect(sendMessage.mock.calls[0]?.[0]).toBe("123");
280-expect(sendMessage.mock.calls[0]?.[1]).toBe("Plugin bind approval required");
279+expect(sendMessage.mock.calls.at(0)?.[0]).toBe("123");
280+expect(sendMessage.mock.calls.at(0)?.[1]).toBe("Plugin bind approval required");
281281expectRecordFields(mockCallArg(sendMessage, 0, 2), {
282282reply_markup: {
283283inline_keyboard: [
@@ -309,8 +309,8 @@ describe("deliverReplies", () => {
309309});
310310311311expect(runtime.error).not.toHaveBeenCalled();
312-expect(sendMessage.mock.calls[0]?.[0]).toBe("123");
313-expect(sendMessage.mock.calls[0]?.[1]).toContain("Retry");
312+expect(sendMessage.mock.calls.at(0)?.[0]).toBe("123");
313+expect(sendMessage.mock.calls.at(0)?.[1]).toContain("Retry");
314314expectRecordFields(mockCallArg(sendMessage, 0, 2), {
315315reply_markup: {
316316inline_keyboard: [[{ text: "Retry", callback_data: "cmd:retry" }]],
@@ -392,8 +392,8 @@ describe("deliverReplies", () => {
392392silent: true,
393393});
394394395-expect(sendMessage.mock.calls[0]?.[0]).toBe("123");
396-expect(typeof sendMessage.mock.calls[0]?.[1]).toBe("string");
395+expect(sendMessage.mock.calls.at(0)?.[0]).toBe("123");
396+expect(typeof sendMessage.mock.calls.at(0)?.[1]).toBe("string");
397397expectRecordFields(mockCallArg(sendMessage, 0, 2), { disable_notification: true });
398398});
399399@@ -455,9 +455,9 @@ describe("deliverReplies", () => {
455455});
456456457457expect(sendMessage).toHaveBeenCalledTimes(1);
458-expect(sendMessage.mock.calls[0]?.[1]).toBeTypeOf("string");
459-expect(sendMessage.mock.calls[0]?.[1]).not.toBe("");
460-expect(sendMessage.mock.calls[0]?.[1]?.trim()).not.toBe("NO_REPLY");
458+expect(sendMessage.mock.calls.at(0)?.[1]).toBeTypeOf("string");
459+expect(sendMessage.mock.calls.at(0)?.[1]).not.toBe("");
460+expect(sendMessage.mock.calls.at(0)?.[1]?.trim()).not.toBe("NO_REPLY");
461461});
462462463463it("uses the policy session key for exact NO_REPLY policy", async () => {
@@ -474,9 +474,9 @@ describe("deliverReplies", () => {
474474});
475475476476expect(sendMessage).toHaveBeenCalledTimes(1);
477-expect(sendMessage.mock.calls[0]?.[1]).toBeTypeOf("string");
478-expect(sendMessage.mock.calls[0]?.[1]).not.toBe("");
479-expect(sendMessage.mock.calls[0]?.[1]?.trim()).not.toBe("NO_REPLY");
477+expect(sendMessage.mock.calls.at(0)?.[1]).toBeTypeOf("string");
478+expect(sendMessage.mock.calls.at(0)?.[1]).not.toBe("");
479+expect(sendMessage.mock.calls.at(0)?.[1]?.trim()).not.toBe("NO_REPLY");
480480});
481481482482it("suppresses exact NO_REPLY for group Telegram sessions", async () => {
@@ -631,8 +631,8 @@ describe("deliverReplies", () => {
631631 bot,
632632});
633633634-expect(sendPhoto.mock.calls[0]?.[0]).toBe("123");
635-if (sendPhoto.mock.calls[0]?.[1] === undefined) {
634+expect(sendPhoto.mock.calls.at(0)?.[0]).toBe("123");
635+if (sendPhoto.mock.calls.at(0)?.[1] === undefined) {
636636throw new Error("Expected Telegram photo media");
637637}
638638expectRecordFields(mockCallArg(sendPhoto, 0, 2), {
@@ -659,8 +659,8 @@ describe("deliverReplies", () => {
659659});
660660661661expect(probeVideoDimensions).toHaveBeenCalledWith(Buffer.from("video"));
662-expect(sendVideo.mock.calls[0]?.[0]).toBe("123");
663-if (sendVideo.mock.calls[0]?.[1] === undefined) {
662+expect(sendVideo.mock.calls.at(0)?.[0]).toBe("123");
663+if (sendVideo.mock.calls.at(0)?.[1] === undefined) {
664664throw new Error("Expected Telegram video media");
665665}
666666expectRecordFields(mockCallArg(sendVideo, 0, 2), {
@@ -688,8 +688,8 @@ describe("deliverReplies", () => {
688688});
689689690690expect(probeVideoDimensions).not.toHaveBeenCalled();
691-expect(sendAnimation.mock.calls[0]?.[0]).toBe("123");
692-if (sendAnimation.mock.calls[0]?.[1] === undefined) {
691+expect(sendAnimation.mock.calls.at(0)?.[0]).toBe("123");
692+if (sendAnimation.mock.calls.at(0)?.[1] === undefined) {
693693throw new Error("Expected Telegram animation media");
694694}
695695const options = mockCallArg(sendAnimation, 0, 2) as Record<string, unknown>;
@@ -735,8 +735,8 @@ describe("deliverReplies", () => {
735735linkPreview: false,
736736});
737737738-expect(sendMessage.mock.calls[0]?.[0]).toBe("123");
739-expect(typeof sendMessage.mock.calls[0]?.[1]).toBe("string");
738+expect(sendMessage.mock.calls.at(0)?.[0]).toBe("123");
739+expect(typeof sendMessage.mock.calls.at(0)?.[1]).toBe("string");
740740expectRecordFields(mockCallArg(sendMessage, 0, 2), {
741741link_preview_options: { is_disabled: true },
742742});
@@ -752,8 +752,8 @@ describe("deliverReplies", () => {
752752thread: { id: 42, scope: "dm" },
753753});
754754755-expect(sendMessage.mock.calls[0]?.[0]).toBe("123");
756-expect(typeof sendMessage.mock.calls[0]?.[1]).toBe("string");
755+expect(sendMessage.mock.calls.at(0)?.[0]).toBe("123");
756+expect(typeof sendMessage.mock.calls.at(0)?.[1]).toBe("string");
757757expectRecordFields(mockCallArg(sendMessage, 0, 2), { message_thread_id: 42 });
758758});
759759@@ -772,7 +772,7 @@ describe("deliverReplies", () => {
772772).rejects.toThrow("message thread not found");
773773774774expect(sendMessage).toHaveBeenCalledTimes(1);
775-expectRecordFields(sendMessage.mock.calls[0]?.[2], { message_thread_id: 42 });
775+expectRecordFields(mockCallArg(sendMessage, 0, 2), { message_thread_id: 42 });
776776expect(runtime.error).toHaveBeenCalledTimes(1);
777777});
778778@@ -853,7 +853,7 @@ describe("deliverReplies", () => {
853853).rejects.toThrow("message thread not found");
854854855855expect(sendPhoto).toHaveBeenCalledTimes(1);
856-expectRecordFields(sendPhoto.mock.calls[0]?.[2], { message_thread_id: 42 });
856+expectRecordFields(mockCallArg(sendPhoto, 0, 2), { message_thread_id: 42 });
857857expect(runtime.error).toHaveBeenCalledTimes(1);
858858});
859859@@ -867,9 +867,9 @@ describe("deliverReplies", () => {
867867linkPreview: true,
868868});
869869870-expect(sendMessage.mock.calls[0]?.[0]).toBe("123");
871-expect(typeof sendMessage.mock.calls[0]?.[1]).toBe("string");
872-expect(sendMessage.mock.calls[0]?.[2]).not.toHaveProperty("link_preview_options");
870+expect(sendMessage.mock.calls.at(0)?.[0]).toBe("123");
871+expect(typeof sendMessage.mock.calls.at(0)?.[1]).toBe("string");
872+expect(mockCallArg(sendMessage, 0, 2)).not.toHaveProperty("link_preview_options");
873873});
874874875875it("falls back to plain text when markdown renders to empty HTML in threaded mode", async () => {
@@ -897,9 +897,9 @@ describe("deliverReplies", () => {
897897});
898898899899expect(sendMessage).toHaveBeenCalledTimes(1);
900-expect(sendMessage.mock.calls[0]?.[0]).toBe("123");
901-expect(sendMessage.mock.calls[0]?.[1]).toBe(">");
902-expectRecordFields(sendMessage.mock.calls[0]?.[2], { message_thread_id: 42 });
900+expect(sendMessage.mock.calls.at(0)?.[0]).toBe("123");
901+expect(sendMessage.mock.calls.at(0)?.[1]).toBe(">");
902+expectRecordFields(mockCallArg(sendMessage, 0, 2), { message_thread_id: 42 });
903903});
904904905905it("skips whitespace-only text replies without calling Telegram", async () => {
@@ -940,9 +940,9 @@ describe("deliverReplies", () => {
940940replyQuoteEntities: [{ type: "bold", offset: 0, length: 6 }],
941941});
942942943-expect(sendMessage.mock.calls[0]?.[0]).toBe("123");
944-expect(typeof sendMessage.mock.calls[0]?.[1]).toBe("string");
945-expectRecordFields(sendMessage.mock.calls[0]?.[2], {
943+expect(sendMessage.mock.calls.at(0)?.[0]).toBe("123");
944+expect(typeof sendMessage.mock.calls.at(0)?.[1]).toBe("string");
945+expectRecordFields(mockCallArg(sendMessage, 0, 2), {
946946reply_parameters: {
947947message_id: 500,
948948quote: " quoted text\n",
@@ -951,7 +951,7 @@ describe("deliverReplies", () => {
951951allow_sending_without_reply: true,
952952},
953953});
954-expect(sendMessage.mock.calls[0]?.[2]).not.toHaveProperty("reply_to_message_id");
954+expect(mockCallArg(sendMessage, 0, 2)).not.toHaveProperty("reply_to_message_id");
955955});
956956957957it("uses the native quote candidate that matches each reply target", async () => {
@@ -976,15 +976,15 @@ describe("deliverReplies", () => {
976976},
977977});
978978979-expectRecordFields(sendMessage.mock.calls[0]?.[2], {
979+expectRecordFields(mockCallArg(sendMessage, 0, 2), {
980980reply_parameters: {
981981message_id: 500,
982982quote: "first quote",
983983quote_position: 0,
984984allow_sending_without_reply: true,
985985},
986986});
987-expectRecordFields(sendMessage.mock.calls[1]?.[2], {
987+expectRecordFields(mockCallArg(sendMessage, 1, 2), {
988988reply_parameters: {
989989message_id: 501,
990990quote: "second quote",
@@ -1020,18 +1020,18 @@ describe("deliverReplies", () => {
10201020});
1021102110221022expect(sendMessage).toHaveBeenCalledTimes(2);
1023-expectRecordFields(sendMessage.mock.calls[0][2], {
1023+expectRecordFields(mockCallArg(sendMessage, 0, 2), {
10241024reply_parameters: {
10251025message_id: 500,
10261026quote: " quoted text\n",
10271027allow_sending_without_reply: true,
10281028},
10291029});
1030-expectRecordFields(sendMessage.mock.calls[1][2], {
1030+expectRecordFields(mockCallArg(sendMessage, 1, 2), {
10311031reply_to_message_id: 500,
10321032allow_sending_without_reply: true,
10331033});
1034-expect(sendMessage.mock.calls[1][2]).not.toHaveProperty("reply_parameters");
1034+expect(mockCallArg(sendMessage, 1, 2)).not.toHaveProperty("reply_parameters");
10351035}
10361036});
10371037@@ -1052,13 +1052,13 @@ describe("deliverReplies", () => {
10521052replyQuoteText: "quoted text",
10531053});
105410541055-expect(sendMessage.mock.calls[0]?.[0]).toBe("123");
1056-expect(typeof sendMessage.mock.calls[0]?.[1]).toBe("string");
1057-expectRecordFields(sendMessage.mock.calls[0]?.[2], {
1055+expect(sendMessage.mock.calls.at(0)?.[0]).toBe("123");
1056+expect(typeof sendMessage.mock.calls.at(0)?.[1]).toBe("string");
1057+expectRecordFields(mockCallArg(sendMessage, 0, 2), {
10581058reply_to_message_id: 501,
10591059allow_sending_without_reply: true,
10601060});
1061-expect(sendMessage.mock.calls[0][2]).not.toHaveProperty("reply_parameters");
1061+expect(mockCallArg(sendMessage, 0, 2)).not.toHaveProperty("reply_parameters");
10621062});
1063106310641064it("omits native quote parameters when reply mode suppresses the reply", async () => {
@@ -1078,8 +1078,8 @@ describe("deliverReplies", () => {
10781078replyQuoteText: "quoted text",
10791079});
108010801081-expect(sendMessage.mock.calls[0][2]).not.toHaveProperty("reply_parameters");
1082-expect(sendMessage.mock.calls[0][2]).not.toHaveProperty("reply_to_message_id");
1081+expect(mockCallArg(sendMessage, 0, 2)).not.toHaveProperty("reply_parameters");
1082+expect(mockCallArg(sendMessage, 0, 2)).not.toHaveProperty("reply_to_message_id");
10831083});
1084108410851085it("uses legacy reply id when quote text has no quoted message id", async () => {
@@ -1098,13 +1098,13 @@ describe("deliverReplies", () => {
10981098replyQuoteText: "quoted text",
10991099});
110011001101-expect(sendMessage.mock.calls[0]?.[0]).toBe("123");
1102-expect(typeof sendMessage.mock.calls[0]?.[1]).toBe("string");
1103-expectRecordFields(sendMessage.mock.calls[0]?.[2], {
1101+expect(sendMessage.mock.calls.at(0)?.[0]).toBe("123");
1102+expect(typeof sendMessage.mock.calls.at(0)?.[1]).toBe("string");
1103+expectRecordFields(mockCallArg(sendMessage, 0, 2), {
11041104reply_to_message_id: 501,
11051105allow_sending_without_reply: true,
11061106});
1107-expect(sendMessage.mock.calls[0][2]).not.toHaveProperty("reply_parameters");
1107+expect(mockCallArg(sendMessage, 0, 2)).not.toHaveProperty("reply_parameters");
11081108});
1109110911101110it("falls back to text when sendVoice fails with VOICE_MESSAGES_FORBIDDEN", async () => {
@@ -1130,9 +1130,9 @@ describe("deliverReplies", () => {
11301130expect(sendVoice).toHaveBeenCalledTimes(1);
11311131// Fallback to text succeeded
11321132expect(sendMessage).toHaveBeenCalledTimes(1);
1133-expect(sendMessage.mock.calls[0]?.[0]).toBe("123");
1134-expect(sendMessage.mock.calls[0]?.[1]).toContain("Hello there");
1135-if (sendMessage.mock.calls[0]?.[2] === undefined) {
1133+expect(sendMessage.mock.calls.at(0)?.[0]).toBe("123");
1134+expect(sendMessage.mock.calls.at(0)?.[1]).toContain("Hello there");
1135+if (sendMessage.mock.calls.at(0)?.[2] === undefined) {
11361136throw new Error("Expected Telegram fallback text options");
11371137}
11381138});
@@ -1158,9 +1158,9 @@ describe("deliverReplies", () => {
11581158});
1159115911601160expect(sendVoice).toHaveBeenCalledTimes(1);
1161-expect(sendMessage.mock.calls[0]?.[0]).toBe("123");
1162-expect(sendMessage.mock.calls[0]?.[1]).toContain("Hello there");
1163-expectRecordFields(sendMessage.mock.calls[0]?.[2], { disable_notification: true });
1161+expect(sendMessage.mock.calls.at(0)?.[0]).toBe("123");
1162+expect(sendMessage.mock.calls.at(0)?.[1]).toContain("Hello there");
1163+expectRecordFields(mockCallArg(sendMessage, 0, 2), { disable_notification: true });
11641164});
1165116511661166it("voice fallback applies reply-to only on first chunk when replyToMode is first", async () => {
@@ -1198,7 +1198,7 @@ describe("deliverReplies", () => {
1198119811991199expect(sendVoice).toHaveBeenCalledTimes(1);
12001200expect(sendMessage.mock.calls.length).toBeGreaterThanOrEqual(2);
1201-expectRecordFields(sendMessage.mock.calls[0][2], {
1201+expectRecordFields(mockCallArg(sendMessage, 0, 2), {
12021202reply_parameters: {
12031203message_id: 77,
12041204quote: "quoted context",
@@ -1208,9 +1208,9 @@ describe("deliverReplies", () => {
12081208inline_keyboard: [[{ text: "Ack", callback_data: "ack" }]],
12091209},
12101210});
1211-expect(sendMessage.mock.calls[1][2]).not.toHaveProperty("reply_to_message_id", 77);
1212-expect(sendMessage.mock.calls[1][2]).not.toHaveProperty("reply_parameters");
1213-expect(sendMessage.mock.calls[1][2]).not.toHaveProperty("reply_markup");
1211+expect(mockCallArg(sendMessage, 1, 2)).not.toHaveProperty("reply_to_message_id", 77);
1212+expect(mockCallArg(sendMessage, 1, 2)).not.toHaveProperty("reply_parameters");
1213+expect(mockCallArg(sendMessage, 1, 2)).not.toHaveProperty("reply_markup");
12141214});
1215121512161216it("rethrows non-VOICE_MESSAGES_FORBIDDEN errors from sendVoice", async () => {
@@ -1255,12 +1255,12 @@ describe("deliverReplies", () => {
1255125512561256expect(sendMessage.mock.calls.length).toBeGreaterThanOrEqual(2);
12571257// First chunk should have reply_to_message_id
1258-expectRecordFields(sendMessage.mock.calls[0][2], {
1258+expectRecordFields(mockCallArg(sendMessage, 0, 2), {
12591259reply_to_message_id: 700,
12601260allow_sending_without_reply: true,
12611261});
12621262// Second chunk should NOT have reply_to_message_id
1263-expect(sendMessage.mock.calls[1][2]).not.toHaveProperty("reply_to_message_id");
1263+expect(mockCallArg(sendMessage, 1, 2)).not.toHaveProperty("reply_to_message_id");
12641264});
1265126512661266it("replyToMode 'all' applies reply-to to every text chunk", async () => {
@@ -1314,12 +1314,12 @@ describe("deliverReplies", () => {
1314131413151315expect(sendPhoto).toHaveBeenCalledTimes(2);
13161316// First media should have reply_to_message_id
1317-expectRecordFields(sendPhoto.mock.calls[0][2], {
1317+expectRecordFields(mockCallArg(sendPhoto, 0, 2), {
13181318reply_to_message_id: 900,
13191319allow_sending_without_reply: true,
13201320});
13211321// Second media should NOT have reply_to_message_id
1322-expect(sendPhoto.mock.calls[1][2]).not.toHaveProperty("reply_to_message_id");
1322+expect(mockCallArg(sendPhoto, 1, 2)).not.toHaveProperty("reply_to_message_id");
13231323});
1324132413251325it("pins the first delivered text message when telegram pin is requested", async () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。