Implemented tests for rules; fixed applyRules logic #18

Merged
inga-lovinde merged 2 commits from feat-13-test-rules into main 10 months ago
  1. 20
      package-lock.json
  2. 2
      package.json
  3. 94
      src/transaction/transaction.controller.spec.ts
  4. 31
      src/transaction/transaction.controller.ts

20
package-lock.json generated

@ -17,6 +17,7 @@
"axios": "0.26.1",
"chai-as-promised": "^7.1.1",
"joi": "17.6.0",
"lodash": "^4.17.21",
"reflect-metadata": "0.1.13",
"rimraf": "3.0.2",
"rxjs": "7.5.5",
@ -29,6 +30,7 @@
"@types/express": "4.17.13",
"@types/jest": "27.4.1",
"@types/joi": "17.2.3",
"@types/lodash": "^4.14.202",
"@types/node": "16.0.0",
"@types/supertest": "2.0.11",
"@typescript-eslint/eslint-plugin": "5.0.0",
@ -2157,6 +2159,12 @@
"integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
"dev": true
},
"node_modules/@types/lodash": {
"version": "4.14.202",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz",
"integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==",
"dev": true
},
"node_modules/@types/mime": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
@ -7032,8 +7040,7 @@
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/lodash.merge": {
"version": "4.6.2",
@ -12381,6 +12388,12 @@
"integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
"dev": true
},
"@types/lodash": {
"version": "4.14.202",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz",
"integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==",
"dev": true
},
"@types/mime": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
@ -16120,8 +16133,7 @@
"lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"lodash.merge": {
"version": "4.6.2",

@ -30,6 +30,7 @@
"axios": "0.26.1",
"chai-as-promised": "^7.1.1",
"joi": "17.6.0",
"lodash": "^4.17.21",
"reflect-metadata": "0.1.13",
"rimraf": "3.0.2",
"rxjs": "7.5.5",
@ -42,6 +43,7 @@
"@types/express": "4.17.13",
"@types/jest": "27.4.1",
"@types/joi": "17.2.3",
"@types/lodash": "^4.14.202",
"@types/node": "16.0.0",
"@types/supertest": "2.0.11",
"@typescript-eslint/eslint-plugin": "5.0.0",

@ -20,7 +20,7 @@ describe('TransactionController Unit Tests', () => {
Promise.reject(new Error('DatabaseNotReachable')),
),
findByClientIdWithinActualMonth: jest.fn((clientId) => {
if (clientId === 42) {
if (clientId === 42 || clientId === 99) {
return [{ base_amount: 1500 }];
}
return [];
@ -70,19 +70,95 @@ describe('TransactionController Unit Tests', () => {
});
it('calling applyRules method minimum result of applied rules should be got', async () => {
const mockTransactionInput = {
date: '2021-01-05',
base_amount: 1000.0,
currency: 'EUR',
{
const result = await transactionController.applyRules(
[
transactionController.discountRule,
transactionController.turnoverRule,
],
{
base_amount: 1000,
client_id: 1,
};
},
);
expect(result).to.eql(5);
}
{
const result = await transactionController.applyRules(
[transactionController.discountRule, transactionController.turnoverRule],
mockTransactionInput,
[
transactionController.discountRule,
transactionController.turnoverRule,
],
{
base_amount: 1,
client_id: 1,
},
);
expect(result).to.eql(5);
expect(result).to.eql(0.05);
}
{
const result = await transactionController.applyRules(
[
transactionController.discountRule,
transactionController.turnoverRule,
],
{
base_amount: 1000,
client_id: 42,
},
);
expect(result).to.eql(0.03);
}
{
const result = await transactionController.applyRules(
[
transactionController.discountRule,
transactionController.turnoverRule,
],
{
base_amount: 1,
client_id: 42,
},
);
expect(result).to.eql(0.03);
}
{
const result = await transactionController.applyRules(
[
transactionController.discountRule,
transactionController.turnoverRule,
],
{
base_amount: 1000,
client_id: 99,
},
);
expect(result).to.eql(0.03);
}
{
const result = await transactionController.applyRules(
[
transactionController.discountRule,
transactionController.turnoverRule,
],
{
base_amount: 1,
client_id: 99,
},
);
expect(result).to.eql(0.03);
}
});
it('calling commission method correct commission should be got', async () => {

@ -1,5 +1,9 @@
import { Controller, Post, UsePipes, Body } from '@nestjs/common';
import { ExchangeRateInput, ExchangeRateResponse } from 'src/exchange-rate/exchange-rate.dto';
import _ from 'lodash';
import {
ExchangeRateInput,
ExchangeRateResponse,
} from 'src/exchange-rate/exchange-rate.dto';
import { ExchangeRateService } from 'src/exchange-rate/exchange-rate.service';
import { TransactionService } from './transaction.service';
import { transactionBodySchema } from './transaction.validation';
@ -31,12 +35,8 @@ export class TransactionController {
return JSON.stringify({
amount:
transactionInput.currency !== Currency.EUR
? parseFloat(
await this.getAmountWithExchange(transactionInput),
).toFixed(2)
: parseFloat(
await this.getAmountWithoutExchange(transactionInput),
).toFixed(2),
? (await this.getAmountWithExchange(transactionInput)).toFixed(2)
: (await this.getAmountWithoutExchange(transactionInput)).toFixed(2),
currency: Currency.EUR,
});
}
@ -96,19 +96,10 @@ export class TransactionController {
) => number | false | undefined | Promise<number | false | undefined>)[],
transactionInput: TransactionRuleData,
) {
let commissionAmount;
for (let i = 0; i < rules.length; i++) {
const ruleResult = await rules[i](transactionInput);
if (ruleResult) {
commissionAmount = ruleResult;
break;
} else {
continue;
}
}
return commissionAmount
? commissionAmount
: this.defaultRule(transactionInput);
const commissions = await Promise.all(
[...rules, this.defaultRule].map((rule) => rule(transactionInput)),
);
return Math.min(..._.compact(commissions));
}
getExchangeRate(exchangeRateInput: ExchangeRateInput) {

Loading…
Cancel
Save