import { UsernameMapper } from '@modules/authentication/username.mapper'; import { PrismaService } from '@modules/authentication/infrastructure/prisma.service'; import { EventEmitter2, EventEmitterModule } from '@nestjs/event-emitter'; import { Test, TestingModule } from '@nestjs/testing'; import { UsernameReadModel, UsernameRepository, } from '@modules/authentication/infrastructure/username.repository'; import { Type } from '@modules/authentication/core/domain/username.types'; import { UsernameEntity } from '@modules/authentication/core/domain/username.entity'; const mockPrismaService = { username: { findFirst: jest.fn().mockImplementation(async () => { const now = new Date('2023-06-21 06:00:00'); const record: UsernameReadModel = { authUuid: '330bd6de-1eb8-450b-8674-0e3c9209f048', type: Type.EMAIL, username: 'john.doe@email.com', createdAt: now, updatedAt: now, }; return record; }), update: jest.fn().mockImplementation(), delete: jest.fn().mockImplementation(), count: jest.fn().mockImplementation(), }, }; const mockMessagePublisher = { publish: jest.fn().mockImplementation(), }; describe('Username repository', () => { let usernameRepository: UsernameRepository; let prismaService: PrismaService; let usernameMapper: UsernameMapper; let eventEmitter: EventEmitter2; beforeAll(async () => { const module: TestingModule = await Test.createTestingModule({ imports: [EventEmitterModule.forRoot()], providers: [ { provide: PrismaService, useValue: mockPrismaService, }, UsernameMapper, ], }).compile(); prismaService = module.get(PrismaService); usernameMapper = module.get(UsernameMapper); eventEmitter = module.get(EventEmitter2); usernameRepository = new UsernameRepository( prismaService, usernameMapper, eventEmitter, mockMessagePublisher, ); }); afterEach(async () => { jest.clearAllMocks(); }); it('should be defined', () => { expect(usernameRepository).toBeDefined(); }); it('should find a username by its userId and Type', async () => { jest.spyOn(usernameRepository, 'findOne'); const username: UsernameEntity = await usernameRepository.findByType( '330bd6de-1eb8-450b-8674-0e3c9209f048', Type.EMAIL, ); expect(usernameRepository.findOne).toHaveBeenCalledTimes(1); expect(usernameRepository.findOne).toHaveBeenCalledWith({ authUuid: '330bd6de-1eb8-450b-8674-0e3c9209f048', type: Type.EMAIL, }); expect(username.getProps().name).toBe('john.doe@email.com'); }); it('should find a username by its name', async () => { jest.spyOn(usernameRepository, 'findOne'); const username: UsernameEntity = await usernameRepository.findByName('john.doe@email.com'); expect(usernameRepository.findOne).toHaveBeenCalledTimes(1); expect(usernameRepository.findOne).toHaveBeenCalledWith({ username: 'john.doe@email.com', }); expect(username.getProps().name).toBe('john.doe@email.com'); }); it('should update a username', async () => { jest.spyOn(usernameRepository, 'update'); const usernameToUpdate: UsernameEntity = await UsernameEntity.create({ userId: '165192d4-398a-4469-a16b-98c02cc6f531', type: Type.EMAIL, name: 'john.doe@new-email.com', }); await usernameRepository.updateUsername( 'john.doe@email.com', usernameToUpdate, ); expect(usernameRepository.update).toHaveBeenCalledTimes(1); expect(usernameRepository.update).toHaveBeenCalledWith( 'john.doe@email.com', usernameToUpdate, 'username', ); }); it('should delete a username', async () => { jest.spyOn(usernameRepository, 'delete'); const usernameToDelete: UsernameEntity = await UsernameEntity.create({ userId: '165192d4-398a-4469-a16b-98c02cc6f531', type: Type.EMAIL, name: 'john.doe@new-email.com', }); await usernameRepository.deleteUsername(usernameToDelete); expect(usernameRepository.delete).toHaveBeenCalledTimes(1); expect(usernameRepository.delete).toHaveBeenCalledWith( usernameToDelete, 'username', ); }); it('should count usernames for a given userId', async () => { jest.spyOn(usernameRepository, 'count'); await usernameRepository.countUsernames('john.doe@email.com'); expect(usernameRepository.count).toHaveBeenCalledTimes(1); expect(usernameRepository.count).toHaveBeenCalledWith({ authUuid: 'john.doe@email.com', }); }); });