import { describe, expect, it } from 'vitest' import { applySourceDshHttpProxy, isSocksProxyUrl, parseSourceDshHttpProxyFile, shouldReexecSourceDshForFetchProxy, SOURCE_DSH_PROXY_REEXEC_MARKER, sourceDshHttpProxyOverlayPresent, } from './apply-source-dsh-http-proxy.ts' describe('applySourceDshHttpProxy', () => { it('leaves the inherited environment unchanged when no overlay is set', () => { const env: NodeJS.ProcessEnv = { HTTPS_PROXY: 'socks5h://127.0.0.1:1080' } applySourceDshHttpProxy({ env, fileText: null }) expect(env.HTTPS_PROXY).toBe('socks5h://127.0.0.1:1080') expect(env.NODE_USE_ENV_PROXY).toBeUndefined() }) it('overwrites inherited SOCKS with DSH_HTTP_PROXY for this process only', () => { const env: NodeJS.ProcessEnv = { HTTPS_PROXY: 'socks5h://127.0.0.1:1080', ALL_PROXY: 'socks5h://127.0.0.1:1080', } applySourceDshHttpProxy({ env, fileText: null, overlayUrl: 'http://127.0.0.1:3067' }) expect(env.HTTPS_PROXY).toBe('http://127.0.0.1:3067') expect(env.HTTP_PROXY).toBe('http://127.0.0.1:3067') expect(env.ALL_PROXY).toBe('http://127.0.0.1:3067') expect(env.https_proxy).toBe('http://127.0.0.1:3067') expect(env.NODE_USE_ENV_PROXY).toBe('1') expect(env.NO_PROXY).toBe('localhost,127.0.0.1,::1') }) it('applies a checkout overlay file and outranks it with DSH_HTTP_PROXY', () => { const env: NodeJS.ProcessEnv = {} const fileText = [ 'HTTPS_PROXY=http://127.0.0.1:3067', 'NODE_USE_ENV_PROXY=1', '# comment', '', ].join('\n') applySourceDshHttpProxy({ env, fileText }) expect(env.HTTPS_PROXY).toBe('http://127.0.0.1:3067') expect(env.NODE_USE_ENV_PROXY).toBe('1') applySourceDshHttpProxy({ env, fileText, overlayUrl: 'http://127.0.0.1:8080' }) expect(env.HTTPS_PROXY).toBe('http://127.0.0.1:8080') }) it('replaces inherited SOCKS on names the overlay file omitted', () => { const env: NodeJS.ProcessEnv = { HTTPS_PROXY: 'socks5h://proxy.home:4067', ALL_PROXY: 'socks5h://proxy.home:4067', } applySourceDshHttpProxy({ env, fileText: 'HTTPS_PROXY=http://127.0.0.1:3067\nNODE_USE_ENV_PROXY=1\n', }) expect(env.HTTPS_PROXY).toBe('http://127.0.0.1:3067') expect(env.ALL_PROXY).toBe('http://127.0.0.1:3067') expect(env.HTTP_PROXY).toBe('http://127.0.0.1:3067') expect(env.NODE_USE_ENV_PROXY).toBe('1') }) it('rejects a SOCKS overlay before the CLI boots', () => { expect(() => applySourceDshHttpProxy({ env: {}, fileText: null, overlayUrl: 'socks5h://127.0.0.1:1080', })).toThrow(/cannot fetch through SOCKS/) expect(() => applySourceDshHttpProxy({ env: {}, fileText: 'ALL_PROXY=socks5://127.0.0.1:1080\n', })).toThrow(/cannot fetch through SOCKS/) }) }) describe('parseSourceDshHttpProxyFile', () => { it('parses quoted values and export lines', () => { expect(parseSourceDshHttpProxyFile('export HTTPS_PROXY="http://127.0.0.1:3067"\n')).toEqual({ HTTPS_PROXY: 'http://127.0.0.1:3067', }) }) it('detects SOCKS schemes', () => { expect(isSocksProxyUrl('socks5h://127.0.0.1:1080')).toBe(true) expect(isSocksProxyUrl('http://127.0.0.1:3067')).toBe(false) }) }) describe('shouldReexecSourceDshForFetchProxy', () => { it('respawns once when an overlay is present so fetch binds HTTP_PROXY at start', () => { expect(sourceDshHttpProxyOverlayPresent(undefined, null)).toBe(false) expect(shouldReexecSourceDshForFetchProxy({}, false)).toBe(false) expect(shouldReexecSourceDshForFetchProxy({}, true)).toBe(true) expect(shouldReexecSourceDshForFetchProxy({ [SOURCE_DSH_PROXY_REEXEC_MARKER]: '1' }, true)).toBe(false) }) })