Skip to content

Instantly share code, notes, and snippets.

@trikitrok
Last active September 26, 2022 17:01
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 trikitrok/1e4fb27cc6acf16acc1cffd5d97a69de to your computer and use it in GitHub Desktop.
Save trikitrok/1e4fb27cc6acf16acc1cffd5d97a69de to your computer and use it in GitHub Desktop.
import {UnusualSpendingDetector} from "../src/UnusualSpendingDetector";
describe('UnusualSpendingDetector', () => {
const currentMonth = '2020-02';
const previousMonth = '2020-01';
const userId = '1234';
let paymentsRepository;
let detector;
beforeEach(() => {
const calendar = {
getCurrentMonth: () => currentMonth,
getPreviousMonth: () => previousMonth,
};
paymentsRepository = {
find: jest.fn()
}
detector = new UnusualSpendingDetector(
paymentsRepository,
calendar
);
}
);
test('detects no unusual spending when there are no payments', () => {
paymentsRepositoryWillReturn([], []);
const unusualSpendings = detector.detect(userId);
expect(unusualSpendings).toEqual([]);
});
test('detects an unusual spending when spending for a category in consecutive months grew 50% or more', () => {
const currentMonthPayments = [payment('food', 200, currentMonth)];
const previousMonthPayments = [payment('food', 100, previousMonth)];
paymentsRepositoryWillReturn(currentMonthPayments, previousMonthPayments);
const unusualSpendings = detector.detect(userId);
expect(unusualSpendings).toEqual([unusualSpending('food', 200)]);
});
test('detects no unusual spending when there are no payments for a category in current month', () => {
const previousMonthPayments = [payment('food', 200, currentMonth)];
paymentsRepositoryWillReturn([], previousMonthPayments);
const unusualSpendings = detector.detect(userId);
expect(unusualSpendings).toEqual([]);
});
test('detects no unusual spending when there were no payments for a category in previous month', () => {
const currentMonthPayments = [payment('transport', 200, currentMonth)];
const previousMonthPayments = [payment('food', 200, currentMonth)];
paymentsRepositoryWillReturn(currentMonthPayments, previousMonthPayments);
const unusualSpendings = detector.detect(userId);
expect(unusualSpendings).toEqual([]);
});
test.each([[100, 100], [149.99, 100]])(
'detects no unusual spending when consecutive monthly spending for a category do not increase by 50% or more',
(currentMonthPaymentAmount, previousMonthPaymentAmount) => {
const currentMonthPayments = [payment('food', currentMonthPaymentAmount, currentMonth)];
const previousMonthPayments = [payment('food', previousMonthPaymentAmount, previousMonth)];
paymentsRepositoryWillReturn(currentMonthPayments, previousMonthPayments);
const unusualSpendings = detector.detect(userId);
expect(unusualSpendings).toEqual([]);
});
test(
'detects an unusual spending when spending for a category having multiple payments grew 50% or more in current month',
() => {
const currentMonthPayments = [
payment('food', 100, currentMonth),
payment('food', 100, currentMonth)
];
const previousMonthPayments = [payment('food', 100, previousMonth)];
paymentsRepositoryWillReturn(currentMonthPayments, previousMonthPayments);
const unusualSpendings = detector.detect(userId);
expect(unusualSpendings).toEqual([unusualSpending('food', 200)]);
});
test(
'detects no unusual spending when spending for a category does not grow over 50% in current month wit multiple payments ',
() => {
const currentMonthPayments = [payment('food', 150, previousMonth)];
const previousMonthPayments = [
payment('food', 100, currentMonth),
payment('food', 100, currentMonth)
];
paymentsRepositoryWillReturn(currentMonthPayments, previousMonthPayments);
const unusualSpendings = detector.detect(userId);
expect(unusualSpendings).toEqual([]);
});
test('detects unusual spendings for multiple categories', () => {
const currentMonthPayments = [
payment('food', 100, previousMonth),
payment('transport', 200, previousMonth)
];
const previousMonthPayments = [
payment('food', 100, currentMonth),
payment('transport', 100, currentMonth)
];
paymentsRepositoryWillReturn(currentMonthPayments, previousMonthPayments);
const unusualSpendings = detector.detect(userId);
expect(unusualSpendings).toEqual([unusualSpending('transport', 200)]);
});
function payment(category, amount, month) {
return {category, amount, month};
}
function unusualSpending(category, amount) {
return {category, amount};
}
function paymentsRepositoryWillReturn(
currentMonthPayments,
previousMonthPayments
) {
paymentsRepository.find.mockImplementation((userId, month) => {
if (month === currentMonth) {
return currentMonthPayments;
} else if (month === previousMonth) {
return previousMonthPayments;
}
});
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment