57 lines
2.7 KiB
TypeScript
57 lines
2.7 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import {
|
|
createLiveConsoleState,
|
|
reduceLiveConsoleState,
|
|
selectVisibleConsoleEntries,
|
|
} from '../../apps/dashboard/src/features/operations/live-console-model.js';
|
|
|
|
function entry(id: string, level: 'debug' | 'info' | 'warn' | 'error', message: string) {
|
|
return { id, occurredAt: '2026-08-08T12:00:00.000Z', level, message };
|
|
}
|
|
|
|
describe('live console state', () => {
|
|
it('bounds entries, rejects duplicate IDs, and filters by level and search', () => {
|
|
let state = createLiveConsoleState(2);
|
|
state = reduceLiveConsoleState(state, { type: 'append', entry: entry('1', 'info', 'Sync started') });
|
|
state = reduceLiveConsoleState(state, { type: 'append', entry: entry('2', 'error', 'Matrix failed') });
|
|
state = reduceLiveConsoleState(state, { type: 'append', entry: entry('2', 'error', 'duplicate') });
|
|
state = reduceLiveConsoleState(state, { type: 'append', entry: entry('3', 'warn', 'Sync slow') });
|
|
state = reduceLiveConsoleState(state, { type: 'set-level', level: 'warn' });
|
|
state = reduceLiveConsoleState(state, { type: 'set-search', search: 'sync' });
|
|
|
|
expect(state.entries.map(({ id }) => id)).toEqual(['2', '3']);
|
|
expect(selectVisibleConsoleEntries(state).map(({ id }) => id)).toEqual(['3']);
|
|
});
|
|
|
|
it('holds bounded pending entries while paused and merges them on resume', () => {
|
|
let state = createLiveConsoleState(2);
|
|
state = reduceLiveConsoleState(state, { type: 'append', entry: entry('1', 'info', 'one') });
|
|
state = reduceLiveConsoleState(state, { type: 'set-paused', paused: true });
|
|
state = reduceLiveConsoleState(state, { type: 'append', entry: entry('2', 'info', 'two') });
|
|
state = reduceLiveConsoleState(state, { type: 'append', entry: entry('3', 'info', 'three') });
|
|
state = reduceLiveConsoleState(state, { type: 'append', entry: entry('4', 'info', 'four') });
|
|
|
|
expect(state.entries.map(({ id }) => id)).toEqual(['1']);
|
|
expect(state.pendingEntries.map(({ id }) => id)).toEqual(['3', '4']);
|
|
|
|
state = reduceLiveConsoleState(state, { type: 'set-paused', paused: false });
|
|
expect(state.entries.map(({ id }) => id)).toEqual(['3', '4']);
|
|
expect(state.pendingEntries).toEqual([]);
|
|
});
|
|
|
|
it('deduplicates the same log delivered by the initial snapshot and SSE replay', () => {
|
|
let state = createLiveConsoleState();
|
|
state = reduceLiveConsoleState(state, {
|
|
type: 'append',
|
|
entry: entry('initial-1', 'info', 'Database initialized'),
|
|
});
|
|
state = reduceLiveConsoleState(state, {
|
|
type: 'append',
|
|
entry: entry('realtime-1', 'info', 'Database initialized'),
|
|
});
|
|
|
|
expect(state.entries).toHaveLength(1);
|
|
expect(state.entries[0]?.id).toBe('initial-1');
|
|
});
|
|
});
|