From 56735efc131ab338d9b7f96188dc5e633c2a0407 Mon Sep 17 00:00:00 2001 From: Brian Pooe Date: Sat, 17 Jun 2023 12:38:13 +0200 Subject: [PATCH] feat: made http service header reusable --- .env.sample | 3 ++ apps/ns-paystack-demo/src/app/app.module.ts | 8 ++-- .../ns-paystack/src/lib/ns-paystack.module.ts | 14 ++---- .../custom-http/custom-http.service.spec.ts | 22 +++++++++ .../custom-http/custom-http.service.ts | 47 +++++++++++++++++++ libs/ns-paystack/src/lib/services/index.ts | 1 + .../transaction-split.service.spec.ts | 26 ++++++++++ .../transaction-split.service.ts | 9 ++++ .../ps-transactions.service.spec.ts | 8 ++-- .../transactions/ps-transactions.service.ts | 46 ++++-------------- lint-staged.config.js | 2 +- 11 files changed, 129 insertions(+), 57 deletions(-) create mode 100644 .env.sample create mode 100644 libs/ns-paystack/src/lib/services/custom-http/custom-http.service.spec.ts create mode 100644 libs/ns-paystack/src/lib/services/custom-http/custom-http.service.ts create mode 100644 libs/ns-paystack/src/lib/services/transaction-split/transaction-split.service.spec.ts create mode 100644 libs/ns-paystack/src/lib/services/transaction-split/transaction-split.service.ts diff --git a/.env.sample b/.env.sample new file mode 100644 index 0000000..e1ae35d --- /dev/null +++ b/.env.sample @@ -0,0 +1,3 @@ +HTTP_TIMEOUT= +BASE_URL= +PAYSTACK_SECRET_KEY= diff --git a/apps/ns-paystack-demo/src/app/app.module.ts b/apps/ns-paystack-demo/src/app/app.module.ts index a8a2ca4..8360a8f 100644 --- a/apps/ns-paystack-demo/src/app/app.module.ts +++ b/apps/ns-paystack-demo/src/app/app.module.ts @@ -8,11 +8,9 @@ import { TransactionController } from './transactions/controllers/transaction.co @Module({ imports: [ NsPaystackModule.registerAsync({ - useFactory: (configService: ConfigService) => { - return { - secretKey: configService.get('PAYSTACK_SECRET_KEY') - }; - }, + useFactory: (configService: ConfigService) => ({ + secretKey: configService.get('PAYSTACK_SECRET_KEY') + }), inject: [ConfigService] }) ], diff --git a/libs/ns-paystack/src/lib/ns-paystack.module.ts b/libs/ns-paystack/src/lib/ns-paystack.module.ts index c89cdd6..16d8109 100644 --- a/libs/ns-paystack/src/lib/ns-paystack.module.ts +++ b/libs/ns-paystack/src/lib/ns-paystack.module.ts @@ -3,19 +3,11 @@ import { PsTransactionsService } from './services'; import { HttpModule } from '@nestjs/axios'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { ConfigurableModuleClass } from './helpers'; +import { CustomHttpService } from './services/custom-http/custom-http.service'; @Module({ - imports: [ - HttpModule.registerAsync({ - imports: [ConfigModule], - useFactory: async (configService: ConfigService) => ({ - timeout: configService.get('HTTP_TIMEOUT'), - baseURL: configService.get('BASE_URL') - }), - inject: [ConfigService] - }) - ], - providers: [PsTransactionsService, ConfigService], + imports: [HttpModule, ConfigModule], + providers: [PsTransactionsService, ConfigService, CustomHttpService], exports: [PsTransactionsService] }) export class NsPaystackModule extends ConfigurableModuleClass {} diff --git a/libs/ns-paystack/src/lib/services/custom-http/custom-http.service.spec.ts b/libs/ns-paystack/src/lib/services/custom-http/custom-http.service.spec.ts new file mode 100644 index 0000000..a5cac3d --- /dev/null +++ b/libs/ns-paystack/src/lib/services/custom-http/custom-http.service.spec.ts @@ -0,0 +1,22 @@ +import { CustomHttpService } from './custom-http.service'; +import { TestBed } from '@automock/jest'; +import { ConfigService } from '@nestjs/config'; + +describe('CustomHttpService', () => { + let service: CustomHttpService; + + beforeAll(() => { + const { unit, unitRef } = TestBed.create(CustomHttpService) + .mock(ConfigService) + .using({ + get: jest.fn() + }) + .compile(); + + service = unit; + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/libs/ns-paystack/src/lib/services/custom-http/custom-http.service.ts b/libs/ns-paystack/src/lib/services/custom-http/custom-http.service.ts new file mode 100644 index 0000000..17e74ee --- /dev/null +++ b/libs/ns-paystack/src/lib/services/custom-http/custom-http.service.ts @@ -0,0 +1,47 @@ +import { Inject, Injectable } from '@nestjs/common'; +import { HttpService } from '@nestjs/axios'; +import { MODULE_OPTIONS_TOKEN, PsConfigModel } from '../../models'; +import { AxiosRequestConfig, AxiosResponse } from 'axios'; +import { Observable } from 'rxjs'; +import { ConfigService } from '@nestjs/config'; + +@Injectable() +export class CustomHttpService extends HttpService { + axiosRequestConfig: AxiosRequestConfig = { + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${this.appConfigService.secretKey}` + } + }; + + constructor( + @Inject(MODULE_OPTIONS_TOKEN) + private readonly appConfigService: PsConfigModel, + private readonly configService: ConfigService + ) { + super(); + this.axiosRef.defaults.timeout = configService.get('HTTP_TIMEOUT'); + this.axiosRef.defaults.baseURL = configService.get('BASE_URL'); + } + + override get( + url: string, + config?: AxiosRequestConfig + ): Observable> { + return super.get(url, { + ...config, + headers: this.axiosRequestConfig.headers + }); + } + + override post( + url: string, + data?: any, + config?: AxiosRequestConfig + ): Observable> { + return super.post(url, data, { + ...config, + headers: this.axiosRequestConfig.headers + }); + } +} diff --git a/libs/ns-paystack/src/lib/services/index.ts b/libs/ns-paystack/src/lib/services/index.ts index 54c33bf..a5f858f 100644 --- a/libs/ns-paystack/src/lib/services/index.ts +++ b/libs/ns-paystack/src/lib/services/index.ts @@ -1 +1,2 @@ export * from './transactions/ps-transactions.service'; +export * from './transaction-split/transaction-split.service'; diff --git a/libs/ns-paystack/src/lib/services/transaction-split/transaction-split.service.spec.ts b/libs/ns-paystack/src/lib/services/transaction-split/transaction-split.service.spec.ts new file mode 100644 index 0000000..677ba96 --- /dev/null +++ b/libs/ns-paystack/src/lib/services/transaction-split/transaction-split.service.spec.ts @@ -0,0 +1,26 @@ +import { TransactionSplitService } from './transaction-split.service'; +import { CustomHttpService } from '../custom-http/custom-http.service'; +import { TestBed } from '@automock/jest'; + +describe(TransactionSplitService.name, () => { + let service: TransactionSplitService; + let httpService: jest.Mocked; + + beforeAll(() => { + const { unit, unitRef } = TestBed.create(TransactionSplitService) + .mock(CustomHttpService) + .using({ + post: jest.fn(), + get: jest.fn() + }) + .compile(); + + service = unit; + + httpService = unitRef.get(CustomHttpService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/libs/ns-paystack/src/lib/services/transaction-split/transaction-split.service.ts b/libs/ns-paystack/src/lib/services/transaction-split/transaction-split.service.ts new file mode 100644 index 0000000..ec3dd4f --- /dev/null +++ b/libs/ns-paystack/src/lib/services/transaction-split/transaction-split.service.ts @@ -0,0 +1,9 @@ +import { Injectable } from '@nestjs/common'; +import { CustomHttpService } from '../custom-http/custom-http.service'; + +@Injectable() +export class TransactionSplitService { + constructor(private readonly httpService: CustomHttpService) {} + + // createSplit() {} +} diff --git a/libs/ns-paystack/src/lib/services/transactions/ps-transactions.service.spec.ts b/libs/ns-paystack/src/lib/services/transactions/ps-transactions.service.spec.ts index 079fe0c..31f13df 100644 --- a/libs/ns-paystack/src/lib/services/transactions/ps-transactions.service.spec.ts +++ b/libs/ns-paystack/src/lib/services/transactions/ps-transactions.service.spec.ts @@ -1,5 +1,4 @@ import { PsTransactionsService } from './ps-transactions.service'; -import { HttpService } from '@nestjs/axios'; import { AxiosResponse } from 'axios'; import { PsChargeTransactionRequestModel, @@ -22,14 +21,15 @@ import { fromExact, fromPartial } from '@total-typescript/shoehorn'; import { of } from 'rxjs'; import { TestBed } from '@automock/jest'; import { subscribeSpyTo } from '@hirez_io/observer-spy'; +import { CustomHttpService } from '../custom-http/custom-http.service'; describe(PsTransactionsService.name, () => { let service: PsTransactionsService; - let httpService: jest.Mocked; + let httpService: jest.Mocked; beforeAll(() => { const { unit, unitRef } = TestBed.create(PsTransactionsService) - .mock(HttpService) + .mock(CustomHttpService) .using({ post: jest.fn(), get: jest.fn() @@ -38,7 +38,7 @@ describe(PsTransactionsService.name, () => { service = unit; - httpService = unitRef.get(HttpService); + httpService = unitRef.get(CustomHttpService); }); describe('initializeTransaction', () => { diff --git a/libs/ns-paystack/src/lib/services/transactions/ps-transactions.service.ts b/libs/ns-paystack/src/lib/services/transactions/ps-transactions.service.ts index 20d19f6..7ba3814 100644 --- a/libs/ns-paystack/src/lib/services/transactions/ps-transactions.service.ts +++ b/libs/ns-paystack/src/lib/services/transactions/ps-transactions.service.ts @@ -1,8 +1,7 @@ -import { BadRequestException, Inject, Injectable } from '@nestjs/common'; +import { BadRequestException, Injectable } from '@nestjs/common'; import { PsChargeTransactionRequestModel, PsChargeTransactionResponseModel, - PsConfigModel, PsExportTransactionRequestModel, PsExportTransactionResponseModel, PsFetchTransactionResponseModel, @@ -17,25 +16,13 @@ import { PsVerifyTransactionResponseModel, PsViewTransactionTimeLineResponseModel } from '../../models'; -import { HttpService } from '@nestjs/axios'; import { Observable } from 'rxjs'; -import { AxiosRequestConfig } from 'axios'; -import { handleResponseAndError, MODULE_OPTIONS_TOKEN } from '../../helpers'; +import { handleResponseAndError } from '../../helpers'; +import { CustomHttpService } from '../custom-http/custom-http.service'; @Injectable() export class PsTransactionsService { - axiosRequestConfig: AxiosRequestConfig = { - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${this.appConfig.secretKey}` - } - }; - - constructor( - @Inject(MODULE_OPTIONS_TOKEN) - private readonly appConfig: PsConfigModel, - private readonly httpService: HttpService - ) {} + constructor(private readonly httpService: CustomHttpService) {} /** * Initialize a transaction @@ -50,8 +37,7 @@ export class PsTransactionsService { return this.httpService .post( 'transaction/initialize', - payload, - this.axiosRequestConfig + payload ) .pipe(handleResponseAndError()); } @@ -64,10 +50,7 @@ export class PsTransactionsService { reference: string ): Observable { return this.httpService - .get( - `transaction/verify/${reference}`, - this.axiosRequestConfig - ) + .get(`transaction/verify/${reference}`) .pipe(handleResponseAndError()); } @@ -80,7 +63,6 @@ export class PsTransactionsService { ): Observable { return this.httpService .get('transaction', { - ...this.axiosRequestConfig, params: queryParamsPayload }) .pipe(handleResponseAndError()); @@ -94,10 +76,7 @@ export class PsTransactionsService { transactionId: number ): Observable { return this.httpService - .get( - `transaction/${transactionId}`, - this.axiosRequestConfig - ) + .get(`transaction/${transactionId}`) .pipe(handleResponseAndError()); } @@ -111,8 +90,7 @@ export class PsTransactionsService { return this.httpService .post( 'transaction/charge_authorization', - payload, - this.axiosRequestConfig + payload ) .pipe(handleResponseAndError()); } @@ -126,8 +104,7 @@ export class PsTransactionsService { ): Observable { return this.httpService .get( - `transaction/timeline/${idOrReference}`, - this.axiosRequestConfig + `transaction/timeline/${idOrReference}` ) .pipe(handleResponseAndError()); } @@ -141,7 +118,6 @@ export class PsTransactionsService { ): Observable { return this.httpService .get(`transaction/totals`, { - ...this.axiosRequestConfig, params: queryParamsPayload }) .pipe(handleResponseAndError()); @@ -156,7 +132,6 @@ export class PsTransactionsService { ): Observable { return this.httpService .get(`transaction/export`, { - ...this.axiosRequestConfig, params: queryParamsPayload }) .pipe(handleResponseAndError()); @@ -172,8 +147,7 @@ export class PsTransactionsService { return this.httpService .post( 'transaction/partial_debit', - payload, - this.axiosRequestConfig + payload ) .pipe(handleResponseAndError()); } diff --git a/lint-staged.config.js b/lint-staged.config.js index f167a48..8a8e72a 100644 --- a/lint-staged.config.js +++ b/lint-staged.config.js @@ -1,5 +1,5 @@ module.exports = { - '{libs,apps, tools, .github}/**/*.{ts,js,json,md,html,css,scss,yml,yaml}': [ + '{libs,apps,tools,.github}/**/*.{ts,js,json,md,html,css,scss,yml,yaml}': [ 'nx affected --target typecheck --uncommitted', 'nx affected --target lint --uncommitted --fix true', 'nx affected --target test --uncommitted',