fix(test): wait for telegram timer flushes

Revert release-time extension lane isolation for Telegram and memory, and make Telegram timer-flush tests wait for async side effects after manually firing timers.

Verification:
- pnpm test:serial extensions/telegram/src/bot.create-telegram-bot.channel-post-media.test.ts extensions/telegram/src/bot.create-telegram-bot.media-group-skip-warning.test.ts extensions/telegram/src/bot.media.stickers-and-fragments.e2e.test.ts extensions/telegram/src/bot.media.downloads-media-file-path-no-file-download.e2e.test.ts test/vitest-scoped-config.test.ts
- pnpm exec oxfmt --check on touched files
- git diff --check on touched files
This commit is contained in:
Vincent Koc
2026-06-01 08:17:33 +01:00
committed by GitHub
parent 5e09113ede
commit 0ece07cc20
7 changed files with 29 additions and 27 deletions

View File

@@ -1,3 +1,4 @@
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const harness = await import("./bot.create-telegram-bot.test-harness.js");
@@ -197,7 +198,7 @@ describe("createTelegramBot channel_post media", () => {
expect(replySpy).not.toHaveBeenCalled();
await flushChannelPostMediaGroup(setTimeoutSpy);
expect(replySpy).toHaveBeenCalledTimes(1);
await vi.waitFor(() => expect(replySpy).toHaveBeenCalledTimes(1));
const payload = replyPayload() as { Body?: string };
expect(payload.Body).toContain("album caption");
} finally {
@@ -235,7 +236,7 @@ describe("createTelegramBot channel_post media", () => {
expect(replySpy).not.toHaveBeenCalled();
await flushChannelPostMediaGroupForDelay(setTimeoutSpy, 75);
expect(replySpy).toHaveBeenCalledTimes(1);
await vi.waitFor(() => expect(replySpy).toHaveBeenCalledTimes(1));
const payload = replyPayload() as { Body?: string };
expect(payload.Body).toContain("configured album");
} finally {
@@ -282,7 +283,7 @@ describe("createTelegramBot channel_post media", () => {
TELEGRAM_TEST_TIMINGS.textFragmentGapMs,
);
expect(replySpy).toHaveBeenCalledTimes(1);
await vi.waitFor(() => expect(replySpy).toHaveBeenCalledTimes(1));
const payload = replyPayload() as { RawBody?: string };
expect(payload.RawBody).toContain(part1.slice(0, 32));
expect(payload.RawBody).toContain(part2.slice(0, 32));
@@ -569,7 +570,7 @@ describe("createTelegramBot channel_post media", () => {
expect(replySpy).not.toHaveBeenCalled();
await flushChannelPostMediaGroup(setTimeoutSpy);
expect(replySpy).toHaveBeenCalledTimes(1);
await vi.waitFor(() => expect(replySpy).toHaveBeenCalledTimes(1));
const payload = replyPayload() as { Body?: string };
expect(payload.Body).toContain("partial album");
} finally {
@@ -582,11 +583,17 @@ describe("createTelegramBot channel_post media", () => {
replySpy.mockReset();
setOpenChannelPostConfig();
const fetchSpy = createImageFetchSpy();
const runtimeError = vi.fn();
const setTimeoutSpy = vi.spyOn(globalThis, "setTimeout");
try {
const handler = getChannelPostHandler();
createTelegramBot({
token: "tok",
testTimings: TELEGRAM_TEST_TIMINGS,
runtime: { error: runtimeError } as unknown as RuntimeEnv,
});
const handler = getOnHandler("channel_post") as (
ctx: Record<string, unknown>,
) => Promise<void>;
await queueChannelPostAlbum(handler, {
caption: "fatal album",
mediaGroupId: "fatal-album-1",
@@ -597,10 +604,14 @@ describe("createTelegramBot channel_post media", () => {
expect(replySpy).not.toHaveBeenCalled();
await flushChannelPostMediaGroup(setTimeoutSpy);
await vi.waitFor(() =>
expect(runtimeError).toHaveBeenCalledWith(
expect.stringContaining("media group handler failed"),
),
);
expect(replySpy).not.toHaveBeenCalled();
} finally {
setTimeoutSpy.mockRestore();
fetchSpy.mockRestore();
}
});
});

View File

@@ -200,7 +200,7 @@ describe("createTelegramBot media-group skip warning (#55216)", () => {
expect(sendMessageSpy).not.toHaveBeenCalled();
await flushChannelPostMediaGroup(setTimeoutSpy);
expect(sendMessageSpy).toHaveBeenCalledTimes(1);
await vi.waitFor(() => expect(sendMessageSpy).toHaveBeenCalledTimes(1));
expect(sendMessageSpy).toHaveBeenCalledWith(
CHANNEL_ID,
expect.stringContaining("1 of 2 images"),
@@ -234,7 +234,7 @@ describe("createTelegramBot media-group skip warning (#55216)", () => {
});
await flushChannelPostMediaGroup(setTimeoutSpy);
expect(sendMessageSpy).toHaveBeenCalledTimes(1);
await vi.waitFor(() => expect(sendMessageSpy).toHaveBeenCalledTimes(1));
const warningText = String(sendMessageSpy.mock.calls[0]?.[1]);
expect(warningText).toContain("0 of 2 images");
expect(warningText).toContain("2 could not be fetched and were skipped");
@@ -263,7 +263,7 @@ describe("createTelegramBot media-group skip warning (#55216)", () => {
});
await flushChannelPostMediaGroup(setTimeoutSpy);
expect(sendMessageSpy).toHaveBeenCalledTimes(1);
await vi.waitFor(() => expect(sendMessageSpy).toHaveBeenCalledTimes(1));
const warningText = String(sendMessageSpy.mock.calls[0]?.[1]);
expect(warningText).toContain("1 of 3 images");
expect(warningText).toContain("2 could not be fetched and were skipped");

View File

@@ -481,7 +481,9 @@ describe("telegram media groups", () => {
delayMs: TELEGRAM_TEST_TIMINGS.mediaGroupFlushMs,
expectedCount: scenario.expectedReplyCount,
});
expect(replySpy).toHaveBeenCalledTimes(scenario.expectedReplyCount);
await vi.waitFor(() =>
expect(replySpy).toHaveBeenCalledTimes(scenario.expectedReplyCount),
);
expect(runtimeError).not.toHaveBeenCalled();
scenario.assert(replySpy);
@@ -568,7 +570,7 @@ describe("telegram media groups", () => {
clearTimeout(timer.handle);
await timer.callback();
}
expect(replySpy).toHaveBeenCalledTimes(2);
await vi.waitFor(() => expect(replySpy).toHaveBeenCalledTimes(2));
const firstPayload = replyPayload(replySpy, 0);
const secondPayload = replyPayload(replySpy, 1);
expect([firstPayload.Body, secondPayload.Body]).toEqual(

View File

@@ -272,7 +272,7 @@ describe("telegram text fragments", () => {
TELEGRAM_TEST_TIMINGS.textFragmentGapMs,
);
expect(replySpy).toHaveBeenCalledTimes(1);
await vi.waitFor(() => expect(replySpy).toHaveBeenCalledTimes(1));
const payload = replySpy.mock.calls.at(0)?.[0] as { RawBody?: string };
expect(payload.RawBody).toContain(part1.slice(0, 32));
expect(payload.RawBody).toContain(part2.slice(0, 32));
@@ -348,9 +348,9 @@ describe("telegram text fragments", () => {
TELEGRAM_TEST_TIMINGS.textFragmentGapMs,
);
await vi.waitFor(() => expect(replySpy).toHaveBeenCalledTimes(1));
expect(readAllowFromStore).toHaveBeenCalledWith("telegram", process.env, "default");
expect(upsertPairingRequest).not.toHaveBeenCalled();
expect(replySpy).toHaveBeenCalledTimes(1);
expect(runtimeError).not.toHaveBeenCalled();
} finally {
setTimeoutSpy.mockRestore();
@@ -430,7 +430,7 @@ describe("telegram text fragments", () => {
clearTimeout(timer.handle);
await timer.callback();
}
expect(replySpy).toHaveBeenCalledTimes(2);
await vi.waitFor(() => expect(replySpy).toHaveBeenCalledTimes(2));
const rawBodies = replySpy.mock.calls.map(
(call) => (call[0] as { RawBody?: string }).RawBody,
);

View File

@@ -495,14 +495,6 @@ describe("scoped vitest configs", () => {
expectThreadedNonIsolatedRunner(defaultExtensionsConfig);
});
it("isolates the Telegram extension lane so release shards do not accumulate suite state", () => {
const testConfig = requireTestConfig(defaultExtensionTelegramConfig);
expect(testConfig.pool).toBe("threads");
expect(testConfig.isolate).toBe(true);
expect(testConfig.runner).toBeUndefined();
expect(testConfig.fileParallelism).toBe(false);
});
it("serializes Slack extension files that share process globals", () => {
expect(requireTestConfig(defaultExtensionSlackConfig).fileParallelism).toBe(false);
});

View File

@@ -17,7 +17,6 @@ export function createExtensionMemoryVitestConfig(
{
dir: "extensions",
env,
isolate: true,
name: "extension-memory",
passWithNoTests: true,
setupFiles: ["test/setup.extensions.ts"],

View File

@@ -18,11 +18,9 @@ export function createExtensionTelegramVitestConfig(
dir: "extensions",
env,
fileParallelism: false,
isolate: true,
name: "extension-telegram",
passWithNoTests: true,
setupFiles: ["test/setup.extensions.ts"],
useNonIsolatedRunner: false,
},
);
}