/ src / node-network.test.ts
node-network.test.ts
 1  import { describe, expect, it } from 'vitest';
 2  
 3  import { decideProxy, hasProxyEnv } from './node-network.js';
 4  
 5  describe('node network proxy decisions', () => {
 6    it('detects common proxy env variables', () => {
 7      expect(hasProxyEnv({ https_proxy: 'http://127.0.0.1:7897' })).toBe(true);
 8      expect(hasProxyEnv({ HTTP_PROXY: 'http://proxy.example:8080' })).toBe(true);
 9      expect(hasProxyEnv({})).toBe(false);
10    });
11  
12    it('routes external https traffic through https_proxy', () => {
13      const decision = decideProxy(
14        new URL('https://www.v2ex.com/api/topics/latest.json'),
15        { https_proxy: 'http://127.0.0.1:7897' },
16      );
17  
18      expect(decision).toEqual({
19        mode: 'proxy',
20        proxyUrl: 'http://127.0.0.1:7897',
21      });
22    });
23  
24    it('falls back to HTTP_PROXY for https traffic when HTTPS_PROXY is absent', () => {
25      const decision = decideProxy(
26        new URL('https://www.v2ex.com/api/topics/latest.json'),
27        { HTTP_PROXY: 'http://127.0.0.1:7897' },
28      );
29  
30      expect(decision).toEqual({
31        mode: 'proxy',
32        proxyUrl: 'http://127.0.0.1:7897',
33      });
34    });
35  
36    it('bypasses proxies for loopback addresses', () => {
37      const env = { https_proxy: 'http://127.0.0.1:7897', http_proxy: 'http://127.0.0.1:7897' };
38  
39      expect(decideProxy(new URL('http://127.0.0.1:19825/status'), env)).toEqual({ mode: 'direct' });
40      expect(decideProxy(new URL('http://localhost:19825/status'), env)).toEqual({ mode: 'direct' });
41      expect(decideProxy(new URL('http://[::1]:19825/status'), env)).toEqual({ mode: 'direct' });
42    });
43  
44    it('honors NO_PROXY domain matches', () => {
45      const decision = decideProxy(
46        new URL('https://api.example.com/v1/items'),
47        {
48          https_proxy: 'http://127.0.0.1:7897',
49          no_proxy: '.example.com',
50        },
51      );
52  
53      expect(decision).toEqual({ mode: 'direct' });
54    });
55  
56    it('supports wildcard-style NO_PROXY subdomain entries', () => {
57      const decision = decideProxy(
58        new URL('https://api.example.com/v1/items'),
59        {
60          https_proxy: 'http://127.0.0.1:7897',
61          no_proxy: '*.example.com',
62        },
63      );
64  
65      expect(decision).toEqual({ mode: 'direct' });
66    });
67  
68    it('matches NO_PROXY entries that rely on the default URL port', () => {
69      const env = { https_proxy: 'http://127.0.0.1:7897', http_proxy: 'http://127.0.0.1:7897' };
70  
71      expect(decideProxy(
72        new URL('https://example.com/'),
73        { ...env, NO_PROXY: 'example.com:443' },
74      )).toEqual({ mode: 'direct' });
75  
76      expect(decideProxy(
77        new URL('http://example.com/health'),
78        { ...env, NO_PROXY: 'example.com:80' },
79      )).toEqual({ mode: 'direct' });
80    });
81  
82    it('falls back to ALL_PROXY when protocol-specific settings are absent', () => {
83      const decision = decideProxy(
84        new URL('http://example.net/data'),
85        { ALL_PROXY: 'socks5://127.0.0.1:1080' },
86      );
87  
88      expect(decision).toEqual({
89        mode: 'proxy',
90        proxyUrl: 'socks5://127.0.0.1:1080',
91      });
92    });
93  });