refactor(test): dedupe web auto-reply group message setup

This commit is contained in:
Peter Steinberger
2026-02-14 20:33:46 +00:00
parent 9be114738f
commit 0e8ec83742
3 changed files with 88 additions and 71 deletions

View File

@@ -3,9 +3,12 @@ import { describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import { monitorWebChannel } from "./auto-reply.js";
import {
createWebInboundDeliverySpies,
createWebListenerFactoryCapture,
installWebAutoReplyTestHomeHooks,
installWebAutoReplyUnitTestHooks,
resetLoadConfigMock,
sendWebGroupInboundMessage,
setLoadConfigMock,
} from "./auto-reply.test-harness.js";
@@ -81,58 +84,37 @@ describe("broadcast groups", () => {
},
} satisfies OpenClawConfig);
const sendMedia = vi.fn();
const reply = vi.fn().mockResolvedValue(undefined);
const sendComposing = vi.fn();
const spies = createWebInboundDeliverySpies();
const resolver = vi.fn().mockResolvedValue({ text: "ok" });
let capturedOnMessage:
| ((msg: import("./inbound.js").WebInboundMessage) => Promise<void>)
| undefined;
const listenerFactory = async (opts: {
onMessage: (msg: import("./inbound.js").WebInboundMessage) => Promise<void>;
}) => {
capturedOnMessage = opts.onMessage;
return { close: vi.fn() };
};
const { listenerFactory, getOnMessage } = createWebListenerFactoryCapture();
await monitorWebChannel(false, listenerFactory, false, resolver);
expect(capturedOnMessage).toBeDefined();
const onMessage = getOnMessage();
expect(onMessage).toBeDefined();
await capturedOnMessage?.({
await sendWebGroupInboundMessage({
onMessage: onMessage!,
spies,
body: "hello group",
from: "123@g.us",
conversationId: "123@g.us",
chatId: "123@g.us",
chatType: "group",
to: "+2",
id: "g1",
senderE164: "+111",
senderName: "Alice",
selfE164: "+999",
sendComposing,
reply,
sendMedia,
});
expect(resolver).not.toHaveBeenCalled();
await capturedOnMessage?.({
await sendWebGroupInboundMessage({
onMessage: onMessage!,
spies,
body: "@bot ping",
from: "123@g.us",
conversationId: "123@g.us",
chatId: "123@g.us",
chatType: "group",
to: "+2",
id: "g2",
senderE164: "+222",
senderName: "Bob",
mentionedJids: ["999@s.whatsapp.net"],
selfE164: "+999",
selfJid: "999@s.whatsapp.net",
sendComposing,
reply,
sendMedia,
});
expect(resolver).toHaveBeenCalledTimes(2);
@@ -153,22 +135,16 @@ describe("broadcast groups", () => {
expect(payload.SenderId).toBe("+222");
}
await capturedOnMessage?.({
await sendWebGroupInboundMessage({
onMessage: onMessage!,
spies,
body: "@bot ping 2",
from: "123@g.us",
conversationId: "123@g.us",
chatId: "123@g.us",
chatType: "group",
to: "+2",
id: "g3",
senderE164: "+333",
senderName: "Clara",
mentionedJids: ["999@s.whatsapp.net"],
selfE164: "+999",
selfJid: "999@s.whatsapp.net",
sendComposing,
reply,
sendMedia,
});
expect(resolver).toHaveBeenCalledTimes(4);

View File

@@ -3,6 +3,7 @@ import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { afterEach, beforeEach, vi } from "vitest";
import type { WebInboundMessage } from "./inbound.js";
import { resetInboundDedupe } from "../auto-reply/reply/inbound-dedupe.js";
import * as ssrf from "../infra/net/ssrf.js";
import { resetLogger, setLoggerOverride } from "../logging.js";
@@ -117,3 +118,61 @@ export function installWebAutoReplyUnitTestHooks(opts?: { pinDns?: boolean }) {
vi.useRealTimers();
});
}
export function createWebListenerFactoryCapture() {
let capturedOnMessage: ((msg: WebInboundMessage) => Promise<void>) | undefined;
const listenerFactory = async (opts: {
onMessage: (msg: WebInboundMessage) => Promise<void>;
}) => {
capturedOnMessage = opts.onMessage;
return { close: vi.fn() };
};
return {
listenerFactory,
getOnMessage: () => capturedOnMessage,
};
}
export function createWebInboundDeliverySpies() {
return {
sendMedia: vi.fn(),
reply: vi.fn().mockResolvedValue(undefined),
sendComposing: vi.fn(),
};
}
export async function sendWebGroupInboundMessage(params: {
onMessage: (msg: WebInboundMessage) => Promise<void>;
body: string;
id: string;
senderE164: string;
senderName: string;
mentionedJids?: string[];
selfE164?: string;
selfJid?: string;
spies: ReturnType<typeof createWebInboundDeliverySpies>;
conversationId?: string;
accountId?: string;
}) {
const conversationId = params.conversationId ?? "123@g.us";
const accountId = params.accountId ?? "default";
await params.onMessage({
body: params.body,
from: conversationId,
conversationId,
chatId: conversationId,
chatType: "group",
to: "+2",
accountId,
id: params.id,
senderE164: params.senderE164,
senderName: params.senderName,
mentionedJids: params.mentionedJids,
selfE164: params.selfE164,
selfJid: params.selfJid,
sendComposing: params.spies.sendComposing,
reply: params.spies.reply,
sendMedia: params.spies.sendMedia,
} as WebInboundMessage);
}

View File

@@ -3,10 +3,13 @@ import os from "node:os";
import path from "node:path";
import { beforeAll, describe, expect, it, vi } from "vitest";
import {
createWebInboundDeliverySpies,
createWebListenerFactoryCapture,
installWebAutoReplyTestHomeHooks,
installWebAutoReplyUnitTestHooks,
resetLoadConfigMock,
rmDirWithRetries,
sendWebGroupInboundMessage,
setLoadConfigMock,
} from "./auto-reply.test-harness.js";
@@ -22,58 +25,37 @@ describe("web auto-reply", () => {
installWebAutoReplyUnitTestHooks();
it("requires mention in group chats and injects history when replying", async () => {
const sendMedia = vi.fn();
const reply = vi.fn().mockResolvedValue(undefined);
const sendComposing = vi.fn();
const spies = createWebInboundDeliverySpies();
const resolver = vi.fn().mockResolvedValue({ text: "ok" });
let capturedOnMessage:
| ((msg: import("./inbound.js").WebInboundMessage) => Promise<void>)
| undefined;
const listenerFactory = async (opts: {
onMessage: (msg: import("./inbound.js").WebInboundMessage) => Promise<void>;
}) => {
capturedOnMessage = opts.onMessage;
return { close: vi.fn() };
};
const { listenerFactory, getOnMessage } = createWebListenerFactoryCapture();
await monitorWebChannel(false, listenerFactory, false, resolver);
expect(capturedOnMessage).toBeDefined();
const onMessage = getOnMessage();
expect(onMessage).toBeDefined();
await capturedOnMessage?.({
await sendWebGroupInboundMessage({
onMessage: onMessage!,
spies,
body: "hello group",
from: "123@g.us",
conversationId: "123@g.us",
chatId: "123@g.us",
chatType: "group",
to: "+2",
id: "g1",
senderE164: "+111",
senderName: "Alice",
selfE164: "+999",
sendComposing,
reply,
sendMedia,
});
expect(resolver).not.toHaveBeenCalled();
await capturedOnMessage?.({
await sendWebGroupInboundMessage({
onMessage: onMessage!,
spies,
body: "@bot ping",
from: "123@g.us",
conversationId: "123@g.us",
chatId: "123@g.us",
chatType: "group",
to: "+2",
id: "g2",
senderE164: "+222",
senderName: "Bob",
mentionedJids: ["999@s.whatsapp.net"],
selfE164: "+999",
selfJid: "999@s.whatsapp.net",
sendComposing,
reply,
sendMedia,
});
expect(resolver).toHaveBeenCalledTimes(1);