import { classes } from '@automapper/classes'; import { AutomapperModule } from '@automapper/nestjs'; import { Test, TestingModule } from '@nestjs/testing'; import { AuthenticationRepository } from '../../adapters/secondaries/authentication.repository'; import { Authentication } from '../../domain/entities/authentication'; import * as bcrypt from 'bcrypt'; import { ValidateAuthenticationUseCase } from '../../domain/usecases/validate-authentication.usecase'; import { ValidateAuthenticationQuery } from '../../queries/validate-authentication.query'; import { UsernameRepository } from '../../adapters/secondaries/username.repository'; import { Type } from '../../domain/dtos/type.enum'; import { NotFoundException, UnauthorizedException } from '@nestjs/common'; import { DatabaseException } from '../../../database/exceptions/database.exception'; import { ValidateAuthenticationRequest } from '../../domain/dtos/validate-authentication.request'; const mockAuthenticationRepository = { findOne: jest .fn() .mockImplementationOnce(() => ({ uuid: 'bb281075-1b98-4456-89d6-c643d3044a91', password: bcrypt.hashSync('John123', 10), })) .mockImplementationOnce(() => ({ uuid: 'bb281075-1b98-4456-89d6-c643d3044a91', password: bcrypt.hashSync('John123', 10), })), }; const mockUsernameRepository = { findOne: jest .fn() .mockImplementationOnce(() => ({ uuid: 'bb281075-1b98-4456-89d6-c643d3044a91', username: 'john.doe@email.com', type: Type.EMAIL, })) .mockImplementationOnce(() => { throw new DatabaseException(); }) .mockImplementationOnce(() => ({ uuid: 'bb281075-1b98-4456-89d6-c643d3044a91', username: 'john.doe@email.com', type: Type.EMAIL, })), }; describe('ValidateAuthenticationUseCase', () => { let validateAuthenticationUseCase: ValidateAuthenticationUseCase; beforeAll(async () => { const module: TestingModule = await Test.createTestingModule({ imports: [AutomapperModule.forRoot({ strategyInitializer: classes() })], providers: [ { provide: AuthenticationRepository, useValue: mockAuthenticationRepository, }, { provide: UsernameRepository, useValue: mockUsernameRepository, }, ValidateAuthenticationUseCase, ], }).compile(); validateAuthenticationUseCase = module.get( ValidateAuthenticationUseCase, ); }); it('should be defined', () => { expect(validateAuthenticationUseCase).toBeDefined(); }); describe('execute', () => { it('should validate an authentication and returns entity object', async () => { const validateAuthenticationRequest: ValidateAuthenticationRequest = new ValidateAuthenticationRequest(); validateAuthenticationRequest.username = 'john.doe@email.com'; validateAuthenticationRequest.password = 'John123'; const authentication: Authentication = await validateAuthenticationUseCase.execute( new ValidateAuthenticationQuery( validateAuthenticationRequest.username, validateAuthenticationRequest.password, ), ); expect(authentication.uuid).toBe('bb281075-1b98-4456-89d6-c643d3044a91'); }); it('should not validate an authentication with unknown username and returns not found exception', async () => { await expect( validateAuthenticationUseCase.execute( new ValidateAuthenticationQuery('jane.doe@email.com', 'Jane123'), ), ).rejects.toBeInstanceOf(NotFoundException); }); it('should not validate an authentication with wrong password and returns unauthorized exception', async () => { await expect( validateAuthenticationUseCase.execute( new ValidateAuthenticationQuery('john.doe@email.com', 'John1234'), ), ).rejects.toBeInstanceOf(UnauthorizedException); }); }); });