import { classes } from '@automapper/classes'; import { AutomapperModule } from '@automapper/nestjs'; import { Test, TestingModule } from '@nestjs/testing'; import { UsernameRepository } from '../../adapters/secondaries/username.repository'; import { Username } from '../../domain/entities/username'; import { UpdateUsernameRequest } from '../../domain/dtos/update-username.request'; import { UpdateUsernameCommand } from '../../commands/update-username.command'; import { Type } from '../../domain/dtos/type.enum'; import { UpdateUsernameUseCase } from '../../domain/usecases/update-username.usecase'; import { CommandBus } from '@nestjs/cqrs'; import { UsernameProfile } from '../../mappers/username.profile'; import { BadRequestException } from '@nestjs/common'; import { Messager } from '../../adapters/secondaries/messager'; const existingUsername = { uuid: 'bb281075-1b98-4456-89d6-c643d3044a91', username: 'john.doe@email.com', type: Type.EMAIL, }; const newUsernameRequest: UpdateUsernameRequest = new UpdateUsernameRequest(); newUsernameRequest.uuid = 'bb281075-1b98-4456-89d6-c643d3044a90'; newUsernameRequest.username = '+33611223344'; newUsernameRequest.type = Type.PHONE; const updateUsernameRequest: UpdateUsernameRequest = new UpdateUsernameRequest(); updateUsernameRequest.uuid = 'bb281075-1b98-4456-89d6-c643d3044a91'; updateUsernameRequest.username = 'johnny.doe@email.com'; updateUsernameRequest.type = Type.EMAIL; const unknownUsernameRequest: UpdateUsernameRequest = new UpdateUsernameRequest(); unknownUsernameRequest.uuid = 'bb281075-1b98-4456-89d6-c643d3044a92'; unknownUsernameRequest.username = 'unknown@email.com'; unknownUsernameRequest.type = Type.EMAIL; const invalidUpdateUsernameRequest: UpdateUsernameRequest = new UpdateUsernameRequest(); invalidUpdateUsernameRequest.uuid = 'bb281075-1b98-4456-89d6-c643d3044a93'; invalidUpdateUsernameRequest.username = ''; invalidUpdateUsernameRequest.type = Type.EMAIL; const newUsernameCommand: UpdateUsernameCommand = new UpdateUsernameCommand( newUsernameRequest, ); const updateUsernameCommand: UpdateUsernameCommand = new UpdateUsernameCommand( updateUsernameRequest, ); const invalidUpdateUsernameCommand: UpdateUsernameCommand = new UpdateUsernameCommand(invalidUpdateUsernameRequest); const unknownUpdateUsernameCommand: UpdateUsernameCommand = new UpdateUsernameCommand(unknownUsernameRequest); const mockUsernameRepository = { findOne: jest.fn().mockImplementation((request) => { if (request.uuid == 'bb281075-1b98-4456-89d6-c643d3044a90') { return Promise.resolve(null); } return Promise.resolve(existingUsername); }), updateWhere: jest.fn().mockImplementation((request) => { if (request.uuid_type.uuid == 'bb281075-1b98-4456-89d6-c643d3044a90') { return Promise.resolve(newUsernameRequest); } if (request.uuid_type.uuid == 'bb281075-1b98-4456-89d6-c643d3044a91') { return Promise.resolve(updateUsernameRequest); } if (request.uuid_type.uuid == 'bb281075-1b98-4456-89d6-c643d3044a92') { throw new Error('Error'); } return Promise.resolve(invalidUpdateUsernameRequest); }), }; const mockAddUsernameCommand = { execute: jest.fn().mockResolvedValue(newUsernameRequest), }; const mockMessager = { publish: jest.fn().mockImplementation(), }; describe('UpdateUsernameUseCase', () => { let updateUsernameUseCase: UpdateUsernameUseCase; beforeAll(async () => { const module: TestingModule = await Test.createTestingModule({ imports: [AutomapperModule.forRoot({ strategyInitializer: classes() })], providers: [ { provide: UsernameRepository, useValue: mockUsernameRepository, }, { provide: CommandBus, useValue: mockAddUsernameCommand, }, { provide: Messager, useValue: mockMessager, }, UpdateUsernameUseCase, UsernameProfile, ], }).compile(); updateUsernameUseCase = module.get( UpdateUsernameUseCase, ); }); it('should be defined', () => { expect(updateUsernameUseCase).toBeDefined(); }); describe('execute', () => { it('should create a new username', async () => { const newUsername: Username = await updateUsernameUseCase.execute( newUsernameCommand, ); expect(newUsername.username).toBe(newUsernameRequest.username); expect(newUsername.type).toBe(newUsernameRequest.type); }); it('should update a username for email type', async () => { const updatedUsername: Username = await updateUsernameUseCase.execute( updateUsernameCommand, ); expect(updatedUsername.username).toBe(updateUsernameRequest.username); expect(updatedUsername.type).toBe(updateUsernameRequest.type); }); it('should throw an error if username does not exist', async () => { await expect( updateUsernameUseCase.execute(unknownUpdateUsernameCommand), ).rejects.toBeInstanceOf(Error); }); it('should throw an exception if username is invalid', async () => { await expect( updateUsernameUseCase.execute(invalidUpdateUsernameCommand), ).rejects.toBeInstanceOf(BadRequestException); }); }); });