From d9d96b8589cace8619dbff1ec42000278864986d Mon Sep 17 00:00:00 2001 From: Eugenio Sales Date: Sat, 15 Oct 2022 23:31:38 -0300 Subject: [PATCH] feature #4 - add controller and serializer of get exchange rate microsservice --- .../exchangeRate/getExchangeRateController.ts | 53 ++++++++++++++++ .../exchangeRate/getExchangeRate/input.ts | 14 +++++ .../exchangeRate/getExchangeRate/output.ts | 5 ++ .../getExchangeRateUseCase.test.ts | 6 +- .../getExchangeRateController.test.ts | 60 +++++++++++++++++++ 5 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 src/3-adapters/controller/exchangeRate/getExchangeRateController.ts create mode 100644 src/3-adapters/serializers/exchangeRate/getExchangeRate/input.ts create mode 100644 src/3-adapters/serializers/exchangeRate/getExchangeRate/output.ts create mode 100644 test/unit/3-adpters/exchangeRate/getExchangeRateController.test.ts diff --git a/src/3-adapters/controller/exchangeRate/getExchangeRateController.ts b/src/3-adapters/controller/exchangeRate/getExchangeRateController.ts new file mode 100644 index 0000000..4334986 --- /dev/null +++ b/src/3-adapters/controller/exchangeRate/getExchangeRateController.ts @@ -0,0 +1,53 @@ +import { IExchangeRateRepository } from '../../../2-business/repositories/iExchangeRateRepository' +import { GetExchangeRateUseCase } from '../../../2-business/useCases/exchangeRate/getExchangeRateUseCase' +import { ControllerBase } from '../../controllerBase' +import { Output } from '../../../2-business/dto/output' +import { ExchangeRate } from '../../../1-domain/entities/exchangeRate' +import { InputGetExchangeRate } from '../../serializers/exchangeRate/getExchangeRate/input' +import { OutputGetExchangeRate } from '../../serializers/exchangeRate/getExchangeRate/output' +import { ExchangeRateError } from '../../../2-business/constants/errorData' + +export class GetExchangeRateController extends ControllerBase { + constructor ( + private readonly exchangeRateRepository: IExchangeRateRepository + ) { super() } + + async run (input: InputGetExchangeRate): Promise> { + const logPrefix = 'GetExchangeRateController' + console.log(`${logPrefix} :: start`) + console.log(`${logPrefix} ::`, input) + + try { + const updateExchangeRateUseCase = new GetExchangeRateUseCase( + this.exchangeRateRepository + ) + + const exchangeRate: ExchangeRate = await updateExchangeRateUseCase.execute(input) + + console.log(`${logPrefix} :: end`) + + return { + httpCode: 200, + status: 'success', + data: { exchangeRate } + } + + } catch (error) { + console.error(error) + + if (error instanceof ExchangeRateError) { + return { + httpCode: 404, + status: 'fail', + message: error.message + } + } + + return { + httpCode: 400, + status: 'error', + message: 'general error' + } + } + } +} diff --git a/src/3-adapters/serializers/exchangeRate/getExchangeRate/input.ts b/src/3-adapters/serializers/exchangeRate/getExchangeRate/input.ts new file mode 100644 index 0000000..35e0ad0 --- /dev/null +++ b/src/3-adapters/serializers/exchangeRate/getExchangeRate/input.ts @@ -0,0 +1,14 @@ +import { InputClassValidator } from '../../../../4-framework/utility/classValidator' +import { IsNotEmpty, IsString } from 'class-validator' +import { CurrencyEnum } from '../../../../2-business/enums/currencyEnum' + +export class InputGetExchangeRate extends InputClassValidator { + @IsNotEmpty() + @IsString() + baseCurrency!: CurrencyEnum + + constructor (obj: Partial) { + super() + Object.assign(this, obj) + } +} diff --git a/src/3-adapters/serializers/exchangeRate/getExchangeRate/output.ts b/src/3-adapters/serializers/exchangeRate/getExchangeRate/output.ts new file mode 100644 index 0000000..1168470 --- /dev/null +++ b/src/3-adapters/serializers/exchangeRate/getExchangeRate/output.ts @@ -0,0 +1,5 @@ +import { ExchangeRate } from '../../../../1-domain/entities/exchangeRate' + +export interface OutputGetExchangeRate { + exchangeRate: ExchangeRate +} diff --git a/test/unit/2-business/exchangeRate/getExchangeRateUseCase.test.ts b/test/unit/2-business/exchangeRate/getExchangeRateUseCase.test.ts index 6975a6f..1fd360d 100644 --- a/test/unit/2-business/exchangeRate/getExchangeRateUseCase.test.ts +++ b/test/unit/2-business/exchangeRate/getExchangeRateUseCase.test.ts @@ -6,7 +6,7 @@ import { GetExchangeRateInputDto } from '../../../../src/2-business/dto/exchange describe('GetExchangeRateUseCase', () => { const exchangeRateMock: ExchangeRate = { - baseCurrency: 'BRL', + baseCurrency: CurrencyEnum.BRL, rates: { 'AUD': 1.566015, 'CAD': 1.560132, @@ -19,7 +19,7 @@ describe('GetExchangeRateUseCase', () => { } const mockInput: GetExchangeRateInputDto = { - base: CurrencyEnum.BRL + baseCurrency: CurrencyEnum.BRL } let exchangeRateRepository: IExchangeRateRepository @@ -56,6 +56,6 @@ describe('GetExchangeRateUseCase', () => { exchangeRateRepository ) - await expect(useCase.execute({ base: CurrencyEnum.USD })).rejects.toThrow() + await expect(useCase.execute({ baseCurrency: CurrencyEnum.USD })).rejects.toThrow() }) }) diff --git a/test/unit/3-adpters/exchangeRate/getExchangeRateController.test.ts b/test/unit/3-adpters/exchangeRate/getExchangeRateController.test.ts new file mode 100644 index 0000000..1cc0045 --- /dev/null +++ b/test/unit/3-adpters/exchangeRate/getExchangeRateController.test.ts @@ -0,0 +1,60 @@ +import { GetExchangeRateController } from '../../../../src/3-adapters/controller/exchangeRate/getExchangeRateController' +import { IExchangeRateRepository } from '../../../../src/2-business/repositories/iExchangeRateRepository' +import { ExchangeRate } from '../../../../src/1-domain/entities/exchangeRate' +import { CurrencyEnum } from '../../../../src/2-business/enums/currencyEnum' +import { InputGetExchangeRate } from '../../../../src/3-adapters/serializers/exchangeRate/getExchangeRate/input' + +jest.mock('../../../../src/2-business/useCases/exchangeRate/updateExchangeRateUseCase') + +describe('UpdateExchangeRateController', () => { + const exchangeRateMock: ExchangeRate = { + baseCurrency: CurrencyEnum.BRL, + rates: { + 'AUD': 1.566015, + 'CAD': 1.560132, + 'CHF': 1.154727, + 'CNY': 7.827874, + 'GBP': 0.882047, + 'JPY': 132.360679, + 'USD': 1.23396 + } + } + + const inputMock = new InputGetExchangeRate({ + baseCurrency: CurrencyEnum.BRL + }) + + let exchangeRateRepository: IExchangeRateRepository + let GetExchangeRateUseCase = jest.fn() + + const setMocks = () => { + exchangeRateRepository = { + upsert: jest.fn().mockResolvedValue(null), + get: jest.fn().mockResolvedValue(exchangeRateMock) + } + GetExchangeRateUseCase.mockClear() + } + + beforeEach(() => { + setMocks() + }) + + test('Success::should get the exchange rates successfully', async () => { + GetExchangeRateUseCase.mockImplementation(() => { + return { + execute: jest.fn().mockResolvedValue(exchangeRateMock) + } + }) + const controller = new GetExchangeRateController( + exchangeRateRepository + ) + + const response = await controller.run(inputMock) + + expect(response).toEqual({ + httpCode: 200, + status: 'success', + data: { exchangeRate: exchangeRateMock } + }) + }) +})