Spaces:
Sleeping
Sleeping
| import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; | |
| import { resetLogger, setLoggerOverride } from "../logging.js"; | |
| import { setActiveWebListener } from "./active-listener.js"; | |
| const loadWebMediaMock = vi.fn(); | |
| vi.mock("./media.js", () => ({ | |
| loadWebMedia: (...args: unknown[]) => loadWebMediaMock(...args), | |
| })); | |
| import { sendMessageWhatsApp, sendPollWhatsApp, sendReactionWhatsApp } from "./outbound.js"; | |
| describe("web outbound", () => { | |
| const sendComposingTo = vi.fn(async () => {}); | |
| const sendMessage = vi.fn(async () => ({ messageId: "msg123" })); | |
| const sendPoll = vi.fn(async () => ({ messageId: "poll123" })); | |
| const sendReaction = vi.fn(async () => {}); | |
| beforeEach(() => { | |
| vi.clearAllMocks(); | |
| setActiveWebListener({ | |
| sendComposingTo, | |
| sendMessage, | |
| sendPoll, | |
| sendReaction, | |
| }); | |
| }); | |
| afterEach(() => { | |
| resetLogger(); | |
| setLoggerOverride(null); | |
| setActiveWebListener(null); | |
| }); | |
| it("sends message via active listener", async () => { | |
| const result = await sendMessageWhatsApp("+1555", "hi", { verbose: false }); | |
| expect(result).toEqual({ | |
| messageId: "msg123", | |
| toJid: "1555@s.whatsapp.net", | |
| }); | |
| expect(sendComposingTo).toHaveBeenCalledWith("+1555"); | |
| expect(sendMessage).toHaveBeenCalledWith("+1555", "hi", undefined, undefined); | |
| }); | |
| it("throws a helpful error when no active listener exists", async () => { | |
| setActiveWebListener(null); | |
| await expect( | |
| sendMessageWhatsApp("+1555", "hi", { verbose: false, accountId: "work" }), | |
| ).rejects.toThrow(/No active WhatsApp Web listener/); | |
| await expect( | |
| sendMessageWhatsApp("+1555", "hi", { verbose: false, accountId: "work" }), | |
| ).rejects.toThrow(/channels login/); | |
| await expect( | |
| sendMessageWhatsApp("+1555", "hi", { verbose: false, accountId: "work" }), | |
| ).rejects.toThrow(/account: work/); | |
| }); | |
| it("maps audio to PTT with opus mime when ogg", async () => { | |
| const buf = Buffer.from("audio"); | |
| loadWebMediaMock.mockResolvedValueOnce({ | |
| buffer: buf, | |
| contentType: "audio/ogg", | |
| kind: "audio", | |
| }); | |
| await sendMessageWhatsApp("+1555", "voice note", { | |
| verbose: false, | |
| mediaUrl: "/tmp/voice.ogg", | |
| }); | |
| expect(sendMessage).toHaveBeenLastCalledWith( | |
| "+1555", | |
| "voice note", | |
| buf, | |
| "audio/ogg; codecs=opus", | |
| ); | |
| }); | |
| it("maps video with caption", async () => { | |
| const buf = Buffer.from("video"); | |
| loadWebMediaMock.mockResolvedValueOnce({ | |
| buffer: buf, | |
| contentType: "video/mp4", | |
| kind: "video", | |
| }); | |
| await sendMessageWhatsApp("+1555", "clip", { | |
| verbose: false, | |
| mediaUrl: "/tmp/video.mp4", | |
| }); | |
| expect(sendMessage).toHaveBeenLastCalledWith("+1555", "clip", buf, "video/mp4"); | |
| }); | |
| it("marks gif playback for video when requested", async () => { | |
| const buf = Buffer.from("gifvid"); | |
| loadWebMediaMock.mockResolvedValueOnce({ | |
| buffer: buf, | |
| contentType: "video/mp4", | |
| kind: "video", | |
| }); | |
| await sendMessageWhatsApp("+1555", "gif", { | |
| verbose: false, | |
| mediaUrl: "/tmp/anim.mp4", | |
| gifPlayback: true, | |
| }); | |
| expect(sendMessage).toHaveBeenLastCalledWith("+1555", "gif", buf, "video/mp4", { | |
| gifPlayback: true, | |
| }); | |
| }); | |
| it("maps image with caption", async () => { | |
| const buf = Buffer.from("img"); | |
| loadWebMediaMock.mockResolvedValueOnce({ | |
| buffer: buf, | |
| contentType: "image/jpeg", | |
| kind: "image", | |
| }); | |
| await sendMessageWhatsApp("+1555", "pic", { | |
| verbose: false, | |
| mediaUrl: "/tmp/pic.jpg", | |
| }); | |
| expect(sendMessage).toHaveBeenLastCalledWith("+1555", "pic", buf, "image/jpeg"); | |
| }); | |
| it("maps other kinds to document with filename", async () => { | |
| const buf = Buffer.from("pdf"); | |
| loadWebMediaMock.mockResolvedValueOnce({ | |
| buffer: buf, | |
| contentType: "application/pdf", | |
| kind: "document", | |
| fileName: "file.pdf", | |
| }); | |
| await sendMessageWhatsApp("+1555", "doc", { | |
| verbose: false, | |
| mediaUrl: "/tmp/file.pdf", | |
| }); | |
| expect(sendMessage).toHaveBeenLastCalledWith("+1555", "doc", buf, "application/pdf"); | |
| }); | |
| it("sends polls via active listener", async () => { | |
| const result = await sendPollWhatsApp( | |
| "+1555", | |
| { question: "Lunch?", options: ["Pizza", "Sushi"], maxSelections: 2 }, | |
| { verbose: false }, | |
| ); | |
| expect(result).toEqual({ | |
| messageId: "poll123", | |
| toJid: "1555@s.whatsapp.net", | |
| }); | |
| expect(sendPoll).toHaveBeenCalledWith("+1555", { | |
| question: "Lunch?", | |
| options: ["Pizza", "Sushi"], | |
| maxSelections: 2, | |
| durationHours: undefined, | |
| }); | |
| }); | |
| it("sends reactions via active listener", async () => { | |
| await sendReactionWhatsApp("1555@s.whatsapp.net", "msg123", "✅", { | |
| verbose: false, | |
| fromMe: false, | |
| }); | |
| expect(sendReaction).toHaveBeenCalledWith( | |
| "1555@s.whatsapp.net", | |
| "msg123", | |
| "✅", | |
| false, | |
| undefined, | |
| ); | |
| }); | |
| }); | |