Allow device routing without pinning
Build and Deploy Gateway / build-and-push (push) Successful in 15s
Build and Deploy Gateway / deploy (push) Successful in 13s

This commit is contained in:
2026-08-07 17:27:13 +03:00
parent 608f8cfcf2
commit dfa9f09695
13 changed files with 114 additions and 61 deletions
+11 -5
View File
@@ -49,7 +49,7 @@ test('Gateway device inventory uses the existing accessible responsive drawer',
assert.match(panel, /gatewayTotal > 0n && <span>Gateway/);
assert.match(panel, /proxyTotal > 0n && <span className="is-proxy">Прокси/);
assert.match(panel, /source\?\.traffic\?\.proxy\?\.error/);
assert.match(panel, /client-device-traffic-slot[\s\S]*client-device-pin-wrap/);
assert.match(panel, /client-device-pin-wrap[\s\S]*client-device-heading/);
assert.doesNotMatch(panel, /client-device-details/);
assert.match(panel, /api\.devices\.setPolicy\(device\.id, mode, snapshot\.revision\)/);
assert.match(panel, /requestError\.code !== 'STATE_CONFLICT'[\s\S]*latestDevice\.desiredPolicy !== device\.desiredPolicy[\s\S]*api\.devices\.setPolicy\(device\.id, mode, latest\.revision\)/);
@@ -58,16 +58,21 @@ test('Gateway device inventory uses the existing accessible responsive drawer',
assert.match(panel, /client-drawer client-instructions client-devices/);
assert.doesNotMatch(panel, /точная MAC|частная MAC|<dt>Источник<\/dt>/);
assert.match(panel, /aria-pressed=\{device\.pinned\}/);
assert.doesNotMatch(panel, /Закрепите устройство, чтобы изменить маршрут|Сначала верните маршрут через Gateway/);
assert.match(panel, /maxLength="64"[\s\S]*autoFocus/);
assert.match(styles, /\.client-devices \{\s*width: min\(560px, 100vw\)/);
assert.match(styles, /\.client-device \{[\s\S]*gap: 3px;[\s\S]*padding: 10px 8px/);
assert.match(styles, /\.client-device-heading \{[\s\S]*grid-template-columns: minmax\(0, 1fr\) auto 32px/);
assert.match(styles, /\.client-device \{[\s\S]*grid-template-columns: 32px minmax\(0, 1fr\);[\s\S]*padding: 10px 8px/);
assert.match(styles, /\.client-device-heading \{[\s\S]*grid-column: 2;[\s\S]*grid-template-columns: minmax\(0, 1fr\) auto/);
assert.match(styles, /\.client-device-meta \{[\s\S]*grid-template-columns: minmax\(0, 1fr\) 72px auto/);
assert.doesNotMatch(styles, /\.client-device-meta \{[^}]*margin-left/);
assert.match(styles, /\.client-device-last-seen\.is-online \{[\s\S]*color: var\(--client-accent\)/);
assert.match(styles, /\.client-text-morph-value \{[\s\S]*transition: opacity 360ms[\s\S]*filter 480ms/);
assert.match(styles, /\.client-device-last-seen:hover \.client-text-morph-value\.is-relative[\s\S]*opacity: 1/);
assert.match(styles, /\.client-device-pin-wrap\.client-tooltip-anchor:hover > \.client-tooltip[\s\S]*translate\(0, 0\)/);
assert.match(styles, /\.client-device-pin:hover:not\(:disabled\) svg[\s\S]*translateY\(-2px\) rotate\(-12deg\)/);
assert.match(styles, /\.client-device-pin\[aria-pressed="true"\] svg/);
assert.match(styles, /\.client-device-edit:hover svg[\s\S]*translate\(1px, -1px\) rotate\(-4deg\)/);
assert.match(styles, /\.client-devices-sort:hover \.client-devices-sort-icon[\s\S]*rotate\(360deg\)/);
assert.match(styles, /\.client-devices-refresh-ring circle[\s\S]*client-devices-refresh-progress 15s/);
assert.match(styles, /@media \(prefers-reduced-motion: reduce\)[\s\S]*\.client-device-policy[\s\S]*\.client-text-morph-value/);
assert.match(styles, /\.client-drawer \{[\s\S]*z-index: 50;[\s\S]*box-shadow:/);
@@ -97,7 +102,8 @@ test('device traffic formatting and sorting preserve uint64 precision and canoni
{ id: 'b', uploadBytes: '9007199254740992', downloadBytes: '2' },
{ id: 'c', uploadBytes: '10', downloadBytes: '10', proxyDownloadBytes: '100' },
{ id: 'd', uploadBytes: '15', downloadBytes: '5', proxyUploadBytes: '100' },
{ id: 'e', pinned: true, uploadBytes: '0', downloadBytes: '0' },
];
assert.deepEqual(sortDevicesByTraffic(devices, 'desc').map(({ id }) => id), ['b', 'a', 'c', 'd']);
assert.deepEqual(sortDevicesByTraffic(devices, 'asc').map(({ id }) => id), ['c', 'd', 'a', 'b']);
assert.deepEqual(sortDevicesByTraffic(devices, 'desc').map(({ id }) => id), ['e', 'b', 'a', 'c', 'd']);
assert.deepEqual(sortDevicesByTraffic(devices, 'asc').map(({ id }) => id), ['e', 'c', 'd', 'a', 'b']);
});