import { describe, expect, it, vi } from "vitest"; import { assertRpaWorkerEnv, isForbiddenQuoteUrl, parseMothershipQuoteUrls, shouldKeepBrowserOpen, shouldKeepBrowserWarm, isParkedSessionEnabled, getRpaPlaceFixMode, validateMothershipQuoteUrls, isWidgetQuoteFallbackEnabled, isPreconfirmedMothershipQuote, resolveBlindAddressFlow, isBlindAddressFlowActive, } from "@/lib/rpa/env"; describe("lib/rpa/env", () => { it("parseMothershipQuoteUrls 解析逗号分隔列表", () => { expect( parseMothershipQuoteUrls( "https://example.com/a , https://example.com/b", ), ).toEqual(["https://example.com/a", "https://example.com/b"]); }); it("isForbiddenQuoteUrl 拦截 dashboard 与 /quote", () => { expect(isForbiddenQuoteUrl("https://dashboard.mothership.com/")).toBe(true); expect(isForbiddenQuoteUrl("https://www.mothership.com/quote")).toBe(true); expect(isForbiddenQuoteUrl("https://ship.mothership.com/rate")).toBe(false); }); it("validateMothershipQuoteUrls 空列表报错", () => { expect(validateMothershipQuoteUrls([])).toContain( "MOTHERSHIP_QUOTE_URLS 未配置或为空", ); }); it("assertRpaWorkerEnv mock 模式跳过校验", () => { vi.stubEnv("RPA_MOCK_MODE", "true"); vi.stubEnv("MOTHERSHIP_QUOTE_URLS", ""); expect(() => assertRpaWorkerEnv()).not.toThrow(); vi.unstubAllEnvs(); }); it("assertRpaWorkerEnv 缺 URL 时 fail-fast", () => { vi.stubEnv("RPA_MOCK_MODE", "false"); vi.stubEnv("MOTHERSHIP_QUOTE_URLS", ""); expect(() => assertRpaWorkerEnv()).toThrow(/MOTHERSHIP_QUOTE_URLS/); vi.unstubAllEnvs(); }); it("assertRpaWorkerEnv 禁止 dashboard URL", () => { vi.stubEnv("RPA_MOCK_MODE", "false"); vi.stubEnv( "MOTHERSHIP_QUOTE_URLS", "https://dashboard.mothership.com/", ); expect(() => assertRpaWorkerEnv()).toThrow(/禁止的报价入口 URL/); vi.unstubAllEnvs(); }); it("shouldKeepBrowserOpen 唯一 config 来源", () => { vi.stubEnv("RPA_KEEP_BROWSER_OPEN", "true"); expect(shouldKeepBrowserOpen()).toBe(true); vi.stubEnv("RPA_KEEP_BROWSER_OPEN", "false"); expect(shouldKeepBrowserOpen()).toBe(false); vi.unstubAllEnvs(); }); it("isRpaHeaded / resolveRpaHeadless:RPA_HEADED 优先", async () => { const { isRpaHeaded, resolveRpaHeadless, resolveRpaSlowMoMs } = await import( "@/lib/rpa/env" ); vi.stubEnv("RPA_HEADED", "true"); vi.stubEnv("RPA_HEADLESS", "true"); expect(isRpaHeaded()).toBe(true); expect(resolveRpaHeadless()).toBe(false); expect(resolveRpaSlowMoMs()).toBe(200); vi.stubEnv("RPA_HEADED", "false"); vi.stubEnv("RPA_HEADLESS", "true"); vi.stubEnv("RPA_SLOW_MO_MS", ""); expect(isRpaHeaded()).toBe(false); expect(resolveRpaHeadless()).toBe(true); expect(resolveRpaSlowMoMs()).toBeUndefined(); vi.unstubAllEnvs(); }); it("shouldKeepBrowserWarm headless 默认保活", () => { vi.stubEnv("RPA_KEEP_BROWSER_WARM", ""); vi.stubEnv("RPA_HEADLESS", "true"); expect(shouldKeepBrowserWarm()).toBe(true); vi.stubEnv("RPA_KEEP_BROWSER_WARM", "false"); expect(shouldKeepBrowserWarm()).toBe(false); vi.unstubAllEnvs(); }); it("isParkedSessionEnabled 默认关,显式 true 才开", () => { vi.stubEnv("RPA_PARKED_SESSION", ""); expect(isParkedSessionEnabled()).toBe(false); vi.stubEnv("RPA_PARKED_SESSION", "true"); expect(isParkedSessionEnabled()).toBe(true); vi.unstubAllEnvs(); }); it("getRpaPlaceFixMode 默认 event,支持 state/legacy", () => { vi.stubEnv("RPA_PLACE_FIX_MODE", ""); expect(getRpaPlaceFixMode()).toBe("event"); vi.stubEnv("RPA_PLACE_FIX_MODE", "state"); expect(getRpaPlaceFixMode()).toBe("state"); vi.stubEnv("RPA_PLACE_FIX_MODE", "legacy"); expect(getRpaPlaceFixMode()).toBe("legacy"); vi.unstubAllEnvs(); }); it("isWidgetQuoteFallbackEnabled 默认开,RPA_DISABLE_WIDGET_QUOTE_FALLBACK=true 关闭", () => { vi.stubEnv("RPA_DISABLE_WIDGET_QUOTE_FALLBACK", ""); expect(isWidgetQuoteFallbackEnabled()).toBe(true); vi.stubEnv("RPA_DISABLE_WIDGET_QUOTE_FALLBACK", "true"); expect(isWidgetQuoteFallbackEnabled()).toBe(false); vi.unstubAllEnvs(); }); it("resolveBlindAddressFlow 对已确认 MotherShip 候选自动启用", () => { vi.stubEnv("RPA_BLIND_ADDRESS_FLOW", "false"); vi.stubEnv("RPA_FAST_QUOTE", "false"); vi.stubEnv("RPA_VISUAL_RUSH", "false"); const req = { pickup: { selectedFromMothership: true, mothershipOptionId: "ChIJ-pickup", placeId: "", }, delivery: { selectedFromMothership: true, mothershipOptionId: "ChIJ-delivery", placeId: "", }, } as Parameters[0]; expect(isPreconfirmedMothershipQuote(req)).toBe(true); expect(resolveBlindAddressFlow(req)).toBe(true); expect( isBlindAddressFlowActive({ state: { blindAddressFlow: true } }), ).toBe(true); vi.unstubAllEnvs(); }); });