Persist traffic settings and support multi-device traffic views
Build and Deploy Gateway / build-and-push (push) Successful in 32s
Build and Deploy Gateway / deploy (push) Successful in 7s

This commit is contained in:
2026-08-31 06:46:59 +03:00
parent 6777422a27
commit 3c2eefe108
18 changed files with 653 additions and 124 deletions
+45
View File
@@ -206,3 +206,48 @@ test('route is unavailable when no traffic collector exists', async () => {
(error) => error.code === 'ENDPOINT_NOT_FOUND',
);
});
test('PUT persists validated traffic settings with revision protection and returns canonical state', async () => {
let state = { revision: 4, traffic: { grouping: 'site', sort: 'popular', retentionSeconds: 10 } };
let sent = false;
const route = createLiveTrafficRoute({
traffic: null,
settingsState: {
read: () => state,
update: (mutator) => { state = { ...mutator(state), revision: state.revision + 1 }; },
},
readBody: async () => ({
settings: { grouping: 'device', sort: 'recent', retentionSeconds: 30 },
expectedRevision: 4,
}),
sendState: async (res) => { sent = true; res.end(JSON.stringify(state)); },
});
const res = response();
assert.equal(await route.handle({ method: 'PUT', url: '/api/traffic/settings' }, res), true);
assert.equal(sent, true);
assert.deepEqual(state.traffic, { grouping: 'device', sort: 'recent', retentionSeconds: 30 });
assert.equal(state.revision, 5);
const conflict = createLiveTrafficRoute({
traffic: null,
settingsState: { read: () => state, update: () => { throw new Error('must not update'); } },
readBody: async () => ({ settings: state.traffic, expectedRevision: 4 }),
sendState: async () => {},
});
await assert.rejects(
conflict.handle({ method: 'PUT', url: '/api/traffic/settings' }, response()),
(error) => error.code === 'STATE_CONFLICT',
);
const invalid = createLiveTrafficRoute({
traffic: null,
settingsState: { read: () => state, update: () => { throw new Error('must not update'); } },
readBody: async () => ({ settings: { grouping: 'guess' }, expectedRevision: 5 }),
sendState: async () => {},
});
await assert.rejects(
invalid.handle({ method: 'PUT', url: '/api/traffic/settings' }, response()),
(error) => error.code === 'REQUEST_INVALID',
);
});