Files
harbor-net/test/server/traffic-history-route.test.js
dokril 1ae23d848b
Build and Deploy Gateway / build-and-push (push) Successful in 1m22s
Build and Deploy Gateway / deploy (push) Successful in 16s
Migrate Harbor state and traffic history to SQLite
2026-09-10 19:21:21 +03:00

42 lines
2.5 KiB
JavaScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { createTrafficHistoryRoute } from '../../dist/server/http/routes/trafficHistoryRoute.js';
import { emptyTrafficHistory, parseTrafficHistoryQuery } from '../../dist/shared/trafficHistory.js';
function response() {
return { writeHead(status) { this.status = status; }, end(body) { this.payload = JSON.parse(body); } };
}
test('history API reads only its local source, enriches labels and returns explicit unavailable coverage', async () => {
const route = createTrafficHistoryRoute({
readHistory: async (query) => ({ ...emptyTrafficHistory(query, 'live'), origins: [{ id: 'dev-a', label: 'IP' }] }),
deviceInventory: { snapshot: () => ({ devices: [{ id: 'dev-a', alias: 'Ноутбук' }] }) },
});
const res = response();
assert.equal(await route.handle({ method: 'GET', url: '/api/traffic/history?range=90d&search=yandex' }, res), true);
assert.equal(res.status, 200);
assert.equal(res.payload.query.search, 'yandex');
assert.equal(res.payload.period.retentionDays, 90);
assert.equal(res.payload.origins[0].label, 'Ноутбук');
const failed = createTrafficHistoryRoute({ readHistory: async () => { throw Error('disk'); } });
await failed.handle({ method: 'GET', url: '/api/traffic/history' }, res);
assert.equal(res.payload.storage.status, 'error');
assert.equal(res.payload.coverage.partial, true);
await createTrafficHistoryRoute({ readHistory: null }).handle({ method: 'GET', url: '/api/traffic/history' }, res);
assert.equal(res.payload.source, 'disabled');
});
test('history API rejects invalid queries and mutation methods before reading storage', async () => {
let reads = 0;
const route = createTrafficHistoryRoute({ readHistory: async (query) => { reads++; return emptyTrafficHistory(query); } });
for (const params of ['range=forever', 'level=ip%3BDROP', 'route=no', 'offset=-1', 'until=Infinity', 'search=%00', `search=${'x'.repeat(201)}`]) {
await assert.rejects(route.handle({ method: 'GET', url: `/api/traffic/history?${params}` }, response()),
(error) => error.code === 'REQUEST_INVALID');
}
await assert.rejects(route.handle({ method: 'DELETE', url: '/api/traffic/history' }, response()),
(error) => error.code === 'ENDPOINT_NOT_FOUND');
assert.equal(await route.handle({ method: 'GET', url: '/api/state' }, response()), false);
assert.equal(reads, 0);
assert.equal(parseTrafficHistoryQuery(new URLSearchParams('range=90d')).range, '90d');
});