40 lines
2.4 KiB
TypeScript
40 lines
2.4 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { RealtimeEventHub } from '../../../src/web/events/realtime-event-hub.js';
|
|
import { createDashboardEventAdapters } from '../../../src/web/events/event-adapters.js';
|
|
import { createDashboardEventPublisher } from '../../../src/web/events/event-publisher.js';
|
|
|
|
describe('dashboard event adapters', () => {
|
|
it('provides a transport-neutral typed publisher over the event hub', () => {
|
|
const hub = new RealtimeEventHub({ capacity: 2 });
|
|
const publisher = createDashboardEventPublisher(hub);
|
|
const event = publisher.publish('bot.status.changed', { status: 'running', dryRun: false });
|
|
expect(event.type).toBe('bot.status.changed');
|
|
expect(hub.recent()).toEqual([event]);
|
|
});
|
|
it('translates every route and service event family to typed dashboard events', () => {
|
|
const hub = new RealtimeEventHub({ capacity: 20 });
|
|
const adapter = createDashboardEventAdapters(hub);
|
|
adapter.bot({ running: true, dryRun: true });
|
|
adapter.messageSent({ id: 'm1', username: 'alice', conversationId: 'c1' });
|
|
adapter.messageFailed({ username: 'bob', error: new Error('blocked'), retryable: false });
|
|
adapter.conversation({ id: 'c1', state: 'awaiting_reply', unread: 2 });
|
|
adapter.reply({ conversationId: 'c1', id: 'r1', username: 'alice', body: 'hello' });
|
|
adapter.sync({ phase: 'started', id: 's1', kind: 'delta' });
|
|
adapter.sync({ phase: 'progress', id: 's1', kind: 'delta', current: 2, total: 3 });
|
|
adapter.sync({ phase: 'completed', id: 's1', kind: 'delta', processed: 3 });
|
|
adapter.sync({ phase: 'failed', id: 's2', kind: 'media', error: 'network' });
|
|
adapter.rateLimit({ blocked: true, remaining: 0, resetAt: 1_786_176_000_000 });
|
|
adapter.redditSession({ state: 'login-required' });
|
|
adapter.log({ level: 'warn', message: 'careful' });
|
|
|
|
expect(hub.recent().map((event) => event.type)).toEqual([
|
|
'bot.status.changed', 'message.sent', 'message.failed', 'conversation.updated', 'reply.received',
|
|
'sync.started', 'sync.progress', 'sync.completed', 'sync.failed', 'rate-limit.changed',
|
|
'reddit.session.changed', 'log.created',
|
|
]);
|
|
expect(hub.recent()[2]?.payload).toMatchObject({ recipient: 'bob', reason: 'blocked' });
|
|
expect(hub.recent()[3]?.payload).toMatchObject({ status: 'awaiting-reply', unreadCount: 2 });
|
|
expect(hub.recent()[10]?.payload).toEqual({ status: 'logged-out' });
|
|
});
|
|
});
|