
























@@ -37,6 +37,52 @@ type TelegramApiMiddleware = (
3737payload: unknown,
3838) => Promise<unknown>;
3939type AsyncVoidFn = () => Promise<void>;
40+type MockCallSource = { mock: { calls: Array<Array<unknown>> } };
41+42+function mockObjectArg(
43+source: MockCallSource,
44+label: string,
45+callIndex = 0,
46+argIndex = 0,
47+): Record<string, unknown> {
48+const call = source.mock.calls[callIndex];
49+if (!call) {
50+throw new Error(`Expected ${label} call ${callIndex} to exist`);
51+}
52+const value = call[argIndex];
53+if (!value || typeof value !== "object") {
54+throw new Error(`Expected ${label} call ${callIndex} argument ${argIndex} to be an object`);
55+}
56+return value as Record<string, unknown>;
57+}
58+59+function logContains(source: MockCallSource, text: string): boolean {
60+return source.mock.calls.some((call) => String(call[0]).includes(text));
61+}
62+63+function expectLogIncludes(source: MockCallSource, text: string): void {
64+expect(logContains(source, text), `Expected log to include ${text}`).toBe(true);
65+}
66+67+function expectLogExcludes(source: MockCallSource, text: string): void {
68+expect(logContains(source, text), `Expected log not to include ${text}`).toBe(false);
69+}
70+71+function statusPatches(source: MockCallSource): Record<string, unknown>[] {
72+return source.mock.calls.map((call, index) => {
73+const patch = call[0];
74+if (!patch || typeof patch !== "object") {
75+throw new Error(`Expected status patch call ${index} to be an object`);
76+}
77+return patch as Record<string, unknown>;
78+});
79+}
80+81+function expectPollingConnectedPatch(patch: Record<string, unknown> | undefined): void {
82+expect(patch).toBeDefined();
83+expect(patch?.connected).toBe(true);
84+expect(patch?.mode).toBe("polling");
85+}
40864187function makeBot() {
4288return {
@@ -276,9 +322,9 @@ describe("TelegramPollingSession", () => {
276322await session.runUntilAbort();
277323278324expect(runMock).toHaveBeenCalledTimes(2);
279-expect(createTelegramBotMock).toHaveBeenCalledWith(
280-expect.objectContaining({ minimumClientTimeoutSeconds: 45 }),
281-);
325+expect(
326+mockObjectArg(createTelegramBotMock, "createTelegramBot").minimumClientTimeoutSeconds,
327+).toBe(45);
282328expect(computeBackoffMock).toHaveBeenCalledTimes(1);
283329expect(sleepWithAbortMock).toHaveBeenCalledTimes(1);
284330});
@@ -383,8 +429,8 @@ describe("TelegramPollingSession", () => {
383429expect(runMock).toHaveBeenCalledTimes(2);
384430expect(firstRunnerStop).toHaveBeenCalledTimes(1);
385431expect(botStop).toHaveBeenCalled();
386-expect(log).toHaveBeenCalledWith(expect.stringContaining("Polling stall detected"));
387-expect(log).toHaveBeenCalledWith(expect.stringContaining("polling stall detected"));
432+expectLogIncludes(log, "Polling stall detected");
433+expectLogIncludes(log, "polling stall detected");
388434} finally {
389435watchdogHarness.restore();
390436}
@@ -438,7 +484,7 @@ describe("TelegramPollingSession", () => {
438484439485expect(runMock).toHaveBeenCalledTimes(2);
440486expect(firstRunnerStop).toHaveBeenCalledTimes(1);
441-expect(log).toHaveBeenCalledWith(expect.stringContaining("Polling stall detected"));
487+expectLogIncludes(log, "Polling stall detected");
442488} finally {
443489watchdogHarness.restore();
444490}
@@ -466,7 +512,7 @@ describe("TelegramPollingSession", () => {
466512467513expect(runnerStop).not.toHaveBeenCalled();
468514expect(botStop).not.toHaveBeenCalled();
469-expect(log).not.toHaveBeenCalledWith(expect.stringContaining("Polling stall detected"));
515+expectLogExcludes(log, "Polling stall detected");
470516471517abort.abort();
472518resolveFirstTask();
@@ -629,7 +675,7 @@ describe("TelegramPollingSession", () => {
629675630676expect(runnerStop).not.toHaveBeenCalled();
631677expect(botStop).not.toHaveBeenCalled();
632-expect(log).not.toHaveBeenCalledWith(expect.stringContaining("Polling stall detected"));
678+expectLogExcludes(log, "Polling stall detected");
633679634680abort.abort();
635681resolveFirstTask();
@@ -665,17 +711,12 @@ describe("TelegramPollingSession", () => {
665711lastEventAt: null,
666712lastTransportActivityAt: null,
667713});
668-const connectedPatch = setStatus.mock.calls.find(
669-([patch]) => (patch as Record<string, unknown>).connected === true,
670-)?.[0] as Record<string, unknown> | undefined;
671-expect(connectedPatch).toMatchObject({
672-connected: true,
673-mode: "polling",
674-lastConnectedAt: expect.any(Number),
675-lastEventAt: expect.any(Number),
676-lastTransportActivityAt: expect.any(Number),
677-lastError: null,
678-});
714+const connectedPatch = statusPatches(setStatus).find((patch) => patch.connected === true);
715+expectPollingConnectedPatch(connectedPatch);
716+expect(connectedPatch?.lastConnectedAt).toBeTypeOf("number");
717+expect(connectedPatch?.lastEventAt).toBeTypeOf("number");
718+expect(connectedPatch?.lastTransportActivityAt).toBeTypeOf("number");
719+expect(connectedPatch?.lastError).toBeNull();
679720expect(connectedPatch?.lastConnectedAt).toBe(connectedPatch?.lastEventAt);
680721expect(connectedPatch?.lastTransportActivityAt).toBe(connectedPatch?.lastEventAt);
681722@@ -746,20 +787,16 @@ describe("TelegramPollingSession", () => {
746787await session.runUntilAbort();
747788748789expect(runMock).toHaveBeenCalledTimes(2);
749-expect(setStatus).toHaveBeenCalledWith(
750-expect.objectContaining({ connected: true, mode: "polling" }),
751-);
752-const disconnectedPatches = setStatus.mock.calls.filter(
753-([patch]) => (patch as Record<string, unknown>).connected === false,
790+expectPollingConnectedPatch(statusPatches(setStatus).find((patch) => patch.connected === true));
791+const disconnectedPatches = statusPatches(setStatus).filter(
792+(patch) => patch.connected === false,
754793);
755794expect(disconnectedPatches).toHaveLength(2);
756-expect(disconnectedPatches[0]?.[0]).toMatchObject({
757-mode: "polling",
758-lastConnectedAt: null,
759-lastEventAt: null,
760-lastTransportActivityAt: null,
761-});
762-expect(disconnectedPatches[1]?.[0]).toEqual({
795+expect(disconnectedPatches[0]?.mode).toBe("polling");
796+expect(disconnectedPatches[0]?.lastConnectedAt).toBeNull();
797+expect(disconnectedPatches[0]?.lastEventAt).toBeNull();
798+expect(disconnectedPatches[0]?.lastTransportActivityAt).toBeNull();
799+expect(disconnectedPatches[1]).toEqual({
763800mode: "polling",
764801connected: false,
765802});
@@ -802,7 +839,7 @@ describe("TelegramPollingSession", () => {
802839// The watchdog should NOT have triggered a restart
803840expect(runnerStop).not.toHaveBeenCalled();
804841expect(botStop).not.toHaveBeenCalled();
805-expect(log).not.toHaveBeenCalledWith(expect.stringContaining("Polling stall detected"));
842+expectLogExcludes(log, "Polling stall detected");
806843807844// Clean up: abort to end the session
808845abort.abort();
@@ -854,7 +891,7 @@ describe("TelegramPollingSession", () => {
854891// The watchdog should NOT have triggered a restart
855892expect(runnerStop).not.toHaveBeenCalled();
856893expect(botStop).not.toHaveBeenCalled();
857-expect(log).not.toHaveBeenCalledWith(expect.stringContaining("Polling stall detected"));
894+expectLogExcludes(log, "Polling stall detected");
858895859896// Resolve the in-flight call to clean up
860897resolveSendMessage?.({ ok: true });
@@ -906,7 +943,7 @@ describe("TelegramPollingSession", () => {
906943907944expect(runnerStop).toHaveBeenCalledTimes(1);
908945expect(botStop).toHaveBeenCalledTimes(1);
909-expect(log).toHaveBeenCalledWith(expect.stringContaining("Polling stall detected"));
946+expectLogIncludes(log, "Polling stall detected");
910947911948resolveSendMessage?.({ ok: true });
912949await sendPromise;
@@ -971,7 +1008,7 @@ describe("TelegramPollingSession", () => {
97110089721009expect(runnerStop).not.toHaveBeenCalled();
9731010expect(botStop).not.toHaveBeenCalled();
974-expect(log).not.toHaveBeenCalledWith(expect.stringContaining("Polling stall detected"));
1011+expectLogExcludes(log, "Polling stall detected");
97510129761013resolveFirstSend?.({ ok: true });
9771014resolveSecondSend?.({ ok: true });
@@ -1047,9 +1084,7 @@ describe("TelegramPollingSession", () => {
1047108410481085await session.runUntilAbort();
104910861050-expect(log).toHaveBeenCalledWith(
1051-expect.stringContaining("Another OpenClaw gateway, script, or Telegram poller"),
1052-);
1087+expectLogIncludes(log, "Another OpenClaw gateway, script, or Telegram poller");
10531088});
1054108910551090it("closes the transport once when runUntilAbort exits normally", async () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。