78 lines
3.0 KiB
TypeScript
78 lines
3.0 KiB
TypeScript
import { expect, it } from 'vitest';
|
|
import { render } from 'svelte/server';
|
|
import { provisioningContext } from '../../src/lib/ui/provisioning-presentation.js';
|
|
import { provisioningStatus, provisioningWarnings } from '../../src/lib/ui/provisioning-queue.js';
|
|
import ProvisioningStatusBadge from '../../src/lib/ui/components/ProvisioningStatusBadge.svelte';
|
|
|
|
it.each([
|
|
['queued', 'Queued', 'neutral'],
|
|
['waiting', 'Waiting', 'neutral'],
|
|
['running', 'Running', 'info'],
|
|
['awaiting-health', 'Validating', 'info'],
|
|
['done', 'Completed', 'online'],
|
|
['warning', 'Completed with warnings', 'warning'],
|
|
['failed', 'Failed', 'danger'],
|
|
['interrupted', 'Interrupted', 'danger'],
|
|
['cancelled', 'Cancelled', 'neutral']
|
|
])('renders the recorded %s lifecycle state consistently', (state, label, tone) => {
|
|
expect(provisioningStatus(state)).toMatchObject({ label, tone });
|
|
const body = render(ProvisioningStatusBadge, { props: { state } }).body;
|
|
expect(body).toContain(label);
|
|
expect(body).toContain(`v-${tone}`);
|
|
expect(body).toContain('aria-hidden="true"');
|
|
});
|
|
|
|
it('keeps waiting reasons and preparation separate from the recorded state', () => {
|
|
const row = {
|
|
state: 'running',
|
|
action: 'restart' as const,
|
|
phase: 'container-action',
|
|
stage: 'Waiting for host acknowledgment',
|
|
waitMessage: 'Waiting for another operation to finish'
|
|
};
|
|
expect(provisioningContext(row)).toEqual({
|
|
step: 'Restart container',
|
|
detail: 'Waiting for another operation to finish'
|
|
});
|
|
expect(provisioningStatus(row.state).label).toBe('Running');
|
|
|
|
const preparing = { ...row, state: 'queued', phase: 'prepare', waitMessage: null };
|
|
expect(provisioningContext(preparing)?.step).toBe('Prepare server files');
|
|
expect(provisioningStatus(preparing.state).label).toBe('Queued');
|
|
});
|
|
|
|
it('preserves legacy stage text without parsing it into a lifecycle label', () => {
|
|
const row = {
|
|
state: 'waiting',
|
|
action: 'rebuild' as const,
|
|
stage: 'Waiting for 3 player(s) to leave.'
|
|
};
|
|
expect(provisioningContext(row)).toEqual({ step: row.stage, detail: null });
|
|
expect(provisioningContext({ ...row, phase: 'future-phase' })).toEqual({
|
|
step: row.stage,
|
|
detail: null
|
|
});
|
|
expect(provisioningStatus(row.state).label).toBe('Waiting');
|
|
});
|
|
|
|
it.each(['done', 'warning', 'failed', 'interrupted', 'cancelled'])(
|
|
'does not describe leftover progress as current for %s jobs',
|
|
(state) => {
|
|
expect(
|
|
provisioningContext({
|
|
state,
|
|
action: 'restart',
|
|
stage: 'Waiting for startup capacity',
|
|
waitMessage: 'Waiting for recovery',
|
|
phase: 'cleanup'
|
|
})
|
|
).toBeNull();
|
|
}
|
|
);
|
|
|
|
it('only displays strings from recorded warning arrays', () => {
|
|
expect(provisioningWarnings('["Warning",null,3]')).toEqual(['Warning']);
|
|
expect(provisioningWarnings('null')).toEqual([]);
|
|
expect(provisioningWarnings('invalid')).toEqual([]);
|
|
});
|