Files
harbor-net/test/server/singbox-client-mode.test.js
T
dokril 7c255192b0
Build and Deploy Gateway / build-and-push (push) Successful in 35s
Build and Deploy Gateway / deploy (push) Successful in 14s
Update Harbor client and gateway functionality
2026-08-17 15:23:16 +03:00

78 lines
2.8 KiB
JavaScript

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(`../../dist/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 preserves mixed user-rule order before fallback', () => {
const config = buildGatewayConfig(subscriptionConfig, 'test-vpn', {
routeRules: [
{ type: 'domain', value: 'api.example.com', enabled: true, outbound: 'vpn' },
{ type: 'domain_suffix', value: 'example.com', enabled: true, outbound: 'direct' },
{ type: 'domain_keyword', value: 'cdn', enabled: false, outbound: 'vpn' },
],
});
assert.deepEqual(config.inbounds.map((inbound) => inbound.tag), [
'mixed-in',
'diagnostics-vpn-in',
]);
assert.equal(config.inbounds[0].listen_port, 8082);
assert.equal(config.inbounds[1].listen_port, 18080);
assert.deepEqual(config.route.rules, [
{
inbound: ['mixed-in', 'diagnostics-vpn-in'],
action: 'sniff',
sniffer: ['http', 'tls', 'quic'],
timeout: '1s',
},
{ inbound: ['diagnostics-vpn-in'], outbound: 'test-vpn' },
{ domain: ['api.example.com'], outbound: 'test-vpn' },
{ domain_suffix: ['example.com'], 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,
routeRules: [
{ type: 'domain', value: 'api.example.com', enabled: true, outbound: 'vpn' },
{ type: 'domain_suffix', value: 'example.com', enabled: true, outbound: 'direct' },
],
});
assert.deepEqual(config.route.rules, [
{
inbound: ['mixed-in', 'diagnostics-vpn-in'],
action: 'sniff',
sniffer: ['http', 'tls', 'quic'],
timeout: '1s',
},
{ inbound: ['diagnostics-vpn-in'], outbound: 'test-vpn' },
{ inbound: ['mixed-in'], outbound: 'direct' },
]);
assert.equal(config.route.final, 'direct');
assert.deepEqual(config.outbounds.map((outbound) => outbound.tag), ['test-vpn', 'direct']);
assert.equal(config.route.rules.some((rule) => Object.keys(rule).some((key) => key.startsWith('domain'))), false);
});