Default new devices to Direct routing
This commit is contained in:
@@ -6,6 +6,7 @@ import { fileURLToPath } from 'node:url';
|
||||
import {
|
||||
formatByteString,
|
||||
formatLastSeen,
|
||||
isNewDevice,
|
||||
positiveByteDelta,
|
||||
sortDevicesByTraffic,
|
||||
stabilizeDevicesByTraffic,
|
||||
@@ -54,6 +55,9 @@ test('Gateway device inventory uses the existing accessible responsive drawer',
|
||||
assert.match(panel, /copyText\(value\)/);
|
||||
assert.match(panel, /const hasName = Boolean\(device\.alias \|\| device\.hostname\)/);
|
||||
assert.match(panel, /const title = device\.alias \|\| device\.hostname \|\| device\.ip \|\| 'Неизвестное устройство'/);
|
||||
assert.match(panel, /const newDevice = isNewDevice\(device\.firstSeenAt\)/);
|
||||
assert.match(panel, /client-device-new-badge[\s\S]*aria-hidden="true"[\s\S]*>NEW<[\s\S]*client-device-new-a11y[\s\S]*Новое устройство/);
|
||||
assert.match(panel, /displayPolicy === 'direct'[\s\S]*newDevice[\s\S]*Новое устройство идёт напрямую\. Нажмите, чтобы разрешить VPN через правила Gateway/);
|
||||
assert.match(panel, /client-device-fallback-name[\s\S]*client-device-identity-details[\s\S]*<b>IP<\/b>[\s\S]*<b>MAC<\/b>[\s\S]*<b>Host<\/b>/);
|
||||
assert.match(panel, /onClick=\{\(\) => startEditing\(device\)\}/);
|
||||
assert.match(panel, /\{!hasName && !editing && <span className="client-device-edit-wrap client-tooltip-anchor">/);
|
||||
@@ -175,6 +179,9 @@ test('Gateway device inventory uses the existing accessible responsive drawer',
|
||||
assert.match(styles, /\.client-device-policy \{[\s\S]*width: 34px;[\s\S]*border-radius: 50%/);
|
||||
assert.match(styles, /\.client-device-alias-trigger \{[\s\S]*font: var\(--type-item-title\)/);
|
||||
assert.match(styles, /\.client-device-alias-trigger\.is-custom-name \{[\s\S]*font: var\(--type-section-title\)/);
|
||||
assert.match(styles, /\.client-device-new-badge \{[\s\S]*height: 14px;[\s\S]*flex: 0 0 auto;[\s\S]*padding: 0 4px;[\s\S]*border: 1px solid color-mix\(in oklch, var\(--client-accent\)[\s\S]*border-radius: 999px;[\s\S]*background: var\(--client-accent-soft\);[\s\S]*font: var\(--type-micro\)/);
|
||||
assert.match(styles, /\.client-device-new-a11y \{[\s\S]*position: absolute;[\s\S]*width: 1px;[\s\S]*clip-path: inset\(50%\)/);
|
||||
assert.doesNotMatch(styles, /client-device-new-badge[^{]*\{[^}]*(?:transition|animation):/);
|
||||
assert.match(styles, /\.client-device-alias-input \{[\s\S]*width: var\(--alias-width\)[\s\S]*caret-color: var\(--client-accent\)[\s\S]*font: var\(--type-section-title\)[\s\S]*client-device-alias-edit-in 360ms/);
|
||||
assert.match(styles, /@keyframes client-device-alias-edit-in[\s\S]*color: var\(--client-accent\)[\s\S]*filter: blur\(2px\)/);
|
||||
assert.doesNotMatch(styles, /\.client-device-alias \{/);
|
||||
@@ -270,6 +277,14 @@ test('device last-seen copy is compact with precise accessible and relative form
|
||||
);
|
||||
});
|
||||
|
||||
test('new-device marker uses an exact seven-day window', () => {
|
||||
const now = Date.parse('2026-08-31T12:00:00.000Z');
|
||||
assert.equal(isNewDevice(new Date(now - (7 * 24 * 60 * 60 * 1000 - 1_000)).toISOString(), now), true);
|
||||
assert.equal(isNewDevice(new Date(now - 7 * 24 * 60 * 60 * 1000).toISOString(), now), false);
|
||||
assert.equal(isNewDevice(new Date(now + 1_000).toISOString(), now), false);
|
||||
assert.equal(isNewDevice('not-a-date', now), false);
|
||||
});
|
||||
|
||||
test('device traffic formatting and sorting preserve uint64 precision and canonical ties', () => {
|
||||
assert.equal(formatByteString('9007199254740993'), '8,0 ПБ');
|
||||
assert.equal(formatByteString('1536'), '1,5 КБ');
|
||||
|
||||
@@ -51,6 +51,7 @@ test('all unknown inventory results pass one identity-preserving runtime parser'
|
||||
hostname: null,
|
||||
mac: '00:11:22:33:44:55',
|
||||
ip: null,
|
||||
firstSeenAt: observedAt,
|
||||
lastSeenAt: null,
|
||||
status: 'online',
|
||||
pinned: true,
|
||||
@@ -126,6 +127,8 @@ test('all unknown inventory results pass one identity-preserving runtime parser'
|
||||
{ ...valid, devices: [{ ...valid.devices[0], desiredPolicy: 'automatic' }] },
|
||||
{ ...valid, devices: [{ ...valid.devices[0], policyStatus: 'queued' }] },
|
||||
{ ...valid, devices: [{ ...valid.devices[0], confidence: 'unknown' }] },
|
||||
{ ...valid, devices: [{ ...valid.devices[0], firstSeenAt: undefined }] },
|
||||
{ ...valid, devices: [{ ...valid.devices[0], firstSeenAt: 'not-a-date' }] },
|
||||
{ ...valid, devices: [{ ...valid.devices[0], lastSeenAt: 'not-a-date' }] },
|
||||
{ ...valid, devices: [{ ...valid.devices[0], trafficHistory: [{ observedAt, gatewayBytes: '1' }] }] },
|
||||
{ ...valid, devices: [{ ...valid.devices[0], outboundTraffic: { observedAt, vpnBytes: '1' } }] },
|
||||
|
||||
@@ -41,24 +41,24 @@ const acceptedLedger = {
|
||||
counts: {
|
||||
cascadeEdges: 1072,
|
||||
customProperties: 111,
|
||||
declarations: 4151,
|
||||
declarations: 4170,
|
||||
important: 0,
|
||||
keyframes: 50,
|
||||
media: 17,
|
||||
rules: 1124,
|
||||
variableReferences: 1036,
|
||||
rules: 1126,
|
||||
variableReferences: 1042,
|
||||
},
|
||||
hashes: {
|
||||
cascadeEdges: 'd60343b571f5a9bcf809609b4731500587da3bdd9ee9f40e33938ecbd8aec6ce',
|
||||
customProperties: '42f9fa9f2caaab6e5d90ae7d224563355822fa270083ea3496cfe2caaaea50bf',
|
||||
declarations: 'ee6b58dc6ef2edd16b8edf1762bb5c19aaf12d908958110c691f0a42f8e9067c',
|
||||
declarations: '15fc1474c16562886582469a7d240dde36882e682b266374fdca7f47f90c2b13',
|
||||
duplicateKeyframes: '4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945',
|
||||
duplicateSelectors: '8982145dba05b33bf1c93b2d54cfbe76305b276ff3c657aa020144016ada5848',
|
||||
keyframes: 'af4b9ae18d070fd2462a9b050293f3821bf5017c6e7cc53bbe18dc826f0fe3b9',
|
||||
ruleDeclarationSequences: 'e6a9c7019ab48d5bb15ac8ff0ffa51f8df7f1143ee9f8f562bdc78237a64b4b1',
|
||||
selectors: '4788b9fbc3aef9455ea9bf071f111dde318fbfe1fa96fe78127cc436131c4506',
|
||||
variableReferences: '04c19450f58f80dbe90e6df8988b8fa97f8c963d579d4f8acdb5bccd9d4020e9',
|
||||
witnesses: '7e42ab6ad3901fd68c9328e612eb413308ad8716031cbedd3134bf85224f6b9a',
|
||||
ruleDeclarationSequences: '16ccf3b3b8b6f76e784c69a3f06a3abb6e3b57d5d0710dff4bdad23f87bad6c3',
|
||||
selectors: 'b32eeeff7896fedd9057a953b61a8b149116a5c5ce110fb84bf06e24d22bf8ee',
|
||||
variableReferences: 'c9f64054cfe384f90e5c47844ffbbc7fba60f5045efac5d272f45f1f451e950b',
|
||||
witnesses: '2d952ddef91d3578857d7aeb1f469a9a6f3b7b4bba998ab6bc054d0028cf2785',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -211,7 +211,7 @@ test('client typography uses the shared semantic scale outside the token owner',
|
||||
|
||||
test('accepted stylesheet has pinned declaration, selector, keyframe, variable, and cascade ledgers', () => {
|
||||
const witnesses = readStyleWitnesses(root);
|
||||
assert.equal(witnesses.length, 1107);
|
||||
assert.equal(witnesses.length, 1110);
|
||||
assert.equal(witnesses.filter((witness) => witness.unknown || witness.ancestorUnknown).length, 0);
|
||||
const ledger = createStyleLedger(readStyleSource(root), { witnesses });
|
||||
assert.deepEqual(ledger.counts, acceptedLedger.counts);
|
||||
@@ -408,8 +408,8 @@ test('main owns one public stylesheet and the regrouped production CSS is determ
|
||||
assert.equal((main.match(/import ['"][^'"]+\.css['"]/g) || []).length, 1);
|
||||
|
||||
const assets = fs.readdirSync(path.join(root, 'dist/assets')).filter((file) => file.endsWith('.css'));
|
||||
assert.deepEqual(assets, ['index-oz5Ps7e5.css']);
|
||||
assert.deepEqual(assets, ['index-jhWgOVxh.css']);
|
||||
const built = fs.readFileSync(path.join(root, 'dist/assets', assets[0]));
|
||||
assert.equal(built.byteLength, 158205);
|
||||
assert.equal(sha256(built), 'b866b95d9cac46602023a35e0f55656af353e87ff230c7ad47d0aaeb768a7d3e');
|
||||
assert.equal(built.byteLength, 158716);
|
||||
assert.equal(sha256(built), 'b10c9602bdf224599db0262e2e872e3db2b3c75b85410d50c2fe42b69d44e14c');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user