From 67e5cca7a465720c281c1d6c0b176b69f2c3688d Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Wed, 22 Apr 2026 20:15:36 +0100 Subject: [PATCH] test: tighten Telegram polling conflict coverage (#69873) (thanks @hclsys) --- CHANGELOG.md | 1 + extensions/telegram/src/monitor.test.ts | 2 ++ extensions/telegram/src/polling-session.test.ts | 5 +++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1170d8a936f..abf1dbc362f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Docs: https://docs.openclaw.ai ### Fixes +- Telegram/polling: rebuild the polling HTTP transport after `getUpdates` 409 conflicts, so retries use a fresh TCP connection instead of looping on a Telegram-terminated keep-alive socket. (#69873) Thanks @hclsys. - Slack/files: resolve `downloadFile` bot tokens from the runtime config when callers provide `cfg` without an explicit token or prebuilt client, preserving cfg-only file downloads outside the action runtime path. (#70160) Thanks @martingarramon. - Slack/HTTP: dispatch registered Request URL webhooks through the same handler registry used by Slack monitor setup, so HTTP-mode Slack events no longer 404 after successful route registration. (#70275) Thanks @FroeMic. - CLI sessions: persist CLI session clearing through the atomic session-store merge path, so expired Claude/Codex CLI bindings are actually removed before retrying without the stale session id. (#70298) Thanks @HFConsultant. diff --git a/extensions/telegram/src/monitor.test.ts b/extensions/telegram/src/monitor.test.ts index 69eba6af4cf..7badd791fed 100644 --- a/extensions/telegram/src/monitor.test.ts +++ b/extensions/telegram/src/monitor.test.ts @@ -844,6 +844,8 @@ describe("monitorTelegramProvider (grammY)", () => { expect(resolveTelegramTransportSpy).toHaveBeenCalledTimes(2); expect(createTelegramBotCalls[0]?.telegramTransport).toBe(telegramTransport1); expect(createTelegramBotCalls[1]?.telegramTransport).toBe(telegramTransport2); + expect(telegramTransport1.close).toHaveBeenCalledTimes(1); + expect(telegramTransport2.close).toHaveBeenCalledTimes(1); }); it("falls back to configured webhookSecret when not passed explicitly", async () => { diff --git a/extensions/telegram/src/polling-session.test.ts b/extensions/telegram/src/polling-session.test.ts index f2ccb8f6957..2d2666e9642 100644 --- a/extensions/telegram/src/polling-session.test.ts +++ b/extensions/telegram/src/polling-session.test.ts @@ -946,10 +946,11 @@ describe("TelegramPollingSession", () => { await session.runUntilAbort(); expect(createTelegramTransport).toHaveBeenCalledTimes(1); + expectTelegramBotTransportSequence(transport1, transport2); // The stale transport is closed by the dirty-rebuild; the new transport // is closed when dispose() fires on session exit. - expect(transport1.close).toHaveBeenCalled(); - expect(transport2.close).toHaveBeenCalled(); + expect(transport1.close).toHaveBeenCalledTimes(1); + expect(transport2.close).toHaveBeenCalledTimes(1); }); it("closes the transport once when runUntilAbort exits normally", async () => {