feat(web): complete fleet and instance management slices
This commit is contained in:
@@ -23,7 +23,18 @@ const instances: readonly FleetInstance[] = [
|
||||
const statuses: ReadonlyMap<string, FleetStatus> = new Map([
|
||||
[
|
||||
'charlie',
|
||||
{ reachable: true, authenticated: true, latencyMs: 55, summary: { carrier: 'Acme' } },
|
||||
{
|
||||
reachable: true,
|
||||
authenticated: true,
|
||||
latencyMs: 55,
|
||||
summary: {
|
||||
carrier: 'Acme',
|
||||
version: '2.4.1',
|
||||
capabilities: ['sms', 'ussd'],
|
||||
freshness: 'stale',
|
||||
anomalies: ['latency spike'],
|
||||
},
|
||||
},
|
||||
],
|
||||
['alpha', { reachable: false, latencyMs: 8 }],
|
||||
['bravo', { reachable: true, authenticated: false, latencyMs: 20 }],
|
||||
@@ -123,4 +134,69 @@ describe('fleet table view model', () => {
|
||||
buildFleetTableViewModel(instances, statuses, { sort: { column: 'name', direction: 'desc' } });
|
||||
expect(instances.map((instance) => instance.id)).toEqual(originalOrder);
|
||||
});
|
||||
|
||||
it('derives optional operational metadata from status summary with safe defaults', () => {
|
||||
const model = buildFleetTableViewModel(instances, statuses);
|
||||
const charlie = model.rows.find((row) => row.id === 'charlie');
|
||||
const alpha = model.rows.find((row) => row.id === 'alpha');
|
||||
|
||||
expect(charlie).toMatchObject({
|
||||
version: '2.4.1',
|
||||
capabilities: ['sms', 'ussd'],
|
||||
freshness: 'stale',
|
||||
anomalies: ['latency spike'],
|
||||
tags: ['west'],
|
||||
});
|
||||
expect(alpha).toMatchObject({
|
||||
version: null,
|
||||
capabilities: [],
|
||||
freshness: 'unknown',
|
||||
anomalies: [],
|
||||
tags: ['east'],
|
||||
});
|
||||
});
|
||||
|
||||
it('combines authentication, capability, version, and tag filters', () => {
|
||||
expect(
|
||||
buildFleetTableViewModel(instances, statuses, {
|
||||
auth: 'authenticated',
|
||||
capability: 'sms',
|
||||
version: '2.4.1',
|
||||
tag: 'west',
|
||||
}).rows.map((row) => row.id),
|
||||
).toEqual(['charlie']);
|
||||
expect(
|
||||
buildFleetTableViewModel(instances, statuses, { auth: 'required' }).rows.map((row) => row.id),
|
||||
).toEqual(['bravo']);
|
||||
});
|
||||
|
||||
it('sorts metadata columns, including scalar freshness, and paginates after filtering and sorting', () => {
|
||||
const model = buildFleetTableViewModel(instances, statuses, {
|
||||
sort: { column: 'version', direction: 'asc' },
|
||||
page: 2,
|
||||
pageSize: 2,
|
||||
});
|
||||
|
||||
expect(model.rows.map((row) => row.id)).toEqual(['bravo', 'delta']);
|
||||
expect(model.filteredCount).toBe(4);
|
||||
expect(model.page).toBe(2);
|
||||
expect(model.pageCount).toBe(2);
|
||||
expect(model.visibleSelection.rowCount).toBe(2);
|
||||
expect(
|
||||
buildFleetTableViewModel(instances, statuses, {
|
||||
sort: { column: 'freshness', direction: 'asc' },
|
||||
}).rows.map((row) => row.id),
|
||||
).toEqual(['charlie', 'alpha', 'bravo', 'delta']);
|
||||
});
|
||||
|
||||
it('clamps invalid pages and exposes filter choices from available data', () => {
|
||||
const model = buildFleetTableViewModel(instances, statuses, { page: 99, pageSize: 3 });
|
||||
expect(model.page).toBe(2);
|
||||
expect(model.rows.map((row) => row.id)).toEqual(['delta']);
|
||||
expect(model.facets).toEqual({
|
||||
capabilities: ['sms', 'ussd'],
|
||||
versions: ['2.4.1'],
|
||||
tags: ['east', 'west'],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user