feat: align admin & agent dashboard summaries with Netify real totals and speeds

This commit is contained in:
vanne committed 2026-07-02 08:53:30 +07:00
1 parent 952c299b37
commit cd31d1954c
7 files changed
+264 -11

No files matched your search

@@ -0,0 +1,85 @@
const test = require('node:test');
const assert = require('node:assert');
// Require the database module to mock it before loading the router
const db = require('../database');
const originalGetStats = db.getStats;
const originalGetTimeline = db.getBandwidthTimeline;
test.afterEach(() => {
db.getStats = originalGetStats;
db.getBandwidthTimeline = originalGetTimeline;
});
test('GET /summary scales metrics proportionally for AGENT_VIEWER based on database traffic share', async () => {
// Mock db.getStats
db.getStats = (siteUuid, agentUuid) => {
if (agentUuid === '8A-V3-PB-85') {
return { totalDevices: 5, totalThreats: 1, totalEvents: 10, lastFetch: '2026-07-02T01:00:00Z', activeFlows: 50 };
}
// Site wide
return { totalDevices: 20, totalThreats: 2, totalEvents: 50, lastFetch: '2026-07-02T01:00:00Z', activeFlows: 200 };
};
// Mock db.getBandwidthTimeline
db.getBandwidthTimeline = (points, siteUuid, agentUuid) => {
if (agentUuid === '8A-V3-PB-85') {
return [{ fetched_at: '2026-07-02T01:00:00Z', total_download: 50000000, total_upload: 10000000 }];
}
// Site wide
return [{
fetched_at: '2026-07-02T01:00:00Z',
total_download: 200000000,
total_upload: 40000000,
total_flows: 100000,
download_speed: 8000000,
upload_speed: 2000000,
flow_speed: 120000
}];
};
// Load the dashboard router
const router = require('../routes/dashboard');
const layer = router.stack.find(l => l.route && l.route.path === '/summary');
assert.ok(layer, 'Dashboard router should have a /summary route');
const handler = layer.route.stack[0].handle;
// Mock req and res for AGENT_VIEWER
const req = {
user: {
role: 'AGENT_VIEWER',
agent_uuid: '8A-V3-PB-85',
site_uuid: '6681452d_9cae_4ff4_8ae8_0d504774265e'
}
};
let responseData = null;
const res = {
json(payload) {
responseData = payload;
}
};
// Execute the route handler
await handler(req, res);
// Assert proportional scaling is correct
assert.ok(responseData);
assert.strictEqual(responseData.ok, true);
const data = responseData.data;
assert.ok(data);
// Unaltered metrics
assert.strictEqual(data.total_devices, 5);
assert.strictEqual(data.total_threats, 1);
assert.strictEqual(data.total_events, 10);
assert.strictEqual(data.bandwidth_down, 50000000);
assert.strictEqual(data.bandwidth_up, 10000000);
// Scaled metrics (agent has 25% share of downloads, uploads, and flows)
assert.strictEqual(data.active_flows, 25000);
assert.strictEqual(data.download_speed, 2000000);
assert.strictEqual(data.upload_speed, 500000);
assert.strictEqual(data.flow_speed, 30000);
});
+55
View File
@@ -0,0 +1,55 @@
const test = require('node:test');
const assert = require('node:assert');
const axios = require('axios');
// Save original axios get method
const originalGet = axios.get;
function mockAxiosGet(mockFn) {
axios.get = mockFn;
}
function restoreAxiosGet() {
axios.get = originalGet;
}
test.afterEach(() => {
restoreAxiosGet();
});
test('fetchBandwidthSummary retrieves /data/stats/summary with correct filter_interval and outputs all metrics', async () => {
const netify = require('../netify');
mockAxiosGet(async (url, config) => {
if (url.endsWith('/data/stats/summary')) {
// Verify query params
assert.strictEqual(config.params?.filter_interval, 1440);
return {
data: {
status_code: 0,
status_message: 'Success.',
data: {
download: 218648938113,
upload: 33551656812,
flow_hourly_count: 2970165,
download_speed: 2530000,
upload_speed: 390000,
flow_speed: 123756
}
}
};
}
throw new Error(`Unexpected mock URL: ${url}`);
});
const summary = await netify.fetchBandwidthSummary(1440);
assert.ok(summary);
assert.strictEqual(summary.download, 218648938113);
assert.strictEqual(summary.upload, 33551656812);
assert.strictEqual(summary.flows, 2970165);
assert.strictEqual(summary.download_speed, 2530000);
assert.strictEqual(summary.upload_speed, 390000);
assert.strictEqual(summary.flow_speed, 123756);
});