diff --git a/src/modules/call/call.controller.spec.ts b/src/modules/call/call.controller.spec.ts index fcb4561..3c1ac66 100644 --- a/src/modules/call/call.controller.spec.ts +++ b/src/modules/call/call.controller.spec.ts @@ -316,11 +316,10 @@ describe('Testing Call Endpoints', () => { describe('Leaving a call', () => { it('When leaving a call for authenticated user, then it should leave successfully', async () => { callUseCase.leaveCall.mockResolvedValue(); + const leaveCallDto = new LeaveCallDto(); + leaveCallDto.userId = mockUserPayload.uuid; - const result = await callController.leaveCall( - mockRoomId, - mockUserPayload, - ); + const result = await callController.leaveCall(mockRoomId, leaveCallDto); expect(result).toBeUndefined(); expect(callUseCase.leaveCall).toHaveBeenCalledWith( @@ -336,7 +335,7 @@ describe('Testing Call Endpoints', () => { callUseCase.leaveCall.mockResolvedValue(); - await callController.leaveCall(mockRoomId, null, leaveCallDto); + await callController.leaveCall(mockRoomId, leaveCallDto); expect(callUseCase.leaveCall).toHaveBeenCalledWith( mockRoomId, @@ -350,16 +349,11 @@ describe('Testing Call Endpoints', () => { callUseCase.leaveCall.mockResolvedValue(); - const userToken = createMockUserToken(); - await callController.leaveCall( - mockRoomId, - userToken.payload, - leaveCallDto, - ); + await callController.leaveCall(mockRoomId, leaveCallDto); expect(callUseCase.leaveCall).toHaveBeenCalledWith( mockRoomId, - userToken.payload.uuid, + 'anonymous-user-id', ); }); @@ -367,20 +361,22 @@ describe('Testing Call Endpoints', () => { const emptyDto = new LeaveCallDto(); callUseCase.leaveCall.mockResolvedValue(); - await callController.leaveCall(mockRoomId, null, emptyDto); - - expect(callUseCase.leaveCall).toHaveBeenCalledWith(mockRoomId, undefined); + await expect( + callController.leaveCall(mockRoomId, emptyDto), + ).rejects.toThrow(BadRequestException); }); it('When room is not found, then it should propagate NotFoundException', async () => { - const userToken = createMockUserToken(); + const anonymousUserId = 'anonymous-user-id'; + const leaveCallDto = new LeaveCallDto(); + leaveCallDto.userId = anonymousUserId; callUseCase.leaveCall.mockRejectedValue( new NotFoundException('Specified room not found'), ); await expect( - callController.leaveCall(mockRoomId, userToken.payload), + callController.leaveCall(mockRoomId, leaveCallDto), ).rejects.toThrow(NotFoundException); }); diff --git a/src/modules/call/call.controller.ts b/src/modules/call/call.controller.ts index 4b44e90..32c77e6 100644 --- a/src/modules/call/call.controller.ts +++ b/src/modules/call/call.controller.ts @@ -173,12 +173,14 @@ export class CallController { }) @ApiNotFoundResponse({ description: 'Call/Room not found' }) @ApiInternalServerErrorResponse({ description: 'Internal server error' }) - leaveCall( + async leaveCall( @Param('id') roomId: string, - @User() user: UserTokenData['payload'], @Body() leaveCallDto?: LeaveCallDto, ): Promise { - const { uuid } = user || {}; - return this.callUseCase.leaveCall(roomId, uuid || leaveCallDto?.userId); + if (!leaveCallDto?.userId) { + this.logger.warn('Attempt to leave call without user ID:', leaveCallDto); + throw new BadRequestException('The user id is needed to leave the call'); + } + return this.callUseCase.leaveCall(roomId, leaveCallDto.userId); } } diff --git a/src/modules/call/call.usecase.spec.ts b/src/modules/call/call.usecase.spec.ts index cf31b28..ea3c821 100644 --- a/src/modules/call/call.usecase.spec.ts +++ b/src/modules/call/call.usecase.spec.ts @@ -246,7 +246,7 @@ describe('CallUseCase', () => { expect(result).toEqual({ token: 'test-jwt-token', room: roomId, - userId, + userId: autoGeneratedUUID, appId: 'jitsi-app-id', }); }); @@ -418,7 +418,7 @@ describe('CallUseCase', () => { expect(result).toEqual({ token: 'test-jwt-token', room: roomId, - userId, + userId: autoGeneratedUUID, appId: 'jitsi-app-id', }); }); @@ -490,7 +490,7 @@ describe('CallUseCase', () => { anonymous: false, }, ); - expect(result.userId).toEqual(roomUserMock.userId); + expect(result.userId).toEqual(roomUserMock.id); }); }); diff --git a/src/modules/call/call.usecase.ts b/src/modules/call/call.usecase.ts index 54d88a7..5cc46b8 100644 --- a/src/modules/call/call.usecase.ts +++ b/src/modules/call/call.usecase.ts @@ -182,7 +182,7 @@ export class CallUseCase { return { token: callTokenData, room: roomId, - userId: roomUser.userId, + userId: roomUser.id, appId: this.configService.get('jitsi.appId'), }; } diff --git a/src/modules/call/infrastructure/room-user.repository.spec.ts b/src/modules/call/infrastructure/room-user.repository.spec.ts index 7d742a5..55974e0 100644 --- a/src/modules/call/infrastructure/room-user.repository.spec.ts +++ b/src/modules/call/infrastructure/room-user.repository.spec.ts @@ -225,7 +225,7 @@ describe('SequelizeRoomUserRepository', () => { expect(deleteRoomUserSpy).toHaveBeenCalledWith({ where: { - userId: 'test-user-id', + id: 'test-user-id', roomId: 'test-room-id', }, }); diff --git a/src/modules/call/infrastructure/room-user.repository.ts b/src/modules/call/infrastructure/room-user.repository.ts index b7b90fe..d0a2653 100644 --- a/src/modules/call/infrastructure/room-user.repository.ts +++ b/src/modules/call/infrastructure/room-user.repository.ts @@ -82,7 +82,7 @@ export class SequelizeRoomUserRepository { } async deleteByUserIdAndRoomId(userId: string, roomId: string): Promise { - await this.roomUserModel.destroy({ where: { userId, roomId } }); + await this.roomUserModel.destroy({ where: { id: userId, roomId } }); } async findByParticipantIdAndRoomId( diff --git a/src/modules/call/services/call.service.spec.ts b/src/modules/call/services/call.service.spec.ts index fcbec6d..6e48b0f 100644 --- a/src/modules/call/services/call.service.spec.ts +++ b/src/modules/call/services/call.service.spec.ts @@ -86,4 +86,21 @@ describe('Call service', () => { expect(paymentService.getUserTier).toHaveBeenCalledWith(userPayload.uuid); }); + + it('When the user has meet enabled and isDevelopment, then a call should be created without calling payment service', async () => { + jest.spyOn(configService, 'get').mockReturnValueOnce(false); + const userPayload = mockUserPayload; + (uuid.v4 as jest.Mock).mockReturnValue('test-room-id'); + (jwt.sign as jest.Mock).mockReturnValue('test-jitsi-token'); + + const result = await callService.createCall(userPayload); + + expect(result).toEqual({ + appId: 'jitsi-app-id', + room: 'test-room-id', + paxPerCall: 10, + }); + + expect(paymentService.getUserTier).not.toHaveBeenCalled(); + }); }); diff --git a/src/modules/call/services/call.service.ts b/src/modules/call/services/call.service.ts index 3184e9f..ce7c368 100644 --- a/src/modules/call/services/call.service.ts +++ b/src/modules/call/services/call.service.ts @@ -48,6 +48,13 @@ export class CallService { private async getMeetFeatureConfigForUser( userUuid: string, ): Promise { + const isProduction = this.configService.get('isProduction'); + if (!isProduction) { + return { + enabled: true, + paxPerCall: 10, + }; + } const userFeatures = await this.paymentService .getUserTier(userUuid) .catch((err) => { diff --git a/src/modules/call/services/room.service.ts b/src/modules/call/services/room.service.ts index 4a819bb..2d2209d 100644 --- a/src/modules/call/services/room.service.ts +++ b/src/modules/call/services/room.service.ts @@ -157,22 +157,10 @@ export class RoomService { { transaction, lock: true }, ); - if (existingUser) { - if (existingUser.participantId) { + if (existingUser?.participantId) { oldParticipantId = existingUser.participantId; - } - - await this.roomUserRepository.update( - existingUser.id, - { - participantId: null, - joinedAt: null, - }, - transaction, - ); + } - roomUser = existingUser; - } else { roomUser = await this.roomUserRepository.create( { roomId, @@ -183,7 +171,6 @@ export class RoomService { }, transaction, ); - } }); return { roomUser, oldParticipantId };