import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; const { ProxyAgent, EnvHttpProxyAgent, undiciFetch, proxyAgentSpy, envAgentSpy, getLastAgent } = vi.hoisted(() => { const undiciFetch = vi.fn(); const proxyAgentSpy = vi.fn(); const envAgentSpy = vi.fn(); class ProxyAgent { static lastCreated: ProxyAgent | undefined; proxyUrl: string; constructor(proxyUrl: string) { this.proxyUrl = proxyUrl; ProxyAgent.lastCreated = this; proxyAgentSpy(proxyUrl); } } class EnvHttpProxyAgent { static lastCreated: EnvHttpProxyAgent | undefined; constructor() { EnvHttpProxyAgent.lastCreated = this; envAgentSpy(); } } return { ProxyAgent, EnvHttpProxyAgent, undiciFetch, proxyAgentSpy, envAgentSpy, getLastAgent: () => ProxyAgent.lastCreated, }; }); vi.mock("undici", () => ({ ProxyAgent, EnvHttpProxyAgent, fetch: undiciFetch, })); import { makeProxyFetch, resolveProxyFetchFromEnv } from "./proxy-fetch.js"; describe("makeProxyFetch", () => { beforeEach(() => vi.clearAllMocks()); it("uses undici fetch with ProxyAgent dispatcher", async () => { const proxyUrl = "http://proxy.test:8080"; undiciFetch.mockResolvedValue({ ok: true }); const proxyFetch = makeProxyFetch(proxyUrl); expect(proxyAgentSpy).not.toHaveBeenCalled(); await proxyFetch("https://api.example.com/v1/audio"); expect(proxyAgentSpy).toHaveBeenCalledWith(proxyUrl); expect(undiciFetch).toHaveBeenCalledWith( "https://api.example.com/v1/audio", expect.objectContaining({ dispatcher: getLastAgent() }), ); }); }); describe("resolveProxyFetchFromEnv", () => { beforeEach(() => vi.clearAllMocks()); afterEach(() => vi.unstubAllEnvs()); it("returns undefined when no proxy env vars are set", () => { expect(resolveProxyFetchFromEnv({})).toBeUndefined(); }); it("returns proxy fetch using EnvHttpProxyAgent when HTTPS_PROXY is set", async () => { undiciFetch.mockResolvedValue({ ok: true }); const fetchFn = resolveProxyFetchFromEnv({ HTTP_PROXY: "", HTTPS_PROXY: "http://proxy.test:8080", }); expect(fetchFn).toBeDefined(); expect(envAgentSpy).toHaveBeenCalled(); await fetchFn!("https://api.example.com"); expect(undiciFetch).toHaveBeenCalledWith( "https://api.example.com", expect.objectContaining({ dispatcher: EnvHttpProxyAgent.lastCreated }), ); }); it("returns proxy fetch when HTTP_PROXY is set", () => { const fetchFn = resolveProxyFetchFromEnv({ HTTPS_PROXY: "", HTTP_PROXY: "http://fallback.test:3128", }); expect(fetchFn).toBeDefined(); expect(envAgentSpy).toHaveBeenCalled(); }); it("returns proxy fetch when lowercase https_proxy is set", () => { const fetchFn = resolveProxyFetchFromEnv({ HTTPS_PROXY: "", HTTP_PROXY: "", http_proxy: "", https_proxy: "http://lower.test:1080", }); expect(fetchFn).toBeDefined(); expect(envAgentSpy).toHaveBeenCalled(); }); it("returns proxy fetch when lowercase http_proxy is set", () => { const fetchFn = resolveProxyFetchFromEnv({ HTTPS_PROXY: "", HTTP_PROXY: "", https_proxy: "", http_proxy: "http://lower-http.test:1080", }); expect(fetchFn).toBeDefined(); expect(envAgentSpy).toHaveBeenCalled(); }); it("returns undefined when EnvHttpProxyAgent constructor throws", () => { envAgentSpy.mockImplementationOnce(() => { throw new Error("Invalid URL"); }); const fetchFn = resolveProxyFetchFromEnv({ HTTP_PROXY: "", https_proxy: "", http_proxy: "", HTTPS_PROXY: "not-a-valid-url", }); expect(fetchFn).toBeUndefined(); }); });