-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
-DebtFilter addresses the problem, where some of the created Debts for a particular Bet would cross-reference each other (PersonA -$50-> PersonB && PersonB -$20-> PersonA) or accumulate as separate entries (PerosnA -$50-> PersonB && PersonA -$20-> PersonB) by filtering them before saving. -Added DebtFilter to Bet model. Debts are now filtered before getting saved.
- Loading branch information
Showing
3 changed files
with
101 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
module DebtFilter | ||
def save_debts(debts) | ||
filter_debts(debts).map do |debt| | ||
debt.save | ||
debt | ||
end | ||
end | ||
|
||
private | ||
|
||
def filter_debts(debts) | ||
reverse_negatives(merge_debts(reverse_duplicates(debts))) | ||
end | ||
|
||
def unique_participants(debts) | ||
uniques = [] | ||
debts.each do |debt| | ||
next if uniques.include?([debt.creditor, debt.debtor]) || | ||
uniques.include?([debt.debtor, debt.creditor]) | ||
uniques << [debt.debtor, debt.creditor] | ||
end | ||
uniques | ||
end | ||
|
||
def reverse_duplicates(debts) | ||
uniques = unique_participants(debts) | ||
debts.map do |debt| | ||
if uniques.include?([debt.debtor, debt.creditor]) | ||
debt | ||
else | ||
Debt.new(debtor: debt.creditor, | ||
creditor: debt.debtor, amount: -debt.amount) | ||
end | ||
end | ||
end | ||
|
||
def merge_debts(debts) | ||
debts.group_by { |debt| [debt.debtor, debt.creditor] }.map do |_, group| | ||
Debt.new(debtor: group.first.debtor, | ||
creditor: group.first.creditor, | ||
amount: group.sum(&:amount)) | ||
end | ||
end | ||
|
||
def reverse_negatives(debts) | ||
debts.map do |debt| | ||
if debt.amount < 0 | ||
Debt.new(debtor: debt.creditor, | ||
creditor: debt.debtor, amount: debt.amount.abs) | ||
else | ||
debt | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
require 'rails_helper' | ||
|
||
RSpec.describe DebtFilter, type: :module do | ||
let(:debt_filter) { Class.new { extend DebtFilter } } | ||
let(:bob) do | ||
User.create(username: 'Bob', email: '[email protected]', password: '123') | ||
end | ||
let(:peter) do | ||
User.create(username: 'Peter', email: '[email protected]', password: 'pete1') | ||
end | ||
let(:jack) do | ||
User.create(username: 'Jack', email: '[email protected]', password: 'jeeek') | ||
end | ||
|
||
let(:debt1) { Debt.new(debtor: bob, creditor: peter, amount: 20) } | ||
let(:debt2) { Debt.new(debtor: peter, creditor: bob, amount: 100) } | ||
let(:debt3) { Debt.new(debtor: bob, creditor: peter, amount: 60) } | ||
let(:debt4) { Debt.new(debtor: jack, creditor: peter, amount: 55.5) } | ||
let(:debts) { [debt1, debt2, debt3, debt4] } | ||
|
||
describe('#save_debts') do | ||
subject(:saved_debts) { debt_filter.save_debts(debts) } | ||
let(:expected_debt1) do | ||
Debt.new(debtor: peter, creditor: bob, amount: 20) | ||
end | ||
let(:expected_debt2) { debt4 } | ||
it 'saves debts after filtering them' do | ||
aggregate_failures 'testing debts' do | ||
expect(saved_debts.first).to( | ||
have_attributes(debtor: expected_debt1.debtor, | ||
creditor: expected_debt1.creditor, | ||
amount: expected_debt1.amount) | ||
) | ||
expect(saved_debts.second).to( | ||
have_attributes(debtor: expected_debt2.debtor, | ||
creditor: expected_debt2.creditor, | ||
amount: expected_debt2.amount) | ||
) | ||
end | ||
end | ||
end | ||
end |