import { PacProxyAgent } from 'pac-proxy-agent'; import { SocksProxyAgent } from 'socks-proxy-agent'; import { ProxyAgent } from 'undici'; import { afterEach, describe, expect, it, vi } from 'vitest'; const loadProxy = async (env: Record) => { vi.resetModules(); for (const [key, value] of Object.entries(env)) { vi.stubEnv(key, value); } return (await import('@/utils/proxy')).default; }; describe('proxy', () => { afterEach(() => { vi.clearAllTimers(); vi.useRealTimers(); vi.unstubAllEnvs(); }); it('uses PAC proxy when PAC_URI is set', async () => { const proxy = await loadProxy({ PAC_URI: 'http://example.com/proxy.pac', PROXY_URIS: '', PROXY_URI: '', }); expect(proxy.agent).toBeInstanceOf(PacProxyAgent); expect(proxy.dispatcher).toBeNull(); expect(proxy.proxyUri).toBe('http://example.com/proxy.pac'); const current = proxy.getCurrentProxy(); expect(current?.uri).toBe('http://example.com/proxy.pac'); }); it('handles multi-proxy selection and updates after failures', async () => { const proxy = await loadProxy({ PROXY_URIS: 'http://proxy1.local:8080,http://proxy2.local:8081', PAC_URI: '', PROXY_URI: '', }); expect(proxy.multiProxy).toBeDefined(); const current = proxy.getCurrentProxy(); expect(current).not.toBeNull(); expect(proxy.getDispatcherForProxy(current!)).toBeInstanceOf(ProxyAgent); expect(proxy.getAgentForProxy({ uri: 'socks5://proxy.local:1080' } as any)).toBeInstanceOf(SocksProxyAgent); proxy.markProxyFailed(current!.uri); const next = proxy.getCurrentProxy(); expect(next).not.toBeNull(); }); it('clears proxy when multi-proxy has no valid entries', async () => { const proxy = await loadProxy({ PROXY_URIS: 'http://inv lid.test', PAC_URI: '', PROXY_URI: '', }); expect(proxy.getCurrentProxy()).toBeNull(); proxy.markProxyFailed('http://inv lid.test'); expect(proxy.agent).toBeNull(); expect(proxy.dispatcher).toBeNull(); expect(proxy.proxyUri).toBeUndefined(); }); it('creates a socks proxy agent for single proxy settings', async () => { const proxy = await loadProxy({ PROXY_URI: 'socks5://proxy.local:1080', PROXY_URIS: '', PAC_URI: '', }); expect(proxy.agent).toBeInstanceOf(SocksProxyAgent); expect(proxy.dispatcher).toBeNull(); expect(proxy.getCurrentProxy()?.uri).toBe('socks5://proxy.local:1080'); }); it('returns null agent for unsupported proxy protocol', async () => { const proxy = await loadProxy({ PROXY_URI: '', PROXY_URIS: '', PAC_URI: '', }); expect(proxy.getAgentForProxy({ uri: 'ftp://proxy.local:21' } as any)).toBeNull(); }); });