From 54b811a72c986f485b5dc33908a007f1b60b648b Mon Sep 17 00:00:00 2001 From: Gsk54 Date: Wed, 11 Jan 2023 12:49:00 +0100 Subject: [PATCH 1/3] better tests --- package.json | 3 +- .../tests/unit/add-username.usecase.spec.ts | 14 ++++- .../tests/unit/create-auth.usecase.spec.ts | 31 ++++++---- .../tests/unit/delete-auth.usecase.spec.ts | 17 ++++-- .../unit/delete-username.usecase.spec.ts | 12 ++-- .../unit/update-password.usecase.spec.ts | 27 ++++++--- .../unit/update-username.usecase.spec.ts | 59 +++++++++++++------ .../tests/unit/validate-auth.usecase.spec.ts | 10 +++- 8 files changed, 124 insertions(+), 49 deletions(-) diff --git a/package.json b/package.json index 742d9d1..bd82535 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "test:unit:ci": "jest --testPathPattern 'tests/unit/' --coverage", "test:integration": "npm run migrate:test && dotenv -e .env.test -- jest --testPathPattern 'tests/integration/' --verbose", "test:integration:ci": "npm run migrate:test:ci && dotenv -e ci/.env.ci -- jest --testPathPattern 'tests/integration/'", - "test:cov": "npm run migrate:test && dotenv -e .env.test -- jest --coverage", + "test:cov": "jest --testPathPattern 'tests/unit/' --coverage", "test:e2e": "jest --config ./test/jest-e2e.json", "migrate": "docker exec v3-auth sh -c 'npx prisma migrate dev'", "migrate:test": "dotenv -e .env.test -- npx prisma migrate deploy", @@ -80,6 +80,7 @@ "json", "ts" ], + "modulePathIgnorePatterns": [".controller.ts",".module.ts"], "rootDir": "src", "testRegex": ".*\\.spec\\.ts$", "transform": { diff --git a/src/modules/auth/tests/unit/add-username.usecase.spec.ts b/src/modules/auth/tests/unit/add-username.usecase.spec.ts index 092e830..e6a3cba 100644 --- a/src/modules/auth/tests/unit/add-username.usecase.spec.ts +++ b/src/modules/auth/tests/unit/add-username.usecase.spec.ts @@ -20,7 +20,14 @@ const addUsernameCommand: AddUsernameCommand = new AddUsernameCommand( ); const mockUsernameRepository = { - create: jest.fn().mockResolvedValue(addUsernameRequest), + create: jest + .fn() + .mockImplementationOnce(() => { + return Promise.resolve(addUsernameRequest); + }) + .mockImplementation(() => { + throw new Error('Already exists'); + }), }; const mockMessager = { @@ -63,5 +70,10 @@ describe('AddUsernameUseCase', () => { expect(addedUsername.username).toBe(addUsernameRequest.username); expect(addedUsername.type).toBe(addUsernameRequest.type); }); + it('should throw an error if user already exists', async () => { + await expect( + addUsernameUseCase.execute(addUsernameCommand), + ).rejects.toBeInstanceOf(Error); + }); }); }); diff --git a/src/modules/auth/tests/unit/create-auth.usecase.spec.ts b/src/modules/auth/tests/unit/create-auth.usecase.spec.ts index e93fb00..6d521f3 100644 --- a/src/modules/auth/tests/unit/create-auth.usecase.spec.ts +++ b/src/modules/auth/tests/unit/create-auth.usecase.spec.ts @@ -11,19 +11,25 @@ import { UsernameRepository } from '../../adapters/secondaries/username.reposito import { Type } from '../../domain/dtos/type.enum'; import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; -const newAuthRequest: CreateAuthRequest = { - uuid: 'bb281075-1b98-4456-89d6-c643d3044a91', - username: 'john.doe@email.com', - password: 'John123', - type: Type.EMAIL, -}; +const newAuthRequest: CreateAuthRequest = new CreateAuthRequest(); +newAuthRequest.uuid = 'bb281075-1b98-4456-89d6-c643d3044a91'; +newAuthRequest.username = 'john.doe@email.com'; +newAuthRequest.password = 'John123'; +newAuthRequest.type = Type.EMAIL; const newAuthCommand: CreateAuthCommand = new CreateAuthCommand(newAuthRequest); const mockAuthRepository = { - create: jest.fn().mockResolvedValue({ - uuid: newAuthRequest.uuid, - password: bcrypt.hashSync(newAuthRequest.password, 10), - }), + create: jest + .fn() + .mockImplementationOnce(() => { + return Promise.resolve({ + uuid: newAuthRequest.uuid, + password: bcrypt.hashSync(newAuthRequest.password, 10), + }); + }) + .mockImplementation(() => { + throw new Error('Already exists'); + }), }; const mockUsernameRepository = { @@ -76,5 +82,10 @@ describe('CreateAuthUseCase', () => { bcrypt.compareSync(newAuthRequest.password, newAuth.password), ).toBeTruthy(); }); + it('should throw an error if user already exists', async () => { + await expect( + createAuthUseCase.execute(newAuthCommand), + ).rejects.toBeInstanceOf(Error); + }); }); }); diff --git a/src/modules/auth/tests/unit/delete-auth.usecase.spec.ts b/src/modules/auth/tests/unit/delete-auth.usecase.spec.ts index 9db5ab2..da0ce4b 100644 --- a/src/modules/auth/tests/unit/delete-auth.usecase.spec.ts +++ b/src/modules/auth/tests/unit/delete-auth.usecase.spec.ts @@ -25,15 +25,19 @@ const usernames = { total: 2, }; -const deleteAuthRequest: DeleteAuthRequest = { - uuid: 'bb281075-1b98-4456-89d6-c643d3044a91', -}; +const deleteAuthRequest: DeleteAuthRequest = new DeleteAuthRequest(); +deleteAuthRequest.uuid = 'bb281075-1b98-4456-89d6-c643d3044a91'; const deleteAuthCommand: DeleteAuthCommand = new DeleteAuthCommand( deleteAuthRequest, ); const mockAuthRepository = { - delete: jest.fn().mockResolvedValue(undefined), + delete: jest + .fn() + .mockResolvedValueOnce(undefined) + .mockImplementation(() => { + throw new Error('Error'); + }), }; const mockUsernameRepository = { @@ -85,5 +89,10 @@ describe('DeleteAuthUseCase', () => { expect(deletedAuth).toBe(undefined); }); + it('should throw an error if auth does not exist', async () => { + await expect( + deleteAuthUseCase.execute(deleteAuthCommand), + ).rejects.toBeInstanceOf(Error); + }); }); }); diff --git a/src/modules/auth/tests/unit/delete-username.usecase.spec.ts b/src/modules/auth/tests/unit/delete-username.usecase.spec.ts index 9ad3c69..501cabd 100644 --- a/src/modules/auth/tests/unit/delete-username.usecase.spec.ts +++ b/src/modules/auth/tests/unit/delete-username.usecase.spec.ts @@ -36,13 +36,13 @@ const usernamesPhone = { total: 1, }; -const deleteUsernameEmailRequest: DeleteUsernameRequest = { - username: 'john.doe@email.com', -}; +const deleteUsernameEmailRequest: DeleteUsernameRequest = + new DeleteUsernameRequest(); +deleteUsernameEmailRequest.username = 'john.doe@email.com'; -const deleteUsernamePhoneRequest: DeleteUsernameRequest = { - username: '0611223344', -}; +const deleteUsernamePhoneRequest: DeleteUsernameRequest = + new DeleteUsernameRequest(); +deleteUsernamePhoneRequest.username = '0611223344'; const deleteUsernameEmailCommand: DeleteUsernameCommand = new DeleteUsernameCommand(deleteUsernameEmailRequest); diff --git a/src/modules/auth/tests/unit/update-password.usecase.spec.ts b/src/modules/auth/tests/unit/update-password.usecase.spec.ts index b074c5b..a7f4990 100644 --- a/src/modules/auth/tests/unit/update-password.usecase.spec.ts +++ b/src/modules/auth/tests/unit/update-password.usecase.spec.ts @@ -9,19 +9,25 @@ import { UpdatePasswordCommand } from '../../commands/update-password.command'; import { UpdatePasswordUseCase } from '../../domain/usecases/update-password.usecase'; import { LoggingMessager } from '../../adapters/secondaries/logging.messager'; -const updatePasswordRequest: UpdatePasswordRequest = { - uuid: 'bb281075-1b98-4456-89d6-c643d3044a91', - password: 'John123', -}; +const updatePasswordRequest: UpdatePasswordRequest = + new UpdatePasswordRequest(); +updatePasswordRequest.uuid = 'bb281075-1b98-4456-89d6-c643d3044a91'; +updatePasswordRequest.password = 'John123'; + const updatePasswordCommand: UpdatePasswordCommand = new UpdatePasswordCommand( updatePasswordRequest, ); const mockAuthRepository = { - update: jest.fn().mockResolvedValue({ - uuid: updatePasswordRequest.uuid, - password: bcrypt.hashSync(updatePasswordRequest.password, 10), - }), + update: jest + .fn() + .mockResolvedValueOnce({ + uuid: updatePasswordRequest.uuid, + password: bcrypt.hashSync(updatePasswordRequest.password, 10), + }) + .mockImplementation(() => { + throw new Error('Error'); + }), }; const mockMessager = { @@ -66,5 +72,10 @@ describe('UpdatePasswordUseCase', () => { bcrypt.compareSync(updatePasswordRequest.password, newAuth.password), ).toBeTruthy(); }); + it('should throw an error if auth does not exist', async () => { + await expect( + updatePasswordUseCase.execute(updatePasswordCommand), + ).rejects.toBeInstanceOf(Error); + }); }); }); diff --git a/src/modules/auth/tests/unit/update-username.usecase.spec.ts b/src/modules/auth/tests/unit/update-username.usecase.spec.ts index 45e10e7..2fcc95b 100644 --- a/src/modules/auth/tests/unit/update-username.usecase.spec.ts +++ b/src/modules/auth/tests/unit/update-username.usecase.spec.ts @@ -18,23 +18,28 @@ const existingUsername = { type: Type.EMAIL, }; -const updateUsernameRequest: UpdateUsernameRequest = { - uuid: 'bb281075-1b98-4456-89d6-c643d3044a91', - username: 'johnny.doe@email.com', - type: Type.EMAIL, -}; +const updateUsernameRequest: UpdateUsernameRequest = + new UpdateUsernameRequest(); +updateUsernameRequest.uuid = 'bb281075-1b98-4456-89d6-c643d3044a91'; +updateUsernameRequest.username = 'johnny.doe@email.com'; +updateUsernameRequest.type = Type.EMAIL; -const newUsernameRequest: UpdateUsernameRequest = { - uuid: 'bb281075-1b98-4456-89d6-c643d3044a91', - username: '+33611223344', - type: Type.PHONE, -}; +const newUsernameRequest: UpdateUsernameRequest = new UpdateUsernameRequest(); +newUsernameRequest.uuid = 'bb281075-1b98-4456-89d6-c643d3044a91'; +newUsernameRequest.username = '+33611223344'; +newUsernameRequest.type = Type.PHONE; -const invalidUpdateUsernameRequest: UpdateUsernameRequest = { - uuid: 'bb281075-1b98-4456-89d6-c643d3044a91', - username: '', - type: Type.EMAIL, -}; +const invalidUpdateUsernameRequest: UpdateUsernameRequest = + new UpdateUsernameRequest(); +invalidUpdateUsernameRequest.uuid = 'bb281075-1b98-4456-89d6-c643d3044a91'; +invalidUpdateUsernameRequest.username = ''; +invalidUpdateUsernameRequest.type = Type.EMAIL; + +const unknownUsernameRequest: UpdateUsernameRequest = + new UpdateUsernameRequest(); +unknownUsernameRequest.uuid = 'bb281075-1b98-4456-89d6-c643d3044a91'; +unknownUsernameRequest.username = 'unknown@email.com'; +unknownUsernameRequest.type = Type.EMAIL; const updateUsernameCommand: UpdateUsernameCommand = new UpdateUsernameCommand( updateUsernameRequest, @@ -47,13 +52,25 @@ const newUsernameCommand: UpdateUsernameCommand = new UpdateUsernameCommand( const invalidUpdateUsernameCommand: UpdateUsernameCommand = new UpdateUsernameCommand(invalidUpdateUsernameRequest); +const unknownUpdateUsernameCommand: UpdateUsernameCommand = + new UpdateUsernameCommand(unknownUsernameRequest); + const mockUsernameRepository = { findOne: jest.fn().mockResolvedValue(existingUsername), updateWhere: jest .fn() - .mockResolvedValueOnce(updateUsernameRequest) - .mockResolvedValueOnce(newUsernameRequest) - .mockResolvedValueOnce(invalidUpdateUsernameRequest), + .mockImplementationOnce(() => { + return Promise.resolve(updateUsernameRequest); + }) + .mockImplementationOnce(() => { + return Promise.resolve(newUsernameRequest); + }) + .mockImplementationOnce(() => { + throw new Error('Error'); + }) + .mockImplementationOnce(() => { + return Promise.resolve(invalidUpdateUsernameRequest); + }), }; const mockAddUsernameCommand = { @@ -116,6 +133,12 @@ describe('UpdateUsernameUseCase', () => { expect(newUsername.type).toBe(newUsernameRequest.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), diff --git a/src/modules/auth/tests/unit/validate-auth.usecase.spec.ts b/src/modules/auth/tests/unit/validate-auth.usecase.spec.ts index 1dc5a54..f1bb4f6 100644 --- a/src/modules/auth/tests/unit/validate-auth.usecase.spec.ts +++ b/src/modules/auth/tests/unit/validate-auth.usecase.spec.ts @@ -10,6 +10,7 @@ import { UsernameRepository } from '../../adapters/secondaries/username.reposito import { Type } from '../../domain/dtos/type.enum'; import { NotFoundException, UnauthorizedException } from '@nestjs/common'; import { DatabaseException } from '../../../database/src/exceptions/DatabaseException'; +import { ValidateAuthRequest } from '../../domain/dtos/validate-auth.request'; const mockAuthRepository = { findOne: jest @@ -70,8 +71,15 @@ describe('ValidateAuthUseCase', () => { describe('execute', () => { it('should validate an auth and returns entity object', async () => { + const validateAuthRequest: ValidateAuthRequest = + new ValidateAuthRequest(); + validateAuthRequest.username = 'john.doe@email.com'; + validateAuthRequest.password = 'John123'; const auth: Auth = await validateAuthUseCase.execute( - new ValidateAuthQuery('john.doe@email.com', 'John123'), + new ValidateAuthQuery( + validateAuthRequest.username, + validateAuthRequest.password, + ), ); expect(auth.uuid).toBe('bb281075-1b98-4456-89d6-c643d3044a91'); From 034b7afc8487566797d4382dcf6edbe74a1825bd Mon Sep 17 00:00:00 2001 From: Gsk54 Date: Wed, 11 Jan 2023 12:50:04 +0100 Subject: [PATCH 2/3] better tests --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1a9ffdf..cbfc0c1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,7 +7,7 @@ stages: # TEST STAGE # ############## -integration-test: +test: stage: test image: docker/compose:latest variables: From c8c37fb1d0192ed72471244cd0bff441fa782159 Mon Sep 17 00:00:00 2001 From: Gsk54 Date: Wed, 11 Jan 2023 12:53:38 +0100 Subject: [PATCH 3/3] better tests --- .gitlab-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cbfc0c1..98ce039 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -17,7 +17,6 @@ test: script: - docker-compose -f docker-compose.ci.yml --env-file ci/.env.ci up -d - sh ci/wait-up.sh - - docker-compose -f docker-compose.ci.yml --env-file ci/.env.ci logs - docker exec -t v3-auth sh -c "npm run test:integration:ci" coverage: /All files[^|]*\|[^|]*\s+([\d\.]+)/ rules: