import { describe, expect, it, vi } from 'vitest'; import { createFleetApiDataSource } from './fleet-api-data-source.js'; describe('Fleet API data source', () => { it('loads the aggregate fleet overview and its resource summaries', async () => { const fetcher = vi.fn( async () => new Response( JSON.stringify({ items: [ { id: 'alpha', name: 'Alpha', origin: 'https://alpha.example/admin', tags: ['lab'], revision: 4, capabilityStatus: 'unknown', freshness: 'unknown', credentialConfigured: false, resources: { cpuPercent: 23.4, memoryPercent: 67.8, maxTemperatureCelsius: 52.6, phoneNumbers: ['13800000000'], hardwareOnline: true, controlOnline: true, simPresent: true, carrier: 'China Mobile', cellularRegistration: 'registered_home', accessTechnology: 'LTE', cellularOnline: true, signalPercent: 72, uptimeSeconds: 93784.9, version: '1.9.4', }, }, ], }), { status: 200, headers: { 'content-type': 'application/json' } }, ), ); const snapshot = await createFleetApiDataSource(fetcher as typeof fetch).load(); expect(snapshot.instances).toEqual([ { id: 'alpha', name: 'Alpha', url: 'https://alpha.example/admin', tags: ['lab'], revision: 4, }, ]); expect(snapshot.statuses.get('alpha')?.summary?.resources).toEqual({ cpuPercent: 23.4, memoryPercent: 67.8, maxTemperatureCelsius: 52.6, phoneNumbers: ['13800000000'], hardwareOnline: true, controlOnline: true, simPresent: true, carrier: 'China Mobile', cellularRegistration: 'registered_home', accessTechnology: 'LTE', cellularOnline: true, signalPercent: 72, uptimeSeconds: 93784, }); expect(snapshot.statuses.get('alpha')?.summary?.version).toBe('1.9.4'); expect(fetcher).toHaveBeenCalledTimes(1); expect(fetcher).toHaveBeenCalledWith( '/api/v1/fleet/overview', expect.objectContaining({ credentials: 'same-origin' }), ); }); it('emits skeleton and complete snapshots from the aggregate overview', async () => { const fetcher = vi.fn( async () => new Response( JSON.stringify({ items: [ { id: 'alpha', name: 'Alpha', origin: 'https://alpha.example/admin', tags: [], revision: 1, capabilityStatus: 'unknown', freshness: 'unknown', credentialConfigured: false, resources: { cpuPercent: 11, memoryPercent: 22 }, }, ], }), { status: 200, headers: { 'content-type': 'application/json' } }, ), ); const partials: unknown[] = []; await createFleetApiDataSource(fetcher as typeof fetch).load(undefined, (snapshot) => { partials.push({ resources: snapshot.statuses.get('alpha')?.summary?.resources, freshness: snapshot.statuses.get('alpha')?.summary?.freshness, }); }); expect(partials.length).toBe(2); expect(partials[0]).toEqual({ resources: undefined, freshness: 'unknown' }); expect(partials.at(-1)).toEqual({ resources: { cpuPercent: 11, memoryPercent: 22 }, freshness: 'fresh', }); }); it('rejects legacy or malformed envelopes instead of rendering a false empty fleet', async () => { const fetcher = vi.fn(async () => new Response(JSON.stringify({ data: [] }), { status: 200 })); await expect(createFleetApiDataSource(fetcher as typeof fetch).load()).rejects.toThrow( 'Fleet response is invalid.', ); }); }); function overviewWith(connection: unknown) { return vi.fn( async () => new Response( JSON.stringify({ items: [ { id: 'alpha', name: 'Alpha', origin: 'https://alpha.example/admin', tags: [], revision: 1, capabilityStatus: 'unknown', freshness: 'unknown', credentialConfigured: false, connection, resources: {}, }, ], }), { status: 200, headers: { 'content-type': 'application/json' } }, ), ); } describe('Fleet resource bounds', () => { const overviewWithResources = (resources: Record) => vi.fn( async () => new Response( JSON.stringify({ items: [ { id: 'alpha', name: 'Alpha', origin: 'https://alpha.example/admin', tags: [], revision: 1, capabilityStatus: 'unknown', freshness: 'unknown', credentialConfigured: false, resources, }, ], }), { status: 200, headers: { 'content-type': 'application/json' } }, ), ) as unknown as typeof fetch; it('drops a negative or non-numeric uptime instead of rendering a bogus clock', async () => { const negative = await createFleetApiDataSource( overviewWithResources({ uptimeSeconds: -1 }), ).load(); const text = await createFleetApiDataSource( overviewWithResources({ uptimeSeconds: '93784' }), ).load(); expect(negative.statuses.get('alpha')?.summary?.resources?.uptimeSeconds).toBeUndefined(); expect(text.statuses.get('alpha')?.summary?.resources?.uptimeSeconds).toBeUndefined(); }); it('keeps a zero uptime, which means the device just booted', async () => { const snapshot = await createFleetApiDataSource( overviewWithResources({ uptimeSeconds: 0 }), ).load(); expect(snapshot.statuses.get('alpha')?.summary?.resources?.uptimeSeconds).toBe(0); }); }); describe('Fleet heartbeat connection state', () => { it('carries a live heartbeat through to the row status', async () => { const snapshot = await createFleetApiDataSource( overviewWith({ probed: true, reachable: true, authenticated: true, checkedAt: '2026-09-05T00:00:00.000Z', }) as typeof fetch, ).load(); expect(snapshot.statuses.get('alpha')).toMatchObject({ probed: true, reachable: true, authenticated: true, checkedAt: '2026-09-05T00:00:00.000Z', }); }); it('marks a device the heartbeat lost as offline but still checked', async () => { const snapshot = await createFleetApiDataSource( overviewWith({ probed: true, reachable: false, authenticated: false, checkedAt: '2026-09-05T00:00:00.000Z', }) as typeof fetch, ).load(); expect(snapshot.statuses.get('alpha')).toMatchObject({ probed: true, reachable: false, authenticated: false, checkedAt: '2026-09-05T00:00:00.000Z', }); }); it('reports a device that has never been probed as unknown', async () => { const snapshot = await createFleetApiDataSource( overviewWith({ probed: false, reachable: false, authenticated: false, checkedAt: null, }) as typeof fetch, ).load(); expect(snapshot.statuses.get('alpha')).toMatchObject({ probed: false, checkedAt: null, }); }); it('keeps the optimistic shape for a server without the heartbeat journal', async () => { const snapshot = await createFleetApiDataSource(overviewWith(undefined) as typeof fetch).load(); expect(snapshot.statuses.get('alpha')).toMatchObject({ reachable: true, authenticated: true, }); expect(snapshot.statuses.get('alpha')?.probed).toBeUndefined(); expect(snapshot.statuses.get('alpha')?.checkedAt).toBeUndefined(); }); it('applies the heartbeat state to the skeleton snapshot too', async () => { const partials: unknown[] = []; await createFleetApiDataSource( overviewWith({ probed: true, reachable: false, authenticated: false, checkedAt: null, }) as typeof fetch, ).load(undefined, (snapshot) => { partials.push(snapshot.statuses.get('alpha')); }); expect(partials[0]).toMatchObject({ probed: true, reachable: false }); expect(partials.at(-1)).toMatchObject({ probed: true, reachable: false }); }); it('carries the identity guard verdict onto the row, in both passes', async () => { const fetcher = vi.fn(async () => { const base = overviewWith({ probed: true, reachable: true, authenticated: true }); const response = await base(); const body = await response.json(); body.items[0].identity = { tracked: true, status: 'pending', reasons: ['imei_claimed'] }; return new Response(JSON.stringify(body), { status: 200, headers: { 'content-type': 'application/json' }, }); }); const partials: unknown[] = []; const snapshot = await createFleetApiDataSource(fetcher as unknown as typeof fetch).load( undefined, (value) => partials.push(value.statuses.get('alpha')), ); expect(partials[0]).toMatchObject({ identity: { status: 'pending' } }); expect(snapshot.statuses.get('alpha')?.identity).toEqual({ tracked: true, status: 'pending', reasons: ['imei_claimed'], }); }); it('leaves the row unbadged for a server without the identity guard', async () => { const snapshot = await createFleetApiDataSource( overviewWith(undefined) as unknown as typeof fetch, ).load(); expect(snapshot.statuses.get('alpha')?.identity).toBeUndefined(); }); });