Search code examples
javascriptsocket.iojestjsnestjssupertest

NestJS, SuperTest - Socket doesn't get event


I am struggling with my e2e test about my socket.

The socket connects and logs well to the NestJS Gateway, but it doesn't come into my listener bedRequest.

My test consists of sending a create request through supertest and at the end, the gateway broadcasts a message to connected sockets and I want to verify it.

In Gateway logs, I see the client connected, logIn, and disconnected if it can help.

Thank you in advance.

 it("/POST bedRequest", (done) => {
        let bedRequestCreate = some payload
        let expectedResult = other payload

        const address = app.getHttpServer().listen().address();
        const baseAddress = `http://[${address.address}]:${address.port}`;
        const client = io(`${baseAddress}/`);

        client.on("connect", () => { // this works
            client.emit("logIn", {access_token: accessToken}, (isConnected) => {
                expect(isConnected).toBeTruthy(); // this works

                client.on("bedRequest", (data) => { // this doesn't work
                    expect(JSON.parse(data)).toMatchObject({
                        siteId: bedRequestCreate.siteId,
                        ...expectedResult
                    });
                    done();
                });
            });
        });

        return request(app.getHttpServer())
            .post("/api/bedRequest/")
            .send(bedRequestCreate)
            .set('Accept', 'application/json')
            .set('Authorization', 'Bearer ' + accessToken)
            .expect('Content-Type', /json/)
            .expect(201)
            .end((err, res) => {
                if (err) return done(err);
                expect(res.body.generatedMaps[0]).toMatchObject(expectedResult); // this works
            });
    });

Gateway :

@WebSocketGateway()
export class SocketGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect {

    @WebSocketServer() server: Server;

    wsClients = [];

    private logger: Logger = new Logger('SocketGateway');

    handleDisconnect(client: Client) {
        for (let i = 0; i < this.wsClients.length; i++) {
            if (this.wsClients[i] === client) {
                this.wsClients.splice(i, 1);
                break;
            }
        }
        this.logger.log(`Client disconnected: ${client.id}`);
    }

    broadcast(event: String, message: any) {
        const broadCastMessage = JSON.stringify(message);
        for (let c of this.wsClients) { // sends to the right client
            c.send(event, broadCastMessage);
        }
    }

    @UseGuards(WebSocketJwtAuthGuard)
    @SubscribeMessage("logIn")
    handleLogIn(client) { // works
        this.logger.log(`Socket Client connected : ${client.id} for user ${client.user.id} / ${client.mail}`);
        this.wsClients.push(client);
        return true;
    }

    handleConnection(client) {
        return `Client connected: ${client.id}`;
    }

    afterInit() {
        this.logger.log("SocketGateway initialized")
    }

}

Solution

  • Okay I found it...

    It was because of this line : c.send(event, broadCastMessage);

    I changed send by emit and it works fine.