




























@@ -14,11 +14,15 @@ const createTelegramBot = (opts: import("./bot.types.js").TelegramBotOptions) =>
1414telegramDeps: telegramBotDepsForTest,
1515});
161617-function createWrappedTelegramClientFetch(proxyFetch: typeof fetch) {
17+function createWrappedTelegramClientFetch(
18+proxyFetch: typeof fetch,
19+config?: import("openclaw/plugin-sdk/config-types").OpenClawConfig,
20+) {
1821const shutdown = new AbortController();
1922botCtorSpy.mockClear();
2023createTelegramBot({
2124token: "tok",
25+ ...(config ? { config } : {}),
2226fetchAbortSignal: shutdown.signal,
2327 proxyFetch,
2428});
@@ -111,6 +115,53 @@ describe("createTelegramBot fetch abort", () => {
111115vi.useRealTimers();
112116});
113117118+it("uses the longer outbound text timeout for sendMessage", async () => {
119+vi.useFakeTimers();
120+const fetchSpy = vi.fn(
121+(_input: RequestInfo | URL, init?: RequestInit) =>
122+new Promise<AbortSignal>((resolve) => {
123+const signal = init?.signal as AbortSignal;
124+signal.addEventListener("abort", () => resolve(signal), { once: true });
125+}),
126+);
127+const { clientFetch } = createWrappedTelegramClientFetch(fetchSpy as unknown as typeof fetch);
128+129+const observedSignalPromise = clientFetch("https://api.telegram.org/bot123456:ABC/sendMessage");
130+await vi.advanceTimersByTimeAsync(60_000);
131+const observedSignal = (await observedSignalPromise) as AbortSignal;
132+133+expect(observedSignal).toBeInstanceOf(AbortSignal);
134+expect(observedSignal.aborted).toBe(true);
135+vi.useRealTimers();
136+});
137+138+it("lets configured timeoutSeconds extend outbound method guards", async () => {
139+vi.useFakeTimers();
140+const fetchSpy = vi.fn(
141+(_input: RequestInfo | URL, init?: RequestInit) =>
142+new Promise<AbortSignal>((resolve) => {
143+const signal = init?.signal as AbortSignal;
144+signal.addEventListener("abort", () => resolve(signal), { once: true });
145+}),
146+);
147+const { clientFetch } = createWrappedTelegramClientFetch(
148+fetchSpy as unknown as typeof fetch,
149+{
150+channels: { telegram: { timeoutSeconds: 90 } },
151+} as never,
152+);
153+154+const observedSignalPromise = clientFetch(
155+"https://api.telegram.org/bot123456:ABC/editMessageText",
156+);
157+await vi.advanceTimersByTimeAsync(90_000);
158+const observedSignal = (await observedSignalPromise) as AbortSignal;
159+160+expect(observedSignal).toBeInstanceOf(AbortSignal);
161+expect(observedSignal.aborted).toBe(true);
162+vi.useRealTimers();
163+});
164+114165it("retries timed-out control calls once after forcing transport fallback", async () => {
115166vi.useFakeTimers();
116167const forceFallback = vi.fn(() => true);
@@ -168,6 +219,33 @@ describe("createTelegramBot fetch abort", () => {
168219},
169220);
170221222+it("retries timed-out sendChatAction once after forcing transport fallback", async () => {
223+vi.useFakeTimers();
224+const forceFallback = vi.fn(() => true);
225+const fetchSpy = vi
226+.fn()
227+.mockImplementationOnce(
228+(_input: RequestInfo | URL, init?: RequestInit) =>
229+new Promise((_resolve, reject) => {
230+const signal = init?.signal as AbortSignal;
231+signal.addEventListener("abort", () => reject(signal.reason), { once: true });
232+}),
233+)
234+.mockResolvedValueOnce({ ok: true } as Response);
235+const { clientFetch } = createWrappedTelegramClientFetchWithTransport({
236+fetch: fetchSpy as unknown as typeof fetch,
237+ forceFallback,
238+});
239+240+const resultPromise = clientFetch("https://api.telegram.org/bot123456:ABC/sendChatAction");
241+await vi.advanceTimersByTimeAsync(60_000);
242+243+await expect(resultPromise).resolves.toEqual({ ok: true });
244+expect(forceFallback).toHaveBeenCalledWith("request-timeout");
245+expect(fetchSpy).toHaveBeenCalledTimes(2);
246+vi.useRealTimers();
247+});
248+171249it("preserves the original fetch error when tagging cannot attach metadata", async () => {
172250const frozenError = Object.freeze(
173251Object.assign(new TypeError("fetch failed"), {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。