Add deprioritized device group
Build and Deploy Gateway / build-and-push (push) Successful in 19s
Build and Deploy Gateway / deploy (push) Successful in 14s

This commit is contained in:
2026-08-10 09:25:29 +03:00
parent ec68ba6a7b
commit f233660dc3
13 changed files with 262 additions and 60 deletions
+47 -3
View File
@@ -79,6 +79,7 @@ test('malformed persisted devices and remote observations cannot enter canonical
id: deviceId(mac),
alias: '',
pinned: false,
deprioritized: false,
hostname: null,
manufacturer: null,
source: 'neighbor',
@@ -183,6 +184,7 @@ test('device inventory discovers, merges, persists metadata and expires anonymou
assert.equal(snapshot.devices[0].status, 'recent');
snapshot = service.update(snapshot.devices[0].id, { alias: 'Телевизор', pinned: true }, snapshot.revision);
const namedId = snapshot.devices[0].id;
const restarted = createDeviceInventoryService({ store, observe: async () => observation, vendor, now: () => current });
assert.deepEqual(restarted.snapshot().devices[0], snapshot.devices[0]);
assert.throws(
@@ -190,15 +192,57 @@ test('device inventory discovers, merges, persists metadata and expires anonymou
(error) => error.code === 'STATE_CONFLICT',
);
observation = { observedAt: current.toISOString(), observations: [], error: 'source unavailable' };
current = new Date('2026-07-01T10:06:00.000Z');
observation = {
observedAt: current.toISOString(),
observations: parseNeighborSnapshot([
{ dst: '192.168.50.18', dev: 'br0', lladdr: '00:11:22:33:44:55', state: ['REACHABLE'] },
], current.toISOString()),
error: null,
};
snapshot = await restarted.refresh();
assert.equal(snapshot.devices.length, 1);
assert.equal(snapshot.devices[0].id, namedId);
assert.equal(snapshot.devices[0].ip, '192.168.50.18');
assert.equal(snapshot.devices[0].alias, 'Телевизор');
assert.equal(snapshot.devices[0].pinned, true);
observation = {
observedAt: current.toISOString(),
observations: parseNeighborSnapshot([
{ dst: '192.168.50.18', dev: 'br0', lladdr: '00:11:22:33:44:66', state: ['REACHABLE'] },
], current.toISOString()),
error: null,
};
snapshot = await restarted.refresh();
const replacement = snapshot.devices.find(({ mac: deviceMac }) => deviceMac === '00:11:22:33:44:66');
assert.notEqual(replacement.id, namedId);
assert.equal(replacement.alias, '');
assert.equal(replacement.pinned, false);
snapshot = restarted.update(namedId, { deprioritized: true }, snapshot.revision);
const deprioritized = snapshot.devices.find(({ id }) => id === namedId);
assert.equal(deprioritized.pinned, false);
assert.equal(deprioritized.deprioritized, true);
assert.throws(
() => restarted.update(namedId, { pinned: true, deprioritized: true }, snapshot.revision),
(error) => error.code === 'REQUEST_INVALID',
);
const persisted = createDeviceInventoryService({ store, observe: async () => observation, vendor, now: () => current });
assert.equal(persisted.snapshot().devices.find(({ id }) => id === namedId).deprioritized, true);
observation = { observedAt: current.toISOString(), observations: [], error: 'source unavailable' };
snapshot = await persisted.refresh();
assert.equal(snapshot.devices.length, 2);
assert.equal(snapshot.source.error, 'source unavailable');
snapshot = restarted.update(snapshot.devices[0].id, { alias: '', pinned: false }, snapshot.revision);
snapshot = persisted.update(namedId, { alias: '' }, snapshot.revision);
current = new Date('2026-08-02T10:00:00.000Z');
observation = { observedAt: current.toISOString(), observations: [], error: null };
snapshot = await restarted.refresh();
snapshot = await persisted.refresh();
assert.deepEqual(snapshot.devices.map(({ id }) => id), [namedId]);
snapshot = persisted.update(namedId, { deprioritized: false }, snapshot.revision);
snapshot = await persisted.refresh();
assert.equal(snapshot.devices.length, 0);
const failed = readNeighborSnapshot(() => ({ status: 1, stderr: 'not available' }), () => current);
+2 -2
View File
@@ -75,7 +75,7 @@ test('device route forwards list and refresh query paths as raw JSON responses',
});
test('device route forwards metadata patch and policy arguments without coercion', async () => {
const patch = { expectedRevision: 7, alias: 'Desk', pinned: false, extra: 0 };
const patch = { expectedRevision: 7, alias: 'Desk', pinned: false, deprioritized: true, extra: 0 };
const metadata = createHarness({ body: patch });
const metadataResponse = response();
assert.equal(await metadata.route.handle({
@@ -85,7 +85,7 @@ test('device route forwards metadata patch and policy arguments without coercion
assert.deepEqual(metadata.calls, [[
'update',
deviceId,
{ alias: 'Desk', pinned: false, extra: 0 },
{ alias: 'Desk', pinned: false, deprioritized: true, extra: 0 },
7,
]]);
assert.deepEqual(metadataResponse.payload, { revision: 3 });