test(notifications): add SSE event handling tests for useNotificationStream
Adds MockEventSource.simulate() helper and two tests covering: - unread notification via SSE prepends to list and increments unreadCount - read notification via SSE adds to list but does not increment unreadCount Fixes @saraholt: "SSE event handling not tested" Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@ let lastEventSource: {
|
|||||||
close: ReturnType<typeof vi.fn>;
|
close: ReturnType<typeof vi.fn>;
|
||||||
onopen: (() => void) | null;
|
onopen: (() => void) | null;
|
||||||
onerror: (() => void) | null;
|
onerror: (() => void) | null;
|
||||||
|
simulate: (type: string, data: string) => void;
|
||||||
} | null = null;
|
} | null = null;
|
||||||
|
|
||||||
class MockEventSource {
|
class MockEventSource {
|
||||||
@@ -23,6 +24,13 @@ class MockEventSource {
|
|||||||
if (!this.listeners[type]) this.listeners[type] = [];
|
if (!this.listeners[type]) this.listeners[type] = [];
|
||||||
this.listeners[type].push(fn);
|
this.listeners[type].push(fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
simulate(type: string, data: string) {
|
||||||
|
const event = new MessageEvent(type, { data });
|
||||||
|
for (const fn of this.listeners[type] ?? []) {
|
||||||
|
fn(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vi.stubGlobal('EventSource', MockEventSource);
|
vi.stubGlobal('EventSource', MockEventSource);
|
||||||
@@ -106,4 +114,29 @@ describe('createNotificationStream', () => {
|
|||||||
stream.destroy();
|
stream.destroy();
|
||||||
expect(lastEventSource!.close).toHaveBeenCalled();
|
expect(lastEventSource!.close).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('SSE notification event prepends notification and increments unreadCount', async () => {
|
||||||
|
mockFetch.mockResolvedValue(new Response(JSON.stringify({ count: 0 }), { status: 200 }));
|
||||||
|
const stream = createNotificationStream();
|
||||||
|
stream.init();
|
||||||
|
|
||||||
|
const notification = makeNotification({ id: 'sse-1', read: false });
|
||||||
|
lastEventSource!.simulate('notification', JSON.stringify(notification));
|
||||||
|
|
||||||
|
expect(stream.notifications).toHaveLength(1);
|
||||||
|
expect(stream.notifications[0].id).toBe('sse-1');
|
||||||
|
expect(stream.unreadCount).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('SSE notification event with read:true does not increment unreadCount', async () => {
|
||||||
|
mockFetch.mockResolvedValue(new Response(JSON.stringify({ count: 0 }), { status: 200 }));
|
||||||
|
const stream = createNotificationStream();
|
||||||
|
stream.init();
|
||||||
|
|
||||||
|
const notification = makeNotification({ id: 'sse-2', read: true });
|
||||||
|
lastEventSource!.simulate('notification', JSON.stringify(notification));
|
||||||
|
|
||||||
|
expect(stream.notifications).toHaveLength(1);
|
||||||
|
expect(stream.unreadCount).toBe(0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user