preadeep xsy
preadeep xsy

Reputation: 21

How to write unit tests for http server upgrade and handle connection to websocket server?

I have following class and methods -

//A.ts
export abstract class A { }

// B.ts
import http from 'http';
import { Socket } from 'net';
import url, { URL } from 'url';
import { Server as WebSocketServer } from 'ws';
import { authenticateToken } from '../authenticate';

export class B extends A {

private _httpServer?: http.Server;
private _wsServer?: WebSocketServer;

constructor() {
    super();
}

protected async connect(): Promise<void> {
    await this.initializeServer();
    await this.upgradeHandler();
    await this.connectionHandler();
}


private async initializeServer(): Promise<void> {
    this._httpServer = http.createServer(async (request, response) => {
        const reqUrl = url.parse(request?.url || "", true);
        if (reqUrl.pathname === "/health" && request.method == 'GET') {
            const statusCode = this._isWorkerHealthy ? 200 : 503;
            response.writeHead(statusCode, { 'Content-Type': 'text/plain' });
            response.end();
        } else
            response.end("server created");
    });
    this._httpServer.on('error', error => console.log(error));
    this._httpServer.listen(8080);
    this._wsServer = new WebSocketServer({ noServer: true, path: '/ws' });
}

private async upgradeHandler(): Promise<void> {
    this._httpServer?.on('upgrade', async (request, clientSocket, head) => {
        try {
            // authenticate code
        }
        catch (err) {
            clientSocket.destroy();
            throw 'client not authenticated';
        }
        this._wsServer?.handleUpgrade(request, clientSocket as Socket, head, ws => {
            this._wsServer?.emit('connection', ws, request);
        });
    });
}

private async connectionHandler(): Promise<void> {
    this._wsServer?.on('connection', async (clientSocket, request) => {
        this._clientSocket = clientSocket;
        if (this._wSocket === undefined) {
            await this.anotherSocket(request.headers);
        }
        this._clientSocket.send("connected");
        this._wSocket?.on('message', data => {
            this._clientSocket?.send(data);
        });
        this._clientSocket?.on('message', data => {
            this._wSocket?.send(data);
        });
        this._clientSocket.on('error', error => {
            console.log(error)
            this.closeConnections();
        });
        this._clientSocket.on('close', async () => {
            close();
        });
    });
}

}

Basically I want to write tests for initializeServer, upgradeHandler and connectionHandler methods.

This is my test file -

//B.spec.ts

describe("B tests", ()=> {
    afterEach(() =>{
        jest.resetAllMocks();
    })
    it.only("",async() => {
        let bVal = new B(); 
        const spied = jest.spyOn(http,'createServer');
        bVal["connect"]();
        expect(spied).toBeCalled();
    })
})

I also want to cover the codes inside upgradeHandler and connectionHandler methods to increase the coverage of my tests but I found out that on('upgrade') method is not being called. I guess I need to pass some fake request with 'upgrade' headers but I am not sure. How can I mock and spy on the methods above and write some tests to increase the coverage?

I guess this is the extension of this post - How to send dummy request for spying on method inside http.createServer listner?

Upvotes: 1

Views: 203

Answers (0)

Related Questions