Skip to content

Commit 43c5fc2

Browse files
committed
chore: 补全测试
1 parent 690b2c1 commit 43c5fc2

3 files changed

Lines changed: 161 additions & 0 deletions

File tree

backend/src/test/proxy-parsers/uri.spec.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,37 @@ describe('Proxy URI parser coverage', function () {
9797
});
9898
});
9999

100+
it('parses shadowsocks v2ray-plugin URI flags for sni, skip-cert-verify, and mux', function () {
101+
const userInfo = encodeURIComponent(
102+
Base64.encode('aes-128-gcm:secret'),
103+
);
104+
const plugin = encodeURIComponent(
105+
'v2ray-plugin;obfs=websocket;host=cdn.example.com;path=/socket;tls;sni=sni.example.com;skip-cert-verify=1;mux=1',
106+
);
107+
const proxy = parseOne(
108+
`ss://${userInfo}@ss.example.com:443/?plugin=${plugin}#SS%20V2ray%20Flags`,
109+
);
110+
111+
expectSubset(proxy, {
112+
type: 'ss',
113+
name: 'SS V2ray Flags',
114+
server: 'ss.example.com',
115+
port: 443,
116+
cipher: 'aes-128-gcm',
117+
password: 'secret',
118+
plugin: 'v2ray-plugin',
119+
'plugin-opts': {
120+
mode: 'websocket',
121+
host: 'cdn.example.com',
122+
path: '/socket',
123+
tls: true,
124+
sni: 'sni.example.com',
125+
'skip-cert-verify': true,
126+
mux: 1,
127+
},
128+
});
129+
});
130+
100131
it('parses v2ray-plugin paths containing escaped equals signs', function () {
101132
const userInfo = encodeURIComponent(
102133
Base64.encode('aes-128-gcm:secret'),

backend/src/test/proxy-producers/structured.spec.js

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,57 @@ describe('Proxy structured producers', function () {
520520
});
521521
});
522522

523+
it('normalizes numeric v2ray-plugin mux values across Clash-family YAML producers', function () {
524+
const buildProxy = (name, mux) => ({
525+
type: 'ss',
526+
name,
527+
server: 'ss.example.com',
528+
port: 8388,
529+
cipher: 'aes-128-gcm',
530+
password: 'secret',
531+
'skip-cert-verify': false,
532+
plugin: 'v2ray-plugin',
533+
'plugin-opts': {
534+
mode: 'websocket',
535+
host: 'cdn.example.com',
536+
path: '/socket',
537+
tls: true,
538+
'skip-cert-verify': true,
539+
mux,
540+
},
541+
});
542+
543+
for (const platform of [
544+
'Clash',
545+
'ClashMeta',
546+
'Shadowrocket',
547+
'Stash',
548+
]) {
549+
const internal = produceInternal(platform, [
550+
buildProxy(`${platform} Mux On`, 1),
551+
buildProxy(`${platform} Mux Off`, 0),
552+
]);
553+
554+
expect(internal, platform).to.have.length(2);
555+
expectSubset(internal[0], {
556+
name: `${platform} Mux On`,
557+
'plugin-opts': {
558+
tls: true,
559+
'skip-cert-verify': true,
560+
mux: true,
561+
},
562+
});
563+
expectSubset(internal[1], {
564+
name: `${platform} Mux Off`,
565+
'plugin-opts': {
566+
tls: true,
567+
'skip-cert-verify': true,
568+
mux: false,
569+
},
570+
});
571+
}
572+
});
573+
523574
it('skips invalid Egern nodes and keeps the rest of the subscription', function () {
524575
const proxies = [
525576
{
@@ -558,6 +609,55 @@ describe('Proxy structured producers', function () {
558609
});
559610
});
560611

612+
it('keeps normalized v2ray-plugin mux state in sing-box plugin opts', function () {
613+
const buildProxy = (name, mux) => ({
614+
type: 'ss',
615+
name,
616+
server: 'ss.example.com',
617+
port: 8388,
618+
cipher: 'aes-128-gcm',
619+
password: 'secret',
620+
plugin: 'v2ray-plugin',
621+
'plugin-opts': {
622+
mode: 'websocket',
623+
host: 'cdn.example.com',
624+
path: '/socket',
625+
tls: true,
626+
mux,
627+
},
628+
});
629+
630+
const output = loadProducedJson('sing-box', [
631+
buildProxy('Sing-box Mux On', 1),
632+
buildProxy('Sing-box Mux Off', 0),
633+
]);
634+
const muxOn = output.outbounds.find(
635+
(outbound) => outbound.tag === 'Sing-box Mux On',
636+
);
637+
const muxOff = output.outbounds.find(
638+
(outbound) => outbound.tag === 'Sing-box Mux Off',
639+
);
640+
641+
expect(output.outbounds).to.have.length(2);
642+
expectSubset(muxOn, {
643+
tag: 'Sing-box Mux On',
644+
type: 'shadowsocks',
645+
plugin: 'v2ray-plugin',
646+
multiplex: {
647+
enabled: true,
648+
},
649+
});
650+
expect(muxOn.plugin_opts).to.include('mux=true');
651+
652+
expectSubset(muxOff, {
653+
tag: 'Sing-box Mux Off',
654+
type: 'shadowsocks',
655+
plugin: 'v2ray-plugin',
656+
});
657+
expect(muxOff).to.not.have.property('multiplex');
658+
expect(muxOff.plugin_opts).to.include('mux=false');
659+
});
660+
561661
it('emits sing-box outbounds with reality tls and websocket transport', function () {
562662
const output = loadProducedJson('sing-box', {
563663
type: 'vless',

backend/src/test/proxy-producers/text.spec.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,36 @@ describe('Proxy text producers', function () {
241241
expect(output).to.not.include('Forced Mihomo=tuic-v5');
242242
});
243243

244+
it('produces URI shadowsocks links with v2ray-plugin mux and tls flags', function () {
245+
const plugin = encodeURIComponent(
246+
'v2ray-plugin;obfs=websocket;obfs-host=cdn.example.com;host=cdn.example.com;path=/socket;tls;sni=sni.example.com;skip-cert-verify=true;mux=0',
247+
);
248+
const output = produceExternal('URI', {
249+
type: 'ss',
250+
name: 'SS V2ray Flags',
251+
server: 'ss.example.com',
252+
port: 443,
253+
cipher: 'aes-128-gcm',
254+
password: 'secret',
255+
plugin: 'v2ray-plugin',
256+
'plugin-opts': {
257+
mode: 'websocket',
258+
host: 'cdn.example.com',
259+
path: '/socket',
260+
tls: true,
261+
sni: 'sni.example.com',
262+
'skip-cert-verify': true,
263+
mux: 0,
264+
},
265+
});
266+
267+
expect(output).to.equal(
268+
`ss://${Base64.encode(
269+
'aes-128-gcm:secret',
270+
)}@ss.example.com:443/?plugin=${plugin}#SS%20V2ray%20Flags`,
271+
);
272+
});
273+
244274
it('produces URI VLESS reality websocket links', function () {
245275
const output = produceExternal('URI', {
246276
type: 'vless',

0 commit comments

Comments
 (0)