import assert from 'node:assert/strict'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import test from 'node:test'; process.env.APP_MODE = 'client'; process.env.DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'vpn-proxy-client-test-')); process.env.SING_BOX_CACHE = path.join(process.env.DATA_DIR, 'cache.db'); const { buildGatewayConfig } = await import(`../../src/server/singbox.js?client=${Date.now()}`); const subscriptionConfig = { outbounds: [{ type: 'vless', tag: 'test-vpn', server: 'vpn.example.test', server_port: 443, uuid: '00000000-0000-4000-8000-000000000000', tls: { enabled: true }, }], }; test('client exposes one local proxy and routes it through the selected VPN', () => { const config = buildGatewayConfig(subscriptionConfig, 'test-vpn'); assert.deepEqual(config.inbounds.map((inbound) => inbound.tag), ['mixed-in']); assert.equal(config.inbounds[0].listen_port, 8082); assert.deepEqual(config.route.rules, [ { domain_suffix: ['ru'], outbound: 'direct' }, { inbound: ['mixed-in'], outbound: 'test-vpn' }, ]); assert.equal(config.route.final, 'test-vpn'); assert.equal(config.route.auto_detect_interface, undefined); }); test('client keeps its local proxy but routes directly when Harbor Gateway is ahead', () => { const config = buildGatewayConfig(subscriptionConfig, 'test-vpn', { clientDirect: true }); assert.deepEqual(config.route.rules, [ { domain_suffix: ['ru'], outbound: 'direct' }, { inbound: ['mixed-in'], outbound: 'direct' }, ]); assert.equal(config.route.final, 'direct'); assert.deepEqual(config.outbounds.map((outbound) => outbound.tag), ['direct', 'block']); });