Add device inventory refresh endpoint and auto-refresh UI
This commit is contained in:
@@ -30,14 +30,21 @@ test('device inventory discovers, merges, persists metadata and expires anonymou
|
||||
], current.toISOString()),
|
||||
error: null,
|
||||
};
|
||||
let observeCalls = 0;
|
||||
const service = createDeviceInventoryService({
|
||||
store,
|
||||
observe: async () => observation,
|
||||
observe: async () => {
|
||||
observeCalls += 1;
|
||||
return observation;
|
||||
},
|
||||
vendor,
|
||||
now: () => current,
|
||||
});
|
||||
|
||||
let snapshot = await service.refresh();
|
||||
const [firstRefresh, sharedRefresh] = await Promise.all([service.refresh(), service.refresh()]);
|
||||
let snapshot = firstRefresh;
|
||||
assert.strictEqual(sharedRefresh, firstRefresh);
|
||||
assert.equal(observeCalls, 1);
|
||||
assert.equal(snapshot.devices.length, 1);
|
||||
assert.equal(snapshot.devices[0].manufacturer, 'Example Devices');
|
||||
assert.equal(snapshot.devices[0].status, 'online');
|
||||
|
||||
@@ -8,12 +8,19 @@ import { formatLastSeen } from '../../src/web/utils/format.js';
|
||||
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
|
||||
const overview = fs.readFileSync(path.join(root, 'src/web/components/ClientOverviewPage.jsx'), 'utf8');
|
||||
const panel = fs.readFileSync(path.join(root, 'src/web/components/DevicesPanel.jsx'), 'utf8');
|
||||
const api = fs.readFileSync(path.join(root, 'src/web/api.js'), 'utf8');
|
||||
const server = fs.readFileSync(path.join(root, 'src/server/index.js'), 'utf8');
|
||||
const styles = fs.readFileSync(path.join(root, 'src/web/styles.css'), 'utf8');
|
||||
|
||||
test('Gateway device inventory uses the existing accessible responsive drawer', () => {
|
||||
assert.match(overview, /isGateway && <button[\s\S]*client-devices-toggle/);
|
||||
assert.match(panel, /api\.devices\.list\(\)/);
|
||||
assert.match(panel, /api\.devices\.refresh\(\)/);
|
||||
assert.match(panel, /api\.devices\.update\(device\.id, patch, snapshot\.revision\)/);
|
||||
assert.match(panel, /deviceNodes\.current\.get\(id\)\?\.animate/);
|
||||
assert.match(panel, /prefers-reduced-motion: reduce/);
|
||||
assert.match(api, /refresh: \(\) => request\('\/api\/devices\/refresh', \{ method: 'POST' \}\)/);
|
||||
assert.match(server, /requestUrl\.pathname === '\/api\/devices\/refresh'[\s\S]*deviceInventory\.refresh\(\)/);
|
||||
assert.match(panel, /<Tooltip>Изменить название<\/Tooltip>/);
|
||||
assert.match(panel, /<TextMorph from=\{seen\.label\} to=\{seen\.relative\} \/>/);
|
||||
assert.doesNotMatch(panel, /client-text-morph-goo/);
|
||||
@@ -24,6 +31,8 @@ test('Gateway device inventory uses the existing accessible responsive drawer',
|
||||
assert.match(styles, /\.client-devices \{\s*width: min\(560px, 100vw\)/);
|
||||
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-devices-refresh-ring circle[\s\S]*client-devices-refresh-progress 15s/);
|
||||
assert.match(styles, /@media \(prefers-reduced-motion: reduce\)[\s\S]*\.client-text-morph-value/);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user