






















@@ -11,6 +11,48 @@ vi.mock("./send.js", () => ({
11111212import { telegramOutbound } from "./outbound-adapter.js";
131314+type MockWithCalls = {
15+mock: { calls: unknown[][] };
16+};
17+18+function callOptionsAt(
19+mock: MockWithCalls,
20+index: number,
21+expectedTo: string,
22+expectedText: string,
23+): Record<string, unknown> {
24+const call = mock.mock.calls[index];
25+expect(call?.[0]).toBe(expectedTo);
26+expect(call?.[1]).toBe(expectedText);
27+const options = call?.[2];
28+if (
29+options === undefined ||
30+options === null ||
31+typeof options !== "object" ||
32+Array.isArray(options)
33+) {
34+throw new Error(`expected call ${index} to include options`);
35+}
36+return options as Record<string, unknown>;
37+}
38+39+function lastCallOptions(
40+mock: MockWithCalls,
41+expectedTo: string,
42+expectedText: string,
43+): Record<string, unknown> {
44+return callOptionsAt(mock, mock.mock.calls.length - 1, expectedTo, expectedText);
45+}
46+47+function callOptionsFromEnd(
48+mock: MockWithCalls,
49+offsetFromEnd: number,
50+expectedTo: string,
51+expectedText: string,
52+): Record<string, unknown> {
53+return callOptionsAt(mock, mock.mock.calls.length - offsetFromEnd, expectedTo, expectedText);
54+}
55+1456describe("telegramOutbound", () => {
1557beforeEach(() => {
1658pinMessageTelegramMock.mockReset();
@@ -32,18 +74,13 @@ describe("telegramOutbound", () => {
3274deps: { sendTelegram: sendMessageTelegramMock },
3375});
347635-expect(sendMessageTelegramMock).toHaveBeenCalledWith(
36-"12345",
37-"hello",
38-expect.objectContaining({
39-mediaUrl: "/tmp/image.png",
40-mediaLocalRoots: ["/tmp/agent-root"],
41-accountId: "ops",
42-replyToMessageId: 900,
43-messageThreadId: 12,
44-textMode: "html",
45-}),
46-);
77+const options = callOptionsAt(sendMessageTelegramMock, 0, "12345", "hello");
78+expect(options.mediaUrl).toBe("/tmp/image.png");
79+expect(options.mediaLocalRoots).toEqual(["/tmp/agent-root"]);
80+expect(options.accountId).toBe("ops");
81+expect(options.replyToMessageId).toBe(900);
82+expect(options.messageThreadId).toBe(12);
83+expect(options.textMode).toBe("html");
4784expect(result).toEqual({ channel: "telegram", messageId: "tg-media" });
4885});
4986@@ -72,30 +109,18 @@ describe("telegramOutbound", () => {
72109});
7311074111expect(sendMessageTelegramMock).toHaveBeenCalledTimes(2);
75-expect(sendMessageTelegramMock).toHaveBeenNthCalledWith(
76-1,
77-"12345",
78-"Approval required",
79-expect.objectContaining({
80-mediaUrl: "https://example.com/1.jpg",
81-mediaLocalRoots: ["/tmp/media"],
82-quoteText: "quoted",
83-buttons: [[{ text: "Allow Once", callback_data: "/approve abc allow-once" }]],
84-}),
85-);
86-expect(sendMessageTelegramMock).toHaveBeenNthCalledWith(
87-2,
88-"12345",
89-"",
90-expect.objectContaining({
91-mediaUrl: "https://example.com/2.jpg",
92-mediaLocalRoots: ["/tmp/media"],
93-quoteText: "quoted",
94-}),
95-);
96-expect(
97-(sendMessageTelegramMock.mock.calls[1]?.[2] as Record<string, unknown>)?.buttons,
98-).toBeUndefined();
112+const firstOptions = callOptionsAt(sendMessageTelegramMock, 0, "12345", "Approval required");
113+expect(firstOptions.mediaUrl).toBe("https://example.com/1.jpg");
114+expect(firstOptions.mediaLocalRoots).toEqual(["/tmp/media"]);
115+expect(firstOptions.quoteText).toBe("quoted");
116+expect(firstOptions.buttons).toEqual([
117+[{ text: "Allow Once", callback_data: "/approve abc allow-once" }],
118+]);
119+const secondOptions = callOptionsAt(sendMessageTelegramMock, 1, "12345", "");
120+expect(secondOptions.mediaUrl).toBe("https://example.com/2.jpg");
121+expect(secondOptions.mediaLocalRoots).toEqual(["/tmp/media"]);
122+expect(secondOptions.quoteText).toBe("quoted");
123+expect(secondOptions.buttons).toBeUndefined();
99124expect(result).toEqual({ channel: "telegram", messageId: "tg-2", chatId: "12345" });
100125});
101126@@ -114,13 +139,8 @@ describe("telegramOutbound", () => {
114139deps: { sendTelegram: sendMessageTelegramMock },
115140});
116141117-expect(sendMessageTelegramMock).toHaveBeenCalledWith(
118-"12345",
119-"- Retry",
120-expect.objectContaining({
121-buttons: [[{ text: "Retry", callback_data: "cmd:retry" }]],
122-}),
123-);
142+const options = callOptionsAt(sendMessageTelegramMock, 0, "12345", "- Retry");
143+expect(options.buttons).toEqual([[{ text: "Retry", callback_data: "cmd:retry" }]]);
124144expect(result).toEqual({ channel: "telegram", messageId: "tg-buttons", chatId: "12345" });
125145});
126146@@ -136,13 +156,8 @@ describe("telegramOutbound", () => {
136156deps: { sendTelegram: sendMessageTelegramMock },
137157});
138158139-expect(sendMessageTelegramMock).toHaveBeenCalledWith(
140-"12345",
141-"quiet",
142-expect.objectContaining({
143-silent: true,
144-}),
145-);
159+const options = callOptionsAt(sendMessageTelegramMock, 0, "12345", "quiet");
160+expect(options.silent).toBe(true);
146161expect(result).toEqual({ channel: "telegram", messageId: "tg-silent", chatId: "12345" });
147162});
148163@@ -161,14 +176,9 @@ describe("telegramOutbound", () => {
161176deps: { sendTelegram: sendMessageTelegramMock },
162177});
163178164-expect(sendMessageTelegramMock).toHaveBeenCalledWith(
165-"12345",
166-"voice caption",
167-expect.objectContaining({
168-mediaUrl: "file:///tmp/note.ogg",
169-asVoice: true,
170-}),
171-);
179+const options = callOptionsAt(sendMessageTelegramMock, 0, "12345", "voice caption");
180+expect(options.mediaUrl).toBe("file:///tmp/note.ogg");
181+expect(options.asVoice).toBe(true);
172182expect(result).toEqual({ channel: "telegram", messageId: "tg-voice", chatId: "12345" });
173183});
174184@@ -181,11 +191,8 @@ describe("telegramOutbound", () => {
181191text: "hello",
182192deps: { sendTelegram: sendMessageTelegramMock },
183193});
184-expect(sendMessageTelegramMock).toHaveBeenLastCalledWith(
185-"12345",
186-"hello",
187-expect.objectContaining({ textMode: "html" }),
188-);
194+const options = lastCallOptions(sendMessageTelegramMock, "12345", "hello");
195+expect(options.textMode).toBe("html");
189196};
190197const proveMedia = async () => {
191198sendMessageTelegramMock.mockResolvedValueOnce({ messageId: "tg-media", chatId: "12345" });
@@ -196,11 +203,8 @@ describe("telegramOutbound", () => {
196203mediaUrl: "https://example.com/a.png",
197204deps: { sendTelegram: sendMessageTelegramMock },
198205});
199-expect(sendMessageTelegramMock).toHaveBeenLastCalledWith(
200-"12345",
201-"caption",
202-expect.objectContaining({ mediaUrl: "https://example.com/a.png" }),
203-);
206+const options = lastCallOptions(sendMessageTelegramMock, "12345", "caption");
207+expect(options.mediaUrl).toBe("https://example.com/a.png");
204208};
205209const provePayload = async () => {
206210sendMessageTelegramMock.mockResolvedValueOnce({ messageId: "tg-payload", chatId: "12345" });
@@ -211,11 +215,7 @@ describe("telegramOutbound", () => {
211215payload: { text: "payload" },
212216deps: { sendTelegram: sendMessageTelegramMock },
213217});
214-expect(sendMessageTelegramMock).toHaveBeenLastCalledWith(
215-"12345",
216-"payload",
217-expect.any(Object),
218-);
218+lastCallOptions(sendMessageTelegramMock, "12345", "payload");
219219};
220220const proveReplyThreadSilent = async () => {
221221sendMessageTelegramMock.mockResolvedValueOnce({ messageId: "tg-thread", chatId: "12345" });
@@ -228,15 +228,10 @@ describe("telegramOutbound", () => {
228228silent: true,
229229deps: { sendTelegram: sendMessageTelegramMock },
230230});
231-expect(sendMessageTelegramMock).toHaveBeenLastCalledWith(
232-"12345",
233-"threaded",
234-expect.objectContaining({
235-replyToMessageId: 900,
236-messageThreadId: 12,
237-silent: true,
238-}),
239-);
231+const options = lastCallOptions(sendMessageTelegramMock, "12345", "threaded");
232+expect(options.replyToMessageId).toBe(900);
233+expect(options.messageThreadId).toBe(12);
234+expect(options.silent).toBe(true);
240235};
241236const proveBatch = async () => {
242237sendMessageTelegramMock
@@ -252,16 +247,10 @@ describe("telegramOutbound", () => {
252247},
253248deps: { sendTelegram: sendMessageTelegramMock },
254249});
255-expect(sendMessageTelegramMock).toHaveBeenCalledWith(
256-"12345",
257-"batch",
258-expect.objectContaining({ mediaUrl: "https://example.com/a.png" }),
259-);
260-expect(sendMessageTelegramMock).toHaveBeenCalledWith(
261-"12345",
262-"",
263-expect.objectContaining({ mediaUrl: "https://example.com/b.png" }),
264-);
250+const firstOptions = callOptionsFromEnd(sendMessageTelegramMock, 2, "12345", "batch");
251+expect(firstOptions.mediaUrl).toBe("https://example.com/a.png");
252+const secondOptions = callOptionsFromEnd(sendMessageTelegramMock, 1, "12345", "");
253+expect(secondOptions.mediaUrl).toBe("https://example.com/b.png");
265254};
266255267256await verifyDurableFinalCapabilityProofs({
@@ -292,14 +281,9 @@ describe("telegramOutbound", () => {
292281pin: { enabled: true, notify: true },
293282});
294283295-expect(pinMessageTelegramMock).toHaveBeenCalledWith(
296-"12345",
297-"tg-1",
298-expect.objectContaining({
299-accountId: "ops",
300-notify: true,
301-verbose: false,
302-}),
303-);
284+const options = callOptionsAt(pinMessageTelegramMock, 0, "12345", "tg-1");
285+expect(options.accountId).toBe("ops");
286+expect(options.notify).toBe(true);
287+expect(options.verbose).toBe(false);
304288});
305289});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。