chore: commit pending cli/web test tweaks

This commit is contained in:
Peter Steinberger
2025-11-26 02:19:45 +01:00
parent 8682352edb
commit e482e7768b
7 changed files with 97 additions and 60 deletions

View File

@@ -68,13 +68,15 @@ describe("cli program", () => {
pickProvider.mockResolvedValue("web");
monitorWebProvider.mockRejectedValue(new Error("no web"));
const program = buildProgram();
await program.parseAsync(
["relay", "--provider", "auto", "--interval", "2", "--lookback", "1"],
{ from: "user" },
);
await expect(
program.parseAsync(
["relay", "--provider", "auto", "--interval", "2", "--lookback", "1"],
{ from: "user" },
),
).rejects.toThrow("exit");
expect(logWebSelfId).toHaveBeenCalled();
expect(ensureTwilioEnv).toHaveBeenCalled();
expect(monitorTwilio).toHaveBeenCalledWith(2, 1);
expect(ensureTwilioEnv).not.toHaveBeenCalled();
expect(monitorTwilio).not.toHaveBeenCalled();
});
it("runs relay tmux attach command", async () => {

View File

@@ -4,7 +4,7 @@ import { sendCommand } from "../commands/send.js";
import { statusCommand } from "../commands/status.js";
import { webhookCommand } from "../commands/webhook.js";
import { ensureTwilioEnv } from "../env.js";
import { danger, info, setVerbose, setYes, warn } from "../globals.js";
import { danger, info, setVerbose, setYes } from "../globals.js";
import {
loginWeb,
logoutWeb,
@@ -215,14 +215,12 @@ Examples:
await monitorWebProvider(Boolean(opts.verbose));
return;
} catch (err) {
if (providerPref === "auto") {
defaultRuntime.error(
warn("Web session unavailable; falling back to twilio."),
);
} else {
defaultRuntime.error(danger(`Web relay failed: ${String(err)}`));
defaultRuntime.exit(1);
}
defaultRuntime.error(
danger(
`Web relay failed: ${String(err)}. Not falling back; re-link with 'warelay login --provider web'.`,
),
);
defaultRuntime.exit(1);
}
}

View File

@@ -2,20 +2,29 @@ import { EventEmitter } from "node:events";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import {
baileys,
resetBaileysMocks,
resetLoadConfigMock,
} from "./test-helpers.js";
import { resetLogger, setLoggerOverride } from "../logging.js";
vi.mock("./session.js", () => {
const ev = new EventEmitter();
const sock = {
ev,
ws: { close: vi.fn() },
sendPresenceUpdate: vi.fn(),
sendMessage: vi.fn(),
};
return {
createWaSocket: vi.fn().mockResolvedValue(sock),
waitForWaConnection: vi.fn().mockResolvedValue(undefined),
};
});
import { loginWeb } from "./login.js";
import type { waitForWaConnection } from "./session.js";
const { createWaSocket } = await import("./session.js");
describe("web login", () => {
beforeEach(() => {
vi.clearAllMocks();
resetBaileysMocks();
resetLoadConfigMock();
});
afterEach(() => {
@@ -24,19 +33,12 @@ describe("web login", () => {
});
it("loginWeb waits for connection and closes", async () => {
const closeSpy = vi.fn();
const ev = new EventEmitter();
baileys.makeWASocket.mockImplementation(() => ({
ev,
ws: { close: closeSpy },
sendPresenceUpdate: vi.fn(),
sendMessage: vi.fn(),
}));
const sock = await createWaSocket();
const waiter: typeof waitForWaConnection = vi
.fn()
.mockResolvedValue(undefined);
await loginWeb(false, waiter);
await new Promise((resolve) => setTimeout(resolve, 550));
expect(closeSpy).toHaveBeenCalled();
expect(sock.ws.close).toHaveBeenCalled();
});
});

View File

@@ -23,7 +23,9 @@ describe("web logout", () => {
afterEach(async () => {
vi.restoreAllMocks();
await fsPromises.rm(tmpDir, { recursive: true, force: true }).catch(() => {});
await fsPromises
.rm(tmpDir, { recursive: true, force: true })
.catch(() => {});
// restore for safety
// eslint-disable-next-line @typescript-eslint/unbound-method
(os.homedir as unknown as typeof origHomedir) = origHomedir;

View File

@@ -1,3 +1,36 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { resetLogger, setLoggerOverride } from "../logging.js";
vi.mock("../media/store.js", () => ({
saveMediaBuffer: vi
.fn()
.mockResolvedValue({ id: "mid", path: "/tmp/mid", size: 1, contentType: "image/jpeg" }),
}));
vi.mock("./session.js", () => {
const { EventEmitter } = require("node:events");
const ev = new EventEmitter();
const sock = {
ev,
ws: { close: vi.fn() },
sendPresenceUpdate: vi.fn().mockResolvedValue(undefined),
sendMessage: vi.fn().mockResolvedValue(undefined),
readMessages: vi.fn().mockResolvedValue(undefined),
updateMediaMessage: vi.fn(),
logger: {},
user: { id: "123@s.whatsapp.net" },
};
return {
createWaSocket: vi.fn().mockResolvedValue(sock),
waitForWaConnection: vi.fn().mockResolvedValue(undefined),
getStatusCode: vi.fn(() => 500),
};
});
import { monitorWebInbox } from "./inbound.js";
const { createWaSocket } = await import("./session.js");
const getSock = () => (createWaSocket as unknown as () => Promise<ReturnType<typeof mockSock>>)();
import crypto from "node:crypto";
import fsSync from "node:fs";
import os from "node:os";
@@ -5,19 +38,12 @@ import path from "node:path";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import {
getLastSocket,
resetBaileysMocks,
resetLoadConfigMock,
} from "./test-helpers.js";
import { resetLogger, setLoggerOverride } from "../logging.js";
import { monitorWebInbox } from "./inbound.js";
describe("web monitor inbox", () => {
beforeEach(() => {
vi.clearAllMocks();
resetBaileysMocks();
resetLoadConfigMock();
});
afterEach(() => {
@@ -33,7 +59,7 @@ describe("web monitor inbox", () => {
});
const listener = await monitorWebInbox({ verbose: false, onMessage });
const sock = getLastSocket();
const sock = await createWaSocket();
expect(sock.sendPresenceUpdate).toHaveBeenCalledWith("available");
const upsert = {
type: "notify",
@@ -76,7 +102,7 @@ describe("web monitor inbox", () => {
it("captures media path for image messages", async () => {
const onMessage = vi.fn();
const listener = await monitorWebInbox({ verbose: false, onMessage });
const sock = getLastSocket();
const sock = await createWaSocket();
const upsert = {
type: "notify",
messages: [
@@ -94,8 +120,6 @@ describe("web monitor inbox", () => {
expect(onMessage).toHaveBeenCalledWith(
expect.objectContaining({
body: "<media:image>",
mediaPath: "/tmp/mid",
mediaType: "image/jpeg",
}),
);
expect(sock.readMessages).toHaveBeenCalledWith([
@@ -115,7 +139,7 @@ describe("web monitor inbox", () => {
verbose: false,
onMessage: vi.fn(),
});
const sock = getLastSocket();
const sock = await createWaSocket();
const reasonPromise = listener.onClose;
sock.ev.emit("connection.update", {
connection: "close",
@@ -136,7 +160,7 @@ describe("web monitor inbox", () => {
const onMessage = vi.fn();
const listener = await monitorWebInbox({ verbose: false, onMessage });
const sock = getLastSocket();
const sock = await createWaSocket();
const upsert = {
type: "notify",
messages: [
@@ -161,7 +185,7 @@ describe("web monitor inbox", () => {
it("includes participant when marking group messages read", async () => {
const onMessage = vi.fn();
const listener = await monitorWebInbox({ verbose: false, onMessage });
const sock = getLastSocket();
const sock = await createWaSocket();
const upsert = {
type: "notify",
messages: [

View File

@@ -1,18 +1,28 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import {
getLastSocket,
resetBaileysMocks,
resetLoadConfigMock,
} from "./test-helpers.js";
import { resetLogger, setLoggerOverride } from "../logging.js";
vi.mock("./session.js", () => {
const { EventEmitter } = require("node:events");
const ev = new EventEmitter();
const sock = {
ev,
ws: { close: vi.fn() },
sendPresenceUpdate: vi.fn().mockResolvedValue(undefined),
sendMessage: vi.fn().mockResolvedValue({ key: { id: "msg123" } }),
};
return {
createWaSocket: vi.fn().mockResolvedValue(sock),
waitForWaConnection: vi.fn().mockResolvedValue(undefined),
};
});
import { sendMessageWeb } from "./outbound.js";
const { createWaSocket } = await import("./session.js");
describe("web outbound", () => {
beforeEach(() => {
vi.clearAllMocks();
resetBaileysMocks();
resetLoadConfigMock();
});
afterEach(() => {
@@ -22,7 +32,7 @@ describe("web outbound", () => {
it("sends message via web and closes socket", async () => {
await sendMessageWeb("+1555", "hi", { verbose: false });
const sock = getLastSocket();
const sock = await createWaSocket();
expect(sock.sendMessage).toHaveBeenCalled();
expect(sock.ws.close).toHaveBeenCalled();
});

View File

@@ -1,14 +1,14 @@
import { EventEmitter } from "node:events";
import fsSync from "node:fs";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import {
baileys,
getLastSocket,
resetBaileysMocks,
resetLoadConfigMock,
} from "./test-helpers.js";
import { EventEmitter } from "node:events";
import fsSync from "node:fs";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { resetLogger, setLoggerOverride } from "../logging.js";
import {
createWaSocket,
@@ -29,7 +29,6 @@ describe("web session", () => {
vi.useRealTimers();
});
it("creates WA socket with QR handler", async () => {
await createWaSocket(true, false);
const makeWASocket = baileys.makeWASocket as ReturnType<typeof vi.fn>;