diff --git a/package.json b/package.json index bbabe30..46efac1 100644 --- a/package.json +++ b/package.json @@ -101,7 +101,7 @@ ".port.ts", "libs/exceptions", "libs/types", - "prisma-service.base.ts", + "prisma.service.ts", "main.ts" ], "rootDir": "src", @@ -121,7 +121,7 @@ ".port.ts", "libs/exceptions", "libs/types", - "prisma-service.base.ts", + "prisma.service.ts", "main.ts" ], "coverageDirectory": "../coverage", diff --git a/src/libs/tests/unit/db/prisma-repository.base.spec.ts b/src/libs/tests/unit/db/prisma-repository.base.spec.ts index 9217dfe..49eca17 100644 --- a/src/libs/tests/unit/db/prisma-repository.base.spec.ts +++ b/src/libs/tests/unit/db/prisma-repository.base.spec.ts @@ -2,7 +2,11 @@ import { ResponseBase } from '@libs/api/response.base'; import { PrismaRepositoryBase } from '@libs/db/prisma-repository.base'; import { PrismaService } from '@libs/db/prisma.service'; import { AggregateID, AggregateRoot, Mapper, RepositoryPort } from '@libs/ddd'; -import { ConflictException } from '@libs/exceptions'; +import { + ConflictException, + DatabaseErrorException, + NotFoundException, +} from '@libs/exceptions'; import { Injectable, Logger } from '@nestjs/common'; import { EventEmitter2 } from '@nestjs/event-emitter'; import { Test, TestingModule } from '@nestjs/testing'; @@ -45,33 +49,33 @@ class FakeResponseDto extends ResponseBase { name: string; } -const fakeDbWriteModel: FakeModel = { +const fakeRecord: FakeModel = { uuid: 'd567ea3b-4981-43c9-9449-a409b5fa9fed', name: 'fakeName', createdAt: new Date('2023-06-28T16:02:00Z'), updatedAt: new Date('2023-06-28T16:02:00Z'), }; -let modelId = 2; -const modelUuid = 'uuid-'; -const modelName = 'name-'; +let recordId = 2; +const recordUuid = 'uuid-'; +const recordName = 'fakeName-'; -const createRandomModel = (): FakeModel => { - const fakeModel: FakeModel = { - uuid: `${modelUuid}${modelId}`, - name: `${modelName}${modelId}`, +const createRandomRecord = (): FakeModel => { + const fakeRecord: FakeModel = { + uuid: `${recordUuid}${recordId}`, + name: `${recordName}${recordId}`, createdAt: new Date('2023-06-30T08:00:00Z'), updatedAt: new Date('2023-06-30T08:00:00Z'), }; - modelId++; + recordId++; - return fakeModel; + return fakeRecord; }; -const fakeModels: FakeModel[] = []; +const fakeRecords: FakeModel[] = []; Array.from({ length: 10 }).forEach(() => { - fakeModels.push(createRandomModel()); + fakeRecords.push(createRandomRecord()); }); @Injectable() @@ -117,12 +121,6 @@ class FakePrismaService extends PrismaService { const mockPrismaService = { $queryRaw: jest .fn() - .mockImplementationOnce(() => { - throw new Prisma.PrismaClientKnownRequestError('unknown request', { - code: 'code', - clientVersion: 'version', - }); - }) .mockImplementationOnce(() => { return true; }) @@ -131,11 +129,14 @@ const mockPrismaService = { code: 'code', clientVersion: 'version', }); + }) + .mockImplementationOnce(() => { + throw new Error(); }), fake: { create: jest .fn() - .mockResolvedValueOnce(fakeDbWriteModel) + .mockResolvedValueOnce(fakeRecord) .mockImplementationOnce(() => { throw new Prisma.PrismaClientKnownRequestError('Already exists', { code: 'code', @@ -143,28 +144,26 @@ const mockPrismaService = { }); }) .mockImplementationOnce(() => { - throw new Error('an unknown error'); + throw new Error('An unknown error'); }), findUnique: jest.fn().mockImplementation(async (params?: any) => { - let model: FakeModel; + let record: FakeModel; if (params?.where?.uuid) { - model = fakeModels.find( - (entity) => entity.uuid === params?.where?.uuid, + record = fakeRecords.find( + (record) => record.uuid === params?.where?.uuid, ); } - if (!model && params?.where?.uuid == 'unknown') { + if (!record && params?.where?.uuid == 'uuid-triggering-error') { throw new Prisma.PrismaClientKnownRequestError('unknown request', { code: 'code', clientVersion: 'version', }); - } else if (!model) { - throw new Error('No record found'); } - return model; + return record; }), }, }; @@ -216,7 +215,7 @@ describe('PrismaRepositoryBase', () => { }); describe('insert', () => { - it('should create a model', async () => { + it('should create a record', async () => { jest.spyOn(prisma.fake, 'create'); await fakeRepository.insert( @@ -227,7 +226,7 @@ describe('PrismaRepositoryBase', () => { expect(prisma.fake.create).toHaveBeenCalledTimes(1); }); - it('should throw a ConflictException if model already exists', async () => { + it('should throw a ConflictException if record already exists', async () => { await expect( fakeRepository.insert( FakeEntity.create({ @@ -237,7 +236,7 @@ describe('PrismaRepositoryBase', () => { ).rejects.toBeInstanceOf(ConflictException); }); - it('should throw an exception an error occurs', async () => { + it('should throw an Error if an error occurs', async () => { await expect( fakeRepository.insert( FakeEntity.create({ @@ -247,4 +246,42 @@ describe('PrismaRepositoryBase', () => { ).rejects.toBeInstanceOf(Error); }); }); + + describe('findOneById', () => { + it('should find a record by its id', async () => { + const record = await fakeRepository.findOneById('uuid-3'); + expect(record.getProps().name).toBe('fakeName-3'); + }); + + it('should throw an Error for client error', async () => { + await expect( + fakeRepository.findOneById('uuid-triggering-error'), + ).rejects.toBeInstanceOf(Error); + }); + + it('should throw a NotFoundException if id is not found', async () => { + await expect( + fakeRepository.findOneById('wrong-id'), + ).rejects.toBeInstanceOf(NotFoundException); + }); + }); + + describe('healthCheck', () => { + it('should return a healthy result', async () => { + const res = await fakeRepository.healthCheck(); + expect(res).toBeTruthy(); + }); + + it('should throw an exception if database is not available', async () => { + await expect(fakeRepository.healthCheck()).rejects.toBeInstanceOf( + DatabaseErrorException, + ); + }); + + it('should throw a DatabaseErrorException if an error occurs', async () => { + await expect(fakeRepository.healthCheck()).rejects.toBeInstanceOf( + DatabaseErrorException, + ); + }); + }); });