Spaces:
Paused
Paused
| 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<string, string>) => { | |
| 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(); | |
| }); | |
| }); | |