fix: resolved conflicts
This commit is contained in:
commit
1f5699b1cf
9 changed files with 374 additions and 28 deletions
|
|
@ -0,0 +1 @@
|
|||
export type RequiredProperties<T, K extends keyof T> = T & Required<Pick<T, K>>;
|
||||
|
|
@ -5,11 +5,11 @@ export interface PsChargeTransactionRequestModel {
|
|||
email: string;
|
||||
authorization_code: string;
|
||||
reference?: string;
|
||||
currency: string;
|
||||
currency?: string;
|
||||
metadata?: string;
|
||||
channels?: Array<PsChannelsModel>;
|
||||
subaccount: string;
|
||||
transaction_charge: number;
|
||||
bearer: string;
|
||||
queue: boolean;
|
||||
subaccount?: string;
|
||||
transaction_charge?: number;
|
||||
bearer?: string;
|
||||
queue?: boolean;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
export interface PsExportTransactionResponseModel {
|
||||
import { PsBaseModel } from './ps-base.model';
|
||||
|
||||
export interface PsExportTransactionResponseModel extends PsBaseModel {
|
||||
data: PsExportTransactionResponseDataModel;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { PsAuthorizationModel, PsCustomerModel } from './';
|
||||
import { PsAuthorizationModel, PsBaseModel, PsCustomerModel } from './';
|
||||
|
||||
export interface PsPartialDebitResponseModel {
|
||||
export interface PsPartialDebitResponseModel extends PsBaseModel {
|
||||
data: PsPartialDebitResponseDataModel;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
export interface PsTransactionTotalsResponseModel {
|
||||
import { PsBaseModel } from './ps-base.model';
|
||||
|
||||
export interface PsTransactionTotalsResponseModel extends PsBaseModel {
|
||||
data: PsTransactionTotalsResponseDataModel;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,14 +2,26 @@ import { PsTransactionsService } from './ps-transactions.service';
|
|||
import { HttpService } from '@nestjs/axios';
|
||||
import { AxiosResponse } from 'axios';
|
||||
import {
|
||||
PsChargeTransactionRequestModel,
|
||||
PsChargeTransactionResponseModel,
|
||||
PsExportTransactionRequestModel,
|
||||
PsExportTransactionResponseModel,
|
||||
PsFetchTransactionResponseModel,
|
||||
PsInitializeTransactionRequestModel,
|
||||
PsInitializeTransactionResponseModel
|
||||
PsInitializeTransactionResponseModel,
|
||||
PsListTransactionsQueryParamsModel,
|
||||
PsListTransactionsResponseModel,
|
||||
PsPartialDebitRequestModel,
|
||||
PsPartialDebitResponseModel,
|
||||
PsTransactionTotalsRequestModel,
|
||||
PsTransactionTotalsResponseModel,
|
||||
PsVerifyTransactionResponseModel,
|
||||
PsViewTransactionTimeLineResponseModel
|
||||
} from '../../models';
|
||||
import { fromExact, fromPartial } from '@total-typescript/shoehorn';
|
||||
import { of } from 'rxjs';
|
||||
import { expectObservable } from '../../helpers/unit-test/unit-test.util';
|
||||
import { TestBed } from '@automock/jest';
|
||||
import DoneCallback = jest.DoneCallback;
|
||||
import { subscribeSpyTo } from '@hirez_io/observer-spy';
|
||||
|
||||
describe(PsTransactionsService.name, () => {
|
||||
let service: PsTransactionsService;
|
||||
|
|
@ -30,7 +42,8 @@ describe(PsTransactionsService.name, () => {
|
|||
});
|
||||
|
||||
describe('initializeTransaction', () => {
|
||||
it('should return initialize transaction response', (done: DoneCallback) => {
|
||||
it('should return initialize transaction response', () => {
|
||||
// Arrange
|
||||
const input: PsInitializeTransactionRequestModel = {
|
||||
amount: '20',
|
||||
email: 'test@gmail.com'
|
||||
|
|
@ -38,6 +51,8 @@ describe(PsTransactionsService.name, () => {
|
|||
const response: AxiosResponse<PsInitializeTransactionResponseModel> =
|
||||
fromPartial({
|
||||
data: fromPartial({
|
||||
status: true,
|
||||
message: 'Authorization URL created',
|
||||
data: fromExact({
|
||||
authorization_url: 'https://checkout.paystack.com/0peioxfhpn',
|
||||
access_code: '0peioxfhpn',
|
||||
|
|
@ -47,15 +62,307 @@ describe(PsTransactionsService.name, () => {
|
|||
});
|
||||
httpService.post.mockReturnValueOnce(of(response));
|
||||
|
||||
expectObservable(
|
||||
{
|
||||
actualObservable: service.initializeTransaction(input),
|
||||
done
|
||||
},
|
||||
(resp) => {
|
||||
expect(resp).toEqual(response.data);
|
||||
}
|
||||
// Act
|
||||
const observerSpy = subscribeSpyTo(service.initializeTransaction(input));
|
||||
|
||||
// Assert
|
||||
expect(observerSpy.getLastValue()).toEqual(response.data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('verifyTransaction', () => {
|
||||
it('should return confirmation of the status of a transaction', () => {
|
||||
// Arrange
|
||||
const input = 'l5b6sesmko';
|
||||
const response: AxiosResponse<PsVerifyTransactionResponseModel> =
|
||||
fromPartial({
|
||||
data: {
|
||||
status: true,
|
||||
message: 'Verification successful',
|
||||
data: fromPartial({
|
||||
id: 2009945086,
|
||||
status: 'success',
|
||||
reference: 'rd0bz6z2wu',
|
||||
amount: 2000,
|
||||
gateway_response: 'Successful'
|
||||
})
|
||||
}
|
||||
});
|
||||
httpService.get.mockReturnValueOnce(of(response));
|
||||
|
||||
// Act
|
||||
const observerSpy = subscribeSpyTo(service.verifyTransaction(input));
|
||||
|
||||
//Assert
|
||||
expect(observerSpy.getLastValue()).toEqual(response.data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('listTransactions', () => {
|
||||
it('should return list transactions carried out', () => {
|
||||
// Arrange
|
||||
const input: PsListTransactionsQueryParamsModel = {
|
||||
page: 1,
|
||||
perPage: 5
|
||||
};
|
||||
const response: AxiosResponse<PsListTransactionsResponseModel> =
|
||||
fromPartial({
|
||||
data: {
|
||||
status: true,
|
||||
message: 'Transactions retrieved',
|
||||
data: [
|
||||
fromPartial({
|
||||
id: 2009945086,
|
||||
status: 'success',
|
||||
reference: 'rd0bz6z2wu',
|
||||
amount: 2000,
|
||||
gateway_response: 'Successful'
|
||||
}),
|
||||
fromPartial({
|
||||
id: 2009945086,
|
||||
status: 'failed',
|
||||
reference: 'Declined',
|
||||
amount: 2000,
|
||||
gateway_response: 'Successful'
|
||||
})
|
||||
]
|
||||
}
|
||||
});
|
||||
httpService.get.mockReturnValueOnce(of(response));
|
||||
|
||||
// Act
|
||||
const observerSpy = subscribeSpyTo(service.listTransactions(input));
|
||||
|
||||
//Assert
|
||||
expect(observerSpy.getLastValue()).toEqual(response.data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchTransaction', () => {
|
||||
it('should return details of a transaction carried out', () => {
|
||||
// Arrange
|
||||
const input = 2836566657;
|
||||
const response: AxiosResponse<PsFetchTransactionResponseModel> =
|
||||
fromPartial({
|
||||
data: {
|
||||
status: true,
|
||||
message: 'Transaction retrieved',
|
||||
data: fromPartial({
|
||||
id: 2836566657,
|
||||
status: 'success',
|
||||
reference: '203520101',
|
||||
amount: 2000,
|
||||
gateway_response: 'Successful'
|
||||
})
|
||||
}
|
||||
});
|
||||
httpService.get.mockReturnValueOnce(of(response));
|
||||
|
||||
// Act
|
||||
const observerSpy = subscribeSpyTo(service.fetchTransaction(input));
|
||||
|
||||
//Assert
|
||||
expect(observerSpy.getLastValue()).toEqual(response.data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('chargeTransaction', () => {
|
||||
it('should return charge transaction response', () => {
|
||||
// Arrange
|
||||
const input: PsChargeTransactionRequestModel = {
|
||||
amount: '2000',
|
||||
email: 'customer@email.com',
|
||||
authorization_code: 'AUTH_72btv547'
|
||||
};
|
||||
const response: AxiosResponse<PsChargeTransactionResponseModel> =
|
||||
fromPartial({
|
||||
data: {
|
||||
status: true,
|
||||
message: 'Charge attempted',
|
||||
data: fromPartial({
|
||||
amount: 2000,
|
||||
status: 'success',
|
||||
reference: 'cn65lf4ixmkzvda',
|
||||
gateway_response: 'Approved',
|
||||
channel: 'card',
|
||||
transaction_date: '2020-05-27T11:45:03.000Z'
|
||||
})
|
||||
}
|
||||
});
|
||||
httpService.post.mockReturnValueOnce(of(response));
|
||||
|
||||
// Act
|
||||
const observerSpy = subscribeSpyTo(service.chargeTransaction(input));
|
||||
|
||||
//Assert
|
||||
expect(observerSpy.getLastValue()).toEqual(response.data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('viewTransactionTimeline', () => {
|
||||
it('should return view transaction timeline of a transaction', () => {
|
||||
// Arrange
|
||||
const input = 'cn65lf4ixmkzvda';
|
||||
const response: AxiosResponse<PsViewTransactionTimeLineResponseModel> =
|
||||
fromPartial({
|
||||
data: {
|
||||
status: true,
|
||||
message: 'Timeline retrieved',
|
||||
data: fromPartial({
|
||||
time_spent: 9061,
|
||||
attempts: 1,
|
||||
success: false,
|
||||
errors: 1,
|
||||
channel: 'card',
|
||||
history: [
|
||||
{
|
||||
type: 'open',
|
||||
message: 'Opened payment page',
|
||||
time: 1
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
message:
|
||||
'Filled these fields: card number, card expiry, card cvc',
|
||||
time: 39
|
||||
},
|
||||
{
|
||||
type: 'action',
|
||||
message: 'Attempted to pay',
|
||||
time: 39
|
||||
},
|
||||
{
|
||||
type: 'error',
|
||||
message: 'Error: Declined',
|
||||
time: 48
|
||||
},
|
||||
{
|
||||
type: 'close',
|
||||
message: 'Page closed',
|
||||
time: 9061
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
});
|
||||
httpService.get.mockReturnValueOnce(of(response));
|
||||
|
||||
// Act
|
||||
const observerSpy = subscribeSpyTo(
|
||||
service.viewTransactionTimeline(input)
|
||||
);
|
||||
|
||||
//Assert
|
||||
expect(observerSpy.getLastValue()).toEqual(response.data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('transactionTotals', () => {
|
||||
it('should return total amount received on your account', () => {
|
||||
// Arrange
|
||||
const input: PsTransactionTotalsRequestModel = {
|
||||
page: 1,
|
||||
perPage: 5
|
||||
};
|
||||
const response: AxiosResponse<PsTransactionTotalsResponseModel> =
|
||||
fromPartial({
|
||||
data: {
|
||||
status: true,
|
||||
message: 'Transaction totals',
|
||||
data: {
|
||||
total_transactions: 10,
|
||||
unique_customers: 3,
|
||||
total_volume: 14000,
|
||||
total_volume_by_currency: [
|
||||
{
|
||||
currency: 'ZAR',
|
||||
amount: 14000
|
||||
}
|
||||
],
|
||||
pending_transfers: 24000,
|
||||
pending_transfers_by_currency: [
|
||||
{
|
||||
currency: 'ZAR',
|
||||
amount: 24000
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
});
|
||||
httpService.get.mockReturnValueOnce(of(response));
|
||||
|
||||
// Act
|
||||
const observerSpy = subscribeSpyTo(service.transactionTotals(input));
|
||||
|
||||
//Assert
|
||||
expect(observerSpy.getLastValue()).toEqual(response.data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('exportTransaction', () => {
|
||||
it('should return an exported list of transactions carried out on your integration', () => {
|
||||
// Arrange
|
||||
const input: PsExportTransactionRequestModel = {
|
||||
page: 1,
|
||||
perPage: 5
|
||||
};
|
||||
const response: AxiosResponse<PsExportTransactionResponseModel> =
|
||||
fromPartial({
|
||||
data: {
|
||||
status: true,
|
||||
message: 'Export successful',
|
||||
data: {
|
||||
path: 'https://files.paystack.co/exports/100032/1460290758207.csv'
|
||||
}
|
||||
}
|
||||
});
|
||||
httpService.get.mockReturnValueOnce(of(response));
|
||||
|
||||
// Act
|
||||
const observerSpy = subscribeSpyTo(service.exportTransaction(input));
|
||||
|
||||
//Assert
|
||||
expect(observerSpy.getLastValue()).toEqual(response.data);
|
||||
});
|
||||
});
|
||||
|
||||
describe('partialDebit', () => {
|
||||
it('should return part of a payment from a customer', () => {
|
||||
// Arrange
|
||||
const input: PsPartialDebitRequestModel = {
|
||||
amount: '2000',
|
||||
email: 'customer@email.com',
|
||||
authorization_code: 'AUTH_72btv547',
|
||||
currency: 'ZAR'
|
||||
};
|
||||
const response: AxiosResponse<PsPartialDebitResponseModel> = fromPartial({
|
||||
data: {
|
||||
status: true,
|
||||
message: 'Charge attempted',
|
||||
data: fromPartial({
|
||||
amount: 2000,
|
||||
status: 'success',
|
||||
reference: 'cn65lf4ixmkzvda',
|
||||
gateway_response: 'Approved',
|
||||
channel: 'card',
|
||||
transaction_date: '2020-05-27T11:45:03.000Z',
|
||||
customer: {
|
||||
id: 37651078,
|
||||
email: 'customer@email.com',
|
||||
customer_code: 'CUS_q8vst7djnx3vq6d',
|
||||
risk_action: 'default',
|
||||
international_format_phone: null
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
httpService.post.mockReturnValueOnce(of(response));
|
||||
|
||||
// Act
|
||||
const observerSpy = subscribeSpyTo(service.partialDebit(input));
|
||||
|
||||
//Assert
|
||||
expect(observerSpy.getLastValue()).toEqual(response.data);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { BadRequestException, Inject, Injectable } from '@nestjs/common';
|
||||
import {
|
||||
PsChargeTransactionRequestModel,
|
||||
PsChargeTransactionResponseModel,
|
||||
|
|
@ -21,6 +21,7 @@ import { HttpService } from '@nestjs/axios';
|
|||
import { Observable } from 'rxjs';
|
||||
import { AxiosRequestConfig } from 'axios';
|
||||
import { handleResponseAndError, MODULE_OPTIONS_TOKEN } from '../../helpers';
|
||||
import { RequiredProperties } from '../../helpers/type.util.ts/required-properties';
|
||||
|
||||
@Injectable()
|
||||
export class PsTransactionsService {
|
||||
|
|
@ -42,8 +43,14 @@ export class PsTransactionsService {
|
|||
* @param payload
|
||||
*/
|
||||
initializeTransaction(
|
||||
payload: PsInitializeTransactionRequestModel
|
||||
payload: RequiredProperties<
|
||||
PsInitializeTransactionRequestModel,
|
||||
'amount' | 'email'
|
||||
>
|
||||
): Observable<PsInitializeTransactionResponseModel> {
|
||||
if (!payload?.amount && !payload?.email) {
|
||||
throw new BadRequestException('amount ');
|
||||
}
|
||||
return this.httpService
|
||||
.post<PsInitializeTransactionResponseModel>(
|
||||
'transaction/initialize',
|
||||
|
|
@ -73,7 +80,10 @@ export class PsTransactionsService {
|
|||
* @param queryParamsPayload - query parameters
|
||||
*/
|
||||
listTransactions(
|
||||
queryParamsPayload: PsListTransactionsQueryParamsModel
|
||||
queryParamsPayload: RequiredProperties<
|
||||
PsListTransactionsQueryParamsModel,
|
||||
'perPage' | 'page'
|
||||
>
|
||||
): Observable<PsListTransactionsResponseModel> {
|
||||
return this.httpService
|
||||
.get<PsListTransactionsResponseModel>('transaction', {
|
||||
|
|
@ -103,7 +113,10 @@ export class PsTransactionsService {
|
|||
* @param payload
|
||||
*/
|
||||
chargeTransaction(
|
||||
payload: PsChargeTransactionRequestModel
|
||||
payload: RequiredProperties<
|
||||
PsChargeTransactionRequestModel,
|
||||
'amount' | 'email' | 'authorization_code'
|
||||
>
|
||||
): Observable<PsChargeTransactionResponseModel> {
|
||||
return this.httpService
|
||||
.post<PsInitializeTransactionResponseModel>(
|
||||
|
|
@ -134,7 +147,10 @@ export class PsTransactionsService {
|
|||
* @param queryParamsPayload
|
||||
*/
|
||||
transactionTotals(
|
||||
queryParamsPayload: PsTransactionTotalsRequestModel
|
||||
queryParamsPayload: RequiredProperties<
|
||||
PsTransactionTotalsRequestModel,
|
||||
'perPage' | 'page'
|
||||
>
|
||||
): Observable<PsTransactionTotalsResponseModel> {
|
||||
return this.httpService
|
||||
.get<PsTransactionTotalsResponseModel>(`transaction/totals`, {
|
||||
|
|
@ -149,7 +165,10 @@ export class PsTransactionsService {
|
|||
* @param queryParamsPayload
|
||||
*/
|
||||
exportTransaction(
|
||||
queryParamsPayload: PsExportTransactionRequestModel
|
||||
queryParamsPayload: RequiredProperties<
|
||||
PsExportTransactionRequestModel,
|
||||
'perPage' | 'page'
|
||||
>
|
||||
): Observable<PsExportTransactionResponseModel> {
|
||||
return this.httpService
|
||||
.get<PsTransactionTotalsResponseModel>(`transaction/export`, {
|
||||
|
|
@ -164,7 +183,10 @@ export class PsTransactionsService {
|
|||
* @param payload
|
||||
*/
|
||||
partialDebit(
|
||||
payload: PsPartialDebitRequestModel
|
||||
payload: RequiredProperties<
|
||||
PsPartialDebitRequestModel,
|
||||
'authorization_code' | 'currency' | 'amount' | 'email'
|
||||
>
|
||||
): Observable<PsPartialDebitResponseModel> {
|
||||
return this.httpService
|
||||
.post<PsInitializeTransactionResponseModel>(
|
||||
|
|
|
|||
11
package-lock.json
generated
11
package-lock.json
generated
|
|
@ -21,6 +21,7 @@
|
|||
"devDependencies": {
|
||||
"@automock/jest": "^1.2.0",
|
||||
"@golevelup/ts-jest": "^0.3.7",
|
||||
"@hirez_io/observer-spy": "^2.2.0",
|
||||
"@nestjs/platform-express": "^9.1.1",
|
||||
"@nestjs/schematics": "^9.1.0",
|
||||
"@nestjs/testing": "^9.1.1",
|
||||
|
|
@ -2440,6 +2441,16 @@
|
|||
"integrity": "sha512-eoRfl9trBEt7BrQ6t3GHY/ZOcDOMBIOgqghd9qkIWMpcqQgWbU5Yf5UeHA6wwnLYpOMIJoKqazJ0cUDM79yr+g==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@hirez_io/observer-spy": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@hirez_io/observer-spy/-/observer-spy-2.2.0.tgz",
|
||||
"integrity": "sha512-G9nv87vjRILgB/X1AtKBv1DZX7yXSYAOCXon/f+QULKoXVhVehYUF5Lv0SQ97ebf1sA48Z2CyQ9h2v4Pz6DgaQ==",
|
||||
"dev": true,
|
||||
"peerDependencies": {
|
||||
"rxjs": ">=6.0.0",
|
||||
"typescript": ">=2.8.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array": {
|
||||
"version": "0.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
"devDependencies": {
|
||||
"@automock/jest": "^1.2.0",
|
||||
"@golevelup/ts-jest": "^0.3.7",
|
||||
"@hirez_io/observer-spy": "^2.2.0",
|
||||
"@nestjs/platform-express": "^9.1.1",
|
||||
"@nestjs/schematics": "^9.1.0",
|
||||
"@nestjs/testing": "^9.1.1",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue