Migrate Harbor state and traffic history to SQLite
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
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');
|
||||
});
|
||||
Reference in New Issue
Block a user