test: speed zalo polling waits

This commit is contained in:
Peter Steinberger
2026-04-24 16:07:53 +01:00
parent 50667db297
commit 4f4288e3b5
3 changed files with 47 additions and 12 deletions

View File

@@ -1,10 +1,11 @@
import { afterAll, beforeEach, describe, expect, it, vi } from "vitest";
import { afterAll, beforeEach, describe, expect, it } from "vitest";
import { createRuntimeEnv } from "../../../test/helpers/plugins/runtime-env.js";
import {
createImageLifecycleCore,
createImageUpdate,
createLifecycleMonitorSetup,
expectImageLifecycleDelivery,
settleAsyncWork,
} from "../test-support/lifecycle-test-support.js";
import {
getUpdatesMock,
@@ -55,7 +56,8 @@ describe("Zalo polling image handling", () => {
abortSignal: abort.signal,
});
await vi.waitFor(() => expect(fetchRemoteMediaMock).toHaveBeenCalledTimes(1));
await settleAsyncWork();
expect(fetchRemoteMediaMock).toHaveBeenCalledTimes(1);
expectImageLifecycleDelivery({
fetchRemoteMediaMock,
saveMediaBufferMock,
@@ -95,7 +97,8 @@ describe("Zalo polling image handling", () => {
abortSignal: abort.signal,
});
await vi.waitFor(() => expect(sendMessageMock).toHaveBeenCalledTimes(1));
await settleAsyncWork();
expect(sendMessageMock).toHaveBeenCalledTimes(1);
expect(fetchRemoteMediaMock).not.toHaveBeenCalled();
expect(saveMediaBufferMock).not.toHaveBeenCalled();
expect(finalizeInboundContextMock).not.toHaveBeenCalled();

View File

@@ -36,6 +36,13 @@ const TEST_ACCOUNT = {
const TEST_CONFIG = {} as OpenClawConfig;
async function settleLifecycleWork(): Promise<void> {
for (let i = 0; i < 6; i += 1) {
await Promise.resolve();
await new Promise((resolve) => setImmediate(resolve));
}
}
async function startLifecycleMonitor(
options: {
useWebhook?: boolean;
@@ -70,7 +77,8 @@ describe("monitorZaloProvider lifecycle", () => {
settled = true;
});
await vi.waitFor(() => expect(getUpdatesMock).toHaveBeenCalledTimes(1));
await settleLifecycleWork();
expect(getUpdatesMock).toHaveBeenCalledTimes(1);
expect(getWebhookInfoMock).toHaveBeenCalledTimes(1);
expect(deleteWebhookMock).not.toHaveBeenCalled();
@@ -94,7 +102,8 @@ describe("monitorZaloProvider lifecycle", () => {
const { abort, runtime, run } = await startLifecycleMonitor();
await vi.waitFor(() => expect(getUpdatesMock).toHaveBeenCalledTimes(1));
await settleLifecycleWork();
expect(getUpdatesMock).toHaveBeenCalledTimes(1);
expect(getWebhookInfoMock).toHaveBeenCalledTimes(1);
expect(deleteWebhookMock).toHaveBeenCalledTimes(1);
@@ -112,7 +121,8 @@ describe("monitorZaloProvider lifecycle", () => {
const { abort, runtime, run } = await startLifecycleMonitor();
await vi.waitFor(() => expect(getUpdatesMock).toHaveBeenCalledTimes(1));
await settleLifecycleWork();
expect(getUpdatesMock).toHaveBeenCalledTimes(1);
expect(getWebhookInfoMock).toHaveBeenCalledTimes(1);
expect(deleteWebhookMock).not.toHaveBeenCalled();
@@ -129,10 +139,24 @@ describe("monitorZaloProvider lifecycle", () => {
const registry = createEmptyPluginRegistry();
setActivePluginRegistry(registry);
let resolveSetWebhookCalled: (() => void) | undefined;
const setWebhookCalled = new Promise<void>((resolve) => {
resolveSetWebhookCalled = resolve;
});
setWebhookMock.mockImplementationOnce(async () => {
resolveSetWebhookCalled?.();
return { ok: true, result: { url: "" } };
});
let resolveDeleteWebhookCalled: (() => void) | undefined;
const deleteWebhookCalled = new Promise<void>((resolve) => {
resolveDeleteWebhookCalled = resolve;
});
let resolveDeleteWebhook: (() => void) | undefined;
deleteWebhookMock.mockImplementationOnce(
() =>
new Promise((resolve) => {
resolveDeleteWebhookCalled?.();
resolveDeleteWebhook = () => resolve({ ok: true, result: { url: "" } });
}),
);
@@ -147,12 +171,15 @@ describe("monitorZaloProvider lifecycle", () => {
settled = true;
});
await vi.waitFor(() => expect(setWebhookMock).toHaveBeenCalledTimes(1), { timeout: 5_000 });
await setWebhookCalled;
await settleLifecycleWork();
expect(setWebhookMock).toHaveBeenCalledTimes(1);
expect(registry.httpRoutes).toHaveLength(2);
abort.abort();
await vi.waitFor(() => expect(deleteWebhookMock).toHaveBeenCalledTimes(1), { timeout: 5000 });
await deleteWebhookCalled;
expect(deleteWebhookMock).toHaveBeenCalledTimes(1);
expect(deleteWebhookMock).toHaveBeenCalledWith("test-token", undefined, 5000);
expect(settled).toBe(false);
expect(registry.httpRoutes).toHaveLength(2);

View File

@@ -6,6 +6,7 @@ import type { PluginRuntime } from "../runtime-api.js";
import {
createLifecycleMonitorSetup,
createTextUpdate,
settleAsyncWork,
} from "../test-support/lifecycle-test-support.js";
import {
getUpdatesMock,
@@ -114,7 +115,8 @@ describe("Zalo polling media replies", () => {
});
try {
await vi.waitFor(() => expect(sendPhotoMock).toHaveBeenCalledTimes(1));
await settleAsyncWork();
expect(sendPhotoMock).toHaveBeenCalledTimes(1);
expect(registry.httpRoutes).toHaveLength(1);
expect(prepareHostedZaloMediaUrlMock).toHaveBeenCalledWith({
@@ -176,7 +178,8 @@ describe("Zalo polling media replies", () => {
});
try {
await vi.waitFor(() => expect(sendPhotoMock).toHaveBeenCalledTimes(1));
await settleAsyncWork();
expect(sendPhotoMock).toHaveBeenCalledTimes(1);
expect(prepareHostedZaloMediaUrlMock).not.toHaveBeenCalled();
expect(sendPhotoMock).toHaveBeenCalledWith(
@@ -223,7 +226,8 @@ describe("Zalo polling media replies", () => {
let secondRun: Promise<void> | undefined;
try {
await vi.waitFor(() => expect(firstRegistry.httpRoutes).toHaveLength(1));
await settleAsyncWork();
expect(firstRegistry.httpRoutes).toHaveLength(1);
setActivePluginRegistry(secondRegistry);
secondRun = monitorZaloProvider({
@@ -234,7 +238,8 @@ describe("Zalo polling media replies", () => {
abortSignal: secondAbort.signal,
});
await vi.waitFor(() => expect(secondRegistry.httpRoutes).toHaveLength(1));
await settleAsyncWork();
expect(secondRegistry.httpRoutes).toHaveLength(1);
} finally {
firstAbort.abort();
secondAbort.abort();