diff --git a/extensions/signal/src/monitor/event-handler.inbound-context.test.ts b/extensions/signal/src/monitor/event-handler.inbound-context.test.ts index b57405bf61a..e89cfa8c026 100644 --- a/extensions/signal/src/monitor/event-handler.inbound-context.test.ts +++ b/extensions/signal/src/monitor/event-handler.inbound-context.test.ts @@ -1,4 +1,4 @@ -import { beforeEach, describe, expect, it, vi } from "vitest"; +import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import type { MsgContext } from "../../../../src/auto-reply/templating.js"; let expectInboundContextContract: typeof import("../../../../src/channels/plugins/contracts/suites.js").expectChannelInboundContextContract; let createBaseSignalEventHandlerDeps: typeof import("./event-handler.test-harness.js").createBaseSignalEventHandlerDeps; @@ -49,7 +49,7 @@ vi.mock("../../../../src/pairing/pairing-store.js", () => ({ let createSignalEventHandler: typeof import("./event-handler.js").createSignalEventHandler; describe("signal createSignalEventHandler inbound context", () => { - beforeEach(async () => { + beforeAll(async () => { vi.useRealTimers(); vi.resetModules(); ({ expectChannelInboundContextContract: expectInboundContextContract } = @@ -57,6 +57,9 @@ describe("signal createSignalEventHandler inbound context", () => { ({ createBaseSignalEventHandlerDeps, createSignalReceiveEvent } = await import("./event-handler.test-harness.js")); ({ createSignalEventHandler } = await import("./event-handler.js")); + }); + + beforeEach(() => { capture.ctx = undefined; sendTypingMock.mockReset().mockResolvedValue(true); sendReadReceiptMock.mockReset().mockResolvedValue(true); diff --git a/extensions/whatsapp/src/auto-reply.web-auto-reply.compresses-common-formats-jpeg-cap.test.ts b/extensions/whatsapp/src/auto-reply.web-auto-reply.compresses-common-formats-jpeg-cap.test.ts index 22b4b1b99ae..8b6105126a7 100644 --- a/extensions/whatsapp/src/auto-reply.web-auto-reply.compresses-common-formats-jpeg-cap.test.ts +++ b/extensions/whatsapp/src/auto-reply.web-auto-reply.compresses-common-formats-jpeg-cap.test.ts @@ -1,6 +1,6 @@ import crypto from "node:crypto"; import sharp from "sharp"; -import { beforeEach, describe, expect, it, vi } from "vitest"; +import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { createMockWebListener, installWebAutoReplyTestHomeHooks, @@ -20,8 +20,7 @@ describe("web auto-reply", () => { const SMALL_MEDIA_CAP_MB = 0.1; const SMALL_MEDIA_CAP_BYTES = Math.floor(SMALL_MEDIA_CAP_MB * 1024 * 1024); - beforeEach(async () => { - vi.resetModules(); + beforeAll(async () => { ({ monitorWebChannel } = await import("./auto-reply.js")); }); diff --git a/extensions/whatsapp/src/monitor-inbox.blocks-messages-from-unauthorized-senders-not-allowfrom.test.ts b/extensions/whatsapp/src/monitor-inbox.blocks-messages-from-unauthorized-senders-not-allowfrom.test.ts index 482c9c4c86b..8689ef2df1b 100644 --- a/extensions/whatsapp/src/monitor-inbox.blocks-messages-from-unauthorized-senders-not-allowfrom.test.ts +++ b/extensions/whatsapp/src/monitor-inbox.blocks-messages-from-unauthorized-senders-not-allowfrom.test.ts @@ -4,9 +4,11 @@ import { DEFAULT_ACCOUNT_ID, expectPairingPromptSent, getAuthDir, + getMonitorWebInbox, getSock, installWebMonitorInboxUnitTestHooks, mockLoadConfig, + settleInboundWork, } from "./monitor-inbox.test-harness.js"; const nowSeconds = (offsetMs = 0) => Math.floor((Date.now() + offsetMs) / 1000); @@ -19,10 +21,6 @@ const TIMESTAMP_OFF_MESSAGES_CFG = { timestampPrefix: false, } as const; -async function flushInboundQueue() { - await new Promise((resolve) => setTimeout(resolve, 25)); -} - const createNotifyUpsert = (message: Record) => ({ type: "notify", messages: [message], @@ -58,7 +56,7 @@ async function startWebInboxMonitor(params: { config?: Record; sendReadReceipts?: boolean; }) { - const { monitorWebInbox } = await import("./inbound.js"); + const monitorWebInbox = getMonitorWebInbox(); if (params.config) { mockLoadConfig.mockReturnValue(params.config); } @@ -111,7 +109,7 @@ describe("web monitor inbox", () => { }), ), ); - await flushInboundQueue(); + await settleInboundWork(); // Should NOT call onMessage for unauthorized senders expect(onMessage).not.toHaveBeenCalled(); @@ -147,7 +145,7 @@ describe("web monitor inbox", () => { }), ), ); - await flushInboundQueue(); + await settleInboundWork(); expect(onMessage).toHaveBeenCalledTimes(1); expect(onMessage).toHaveBeenCalledWith( @@ -172,7 +170,7 @@ describe("web monitor inbox", () => { }), ), ); - await flushInboundQueue(); + await settleInboundWork(); expect(onMessage).toHaveBeenCalledTimes(1); expect(sock.readMessages).not.toHaveBeenCalled(); @@ -197,7 +195,7 @@ describe("web monitor inbox", () => { }), ), ); - await flushInboundQueue(); + await settleInboundWork(); expect(onMessage).toHaveBeenCalledTimes(1); const payload = onMessage.mock.calls[0][0]; @@ -224,7 +222,7 @@ describe("web monitor inbox", () => { }), ), ); - await flushInboundQueue(); + await settleInboundWork(); // Should NOT call onMessage because groupPolicy is disabled expect(onMessage).not.toHaveBeenCalled(); @@ -254,7 +252,7 @@ describe("web monitor inbox", () => { }), ), ); - await flushInboundQueue(); + await settleInboundWork(); // Should NOT call onMessage because sender +999 not in groupAllowFrom expect(onMessage).not.toHaveBeenCalled(); @@ -284,7 +282,7 @@ describe("web monitor inbox", () => { }), ), ); - await flushInboundQueue(); + await settleInboundWork(); // Should call onMessage because sender is in groupAllowFrom expect(onMessage).toHaveBeenCalledTimes(1); @@ -318,7 +316,7 @@ describe("web monitor inbox", () => { }), ), ); - await flushInboundQueue(); + await settleInboundWork(); // Should call onMessage because wildcard allows all senders expect(onMessage).toHaveBeenCalledTimes(1); @@ -349,7 +347,7 @@ describe("web monitor inbox", () => { }), ), ); - await flushInboundQueue(); + await settleInboundWork(); expect(onMessage).not.toHaveBeenCalled(); diff --git a/extensions/whatsapp/src/monitor-inbox.captures-media-path-image-messages.test.ts b/extensions/whatsapp/src/monitor-inbox.captures-media-path-image-messages.test.ts index 726be66f31b..634cb1cdff2 100644 --- a/extensions/whatsapp/src/monitor-inbox.captures-media-path-image-messages.test.ts +++ b/extensions/whatsapp/src/monitor-inbox.captures-media-path-image-messages.test.ts @@ -3,6 +3,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; import { DEFAULT_ACCOUNT_ID, getAuthDir, + getMonitorWebInbox, getSock, installWebMonitorInboxUnitTestHooks, mockLoadConfig, @@ -26,10 +27,9 @@ vi.mock("openclaw/plugin-sdk/text-runtime", async (importOriginal) => { describe("web monitor inbox", () => { installWebMonitorInboxUnitTestHooks(); - beforeEach(async () => { - vi.resetModules(); + beforeEach(() => { inboundLoggerInfoMock.mockReset(); - ({ monitorWebInbox } = await import("./inbound.js")); + monitorWebInbox = getMonitorWebInbox(); }); async function openMonitor(onMessage = vi.fn()) { diff --git a/extensions/whatsapp/src/monitor-inbox.test-harness.ts b/extensions/whatsapp/src/monitor-inbox.test-harness.ts index b7c7ff2adf5..10db2e3eeb3 100644 --- a/extensions/whatsapp/src/monitor-inbox.test-harness.ts +++ b/extensions/whatsapp/src/monitor-inbox.test-harness.ts @@ -144,6 +144,13 @@ type MonitorWebInbox = typeof import("./inbound.js").monitorWebInbox; export type InboxOnMessage = NonNullable[0]["onMessage"]>; let monitorWebInbox: MonitorWebInbox; +export function getMonitorWebInbox(): MonitorWebInbox { + if (!monitorWebInbox) { + throw new Error("monitorWebInbox not initialized"); + } + return monitorWebInbox; +} + export async function settleInboundWork() { await new Promise((resolve) => setTimeout(resolve, 25)); } diff --git a/extensions/whatsapp/src/setup-surface.test.ts b/extensions/whatsapp/src/setup-surface.test.ts index 941148a76c6..9597bd536de 100644 --- a/extensions/whatsapp/src/setup-surface.test.ts +++ b/extensions/whatsapp/src/setup-surface.test.ts @@ -1,4 +1,4 @@ -import { beforeEach, describe, expect, it, vi } from "vitest"; +import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js"; import type { RuntimeEnv } from "../../../src/runtime.js"; import { @@ -91,11 +91,14 @@ async function runSeparatePhoneFlow(params: { selectValues: string[]; textValues } describe("whatsapp setup wizard", () => { - beforeEach(async () => { + beforeAll(async () => { vi.resetModules(); - vi.clearAllMocks(); const { whatsappPlugin } = await import("./channel.js"); whatsappConfigure = createPluginSetupWizardConfigure(whatsappPlugin); + }); + + beforeEach(() => { + vi.clearAllMocks(); pathExistsMock.mockResolvedValue(false); listWhatsAppAccountIdsMock.mockReturnValue([]); resolveDefaultWhatsAppAccountIdMock.mockReturnValue(DEFAULT_ACCOUNT_ID);