Refactor VPN proxy components and update related behavior
Build and Deploy Gateway / build-and-push (push) Successful in 20s
Build and Deploy Gateway / deploy (push) Successful in 13s

This commit is contained in:
2026-08-11 01:27:46 +03:00
parent c89e56942a
commit aa9c959368
58 changed files with 4234 additions and 2755 deletions
+14 -3
View File
@@ -26,17 +26,28 @@ test('connection feature is the sole always-mounted power panel owner', () => {
test('connection feature preserves actions, local preference and opaque neighbor slots', () => {
assert.doesNotMatch(panel, /from ['"][^'"]*\/api\/|\bapi\./);
assert.doesNotMatch(panel, /setInterval|setTimeout|useState\([^)]*state|useReducer/);
assert.match(panel, /connectionAction\(\{ connected, selectedServerId, configExists: configured \}\)/);
assert.match(panel, /action\?\.type === 'stop'[\s\S]*action\?\.type === 'apply'[\s\S]*action\?\.type === 'restart'/);
assert.match(panel, /connectionAction\(\{ connected, selectedServerId \}\)/);
assert.match(panel, /action\?\.type === 'stop'[\s\S]*action\?\.type === 'apply'/);
assert.doesNotMatch(panel, /action\?\.type === 'restart'/);
assert.match(panel, /if \(!await onStop\(\)\) return;[\s\S]*setConfirmingStop\(false\)/);
assert.match(panel, /localStorage\.getItem\(DURATION_MODE_STORAGE_KEY\) === 'words'[\s\S]*localStorage\.setItem\(DURATION_MODE_STORAGE_KEY, nextMode\)/);
assert.match(panel, /client-state-detail[\s\S]*\{routingSlot\}[\s\S]*client-state-copy[\s\S]*\{serverSlot\}[\s\S]*client-proxies[\s\S]*\{statusSlot\}/);
assert.match(page, /routingSlot=\{<RoutingPendingStatus[\s\S]*blocked=\{connectionBlocked\}[\s\S]*onRestart=\{onRestart\}/);
assert.match(routing, /client-route-rules-pending[\s\S]*Перезапустить VPN/);
assert.match(page, /serverSlot=\{isGateway && <div className="client-gateway-route-summary"/);
assert.match(page, /serverSlot=\{<AppliedIdentity identity=\{mainIdentity\} operation=\{switchIdentity\} \/>\}/);
assert.match(page, /mainIdentity[\s\S]*appliedProfile[\s\S]*appliedServer/);
assert.match(page, /statusSlot=\{<>[\s\S]*InlineError[\s\S]*InlineProgress/);
});
test('gateway-direct is remote-owned even when the local runtime is stopped', () => {
assert.match(page, /const mainIdentity = gatewayDirect[\s\S]*Gateway · сервер не определён[\s\S]*: connected/);
assert.match(page, /const switchIdentity = gatewayDirect[\s\S]*Данные применённого сервера Gateway недоступны/);
assert.match(panel, /const remoteOwned = !isGateway && gatewayDirect/);
assert.match(panel, /const powerUnavailable = remoteOwned \|\| \(!connected && !canStart\)/);
assert.match(panel, /aria-checked=\{connected \|\| remoteOwned\}[\s\S]*disabled=\{blocked \|\| powerUnavailable\}/);
assert.match(panel, /remoteOwned[\s\S]*Подключением управляет Harbor Gateway[\s\S]*Gateway подключён/);
});
test('shared clock, copy feedback and live announcement stay single-owned by the page', () => {
const pageBody = page.slice(page.indexOf('export function ClientOverviewPage'));
assert.equal((page.match(/setInterval\(\(\) => setNow\(Date\.now\(\)\), 1000\)/g) || []).length, 1);