From 3398d65d2d7947d0e4580d388ef9220710ed6419 Mon Sep 17 00:00:00 2001 From: afrokick Date: Mon, 16 Dec 2019 11:16:43 +0300 Subject: [PATCH] refactoring index.js --- dist/src/index.js | 56 +---------- dist/src/instance.js | 51 ++++++++++ .../handlers/transmission/index.js | 3 +- dist/src/messageHandler/handlersRegistry.js | 20 ++++ dist/src/messageHandler/index.js | 30 +++--- dist/src/services/webSocketServer/index.js | 9 +- src/api/index.ts | 6 +- src/index.ts | 82 ++-------------- src/instance.ts | 71 ++++++++++++++ ...messageHandlers.ts => handlersRegistry.ts} | 4 +- src/messageHandler/index.ts | 30 +++--- src/services/webSocketServer/index.ts | 2 +- .../handlers/transmission/index.ts | 96 +++++++++++++++++++ test/messageHandler/handlersRegistry.ts | 23 +++++ 14 files changed, 314 insertions(+), 169 deletions(-) create mode 100644 dist/src/instance.js create mode 100644 dist/src/messageHandler/handlersRegistry.js create mode 100644 src/instance.ts rename src/messageHandler/{messageHandlers.ts => handlersRegistry.ts} (89%) create mode 100644 test/messageHandler/handlers/transmission/index.ts create mode 100644 test/messageHandler/handlersRegistry.ts diff --git a/dist/src/index.js b/dist/src/index.js index 92282b4..dc4a6fb 100644 --- a/dist/src/index.js +++ b/dist/src/index.js @@ -6,56 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true }); const express_1 = __importDefault(require("express")); const http_1 = __importDefault(require("http")); const https_1 = __importDefault(require("https")); -const api_1 = require("./api"); const config_1 = __importDefault(require("./config")); -const messageHandler_1 = require("./messageHandler"); -const realm_1 = require("./models/realm"); -const checkBrokenConnections_1 = require("./services/checkBrokenConnections"); -const messagesExpire_1 = require("./services/messagesExpire"); -const webSocketServer_1 = require("./services/webSocketServer"); -const init = ({ app, server, options }) => { - const config = options; - const realm = new realm_1.Realm(); - const messageHandler = new messageHandler_1.MessageHandler(realm); - const api = api_1.Api({ config, realm, messageHandler }); - const messagesExpire = new messagesExpire_1.MessagesExpire({ realm, config, messageHandler }); - const checkBrokenConnections = new checkBrokenConnections_1.CheckBrokenConnections({ - realm, - config, - onClose: (client) => { - app.emit("disconnect", client); - } - }); - app.use(options.path, api); - const wss = new webSocketServer_1.WebSocketServer({ - server, - realm, - config - }); - wss.on("connection", (client) => { - const messageQueue = realm.getMessageQueueById(client.getId()); - if (messageQueue) { - let message; - while (message = messageQueue.readMessage()) { - messageHandler.handle(client, message); - } - realm.clearMessageQueue(client.getId()); - } - app.emit("connection", client); - }); - wss.on("message", (client, message) => { - app.emit("message", client, message); - messageHandler.handle(client, message); - }); - wss.on("close", (client) => { - app.emit("disconnect", client); - }); - wss.on("error", (error) => { - app.emit("error", error); - }); - messagesExpire.startMessagesExpiration(); - checkBrokenConnections.start(); -}; +const instance_1 = require("./instance"); function ExpressPeerServer(server, options) { const app = express_1.default(); const newOptions = Object.assign(Object.assign({}, config_1.default), options); @@ -67,7 +19,7 @@ function ExpressPeerServer(server, options) { throw new Error("Server is not passed to constructor - " + "can't start PeerServer"); } - init({ app, server, options: newOptions }); + instance_1.createInstance({ app, server, options: newOptions }); }); return app; } @@ -77,10 +29,10 @@ function PeerServer(options = {}, callback) { const newOptions = Object.assign(Object.assign({}, config_1.default), options); let path = newOptions.path; const port = newOptions.port; - if (path[0] !== "/") { + if (!path.startsWith('/')) { path = "/" + path; } - if (path[path.length - 1] !== "/") { + if (!path.endsWith('/')) { path += "/"; } let server; diff --git a/dist/src/instance.js b/dist/src/instance.js new file mode 100644 index 0000000..458e01c --- /dev/null +++ b/dist/src/instance.js @@ -0,0 +1,51 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const realm_1 = require("./models/realm"); +const checkBrokenConnections_1 = require("./services/checkBrokenConnections"); +const messagesExpire_1 = require("./services/messagesExpire"); +const webSocketServer_1 = require("./services/webSocketServer"); +const messageHandler_1 = require("./messageHandler"); +const api_1 = require("./api"); +exports.createInstance = ({ app, server, options }) => { + const config = options; + const realm = new realm_1.Realm(); + const messageHandler = new messageHandler_1.MessageHandler(realm); + const api = api_1.Api({ config, realm, messageHandler }); + const messagesExpire = new messagesExpire_1.MessagesExpire({ realm, config, messageHandler }); + const checkBrokenConnections = new checkBrokenConnections_1.CheckBrokenConnections({ + realm, + config, + onClose: client => { + app.emit("disconnect", client); + } + }); + app.use(options.path, api); + const wss = new webSocketServer_1.WebSocketServer({ + server, + realm, + config + }); + wss.on("connection", (client) => { + const messageQueue = realm.getMessageQueueById(client.getId()); + if (messageQueue) { + let message; + while (message = messageQueue.readMessage()) { + messageHandler.handle(client, message); + } + realm.clearMessageQueue(client.getId()); + } + app.emit("connection", client); + }); + wss.on("message", (client, message) => { + app.emit("message", client, message); + messageHandler.handle(client, message); + }); + wss.on("close", (client) => { + app.emit("disconnect", client); + }); + wss.on("error", (error) => { + app.emit("error", error); + }); + messagesExpire.startMessagesExpiration(); + checkBrokenConnections.start(); +}; diff --git a/dist/src/messageHandler/handlers/transmission/index.js b/dist/src/messageHandler/handlers/transmission/index.js index 390eb6e..5183eb4 100644 --- a/dist/src/messageHandler/handlers/transmission/index.js +++ b/dist/src/messageHandler/handlers/transmission/index.js @@ -40,7 +40,8 @@ exports.TransmissionHandler = ({ realm }) => { else { // Wait for this client to connect/reconnect (XHR) for important // messages. - if (type !== enums_1.MessageType.LEAVE && type !== enums_1.MessageType.EXPIRE && dstId) { + const ignoredTypes = [enums_1.MessageType.LEAVE, enums_1.MessageType.EXPIRE]; + if (!ignoredTypes.includes(type) && dstId) { realm.addMessageToQueue(dstId, message); } else if (type === enums_1.MessageType.LEAVE && !dstId) { diff --git a/dist/src/messageHandler/handlersRegistry.js b/dist/src/messageHandler/handlersRegistry.js new file mode 100644 index 0000000..6875bd7 --- /dev/null +++ b/dist/src/messageHandler/handlersRegistry.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class HandlersRegistry { + constructor() { + this.handlers = new Map(); + } + registerHandler(messageType, handler) { + if (this.handlers.has(messageType)) + return; + this.handlers.set(messageType, handler); + } + handle(client, message) { + const { type } = message; + const handler = this.handlers.get(type); + if (!handler) + return false; + return handler(client, message); + } +} +exports.HandlersRegistry = HandlersRegistry; diff --git a/dist/src/messageHandler/index.js b/dist/src/messageHandler/index.js index b3acd87..c8393ca 100644 --- a/dist/src/messageHandler/index.js +++ b/dist/src/messageHandler/index.js @@ -2,30 +2,30 @@ Object.defineProperty(exports, "__esModule", { value: true }); const enums_1 = require("../enums"); const handlers_1 = require("./handlers"); -const messageHandlers_1 = require("./messageHandlers"); +const handlersRegistry_1 = require("./handlersRegistry"); class MessageHandler { - constructor(realm) { - this.messageHandlers = new messageHandlers_1.MessageHandlers(); + constructor(realm, handlersRegistry = new handlersRegistry_1.HandlersRegistry()) { + this.handlersRegistry = handlersRegistry; const transmissionHandler = handlers_1.TransmissionHandler({ realm }); const heartbeatHandler = handlers_1.HeartbeatHandler; - const handleTransmission = (client, message) => { + const handleTransmission = (client, { type, src, dst, payload }) => { return transmissionHandler(client, { - type: message.type, - src: message.src, - dst: message.dst, - payload: message.payload + type, + src, + dst, + payload, }); }; const handleHeartbeat = (client, message) => heartbeatHandler(client, message); - this.messageHandlers.registerHandler(enums_1.MessageType.HEARTBEAT, handleHeartbeat); - this.messageHandlers.registerHandler(enums_1.MessageType.OFFER, handleTransmission); - this.messageHandlers.registerHandler(enums_1.MessageType.ANSWER, handleTransmission); - this.messageHandlers.registerHandler(enums_1.MessageType.CANDIDATE, handleTransmission); - this.messageHandlers.registerHandler(enums_1.MessageType.LEAVE, handleTransmission); - this.messageHandlers.registerHandler(enums_1.MessageType.EXPIRE, handleTransmission); + this.handlersRegistry.registerHandler(enums_1.MessageType.HEARTBEAT, handleHeartbeat); + this.handlersRegistry.registerHandler(enums_1.MessageType.OFFER, handleTransmission); + this.handlersRegistry.registerHandler(enums_1.MessageType.ANSWER, handleTransmission); + this.handlersRegistry.registerHandler(enums_1.MessageType.CANDIDATE, handleTransmission); + this.handlersRegistry.registerHandler(enums_1.MessageType.LEAVE, handleTransmission); + this.handlersRegistry.registerHandler(enums_1.MessageType.EXPIRE, handleTransmission); } handle(client, message) { - return this.messageHandlers.handle(client, message); + return this.handlersRegistry.handle(client, message); } } exports.MessageHandler = MessageHandler; diff --git a/dist/src/services/webSocketServer/index.js b/dist/src/services/webSocketServer/index.js index 5f45f5f..fde0b03 100644 --- a/dist/src/services/webSocketServer/index.js +++ b/dist/src/services/webSocketServer/index.js @@ -8,6 +8,7 @@ const url_1 = __importDefault(require("url")); const ws_1 = __importDefault(require("ws")); const enums_1 = require("../../enums"); const client_1 = require("../../models/client"); +const WS_PATH = 'peerjs'; class WebSocketServer extends events_1.default { constructor({ server, realm, config }) { super(); @@ -15,10 +16,10 @@ class WebSocketServer extends events_1.default { this.realm = realm; this.config = config; const path = this.config.path; - this.path = path + (path[path.length - 1] !== "/" ? "/" : "") + "peerjs"; - this.webSocketServer = new ws_1.default.Server({ path, server }); - this.webSocketServer.on("connection", (socket, req) => this._onSocketConnection(socket, req)); - this.webSocketServer.on("error", (error) => this._onSocketError(error)); + this.path = `${path}${path.endsWith('/') ? "" : "/"}${WS_PATH}`; + this.socketServer = new ws_1.default.Server({ path: this.path, server }); + this.socketServer.on("connection", (socket, req) => this._onSocketConnection(socket, req)); + this.socketServer.on("error", (error) => this._onSocketError(error)); } _onSocketConnection(socket, req) { const { query = {} } = url_1.default.parse(req.url, true); diff --git a/src/api/index.ts b/src/api/index.ts index f1539af..257bf24 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -10,9 +10,9 @@ import CallsApi from "./v1/calls"; import PublicApi from "./v1/public"; export const Api = ({ config, realm, messageHandler }: { - config: IConfig, - realm: IRealm, - messageHandler: IMessageHandler + config: IConfig; + realm: IRealm; + messageHandler: IMessageHandler; }): express.Router => { const authMiddleware = new AuthMiddleware(config, realm); diff --git a/src/index.ts b/src/index.ts index dc6e4ec..61f55b3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,77 +1,13 @@ -import { IRealm } from "./models/realm"; - import express from "express"; import http from "http"; import https from "https"; - import { Server } from "net"; -import { Api } from "./api"; + import defaultConfig, { IConfig } from "./config"; -import { MessageHandler } from "./messageHandler"; -import { IClient } from "./models/client"; -import { IMessage } from "./models/message"; -import { Realm } from "./models/realm"; -import { CheckBrokenConnections } from "./services/checkBrokenConnections"; -import { IMessagesExpire, MessagesExpire } from "./services/messagesExpire"; -import { IWebSocketServer, WebSocketServer } from "./services/webSocketServer"; +import { createInstance } from "./instance"; -const init = ({ app, server, options }: { - app: express.Express, - server: Server, - options: IConfig; -}) => { - const config = options; - const realm: IRealm = new Realm(); - const messageHandler = new MessageHandler(realm); - const api = Api({ config, realm, messageHandler }); - - const messagesExpire: IMessagesExpire = new MessagesExpire({ realm, config, messageHandler }); - const checkBrokenConnections = new CheckBrokenConnections({ - realm, - config, - onClose: (client: IClient) => { - app.emit("disconnect", client); - } - }); - - app.use(options.path, api); - - const wss: IWebSocketServer = new WebSocketServer({ - server, - realm, - config - }); - - wss.on("connection", (client: IClient) => { - const messageQueue = realm.getMessageQueueById(client.getId()); - - if (messageQueue) { - let message: IMessage | undefined; - - while (message = messageQueue.readMessage()) { - messageHandler.handle(client, message); - } - realm.clearMessageQueue(client.getId()); - } - - app.emit("connection", client); - }); - - wss.on("message", (client: IClient, message: IMessage) => { - app.emit("message", client, message); - messageHandler.handle(client, message); - }); - - wss.on("close", (client: IClient) => { - app.emit("disconnect", client); - }); - - wss.on("error", (error: Error) => { - app.emit("error", error); - }); - - messagesExpire.startMessagesExpiration(); - checkBrokenConnections.start(); +type Optional = { + [P in keyof T]?: (T[P] | undefined); }; function ExpressPeerServer(server: Server, options?: IConfig) { @@ -92,16 +28,12 @@ function ExpressPeerServer(server: Server, options?: IConfig) { "can't start PeerServer"); } - init({ app, server, options: newOptions }); + createInstance({ app, server, options: newOptions }); }); return app; } -type Optional = { - [P in keyof T]?: (T[P] | undefined); -}; - function PeerServer(options: Optional = {}, callback?: (server: Server) => void) { const app = express(); @@ -113,11 +45,11 @@ function PeerServer(options: Optional = {}, callback?: (server: Server) let path = newOptions.path; const port = newOptions.port; - if (path[0] !== "/") { + if (!path.startsWith('/')) { path = "/" + path; } - if (path[path.length - 1] !== "/") { + if (!path.endsWith('/')) { path += "/"; } diff --git a/src/instance.ts b/src/instance.ts new file mode 100644 index 0000000..cd8cc66 --- /dev/null +++ b/src/instance.ts @@ -0,0 +1,71 @@ +import express from "express"; +import { Server } from "net"; +import { IClient } from "./models/client"; +import { IMessage } from "./models/message"; +import { Realm } from "./models/realm"; +import { IRealm } from "./models/realm"; +import { CheckBrokenConnections } from "./services/checkBrokenConnections"; +import { IMessagesExpire, MessagesExpire } from "./services/messagesExpire"; +import { IWebSocketServer, WebSocketServer } from "./services/webSocketServer"; +import { MessageHandler } from "./messageHandler"; +import { Api } from "./api"; +import { IConfig } from "./config"; + +export const createInstance = ({ app, server, options }: { + app: express.Application, + server: Server, + options: IConfig; +}): void => { + const config = options; + const realm: IRealm = new Realm(); + const messageHandler = new MessageHandler(realm); + + const api = Api({ config, realm, messageHandler }); + const messagesExpire: IMessagesExpire = new MessagesExpire({ realm, config, messageHandler }); + const checkBrokenConnections = new CheckBrokenConnections({ + realm, + config, + onClose: client => { + app.emit("disconnect", client); + } + }); + + app.use(options.path, api); + + const wss: IWebSocketServer = new WebSocketServer({ + server, + realm, + config + }); + + wss.on("connection", (client: IClient) => { + const messageQueue = realm.getMessageQueueById(client.getId()); + + if (messageQueue) { + let message: IMessage | undefined; + + while (message = messageQueue.readMessage()) { + messageHandler.handle(client, message); + } + realm.clearMessageQueue(client.getId()); + } + + app.emit("connection", client); + }); + + wss.on("message", (client: IClient, message: IMessage) => { + app.emit("message", client, message); + messageHandler.handle(client, message); + }); + + wss.on("close", (client: IClient) => { + app.emit("disconnect", client); + }); + + wss.on("error", (error: Error) => { + app.emit("error", error); + }); + + messagesExpire.startMessagesExpiration(); + checkBrokenConnections.start(); +}; \ No newline at end of file diff --git a/src/messageHandler/messageHandlers.ts b/src/messageHandler/handlersRegistry.ts similarity index 89% rename from src/messageHandler/messageHandlers.ts rename to src/messageHandler/handlersRegistry.ts index 4aa82d9..def2ac8 100644 --- a/src/messageHandler/messageHandlers.ts +++ b/src/messageHandler/handlersRegistry.ts @@ -3,12 +3,12 @@ import { IClient } from "../models/client"; import { IMessage } from "../models/message"; import { Handler } from "./handler"; -export interface IMessageHandlers { +export interface IHandlersRegistry { registerHandler(messageType: MessageType, handler: Handler): void; handle(client: IClient | undefined, message: IMessage): boolean; } -export class MessageHandlers implements IMessageHandlers { +export class HandlersRegistry implements IHandlersRegistry { private readonly handlers: Map = new Map(); public registerHandler(messageType: MessageType, handler: Handler): void { diff --git a/src/messageHandler/index.ts b/src/messageHandler/index.ts index de03c45..7f6c67a 100644 --- a/src/messageHandler/index.ts +++ b/src/messageHandler/index.ts @@ -4,39 +4,37 @@ import { IMessage } from "../models/message"; import { IRealm } from "../models/realm"; import { Handler } from "./handler"; import { HeartbeatHandler, TransmissionHandler } from "./handlers"; -import { IMessageHandlers, MessageHandlers } from "./messageHandlers"; +import { IHandlersRegistry, HandlersRegistry } from "./handlersRegistry"; export interface IMessageHandler { handle(client: IClient | undefined, message: IMessage): boolean; } export class MessageHandler implements IMessageHandler { - private readonly messageHandlers: IMessageHandlers = new MessageHandlers(); - - constructor(realm: IRealm) { + constructor(realm: IRealm, private readonly handlersRegistry: IHandlersRegistry = new HandlersRegistry()) { const transmissionHandler: Handler = TransmissionHandler({ realm }); const heartbeatHandler: Handler = HeartbeatHandler; - const handleTransmission: Handler = (client: IClient | undefined, message: IMessage): boolean => { + const handleTransmission: Handler = (client: IClient | undefined, { type, src, dst, payload }: IMessage): boolean => { return transmissionHandler(client, { - type: message.type, - src: message.src, - dst: message.dst, - payload: message.payload + type, + src, + dst, + payload, }); }; const handleHeartbeat = (client: IClient | undefined, message: IMessage) => heartbeatHandler(client, message); - this.messageHandlers.registerHandler(MessageType.HEARTBEAT, handleHeartbeat); - this.messageHandlers.registerHandler(MessageType.OFFER, handleTransmission); - this.messageHandlers.registerHandler(MessageType.ANSWER, handleTransmission); - this.messageHandlers.registerHandler(MessageType.CANDIDATE, handleTransmission); - this.messageHandlers.registerHandler(MessageType.LEAVE, handleTransmission); - this.messageHandlers.registerHandler(MessageType.EXPIRE, handleTransmission); + this.handlersRegistry.registerHandler(MessageType.HEARTBEAT, handleHeartbeat); + this.handlersRegistry.registerHandler(MessageType.OFFER, handleTransmission); + this.handlersRegistry.registerHandler(MessageType.ANSWER, handleTransmission); + this.handlersRegistry.registerHandler(MessageType.CANDIDATE, handleTransmission); + this.handlersRegistry.registerHandler(MessageType.LEAVE, handleTransmission); + this.handlersRegistry.registerHandler(MessageType.EXPIRE, handleTransmission); } public handle(client: IClient | undefined, message: IMessage): boolean { - return this.messageHandlers.handle(client, message); + return this.handlersRegistry.handle(client, message); } } diff --git a/src/services/webSocketServer/index.ts b/src/services/webSocketServer/index.ts index de96049..3b237a1 100644 --- a/src/services/webSocketServer/index.ts +++ b/src/services/webSocketServer/index.ts @@ -40,7 +40,7 @@ export class WebSocketServer extends EventEmitter implements IWebSocketServer { const path = this.config.path; this.path = `${path}${path.endsWith('/') ? "" : "/"}${WS_PATH}`; - this.socketServer = new WebSocketLib.Server({ path, server }); + this.socketServer = new WebSocketLib.Server({ path: this.path, server }); this.socketServer.on("connection", (socket: MyWebSocket, req) => this._onSocketConnection(socket, req)); this.socketServer.on("error", (error: Error) => this._onSocketError(error)); diff --git a/test/messageHandler/handlers/transmission/index.ts b/test/messageHandler/handlers/transmission/index.ts new file mode 100644 index 0000000..83b1ff6 --- /dev/null +++ b/test/messageHandler/handlers/transmission/index.ts @@ -0,0 +1,96 @@ +import { expect } from 'chai'; +import { Client } from '../../../../src/models/client'; +import { TransmissionHandler } from '../../../../src/messageHandler/handlers'; +import { Realm } from '../../../../src/models/realm'; +import { MessageType } from '../../../../src/enums'; +import { MyWebSocket } from '../../../../src/services/webSocketServer/webSocket'; + +const createFakeSocket = (): MyWebSocket => { + /* eslint-disable @typescript-eslint/no-empty-function */ + const sock = { + send: (): void => { }, + close: (): void => { }, + on: (): void => { }, + }; + /* eslint-enable @typescript-eslint/no-empty-function */ + + return (sock as unknown as MyWebSocket); +}; + +describe('Transmission handler', () => { + it('should save message in queue when destination client not connected', () => { + const realm = new Realm(); + const handleTransmission = TransmissionHandler({ realm }); + + const clientFrom = new Client({ id: 'id1', token: '' }); + const idTo = 'id2'; + realm.setClient(clientFrom, clientFrom.getId()); + + handleTransmission(clientFrom, { type: MessageType.OFFER, src: clientFrom.getId(), dst: idTo }); + + expect(realm.getMessageQueueById(idTo)?.getMessages().length).to.be.eq(1); + }); + + it('should not save LEAVE and EXPIRE messages in queue when destination client not connected', () => { + const realm = new Realm(); + const handleTransmission = TransmissionHandler({ realm }); + + const clientFrom = new Client({ id: 'id1', token: '' }); + const idTo = 'id2'; + realm.setClient(clientFrom, clientFrom.getId()); + + handleTransmission(clientFrom, { type: MessageType.LEAVE, src: clientFrom.getId(), dst: idTo }); + handleTransmission(clientFrom, { type: MessageType.EXPIRE, src: clientFrom.getId(), dst: idTo }); + + expect(realm.getMessageQueueById(idTo)).to.be.undefined; + }); + + it('should send message to destination client when destination client connected', () => { + const realm = new Realm(); + const handleTransmission = TransmissionHandler({ realm }); + + const clientFrom = new Client({ id: 'id1', token: '' }); + const clientTo = new Client({ id: 'id2', token: '' }); + const socketTo = createFakeSocket(); + clientTo.setSocket(socketTo); + realm.setClient(clientTo, clientTo.getId()); + + let sent = false; + socketTo.send = (): void => { + sent = true; + }; + + handleTransmission(clientFrom, { type: MessageType.OFFER, src: clientFrom.getId(), dst: clientTo.getId() }); + + expect(sent).to.be.true; + }); + + it('should send LEAVE message to source client when sending to destination client failed', () => { + const realm = new Realm(); + const handleTransmission = TransmissionHandler({ realm }); + + const clientFrom = new Client({ id: 'id1', token: '' }); + const clientTo = new Client({ id: 'id2', token: '' }); + const socketFrom = createFakeSocket(); + const socketTo = createFakeSocket(); + clientFrom.setSocket(socketFrom); + clientTo.setSocket(socketTo); + realm.setClient(clientFrom, clientFrom.getId()); + realm.setClient(clientTo, clientTo.getId()); + + let sent = false; + socketFrom.send = (data: string): void => { + if (JSON.parse(data)?.type === MessageType.LEAVE) { + sent = true; + } + }; + + socketTo.send = (): void => { + throw Error(); + }; + + handleTransmission(clientFrom, { type: MessageType.OFFER, src: clientFrom.getId(), dst: clientTo.getId() }); + + expect(sent).to.be.true; + }); +}); diff --git a/test/messageHandler/handlersRegistry.ts b/test/messageHandler/handlersRegistry.ts new file mode 100644 index 0000000..6791056 --- /dev/null +++ b/test/messageHandler/handlersRegistry.ts @@ -0,0 +1,23 @@ +import { expect } from 'chai'; +import { HandlersRegistry } from '../../src/messageHandler/handlersRegistry'; +import { Handler } from '../../src/messageHandler/handler'; +import { MessageType } from '../../src/enums'; + +describe('HandlersRegistry', () => { + it('should execute handler for message type', () => { + const handlersRegistry = new HandlersRegistry(); + + let handled = false; + + const handler: Handler = (): boolean => { + handled = true; + return true; + }; + + handlersRegistry.registerHandler(MessageType.OPEN, handler); + + handlersRegistry.handle(undefined, { type: MessageType.OPEN, src: 'src', dst: 'dst' }); + + expect(handled).to.be.true; + }); +});