import assert from 'node:assert/strict'; import test from 'node:test'; import { canAppendRouteRule, normalizeRouteRules } from '../../dist/shared/routingRules.js'; test('local route rules normalize URLs, suffixes and duplicates', () => { assert.deepEqual(normalizeRouteRules([ { type: 'domain', value: 'https://Example.com/news?id=1', outbound: 'vpn' }, { type: 'domain_suffix', value: '*.Example.org', outbound: 'direct' }, { type: 'domain_keyword', value: ' CDN ', outbound: 'vpn' }, { type: 'domain', value: 'example.com', outbound: 'direct' }, { type: 'domain_suffix', value: '.ru', enabled: false, outbound: 'direct' }, ], { strict: true }), [ { type: 'domain', value: 'example.com', enabled: true, outbound: 'vpn' }, { type: 'domain_suffix', value: 'example.org', enabled: true, outbound: 'direct' }, { type: 'domain_keyword', value: 'cdn', enabled: true, outbound: 'vpn' }, { type: 'domain_suffix', value: 'ru', enabled: false, outbound: 'direct' }, ]); assert.equal(canAppendRouteRule([{ value: 'filled' }]), true); assert.equal(canAppendRouteRule([{ value: '' }]), false); }); test('invalid local route rules fail at the strict boundary', () => { assert.throws( () => normalizeRouteRules([{ type: 'domain_regex', value: '.*', outbound: 'direct' }], { strict: true }), /Invalid domain rule type/, ); assert.throws( () => normalizeRouteRules([{ type: 'domain_keyword', value: 'bad/path', outbound: 'direct' }], { strict: true }), /Invalid domain rule value/, ); assert.throws( () => normalizeRouteRules([{ type: 'domain', value: 'example.com' }], { strict: true }), /outbound is required/, ); assert.throws( () => normalizeRouteRules([{ type: 'domain', value: 'example.com', outbound: 'block' }], { strict: true }), /Invalid route rule outbound/, ); }); test('legacy rules default to direct while order and first duplicate stay canonical', () => { assert.deepEqual(normalizeRouteRules([ { type: 'domain_suffix', value: 'example.com' }, { type: 'domain', value: 'api.example.com', outbound: 'vpn' }, { type: 'domain_suffix', value: 'example.com', outbound: 'vpn' }, ]), [ { type: 'domain_suffix', value: 'example.com', enabled: true, outbound: 'direct' }, { type: 'domain', value: 'api.example.com', enabled: true, outbound: 'vpn' }, ]); });