-
Notifications
You must be signed in to change notification settings - Fork 8.6k
Expand file tree
/
Copy pathclash-builder.test.js
More file actions
140 lines (117 loc) · 4.24 KB
/
clash-builder.test.js
File metadata and controls
140 lines (117 loc) · 4.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import { describe, it, expect } from 'vitest';
import yaml from 'js-yaml';
import { createTranslator } from '../src/i18n/index.js';
import { ClashConfigBuilder } from '../src/builders/ClashConfigBuilder.js';
import { sanitizeClashProxyGroups } from '../src/builders/helpers/clashConfigUtils.js';
// Create translator for tests
const t = createTranslator('zh-CN');
describe('Clash Builder Tests', () => {
it('should clean up proxy-groups and remove non-existent proxies', async () => {
const input = `
proxies:
- name: Valid-SS
type: ss
server: example.com
port: 443
cipher: aes-128-gcm
password: test
proxy-groups:
- name: 自定义选择
type: select
proxies:
- DIRECT
- REJECT
- Valid-SS
- NotExist
`;
const builder = new ClashConfigBuilder(input, 'minimal', [], null, 'zh-CN', 'test-agent');
const yamlText = await builder.build();
const built = yaml.load(yamlText);
const grp = (built['proxy-groups'] || []).find(g => g && g.name === '自定义选择');
expect(grp).toBeDefined();
const expected = ['DIRECT', 'REJECT', 'Valid-SS'];
const actual = grp.proxies || [];
expect(actual).toEqual(expected);
});
it('should reference user-defined proxy-providers in generated proxy-groups', async () => {
const input = `
proxy-providers:
my-provider:
type: http
url: https://example.com/sub
path: ./my.yaml
interval: 3600
proxies:
- name: local
type: ss
server: 127.0.0.1
port: 1080
cipher: aes-256-gcm
password: test
`;
const builder = new ClashConfigBuilder(input, 'minimal', [], null, 'zh-CN', 'test-agent');
const yamlText = await builder.build();
const built = yaml.load(yamlText);
const nodeSelect = (built['proxy-groups'] || []).find(g => g && g.name === '🚀 节点选择');
expect(nodeSelect).toBeDefined();
expect(nodeSelect.use).toContain('my-provider');
});
it('sanitizeClashProxyGroups should not remove provider node references when group uses providers', () => {
const config = {
proxies: [],
'proxy-groups': [
{
name: 'Custom Group',
type: 'select',
use: ['my-provider'],
proxies: ['node-from-provider']
}
]
};
sanitizeClashProxyGroups(config);
const grp = (config['proxy-groups'] || [])[0];
expect(grp).toBeDefined();
expect(grp.proxies).toContain('node-from-provider');
});
it('should default Private and Location:CN groups to DIRECT', async () => {
const input = `
ss://YWVzLTEyOC1nY206dGVzdA@example.com:443#HK-Node-1
ss://YWVzLTEyOC1nY206dGVzdA@example.com:444#US-Node-1
`;
const builder = new ClashConfigBuilder(input, 'minimal', [], null, 'zh-CN', 'test-agent');
const yamlText = await builder.build();
const built = yaml.load(yamlText);
const privateName = t('outboundNames.Private');
const cnName = t('outboundNames.Location:CN');
const privateGroup = (built['proxy-groups'] || []).find(g => g && g.name === privateName);
const cnGroup = (built['proxy-groups'] || []).find(g => g && g.name === cnName);
expect(privateGroup).toBeDefined();
expect(cnGroup).toBeDefined();
// DIRECT should be the first option (default selected)
expect(privateGroup.proxies[0]).toBe('DIRECT');
expect(cnGroup.proxies[0]).toBe('DIRECT');
// Other groups should NOT default to DIRECT
const fallbackName = t('outboundNames.Fall Back');
const fallbackGroup = (built['proxy-groups'] || []).find(g => g && g.name === fallbackName);
expect(fallbackGroup).toBeDefined();
expect(fallbackGroup.proxies[0]).not.toBe('DIRECT');
});
it('should enable local TUN-compatible defaults in Clash config', async () => {
const input = `
ss://YWVzLTEyOC1nY206dGVzdA@example.com:443#HK-Node-1
`;
const builder = new ClashConfigBuilder(input, 'minimal', [], null, 'zh-CN', 'test-agent');
const yamlText = await builder.build();
const built = yaml.load(yamlText);
expect(built.dns.ipv6).toBe(false);
expect(built.tun).toEqual({
enable: true,
stack: 'mixed',
'dns-hijack': ['any:53', 'tcp://any:53'],
'auto-route': true,
'auto-redirect': true,
'auto-detect-interface': true,
'strict-route': true,
});
});
});