refactor: extracted rule-applying code to a separate method (closes #10)

pull/21/head
Inga 🏳‍🌈 12 months ago
parent 8758bfb17e
commit fbd6fb52c1
  1. 11
      src/shared/rules.ts
  2. 84
      src/transaction/transaction.controller.spec.ts
  3. 25
      src/transaction/transaction.controller.ts

@ -0,0 +1,11 @@
import _ from 'lodash';
type RuleResult = number | false | undefined;
export const getMinimumRuleOutput = async <T>(
rules: ((input: T) => RuleResult | Promise<RuleResult>)[],
input: T,
) => {
const results = await Promise.all(rules.map((rule) => rule(input)));
return Math.min(..._.compact(results));
};

@ -71,91 +71,55 @@ describe('TransactionController Unit Tests', () => {
it('calling applyRules method minimum result of applied rules should be got', async () => {
{
const result = await transactionController.applyRules(
[
transactionController.discountRule,
transactionController.turnoverRule,
],
{
base_amount: 1000,
client_id: 1,
},
);
const result = await transactionController.applyRules({
base_amount: 1000,
client_id: 1,
});
expect(result).to.eql(5);
}
{
const result = await transactionController.applyRules(
[
transactionController.discountRule,
transactionController.turnoverRule,
],
{
base_amount: 1,
client_id: 1,
},
);
const result = await transactionController.applyRules({
base_amount: 1,
client_id: 1,
});
expect(result).to.eql(0.05);
}
{
const result = await transactionController.applyRules(
[
transactionController.discountRule,
transactionController.turnoverRule,
],
{
base_amount: 1000,
client_id: 42,
},
);
const result = await transactionController.applyRules({
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,
},
);
const result = await transactionController.applyRules({
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,
},
);
const result = await transactionController.applyRules({
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,
},
);
const result = await transactionController.applyRules({
base_amount: 1,
client_id: 99,
});
expect(result).to.eql(0.03);
}

@ -1,5 +1,4 @@
import { Controller, Post, UsePipes, Body } from '@nestjs/common';
import _ from 'lodash';
import {
ExchangeRateInput,
ExchangeRateResponse,
@ -17,6 +16,7 @@ import {
HighTurnoverDiscount,
} from './transaction.dto';
import { Transaction } from './transaction.entity';
import { getMinimumRuleOutput } from 'src/shared/rules';
type TransactionRuleData = Pick<Transaction, 'base_amount' | 'client_id'>;
@ -90,16 +90,11 @@ export class TransactionController {
: commissionAmount;
}
async applyRules(
rules: ((
transactionInput: TransactionRuleData,
) => number | false | undefined | Promise<number | false | undefined>)[],
transactionInput: TransactionRuleData,
) {
const commissions = await Promise.all(
[...rules, this.defaultRule].map((rule) => rule(transactionInput)),
async applyRules(transactionInput: TransactionRuleData) {
return getMinimumRuleOutput(
[this.turnoverRule, this.discountRule, this.defaultRule],
transactionInput,
);
return Math.min(..._.compact(commissions));
}
getExchangeRate(exchangeRateInput: ExchangeRateInput) {
@ -131,10 +126,7 @@ export class TransactionController {
transactionAmount / exchangeRateResponse[transactionInput.currency],
};
const commissionAmount = this.applyRules(
[this.turnoverRule, this.discountRule],
transactionData,
);
const commissionAmount = this.applyRules(transactionData);
commissionAmount
.then((commission) =>
@ -158,10 +150,7 @@ export class TransactionController {
base_amount: parseInt(transactionInput.amount),
};
const commissionAmount = await this.applyRules(
[this.turnoverRule, this.discountRule],
transactionData,
);
const commissionAmount = await this.applyRules(transactionData);
try {
this.transactionService
.insertOne({

Loading…
Cancel
Save