import { EventEmitter } from 'events'; import type { WebSocket } from 'ws'; import { BasicRepresentation } from '../../../../../src/http/representation/BasicRepresentation'; import type { SubscriptionInfo, } from '../../../../../src/server/notifications/SubscriptionStorage'; import { WebSocket2021Emitter, } from '../../../../../src/server/notifications/WebSocketSubscription2021/WebSocket2021Emitter'; import type { SetMultiMap } from '../../../../../src/util/map/SetMultiMap'; import { WrappedSetMultiMap } from '../../../../../src/util/map/WrappedSetMultiMap'; describe('A WebSocket2021Emitter', (): void => { const info: SubscriptionInfo = { id: 'id', topic: 'http://example.com/foo', type: 'type', features: {}, lastEmit: 0, }; let webSocket: jest.Mocked; let socketMap: SetMultiMap; let emitter: WebSocket2021Emitter; beforeEach(async(): Promise => { webSocket = new EventEmitter() as any; webSocket.send = jest.fn(); webSocket.close = jest.fn(); socketMap = new WrappedSetMultiMap(); emitter = new WebSocket2021Emitter(socketMap); }); it('emits notifications to the stored WebSockets.', async(): Promise => { socketMap.add(info.id, webSocket); const representation = new BasicRepresentation('notification', 'text/plain'); await expect(emitter.handle({ info, representation })).resolves.toBeUndefined(); expect(webSocket.send).toHaveBeenCalledTimes(1); expect(webSocket.send).toHaveBeenLastCalledWith('notification'); }); it('destroys the representation if there is no matching WebSocket.', async(): Promise => { const representation = new BasicRepresentation('notification', 'text/plain'); await expect(emitter.handle({ info, representation })).resolves.toBeUndefined(); expect(webSocket.send).toHaveBeenCalledTimes(0); expect(representation.data.destroyed).toBe(true); }); it('can send to multiple matching WebSockets.', async(): Promise => { const webSocket2: jest.Mocked = new EventEmitter() as any; webSocket2.send = jest.fn(); socketMap.add(info.id, webSocket); socketMap.add(info.id, webSocket2); const representation = new BasicRepresentation('notification', 'text/plain'); await expect(emitter.handle({ info, representation })).resolves.toBeUndefined(); expect(webSocket.send).toHaveBeenCalledTimes(1); expect(webSocket.send).toHaveBeenLastCalledWith('notification'); expect(webSocket2.send).toHaveBeenCalledTimes(1); expect(webSocket2.send).toHaveBeenLastCalledWith('notification'); }); it('only sends to the matching WebSockets.', async(): Promise => { const webSocket2: jest.Mocked = new EventEmitter() as any; webSocket2.send = jest.fn(); const info2: SubscriptionInfo = { ...info, id: 'other', }; socketMap.add(info.id, webSocket); socketMap.add(info2.id, webSocket2); const representation = new BasicRepresentation('notification', 'text/plain'); await expect(emitter.handle({ info, representation })).resolves.toBeUndefined(); expect(webSocket.send).toHaveBeenCalledTimes(1); expect(webSocket.send).toHaveBeenLastCalledWith('notification'); expect(webSocket2.send).toHaveBeenCalledTimes(0); }); });