Drop the redundant advanced table so fleet stays resource-first cards. Keep multi-select batch service/system restart via prepare→execute, card restarts, overview system ops, and progressive fleet loading.
112 lines
4.0 KiB
TypeScript
112 lines
4.0 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest';
|
|
|
|
import { createFleetApiDataSource } from './fleet-api-data-source.js';
|
|
|
|
describe('Fleet API data source', () => {
|
|
it('loads instances and their allowlisted resource summaries', async () => {
|
|
const fetcher = vi.fn(
|
|
async (input: RequestInfo | URL) =>
|
|
new Response(
|
|
JSON.stringify(
|
|
String(input).endsWith('/resources')
|
|
? {
|
|
cpuPercent: 23.4,
|
|
memoryPercent: 67.8,
|
|
maxTemperatureCelsius: 52.6,
|
|
phoneNumbers: ['13800000000'],
|
|
}
|
|
: {
|
|
items: [
|
|
{
|
|
id: 'alpha',
|
|
name: 'Alpha',
|
|
origin: 'https://alpha.example/admin',
|
|
tags: ['lab'],
|
|
revision: 4,
|
|
capabilityStatus: 'unknown',
|
|
freshness: 'unknown',
|
|
credentialConfigured: false,
|
|
},
|
|
],
|
|
page: { page: 1, pageSize: 20, total: 1 },
|
|
},
|
|
),
|
|
{ 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'],
|
|
});
|
|
expect(fetcher).toHaveBeenCalledWith(
|
|
'/api/v1/instances',
|
|
expect.objectContaining({ credentials: 'same-origin' }),
|
|
);
|
|
expect(fetcher).toHaveBeenCalledWith(
|
|
'/api/v1/instances/alpha/resources',
|
|
expect.objectContaining({ credentials: 'same-origin' }),
|
|
);
|
|
});
|
|
|
|
it('emits a partial fleet snapshot before resource enrichment completes', async () => {
|
|
let resolveResources!: (value: Response) => void;
|
|
const resourcesPromise = new Promise<Response>((resolve) => {
|
|
resolveResources = resolve;
|
|
});
|
|
const fetcher = vi.fn(async (input: RequestInfo | URL) => {
|
|
if (String(input).endsWith('/resources')) return resourcesPromise;
|
|
return new Response(
|
|
JSON.stringify({
|
|
items: [
|
|
{
|
|
id: 'alpha',
|
|
name: 'Alpha',
|
|
origin: 'https://alpha.example/admin',
|
|
tags: [],
|
|
revision: 1,
|
|
capabilityStatus: 'unknown',
|
|
freshness: 'unknown',
|
|
credentialConfigured: false,
|
|
},
|
|
],
|
|
page: { page: 1, pageSize: 20, total: 1 },
|
|
}),
|
|
{ status: 200, headers: { 'content-type': 'application/json' } },
|
|
);
|
|
});
|
|
const partials: unknown[] = [];
|
|
const pending = createFleetApiDataSource(fetcher as typeof fetch).load(undefined, (snapshot) => {
|
|
partials.push({
|
|
resources: snapshot.statuses.get('alpha')?.summary?.resources,
|
|
freshness: snapshot.statuses.get('alpha')?.summary?.freshness,
|
|
});
|
|
});
|
|
await vi.waitFor(() => expect(partials.length).toBe(1));
|
|
expect(partials[0]).toEqual({ resources: undefined, freshness: 'unknown' });
|
|
resolveResources(
|
|
new Response(JSON.stringify({ cpuPercent: 11, memoryPercent: 22 }), {
|
|
status: 200,
|
|
headers: { 'content-type': 'application/json' },
|
|
}),
|
|
);
|
|
await pending;
|
|
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.',
|
|
);
|
|
});
|
|
});
|