Skip to content

Commit 008d785

Browse files
mcaxtrshakkernerd
authored andcommitted
test(whatsapp): update auto reply inbound fixtures
1 parent eebcb10 commit 008d785

24 files changed

Lines changed: 914 additions & 808 deletions

extensions/whatsapp/src/auto-reply.broadcast-groups.combined.test.ts

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ import {
77
sendWebDirectInboundAndCollectSessionKeys,
88
} from "./auto-reply.broadcast-groups.test-harness.js";
99
import {
10-
createAcceptedWhatsAppSendResult,
10+
createWebInboundDeliverySpies,
1111
installWebAutoReplyTestHomeHooks,
1212
installWebAutoReplyUnitTestHooks,
1313
resetLoadConfigMock,
1414
sendWebGroupInboundMessage,
1515
setLoadConfigMock,
1616
} from "./auto-reply.test-harness.js";
17+
import { createTestWebInboundMessage } from "./inbound/test-message.test-helper.js";
1718

1819
installWebAutoReplyTestHomeHooks();
1920

@@ -204,9 +205,7 @@ describe("broadcast groups", () => {
204205
},
205206
} satisfies OpenClawConfig);
206207

207-
const sendMedia = vi.fn().mockResolvedValue(createAcceptedWhatsAppSendResult("media", "m1"));
208-
const reply = vi.fn().mockResolvedValue(createAcceptedWhatsAppSendResult("text", "r1"));
209-
const sendComposing = vi.fn();
208+
const { sendMedia, reply, sendComposing } = createWebInboundDeliverySpies();
210209

