Skip to content

Instantly share code, notes, and snippets.

@DominicGBauer
Created October 11, 2023 05:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DominicGBauer/a5596cf609efa5760330b9984784bc4f to your computer and use it in GitHub Desktop.
Save DominicGBauer/a5596cf609efa5760330b9984784bc4f to your computer and use it in GitHub Desktop.
Example for Job Application
import { expect } from 'chai';
import * as sinon from 'sinon';
import * as dayjs from 'dayjs';
import * as mongoose from 'mongoose';
import { set } from 'lodash';
import * as sut from './paymentProviderSettlements.rules';
import * as model from './paymentProviderSettlements.models';
import * as paymentRules from '../../models/payments.rules';
import { IPayments } from '../../models/payments.types';
import { IPaymentProviderSettlements } from './paymentProviderSettlements.types';
describe('rules: payment provider settlements', () => {
afterEach(sinon.restore);
describe('create', () => {
it('should create payment provider settlements record', async () => {
sinon.stub(model, 'create').resolves([
{
_id: '51a7e105-f193-450d-9030-c5114acce4f8' as any,
amountInCents: 90000,
bankTransactionId: '40b85fa0-95e4-44df-8cd0-18d265603247' as any,
bankTransactionReference: 'ExampleRef6789',
paymentProvider: 'PEACH',
paymentProviderPaymentId: '444-444',
paymentReference: '1234-5678',
transactionDate: dayjs('2018-01-01T00:00:00.000Z').toDate(),
settlementDate: dayjs('2023-08-31T10:00:00.034Z').toDate(),
originalPaymentId: '40615926-47a4-4278-bbf5-e9806e4f4713' as any,
fileStorageReference: '/incoming/examplePath.csv',
} as any, // Fixed in mongoose v7.5.4: https://github.com/Automattic/mongoose/issues/13930
]);
sinon.stub(paymentRules, 'getSuccessfulUnreconciledPayments').resolves([]);
sinon.stub(sut, 'matchPaymentProviderSettlementsToPayments').resolves([]);
const paymentProviderSettlementsToCreate = [
{
paymentProviderPaymentId: '444-444',
amountInCents: 90000,
bankTransactionReference: 'ExampleRef6789',
paymentProvider: 'PEACH',
transactionDate: dayjs('2018-01-01T00:00:00.000Z').toDate(),
paymentReference: '1234-5678',
fileStorageReference: '/incoming/examplePath.csv',
},
];
const createdSettlements = await sut.create(paymentProviderSettlementsToCreate);
expect(createdSettlements).to.be.undefined;
});
});
describe('updateById', () => {
it('should update payment provider settlement', async () => {
sinon.stub(model, 'updateById').resolves();
const bankToUpdate = {
bankTransactionId: '40b85fa0-95e4-44df-8cd0-18d265603247' as any,
};
await sut.updateById('51a7e105-f193-450d-9030-c5114acce4f8', bankToUpdate);
});
});
describe('matchPaymentProviderSettlementsToPayments', () => {
it('should match a payment to a settlement by changing the original payment ID on payment provider settlement', async () => {
const connectorId = new mongoose.Types.ObjectId();
const paymentProviderSettlements = [
{
paymentReference: connectorId.toString(),
},
] as IPaymentProviderSettlements;
const payments = [
{
_id: new mongoose.Types.ObjectId(),
connectorData: { connectorId: connectorId.toString() } as any,
reconciliated: false,
paid: true,
},
] as IPayments;
const result = sut.matchPaymentProviderSettlementsToPayments(paymentProviderSettlements, payments);
expect(result).to.deep.equal([
{
paymentReference: connectorId.toString(),
originalPaymentId: payments[0]._id,
},
]);
});
it('should ignore payments that have been reconciled', async () => {
const connectorId = new mongoose.Types.ObjectId();
const paymentProviderSettlements = [
{
paymentReference: connectorId.toString(),
},
] as IPaymentProviderSettlements;
const payments = [
{
_id: new mongoose.Types.ObjectId(),
connectorData: { connectorId } as any,
reconciliated: true,
paid: true,
},
] as IPayments;
const result = sut.matchPaymentProviderSettlementsToPayments(paymentProviderSettlements, payments);
expect(result).to.deep.equal([{ paymentReference: connectorId.toString() }]);
});
it('should only match when connector ID is the same as payment reference', async () => {
const connectorId = new mongoose.Types.ObjectId();
const paymentProviderSettlements = [
{
paymentReference: 'some random reference',
},
] as IPaymentProviderSettlements;
const payments = [
{
_id: new mongoose.Types.ObjectId(),
connectorData: { connectorId } as any,
reconciliated: false,
paid: true,
},
] as IPayments;
const result = sut.matchPaymentProviderSettlementsToPayments(paymentProviderSettlements, payments);
expect(result).to.deep.equal([{ paymentReference: 'some random reference' }]);
});
});
describe('getAllWithoutBankTransactionId', () => {
it('should get all payment provider settlements that do not have a bank transaction Id', async () => {
sinon.stub(model, 'getAllWithoutBanksTransactionId').resolves([{ _id: 'some id' }] as any);
const transactions = await sut.getAllWithoutBankTransactionId();
expect(transactions).to.deep.equal([{ _id: 'some id' }]);
});
});
describe('matchPaymentProviderSettlementToBankTransaction', () => {
it('should match a bank transaction to a payment provider settlement by changing the bank transaction ID on payment provider settlement and ignore unmatched settlements', async () => {
const transactions = [{ _id: new mongoose.Types.ObjectId(), reference: 'matched reference' }] as any;
const settlements = [{ bankTransactionReference: 'matched reference' }];
sinon.stub(model, 'getAllWithoutBanksTransactionId').resolves(settlements as any);
const matchedSettlements = await sut.matchPaymentProviderSettlementToBankTransaction(transactions);
expect(matchedSettlements).to.deep.equal([
{ bankTransactionId: transactions[0]._id, bankTransactionReference: 'matched reference' },
]);
});
it('should not add any IDs to unmatched settlements', async () => {
const transactions = [{ _id: new mongoose.Types.ObjectId(), reference: 'unmatched reference' }] as any;
const settlements = [{ bankTransactionReference: 'random reference' }];
sinon.stub(model, 'getAllWithoutBanksTransactionId').resolves(settlements as any);
const matchedSettlements = await sut.matchPaymentProviderSettlementToBankTransaction(transactions);
expect(matchedSettlements).to.deep.equal([{ bankTransactionReference: 'random reference' }]);
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment