import assert from 'node:assert/strict'; import test from 'node:test'; import { parseSubscriptionBody, selectRefreshedServer, } from '../../src/server/subscription.js'; const parse = (outbounds) => parseSubscriptionBody(JSON.stringify({ outbounds })); const outbound = (tag, server, server_port = 443) => ({ type: 'vless', tag, server, server_port, }); test('duplicate labels remain independently addressable by stable ID', () => { const { config, servers } = parse([ outbound('Amsterdam', 'nl-1.example'), outbound('Amsterdam', 'nl-2.example'), ]); assert.equal(servers.length, 2); assert.equal(servers[0].label, 'Amsterdam'); assert.equal(servers[1].label, 'Amsterdam'); assert.notEqual(servers[0].id, servers[1].id); assert.deepEqual(config.outbounds.map((item) => item.tag), servers.map((server) => server.id)); }); test('provider reorder does not change server IDs or selection', () => { const before = parse([outbound('DE', 'de.example'), outbound('NL', 'nl.example')]).servers; const after = parse([outbound('NL', 'nl.example'), outbound('DE', 'de.example')]).servers; const selectedId = before[1].id; assert.deepEqual( new Map(after.map((server) => [server.host, server.id])), new Map(before.map((server) => [server.host, server.id])), ); assert.equal(selectRefreshedServer(selectedId, before, after), selectedId); }); test('cosmetic rename keeps selection for the same endpoint', () => { const before = parse([outbound('Old name', 'nl.example')]).servers; const after = parse([outbound('New name', 'nl.example')]).servers; assert.equal(after[0].id, before[0].id); assert.equal(selectRefreshedServer(before[0].id, before, after), before[0].id); }); test('removed selected server requires an explicit new choice', () => { const before = parse([outbound('DE', 'de.example'), outbound('NL', 'nl.example')]).servers; const after = parse([outbound('DE', 'de.example')]).servers; assert.equal(selectRefreshedServer(before[1].id, before, after), ''); assert.equal(selectRefreshedServer('', before, after), ''); });