211210
let started = 0;
212211
let release: (() => void) | undefined;
@@ -226,20 +225,28 @@ describe("broadcast groups", () => {
226225

227226
const { onMessage: capturedOnMessage } = await monitorWebChannelWithCapture(resolver);
228227

229-
await capturedOnMessage({
230-
id: "m1",
231-
from: "+1000",
232-
conversationId: "+1000",
233-
to: "+2000",
234-
accountId: "default",
235-
body: "hello",
236-
timestamp: Date.now(),
237-
chatType: "direct",
238-
chatId: "direct:+1000",
239-
sendComposing,
240-
reply,
241-
sendMedia,
242-
});
228+
await capturedOnMessage(
229+
createTestWebInboundMessage({
230+
event: {
231+
id: "m1",
232+
timestamp: Date.now(),
233+
},
234+
payload: {
235+
body: "hello",
236+
},
237+
platform: {
238+
chatJid: "direct:+1000",
239+
recipientJid: "+2000",
240+
sendComposing,
241+
reply,
242+
sendMedia,
243+
},
244+
from: "+1000",
245+
conversationId: "+1000",
246+
accountId: "default",
247+
chatType: "direct",
248+
}),
249+
);
243250

244251
expect(resolver).toHaveBeenCalledTimes(2);
245252
resetLoadConfigMock();

extensions/whatsapp/src/auto-reply.broadcast-groups.test-harness.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ import {
66
sendWebDirectInboundMessage,
77
} from "./auto-reply.test-harness.js";
88
import { monitorWebChannel } from "./auto-reply/monitor.js";
9-
import type { WebInboundMessage } from "./inbound.js";
9+
import type { WebInboundMessageInput } from "./inbound.js";
1010

1111
export async function monitorWebChannelWithCapture(resolver: unknown): Promise<{
1212
spies: ReturnType<typeof createWebInboundDeliverySpies>;
13-
onMessage: (msg: WebInboundMessage) => Promise<void>;
13+
onMessage: (msg: WebInboundMessageInput) => Promise<void>;
1414
}> {
1515
const spies = createWebInboundDeliverySpies();
1616
const { listenerFactory, getOnMessage } = createWebListenerFactoryCapture();

extensions/whatsapp/src/auto-reply.test-harness.ts

Lines changed: 80 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@ import { resetLogger, setLoggerOverride } from "openclaw/plugin-sdk/runtime-env"
99
import { mockPinnedHostnameResolution } from "openclaw/plugin-sdk/test-env";
1010
import { afterAll, afterEach, beforeAll, beforeEach, vi, type Mock } from "vitest";
1111
import type { WebChannelStatus } from "./auto-reply/types.js";
12-
import type { WebInboundMessage, WebListenerCloseReason } from "./inbound.js";
13-
import type { WhatsAppSendKind, WhatsAppSendResult } from "./inbound/send-result.js";
12+
import type { WebInboundMessageInput, WebListenerCloseReason } from "./inbound.js";
13+
import type { WhatsAppSendResult } from "./inbound/send-result.js";
14+
import { createAcceptedWhatsAppSendResult as createAcceptedWhatsAppSendResultForHarness } from "./inbound/send-result.test-helper.js";
15+
import { createTestWebInboundMessage } from "./inbound/test-message.test-helper.js";
1416
import {
1517
resetBaileysMocks as _resetBaileysMocks,
1618
resetLoadConfigMock as _resetLoadConfigMock,
1719
} from "./test-helpers.js";
1820

21+
export { createAcceptedWhatsAppSendResult } from "./inbound/send-result.test-helper.js";
1922
export {
2023
resetLoadConfigMock,
2124
setLoadConfigMock,
@@ -235,16 +238,18 @@ export function installWebAutoReplyUnitTestHooks(opts?: { pinDns?: boolean }) {
235238
}
236239

237240
export function createWebListenerFactoryCapture(): AnyExport {
238-
let capturedOnMessage: ((msg: WebInboundMessage) => Promise<void>) | undefined;
241+
let capturedOnMessage: ((msg: WebInboundMessageInput) => Promise<void>) | undefined;
239242
let capturedOptions:
240243
| {
241-
onMessage: (msg: WebInboundMessage) => Promise<void>;
244+
onMessage: (msg: WebInboundMessageInput) => Promise<void>;
245+
shouldDebounce?: (msg: WebInboundMessageInput) => boolean;
242246
debounceMs?: number;
243247
selfChatMode?: boolean;
244248
}
245249
| undefined;
246250
const listenerFactory = async (opts: {
247-
onMessage: (msg: WebInboundMessage) => Promise<void>;
251+
onMessage: (msg: WebInboundMessageInput) => Promise<void>;
252+
shouldDebounce?: (msg: WebInboundMessageInput) => boolean;
248253
debounceMs?: number;
249254
selfChatMode?: boolean;
250255
}) => {
@@ -265,35 +270,31 @@ export function createMockWebListener(): MockWebListener {
265270
close: vi.fn(async () => undefined),
266271
onClose: new Promise<WebListenerCloseReason>(() => {}),
267272
signalClose: vi.fn(),
268-
sendMessage: vi.fn(async () => createAcceptedWhatsAppSendResult("text", "msg-1")),
269-
sendPoll: vi.fn(async () => createAcceptedWhatsAppSendResult("poll", "poll-1")),
270-
sendContact: vi.fn(async () => createAcceptedWhatsAppSendResult("contact", "contact-1")),
271-
sendLocation: vi.fn(async () => createAcceptedWhatsAppSendResult("location", "location-1")),
272-
sendSticker: vi.fn(async () => createAcceptedWhatsAppSendResult("sticker", "sticker-1")),
273-
sendReaction: vi.fn(async () => createAcceptedWhatsAppSendResult("reaction", "reaction-1")),
273+
sendMessage: vi.fn(async () => createAcceptedWhatsAppSendResultForHarness("text", "msg-1")),
274+
sendPoll: vi.fn(async () => createAcceptedWhatsAppSendResultForHarness("poll", "poll-1")),
275+
sendContact: vi.fn(async () =>
276+
createAcceptedWhatsAppSendResultForHarness("contact", "contact-1"),
277+
),
278+
sendLocation: vi.fn(async () =>
279+
createAcceptedWhatsAppSendResultForHarness("location", "location-1"),
280+
),
281+
sendSticker: vi.fn(async () =>
282+
createAcceptedWhatsAppSendResultForHarness("sticker", "sticker-1"),
283+
),
284+
sendReaction: vi.fn(async () =>
285+
createAcceptedWhatsAppSendResultForHarness("reaction", "reaction-1"),
286+
),
274287
sendComposingTo: vi.fn(async () => undefined),
275288
};
276289
}
277290

278-
export function createAcceptedWhatsAppSendResult(
279-
kind: WhatsAppSendKind,
280-
id: string,
281-
): WhatsAppSendResult {
282-
return {
283-
kind,
284-
messageId: id,
285-
keys: [{ id }],
286-
providerAccepted: true,
287-
};
288-
}
289-
290291
export function createScriptedWebListenerFactory(): AnyExport {
291-
const onMessages: Array<(msg: WebInboundMessage) => Promise<void>> = [];
292+
const onMessages: Array<(msg: WebInboundMessageInput) => Promise<void>> = [];
292293
const closeResolvers: Array<(reason: unknown) => void> = [];
293294
const listeners: MockWebListener[] = [];
294295

295296
const listenerFactory = vi.fn(
296-
async (opts: { onMessage: (msg: WebInboundMessage) => Promise<void> }) => {
297+
async (opts: { onMessage: (msg: WebInboundMessageInput) => Promise<void> }) => {
297298
onMessages.push(opts.onMessage);
298299
let resolveClose: (reason: unknown) => void = () => {};
299300
const onClose = new Promise<WebListenerCloseReason>((res) => {
@@ -321,8 +322,8 @@ export function createScriptedWebListenerFactory(): AnyExport {
321322

322323
export function createWebInboundDeliverySpies(): AnyExport {
323324
return {
324-
sendMedia: vi.fn().mockResolvedValue(createAcceptedWhatsAppSendResult("media", "m1")),
325-
reply: vi.fn().mockResolvedValue(createAcceptedWhatsAppSendResult("text", "r1")),
325+
sendMedia: vi.fn().mockResolvedValue(createAcceptedWhatsAppSendResultForHarness("media", "m1")),
326+
reply: vi.fn().mockResolvedValue(createAcceptedWhatsAppSendResultForHarness("text", "r1")),
326327
sendComposing: vi.fn(),
327328
};
328329
}
@@ -373,7 +374,7 @@ export function startWebAutoReplyMonitor(params: {
373374
}
374375

375376
export async function sendWebGroupInboundMessage(params: {
376-
onMessage: (msg: WebInboundMessage) => Promise<void>;
377+
onMessage: (msg: WebInboundMessageInput) => Promise<void>;
377378
body: string;
378379
id: string;
379380
senderE164: string;
@@ -387,28 +388,38 @@ export async function sendWebGroupInboundMessage(params: {
387388
}) {
388389
const conversationId = params.conversationId ?? "123@g.us";
389390
const accountId = params.accountId ?? "default";
390-
await params.onMessage({
391-
body: params.body,
392-
from: conversationId,
393-
conversationId,
394-
chatId: conversationId,
395-
chatType: "group",
396-
to: "+2",
397-
accountId,
398-
id: params.id,
399-
senderE164: params.senderE164,
400-
senderName: params.senderName,
401-
mentionedJids: params.mentionedJids,
402-
selfE164: params.selfE164,
403-
selfJid: params.selfJid,
404-
sendComposing: params.spies.sendComposing,
405-
reply: params.spies.reply,
406-
sendMedia: params.spies.sendMedia,
407-
} as WebInboundMessage);
391+
await params.onMessage(
392+
createTestWebInboundMessage({
393+
event: { id: params.id },
394+
payload: { body: params.body },
395+
platform: {
396+
chatJid: conversationId,
397+
recipientJid: "+2",
398+
senderE164: params.senderE164,
399+
senderName: params.senderName,
400+
selfE164: params.selfE164,
401+
selfJid: params.selfJid,
402+
sendComposing: params.spies.sendComposing,
403+
reply: params.spies.reply,
404+
sendMedia: params.spies.sendMedia,
405+
},
406+
from: conversationId,
407+
conversationId,
408+
chatType: "group",
409+
accountId,
410+
group: params.mentionedJids?.length
411+
? {
412+
mentions: {
413+
jids: params.mentionedJids,
414+
},
415+
}
416+
: undefined,
417+
}),
418+
);
408419
}
409420

410421
export async function sendWebDirectInboundMessage(params: {
411-
onMessage: (msg: WebInboundMessage) => Promise<void>;
422+
onMessage: (msg: WebInboundMessageInput) => Promise<void>;
412423
body: string;
413424
id: string;
414425
from: string;
@@ -418,18 +429,26 @@ export async function sendWebDirectInboundMessage(params: {
418429
timestamp?: number;
419430
}) {
420431
const accountId = params.accountId ?? "default";
421-
await params.onMessage({
422-
accountId,
423-
id: params.id,
424-
from: params.from,
425-
conversationId: params.from,
426-
to: params.to,
427-
body: params.body,
428-
timestamp: params.timestamp ?? Date.now(),
429-
chatType: "direct",
430-
chatId: `direct:${params.from}`,
431-
sendComposing: params.spies.sendComposing,
432-
reply: params.spies.reply,
433-
sendMedia: params.spies.sendMedia,
434-
} as WebInboundMessage);
432+
await params.onMessage(
433+
createTestWebInboundMessage({
434+
accountId,
435+
event: {
436+
id: params.id,
437+
timestamp: params.timestamp ?? Date.now(),
438+
},
439+
payload: {
440+
body: params.body,
441+
},
442+
platform: {
443+
chatJid: `direct:${params.from}`,
444+
recipientJid: params.to,
445+
sendComposing: params.spies.sendComposing,
446+
reply: params.spies.reply,
447+
sendMedia: params.spies.sendMedia,
448+
},
449+
from: params.from,
450+
conversationId: params.from,
451+
chatType: "direct",
452+
}),
453+
);
435454
}

0 commit comments

Comments
 (0)