mirror of
https://github.com/hexastack/hexabot
synced 2025-06-26 18:27:28 +00:00
fix(api): update WebsocketGateway unit tests
This commit is contained in:
parent
e203485d75
commit
22ef79b05f
@ -8,6 +8,7 @@
|
||||
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import { Socket, io } from 'socket.io-client';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import {
|
||||
closeInMongodConnection,
|
||||
@ -16,12 +17,16 @@ import {
|
||||
import { buildTestingMocks } from '@/utils/test/utils';
|
||||
|
||||
import { SocketEventDispatcherService } from './services/socket-event-dispatcher.service';
|
||||
import { Room } from './types';
|
||||
import { WebsocketGateway } from './websocket.gateway';
|
||||
|
||||
describe('WebsocketGateway', () => {
|
||||
let gateway: WebsocketGateway;
|
||||
let app: INestApplication;
|
||||
let ioClient: Socket;
|
||||
let createSocket: (index: number) => Socket;
|
||||
let sockets: Socket[];
|
||||
let sessionIds: string[];
|
||||
let validSessionIds: string[];
|
||||
|
||||
beforeAll(async () => {
|
||||
// Instantiate the app
|
||||
@ -39,12 +44,20 @@ describe('WebsocketGateway', () => {
|
||||
// Get the gateway instance from the app instance
|
||||
gateway = app.get<WebsocketGateway>(WebsocketGateway);
|
||||
// Create a new client that will interact with the gateway
|
||||
ioClient = io('http://localhost:3000', {
|
||||
autoConnect: false,
|
||||
transports: ['websocket', 'polling'],
|
||||
// path: '/socket.io/?EIO=4&transport=websocket&channel=web-channel',
|
||||
query: { EIO: '4', transport: 'websocket', channel: 'web-channel' },
|
||||
});
|
||||
|
||||
sessionIds = [uuidv4(), uuidv4(), uuidv4()];
|
||||
validSessionIds = [sessionIds[0], sessionIds[2]];
|
||||
|
||||
createSocket = (index: number) =>
|
||||
io('http://localhost:3000', {
|
||||
autoConnect: false,
|
||||
transports: ['websocket', 'polling'],
|
||||
// path: '/socket.io/?EIO=4&transport=websocket&channel=web-channel',
|
||||
query: { EIO: '4', transport: 'websocket', channel: 'web-channel' },
|
||||
extraHeaders: { sessionid: sessionIds[index] },
|
||||
});
|
||||
|
||||
sockets = sessionIds.map((e, index) => createSocket(index));
|
||||
|
||||
await app.listen(3000);
|
||||
});
|
||||
@ -59,31 +72,102 @@ describe('WebsocketGateway', () => {
|
||||
});
|
||||
|
||||
it('should connect successfully', async () => {
|
||||
const socketClient = ioClient.connect();
|
||||
const [socket1] = sockets;
|
||||
socket1.connect();
|
||||
|
||||
await new Promise<void>((resolve) => {
|
||||
socketClient.on('connect', () => {
|
||||
socket1.on('connect', async () => {
|
||||
expect(true).toBe(true);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
socketClient.disconnect();
|
||||
socket1.disconnect();
|
||||
});
|
||||
|
||||
it('should emit "OK" on "healthcheck"', async () => {
|
||||
const socketClient = ioClient.connect();
|
||||
const [socket1] = sockets;
|
||||
|
||||
socket1.connect();
|
||||
|
||||
await new Promise<void>((resolve) => {
|
||||
socketClient.on('connect', () => {
|
||||
socketClient.emit('healthcheck', 'Hello world!');
|
||||
socketClient.on('event', (data) => {
|
||||
socket1.on('connect', () => {
|
||||
socket1.emit('healthcheck', 'Hello world!');
|
||||
socket1.on('event', (data) => {
|
||||
expect(data).toBe('OK');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
socketClient.disconnect();
|
||||
socket1.disconnect();
|
||||
});
|
||||
|
||||
describe('joinNotificationSockets', () => {
|
||||
it('should join socket1 and socket3 to room MESSAGE', async () => {
|
||||
const [socket1, , socket3] = sockets;
|
||||
|
||||
[socket1, , socket3].forEach((socket) => socket?.connect());
|
||||
|
||||
for (const socket of [socket1, , socket3]) {
|
||||
if (socket) {
|
||||
await new Promise<void>((resolve) => {
|
||||
socket.on('connect', async () => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
jest.spyOn(gateway, 'getNotificationSockets').mockResolvedValueOnce(
|
||||
(await gateway.io.fetchSockets()).filter(({ handshake }) => {
|
||||
const uuid = handshake.headers.sessionid?.toString() || '';
|
||||
|
||||
return validSessionIds.includes(uuid);
|
||||
}),
|
||||
);
|
||||
|
||||
await gateway.joinNotificationSockets('sessionId', Room.MESSAGE);
|
||||
|
||||
expect(gateway.getNotificationSockets).toHaveBeenCalledWith('sessionId');
|
||||
|
||||
gateway.io.to(Room.MESSAGE).emit('message', { data: 'OK' });
|
||||
|
||||
for (const socket of [socket1, , socket3]) {
|
||||
if (socket)
|
||||
await new Promise<void>((resolve) => {
|
||||
socket.on('message', async ({ data }) => {
|
||||
expect(data).toBe('OK');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
sockets.forEach((socket) => socket.disconnect());
|
||||
});
|
||||
|
||||
it('should throw an error when socket array is empty', async () => {
|
||||
jest.spyOn(gateway, 'getNotificationSockets').mockResolvedValueOnce([]);
|
||||
|
||||
expect(gateway.getNotificationSockets).toHaveBeenCalledWith('sessionId');
|
||||
|
||||
await expect(
|
||||
gateway.joinNotificationSockets('sessionId', Room.MESSAGE),
|
||||
).rejects.toThrow('No notification sockets found!');
|
||||
});
|
||||
|
||||
it('should throw an error with empty sessionId', async () => {
|
||||
await expect(
|
||||
gateway.joinNotificationSockets('', Room.MESSAGE),
|
||||
).rejects.toThrow('SessionId is required!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getNotificationSockets', () => {
|
||||
it('should throw an error with empty sessionId', async () => {
|
||||
await expect(gateway.getNotificationSockets('')).rejects.toThrow(
|
||||
'SessionId is required!',
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -416,6 +416,10 @@ export class WebsocketGateway
|
||||
async getNotificationSockets(
|
||||
sessionId: string,
|
||||
): Promise<RemoteSocket<DefaultEventsMap, any>[]> {
|
||||
if (!sessionId) {
|
||||
throw new Error('SessionId is required!');
|
||||
}
|
||||
|
||||
return (await this.io.fetchSockets()).filter(
|
||||
({ handshake, data }) =>
|
||||
!handshake.query.channel && data.sessionID === sessionId,
|
||||
@ -429,8 +433,16 @@ export class WebsocketGateway
|
||||
* @param room - the joined room name
|
||||
*/
|
||||
async joinNotificationSockets(sessionId: string, room: Room): Promise<void> {
|
||||
if (!sessionId) {
|
||||
throw new Error('SessionId is required!');
|
||||
}
|
||||
|
||||
const notificationSockets = await this.getNotificationSockets(sessionId);
|
||||
|
||||
if (!notificationSockets.length) {
|
||||
throw new Error('No notification sockets found!');
|
||||
}
|
||||
|
||||
notificationSockets.forEach((notificationSocket) =>
|
||||
notificationSocket.join(room),
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user