From 49ae71fa62bbda54665ba370f1b3e7fee34f34df Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 24 Mar 2026 15:56:28 +0000 Subject: [PATCH] test: speed up signal and whatsapp extension suites --- .../event-handler.mention-gating.test.ts | 9 ++++++--- .../src/auto-reply/deliver-reply.test.ts | 4 ++-- .../src/auto-reply/heartbeat-runner.test.ts | 9 ++++++--- .../whatsapp/src/inbound/access-control.test.ts | 17 ++++++----------- extensions/whatsapp/src/resolve-target.test.ts | 8 ++++++-- 5 files changed, 26 insertions(+), 21 deletions(-) diff --git a/extensions/signal/src/monitor/event-handler.mention-gating.test.ts b/extensions/signal/src/monitor/event-handler.mention-gating.test.ts index 3375df40da6..b459aa7f163 100644 --- a/extensions/signal/src/monitor/event-handler.mention-gating.test.ts +++ b/extensions/signal/src/monitor/event-handler.mention-gating.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"; import { buildDispatchInboundCaptureMock } from "../../../../src/channels/plugins/contracts/inbound-testkit.js"; import type { OpenClawConfig } from "../../../../src/config/types.js"; @@ -100,15 +100,18 @@ async function expectSkippedGroupHistory(opts: GroupEventOpts, expectedBody: str } describe("signal mention gating", () => { - beforeEach(async () => { + beforeAll(async () => { vi.resetModules(); - capturedCtx = undefined; ({ createBaseSignalEventHandlerDeps, createSignalReceiveEvent } = await import("./event-handler.test-harness.js")); ({ createSignalEventHandler } = await import("./event-handler.js")); ({ renderSignalMentions } = await import("./mentions.js")); }); + beforeEach(() => { + capturedCtx = undefined; + }); + it("drops group messages without mention when requireMention is configured", async () => { const handler = createMentionHandler({ requireMention: true }); diff --git a/extensions/whatsapp/src/auto-reply/deliver-reply.test.ts b/extensions/whatsapp/src/auto-reply/deliver-reply.test.ts index 92d89a8fe4f..56456a3d3ab 100644 --- a/extensions/whatsapp/src/auto-reply/deliver-reply.test.ts +++ b/extensions/whatsapp/src/auto-reply/deliver-reply.test.ts @@ -1,4 +1,4 @@ -import { beforeEach, describe, expect, it, vi } from "vitest"; +import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { logVerbose } from "../../../../src/globals.js"; import { sleep } from "../../../../src/utils.js"; import { loadWebMedia } from "../media.js"; @@ -85,7 +85,7 @@ async function expectReplySuppressed(replyResult: { text: string; isReasoning?: } describe("deliverWebReply", () => { - beforeEach(async () => { + beforeAll(async () => { vi.resetModules(); ({ deliverWebReply } = await import("./deliver-reply.js")); }); diff --git a/extensions/whatsapp/src/auto-reply/heartbeat-runner.test.ts b/extensions/whatsapp/src/auto-reply/heartbeat-runner.test.ts index fbfbd017591..7e8a7467421 100644 --- a/extensions/whatsapp/src/auto-reply/heartbeat-runner.test.ts +++ b/extensions/whatsapp/src/auto-reply/heartbeat-runner.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 { getReplyFromConfig } from "../../../../src/auto-reply/reply.js"; import { HEARTBEAT_TOKEN } from "../../../../src/auto-reply/tokens.js"; import { redactIdentifier } from "../../../../src/logging/redact-identifier.js"; @@ -160,8 +160,12 @@ describe("runWebHeartbeatOnce", () => { ...overrides, }); - beforeEach(async () => { + beforeAll(async () => { vi.resetModules(); + ({ runWebHeartbeatOnce } = await import("./heartbeat-runner.js")); + }); + + beforeEach(() => { state.visibility = { showAlerts: true, showOk: true, useIndicator: false }; state.store = { k: { updatedAt: 999, sessionId: "s1" } }; state.snapshot = { @@ -182,7 +186,6 @@ describe("runWebHeartbeatOnce", () => { sender = senderMock as unknown as typeof sendMessageWhatsApp; replyResolverMock = vi.fn(async () => undefined); replyResolver = replyResolverMock as unknown as typeof getReplyFromConfig; - ({ runWebHeartbeatOnce } = await import("./heartbeat-runner.js")); }); it("supports manual override body dry-run without sending", async () => { diff --git a/extensions/whatsapp/src/inbound/access-control.test.ts b/extensions/whatsapp/src/inbound/access-control.test.ts index be22d7d7e54..80313fdef05 100644 --- a/extensions/whatsapp/src/inbound/access-control.test.ts +++ b/extensions/whatsapp/src/inbound/access-control.test.ts @@ -1,4 +1,4 @@ -import { beforeEach, describe, expect, it, vi } from "vitest"; +import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { readAllowFromStoreMock, sendMessageMock, @@ -10,6 +10,11 @@ import { setupAccessControlTestHarness(); let checkInboundAccessControl: typeof import("./access-control.js").checkInboundAccessControl; +beforeAll(async () => { + vi.resetModules(); + ({ checkInboundAccessControl } = await import("./access-control.js")); +}); + async function checkUnauthorizedWorkDmSender() { return checkInboundAccessControl({ accountId: "work", @@ -31,11 +36,6 @@ function expectSilentlyBlocked(result: { allowed: boolean }) { } describe("checkInboundAccessControl pairing grace", () => { - beforeEach(async () => { - vi.resetModules(); - ({ checkInboundAccessControl } = await import("./access-control.js")); - }); - async function runPairingGraceCase(messageTimestampMs: number) { const connectedAtMs = 1_000_000; return await checkInboundAccessControl({ @@ -72,11 +72,6 @@ describe("checkInboundAccessControl pairing grace", () => { }); describe("WhatsApp dmPolicy precedence", () => { - beforeEach(async () => { - vi.resetModules(); - ({ checkInboundAccessControl } = await import("./access-control.js")); - }); - it("uses account-level dmPolicy instead of channel-level (#8736)", async () => { // Channel-level says "pairing" but the account-level says "allowlist". // The account-level override should take precedence, so an unauthorized diff --git a/extensions/whatsapp/src/resolve-target.test.ts b/extensions/whatsapp/src/resolve-target.test.ts index 4a9074f4ee7..521c5995f41 100644 --- a/extensions/whatsapp/src/resolve-target.test.ts +++ b/extensions/whatsapp/src/resolve-target.test.ts @@ -1,5 +1,5 @@ import { installCommonResolveTargetErrorCases } from "openclaw/plugin-sdk/testing"; -import { beforeEach, describe, expect, it, vi } from "vitest"; +import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; vi.mock("./runtime-api.js", async () => { const actual = await vi.importActual("./runtime-api.js"); @@ -71,7 +71,7 @@ let resolveTarget: NonNullable< >; describe("whatsapp resolveTarget", () => { - beforeEach(async () => { + beforeAll(async () => { vi.resetModules(); const outbound = (await import("./channel.js")).whatsappPlugin.outbound; if (!outbound?.resolveTarget) { @@ -80,6 +80,10 @@ describe("whatsapp resolveTarget", () => { resolveTarget = outbound.resolveTarget; }); + beforeEach(() => { + vi.clearAllMocks(); + }); + it("should resolve valid target in explicit mode", () => { const result = resolveTarget({ to: "5511999999999",