diff --git a/src/modules/authentication/authentication.module.ts b/src/modules/authentication/authentication.module.ts index 71b9b4c..9b5ad69 100644 --- a/src/modules/authentication/authentication.module.ts +++ b/src/modules/authentication/authentication.module.ts @@ -26,6 +26,7 @@ import { UpdatePasswordService } from './core/application/commands/update-passwo import { ValidateAuthenticationGrpcController } from './interface/grpc-controllers/validate-authentication.grpc.controller'; import { ValidateAuthenticationQueryHandler } from './core/application/queries/validate-authentication/validate-authentication.query-handler'; import { UserUpdatedMessageHandler } from './interface/message-handlers/user-updated.message-handler'; +import { UserDeletedMessageHandler } from './interface/message-handlers/user-deleted.message-handler'; const grpcControllers = [ CreateAuthenticationGrpcController, @@ -37,7 +38,7 @@ const grpcControllers = [ ValidateAuthenticationGrpcController, ]; -const messageHandlers = [UserUpdatedMessageHandler]; +const messageHandlers = [UserUpdatedMessageHandler, UserDeletedMessageHandler]; const commandHandlers: Provider[] = [ CreateAuthenticationService, diff --git a/src/modules/authentication/interface/message-handlers/user-deleted.message-handler.ts b/src/modules/authentication/interface/message-handlers/user-deleted.message-handler.ts new file mode 100644 index 0000000..ccbe54d --- /dev/null +++ b/src/modules/authentication/interface/message-handlers/user-deleted.message-handler.ts @@ -0,0 +1,24 @@ +import { Injectable } from '@nestjs/common'; +import { CommandBus } from '@nestjs/cqrs'; +import { RabbitSubscribe } from '@mobicoop/message-broker-module'; +import { DeleteAuthenticationCommand } from '@modules/authentication/core/application/commands/delete-authentication/delete-authentication.command'; + +@Injectable() +export class UserDeletedMessageHandler { + constructor(private readonly commandBus: CommandBus) {} + + @RabbitSubscribe({ + name: 'userDeleted', + }) + public async userDeleted(message: string) { + const deletedUser = JSON.parse(message); + try { + if (!deletedUser.hasOwnProperty('userId')) throw new Error(); + await this.commandBus.execute( + new DeleteAuthenticationCommand({ + userId: deletedUser.userId, + }), + ); + } catch (e: any) {} + } +} diff --git a/src/modules/authentication/tests/unit/interface/user-deleted.message-handler.spec.ts b/src/modules/authentication/tests/unit/interface/user-deleted.message-handler.spec.ts new file mode 100644 index 0000000..17e8c1d --- /dev/null +++ b/src/modules/authentication/tests/unit/interface/user-deleted.message-handler.spec.ts @@ -0,0 +1,54 @@ +import { UserDeletedMessageHandler } from '@modules/authentication/interface/message-handlers/user-deleted.message-handler'; +import { CommandBus } from '@nestjs/cqrs'; +import { Test, TestingModule } from '@nestjs/testing'; + +const userDeletedMessage = '{"userId":"2436d413-b7c7-429e-9792-b78edc17b3ca"}'; + +const userIdNotProvidedDeletedMessage = + '{"user":"2436d413-b7c7-429e-9792-b78edc17b300"}'; + +const mockCommandBus = { + execute: jest.fn().mockImplementationOnce(() => 'john.doe@email.com'), +}; + +describe('User Deleted Message Handler', () => { + let userDeletedMessageHandler: UserDeletedMessageHandler; + + beforeAll(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + { + provide: CommandBus, + useValue: mockCommandBus, + }, + UserDeletedMessageHandler, + ], + }).compile(); + + userDeletedMessageHandler = module.get( + UserDeletedMessageHandler, + ); + }); + + afterEach(async () => { + jest.clearAllMocks(); + }); + + it('should be defined', () => { + expect(userDeletedMessageHandler).toBeDefined(); + }); + + it('should delete an authentication', async () => { + jest.spyOn(mockCommandBus, 'execute'); + await userDeletedMessageHandler.userDeleted(userDeletedMessage); + expect(mockCommandBus.execute).toHaveBeenCalledTimes(1); + }); + + it('should not update an authentication if userId is not provided', async () => { + jest.spyOn(mockCommandBus, 'execute'); + await userDeletedMessageHandler.userDeleted( + userIdNotProvidedDeletedMessage, + ); + expect(mockCommandBus.execute).toHaveBeenCalledTimes(0); + }); +}); diff --git a/src/modules/authentication/tests/unit/interface/user-updated.message-handler.spec.ts b/src/modules/authentication/tests/unit/interface/user-updated.message-handler.spec.ts index 5f490e7..6b18907 100644 --- a/src/modules/authentication/tests/unit/interface/user-updated.message-handler.spec.ts +++ b/src/modules/authentication/tests/unit/interface/user-updated.message-handler.spec.ts @@ -66,35 +66,11 @@ describe('User Updated Message Handler', () => { expect(mockCommandBus.execute).toHaveBeenCalledTimes(0); }); - it('should not update a username if userId is unknown', async () => { + it('should not update a username if userId is not provided', async () => { jest.spyOn(mockCommandBus, 'execute'); await userUpdatedMessageHandler.userUpdated( userIdNotProvidedUpdatedMessage, ); expect(mockCommandBus.execute).toHaveBeenCalledTimes(0); }); - - // it('should throw a dedicated RpcException if username already exists', async () => { - // jest.spyOn(mockCommandBus, 'execute'); - // expect.assertions(3); - // try { - // await updateUsernameGrpcController.updateUsername(updateUsernameRequest); - // } catch (e: any) { - // expect(e).toBeInstanceOf(RpcException); - // expect(e.error.code).toBe(RpcExceptionCode.ALREADY_EXISTS); - // } - // expect(mockCommandBus.execute).toHaveBeenCalledTimes(1); - // }); - - // it('should throw a generic RpcException', async () => { - // jest.spyOn(mockCommandBus, 'execute'); - // expect.assertions(3); - // try { - // await updateUsernameGrpcController.updateUsername(updateUsernameRequest); - // } catch (e: any) { - // expect(e).toBeInstanceOf(RpcException); - // expect(e.error.code).toBe(RpcExceptionCode.UNKNOWN); - // } - // expect(mockCommandBus.execute).toHaveBeenCalledTimes(1); - // }); });