import { beforeEach, describe, expect, it, vi } from "vitest"; import type { FlockRunQuoteResult } from "@/workers/rpa/flock/types"; const visualChainMock = vi.fn<() => Promise>(); vi.mock("@/workers/rpa/flock/visual-chain", () => ({ runFlockVisualChain: () => visualChainMock(), })); describe("runFlockVisualChainWithRotations", () => { beforeEach(() => { visualChainMock.mockReset(); process.env.FLOCK_SESSION_MAX_ROTATIONS = "3"; }); it("拒号时换邮箱重试直至成功", async () => { visualChainMock .mockResolvedValueOnce({ ok: false, quotes: [], errorMessage: "FLOCK_ACCOUNT_REJECTED:issue creating your account", }) .mockResolvedValueOnce({ ok: true, quotes: [{ tier: "standard", totalUsd: 100 } as FlockRunQuoteResult["quotes"][0]], }); const { runFlockVisualChainWithRotations } = await import( "@/workers/rpa/flock/run-quote" ); const result = await runFlockVisualChainWithRotations({ pickupZip: "94102", deliveryZip: "90212", pickupDate: "2026-07-20", palletCount: 4, totalWeightLb: 2800, lengthIn: 48, widthIn: 40, heightIn: 48, }); expect(result.ok).toBe(true); expect(visualChainMock).toHaveBeenCalledTimes(2); }); it("报价上限时不轮换", async () => { visualChainMock.mockResolvedValue({ ok: false, quotes: [], errorMessage: "FLOCK_QUOTE_LIMIT:Thank you for your interest", }); const { runFlockVisualChainWithRotations } = await import( "@/workers/rpa/flock/run-quote" ); const result = await runFlockVisualChainWithRotations({ pickupZip: "94102", deliveryZip: "90212", pickupDate: "2026-07-20", palletCount: 4, totalWeightLb: 2800, lengthIn: 48, widthIn: 40, heightIn: 48, }); expect(result.ok).toBe(false); expect(visualChainMock).toHaveBeenCalledTimes(1); }); });