mirror of https://github.com/openclaw/openclaw.git
93 lines
3.0 KiB
TypeScript
93 lines
3.0 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
import { startWebLoginWithQr, waitForWebLogin } from "./login-qr.js";
|
|
import {
|
|
createWaSocket,
|
|
logoutWeb,
|
|
waitForCredsSaveQueueWithTimeout,
|
|
waitForWaConnection,
|
|
} from "./session.js";
|
|
|
|
vi.mock("./session.js", () => {
|
|
const createWaSocket = vi.fn(
|
|
async (_printQr: boolean, _verbose: boolean, opts?: { onQr?: (qr: string) => void }) => {
|
|
const sock = { ws: { close: vi.fn() } };
|
|
if (opts?.onQr) {
|
|
setImmediate(() => opts.onQr?.("qr-data"));
|
|
}
|
|
return sock;
|
|
},
|
|
);
|
|
const waitForWaConnection = vi.fn();
|
|
const formatError = vi.fn((err: unknown) => `formatted:${String(err)}`);
|
|
const getStatusCode = vi.fn(
|
|
(err: unknown) =>
|
|
(err as { output?: { statusCode?: number } })?.output?.statusCode ??
|
|
(err as { status?: number })?.status ??
|
|
(err as { error?: { output?: { statusCode?: number } } })?.error?.output?.statusCode,
|
|
);
|
|
const webAuthExists = vi.fn(async () => false);
|
|
const readWebSelfId = vi.fn(() => ({ e164: null, jid: null }));
|
|
const logoutWeb = vi.fn(async () => true);
|
|
const waitForCredsSaveQueueWithTimeout = vi.fn(async () => {});
|
|
return {
|
|
createWaSocket,
|
|
waitForWaConnection,
|
|
formatError,
|
|
getStatusCode,
|
|
webAuthExists,
|
|
readWebSelfId,
|
|
logoutWeb,
|
|
waitForCredsSaveQueueWithTimeout,
|
|
};
|
|
});
|
|
|
|
vi.mock("./qr-image.js", () => ({
|
|
renderQrPngBase64: vi.fn(async () => "base64"),
|
|
}));
|
|
|
|
const createWaSocketMock = vi.mocked(createWaSocket);
|
|
const waitForWaConnectionMock = vi.mocked(waitForWaConnection);
|
|
const waitForCredsSaveQueueWithTimeoutMock = vi.mocked(waitForCredsSaveQueueWithTimeout);
|
|
const logoutWebMock = vi.mocked(logoutWeb);
|
|
|
|
async function flushTasks() {
|
|
await Promise.resolve();
|
|
await Promise.resolve();
|
|
}
|
|
|
|
describe("login-qr", () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it("restarts login once on status 515 and completes", async () => {
|
|
let releaseCredsFlush: (() => void) | undefined;
|
|
const credsFlushGate = new Promise<void>((resolve) => {
|
|
releaseCredsFlush = resolve;
|
|
});
|
|
waitForWaConnectionMock
|
|
// Baileys v7 wraps the error: { error: BoomError(515) }
|
|
.mockRejectedValueOnce({ error: { output: { statusCode: 515 } } })
|
|
.mockResolvedValueOnce(undefined);
|
|
waitForCredsSaveQueueWithTimeoutMock.mockReturnValueOnce(credsFlushGate);
|
|
|
|
const start = await startWebLoginWithQr({ timeoutMs: 5000 });
|
|
expect(start.qrDataUrl).toBe("data:image/png;base64,base64");
|
|
|
|
const resultPromise = waitForWebLogin({ timeoutMs: 5000 });
|
|
await flushTasks();
|
|
await flushTasks();
|
|
|
|
expect(createWaSocketMock).toHaveBeenCalledTimes(1);
|
|
expect(waitForCredsSaveQueueWithTimeoutMock).toHaveBeenCalledOnce();
|
|
expect(waitForCredsSaveQueueWithTimeoutMock).toHaveBeenCalledWith(expect.any(String));
|
|
|
|
releaseCredsFlush?.();
|
|
const result = await resultPromise;
|
|
|
|
expect(result.connected).toBe(true);
|
|
expect(createWaSocketMock).toHaveBeenCalledTimes(2);
|
|
expect(logoutWebMock).not.toHaveBeenCalled();
|
|
});
|
|
});
|