import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { DisconnectReason } from "@whiskeysockets/baileys"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; const rmMock = vi.spyOn(fs, "rm"); const authDir = path.join(os.tmpdir(), "wa-creds"); vi.mock("../config/config.js", () => ({ loadConfig: () => ({ channels: { whatsapp: { accounts: { default: { enabled: true, authDir }, }, }, }, }) as never, })); vi.mock("./session.js", () => { const sockA = { ws: { close: vi.fn() } }; const sockB = { ws: { close: vi.fn() } }; let call = 0; const createWaSocket = vi.fn(async () => (call++ === 0 ? sockA : sockB)); const waitForWaConnection = vi.fn(); const formatError = vi.fn((err: unknown) => `formatted:${String(err)}`); return { createWaSocket, waitForWaConnection, formatError, WA_WEB_AUTH_DIR: authDir, logoutWeb: vi.fn(async (params: { authDir?: string }) => { await fs.rm(params.authDir ?? authDir, { recursive: true, force: true, }); return true; }), }; }); const { createWaSocket, waitForWaConnection, formatError } = await import("./session.js"); const { loginWeb } = await import("./login.js"); describe("loginWeb coverage", () => { beforeEach(() => { vi.useFakeTimers(); vi.clearAllMocks(); rmMock.mockClear(); }); afterEach(() => { vi.useRealTimers(); }); it("restarts once when WhatsApp requests code 515", async () => { waitForWaConnection .mockRejectedValueOnce({ output: { statusCode: 515 } }) .mockResolvedValueOnce(undefined); const runtime = { log: vi.fn(), error: vi.fn() } as never; await loginWeb(false, waitForWaConnection as never, runtime); expect(createWaSocket).toHaveBeenCalledTimes(2); const firstSock = await createWaSocket.mock.results[0].value; expect(firstSock.ws.close).toHaveBeenCalled(); vi.runAllTimers(); const secondSock = await createWaSocket.mock.results[1].value; expect(secondSock.ws.close).toHaveBeenCalled(); }); it("clears creds and throws when logged out", async () => { waitForWaConnection.mockRejectedValueOnce({ output: { statusCode: DisconnectReason.loggedOut }, }); await expect(loginWeb(false, waitForWaConnection as never)).rejects.toThrow(/cache cleared/i); expect(rmMock).toHaveBeenCalledWith(authDir, { recursive: true, force: true, }); }); it("formats and rethrows generic errors", async () => { waitForWaConnection.mockRejectedValueOnce(new Error("boom")); await expect(loginWeb(false, waitForWaConnection as never)).rejects.toThrow( "formatted:Error: boom", ); expect(formatError).toHaveBeenCalled(); }); });