import assert from 'node:assert/strict'; import test from 'node:test'; import { createConnectivityDiagnosticsService, CURL_META_MARKER, } from '../../src/server/services/connectivityDiagnosticsService.js'; function response(body = '', overrides = {}) { return { exitCode: 0, error: '', stderr: '', stdout: `${body}${CURL_META_MARKER}${JSON.stringify({ exitcode: 0, http_code: 204, time_starttransfer: 0.12, time_total: 0.15, ...overrides, })}`, }; } test('connectivity diagnostics force separate direct and VPN paths', async () => { const calls = []; const execute = async (args) => { calls.push(args); const vpn = args.includes('--proxy'); const url = args.at(-1); if (url.includes('cloudflare')) return response(`ip=${vpn ? '203.0.113.20' : '198.51.100.10'}\n`); if (url.includes('api6')) return response(vpn ? '2001:db8::20' : '2001:db8::10'); if (url.includes('ipify')) return response(vpn ? '203.0.113.20' : '198.51.100.10'); return response(); }; const service = createConnectivityDiagnosticsService({ proxyPort: 18080, execute, now: () => '2026-08-07T12:00:00.000Z', }); const result = await service.run({ vpnAvailable: true }); assert.deepEqual(result.direct.ipv4.addresses, ['198.51.100.10']); assert.deepEqual(result.vpn.ipv4.addresses, ['203.0.113.20']); assert.equal(result.direct.ipv6, '2001:db8::10'); assert.equal(result.vpn.ipv6, '2001:db8::20'); assert.equal(result.assessment.summary, 'available'); assert.ok(calls.some((args) => args.includes('--noproxy') && args.includes('*'))); assert.ok(calls.some((args) => args.includes('--proxy') && args.includes('http://127.0.0.1:18080'))); }); test('connectivity diagnostics reports a likely direct restriction without claiming its owner', async () => { const attempts = new Map(); const execute = async (args) => { const vpn = args.includes('--proxy'); const url = args.at(-1); if (url.includes('cloudflare')) return response(`ip=${vpn ? '203.0.113.20' : '198.51.100.10'}\n`); if (url.includes('api6')) return response('', { exitcode: 6, http_code: 0, errormsg: 'resolve failed' }); if (url.includes('ipify')) return response(vpn ? '203.0.113.20' : '198.51.100.10'); const key = `${vpn}:${url}`; attempts.set(key, (attempts.get(key) || 0) + 1); if (!vpn && url.includes('youtube')) { return response('', { exitcode: 28, http_code: 0, errormsg: 'timeout' }); } return response(); }; const result = await createConnectivityDiagnosticsService({ proxyPort: 18080, execute }) .run({ vpnAvailable: true }); assert.equal(result.assessment.summary, 'likely-direct-restriction'); assert.equal( result.assessment.comparisons.find((item) => item.id === 'youtube').assessment, 'likely-direct-restriction', ); assert.equal(attempts.get('false:https://www.youtube.com/generate_204'), 2); }); test('connectivity diagnostics skips VPN probes when sing-box is off', async () => { const calls = []; const execute = async (args) => { calls.push(args); const url = args.at(-1); if (url.includes('cloudflare')) return response('ip=198.51.100.10\n'); if (url.includes('api6')) return response('', { exitcode: 6, http_code: 0, errormsg: 'resolve failed' }); if (url.includes('ipify')) return response('198.51.100.10'); return response(); }; const result = await createConnectivityDiagnosticsService({ proxyPort: 18080, execute }) .run({ vpnAvailable: false }); assert.equal(result.vpn.available, false); assert.equal(result.assessment.summary, 'vpn-off'); assert.equal(calls.some((args) => args.includes('--proxy')), false); }); test('connectivity diagnostics keeps a partial snapshot and falls back when one IP source fails', async () => { const execute = async (args) => { const url = args.at(-1); if (url.includes('cloudflare')) { return response('', { exitcode: 28, http_code: 0, errormsg: 'timeout' }); } if (url.includes('api6')) return response('', { exitcode: 6, http_code: 0, errormsg: 'resolve failed' }); if (url.includes('ipify')) return response('198.51.100.10'); if (url.includes('amazonaws')) return response('198.51.100.10'); return response(); }; const result = await createConnectivityDiagnosticsService({ proxyPort: 18080, execute }) .run({ vpnAvailable: false }); assert.equal(result.direct.internetAvailable, true); assert.deepEqual(result.direct.ipv4.addresses, ['198.51.100.10']); assert.deepEqual(result.direct.ipv4.sources.map((source) => source.source), [ 'cloudflare', 'ipify', 'aws', ]); });