Finishing refactor of bill item updater spec

This commit is contained in:
Rob Harrington
2015-06-26 15:59:49 +08:00
parent 77f735c722
commit fc44e57171

View File

@@ -5,7 +5,7 @@ def travel_to(time)
end
describe UpdateBillItems do
describe "unit tests" do
describe "unit specs" do
let!(:start_of_july) { Time.now.beginning_of_year + 6.months }
let!(:updater) { UpdateBillItems.new }
@@ -373,555 +373,146 @@ describe UpdateBillItems do
end
end
describe "validation tests" do
describe "validation spec" do
# Chose july to test with because June has 30 days and so is easy to calculate end date for shop trial
let!(:start_of_july) { Time.now.beginning_of_year + 6.months }
let!(:enterprise) { create(:supplier_enterprise, sells: 'any') }
let!(:order1) { create(:order, completed_at: start_of_july + 5.days, distributor: enterprise) }
let!(:order2) { create(:order, completed_at: start_of_july + 15.days, distributor: enterprise) }
let!(:order3) { create(:order, completed_at: start_of_july + 25.days, distributor: enterprise) }
let!(:original_owner) { enterprise.owner }
let!(:new_owner) { create(:user) }
let!(:order1) { create(:order, completed_at: start_of_july + 1.days, distributor: enterprise) }
let!(:order2) { create(:order, completed_at: start_of_july + 3.days, distributor: enterprise) }
let!(:order3) { create(:order, completed_at: start_of_july + 5.days, distributor: enterprise) }
let!(:order4) { create(:order, completed_at: start_of_july + 7.days, distributor: enterprise) }
let!(:order5) { create(:order, completed_at: start_of_july + 9.days, distributor: enterprise) }
let!(:order6) { create(:order, completed_at: start_of_july + 11.days, distributor: enterprise) }
let!(:order7) { create(:order, completed_at: start_of_july + 13.days, distributor: enterprise) }
let!(:order8) { create(:order, completed_at: start_of_july + 15.days, distributor: enterprise) }
let!(:order9) { create(:order, completed_at: start_of_july + 17.days, distributor: enterprise) }
let!(:order10) { create(:order, completed_at: start_of_july + 19.days, distributor: enterprise) }
before do
order1.line_items = [ create(:line_item, price: 12.56, order: order1) ]
order2.line_items = [ create(:line_item, price: 87.44, order: order2) ]
order3.line_items = [ create(:line_item, price: 50.00, order: order3) ]
[order1, order2, order3].each(&:update!)
order4.line_items = [ create(:line_item, price: 73.37, order: order4) ]
order5.line_items = [ create(:line_item, price: 22.46, order: order5) ]
order6.line_items = [ create(:line_item, price: 44.85, order: order6) ]
order7.line_items = [ create(:line_item, price: 93.45, order: order7) ]
order8.line_items = [ create(:line_item, price: 59.38, order: order8) ]
order9.line_items = [ create(:line_item, price: 47.23, order: order9) ]
order10.line_items = [ create(:line_item, price: 2.35, order: order10) ]
[order1, order2, order3, order4, order5, order6, order7, order8, order9, order10].each(&:update!)
allow(Enterprise).to receive(:select) { [enterprise] }
end
context "where the enterprise existed at the beginning of the current billing period", versioning: true do
context "super complex example", versioning: true do
before do
enterprise.update_attribute(:created_at, start_of_july - 2.months)
enterprise.update_attribute(:created_at, start_of_july + 2.days)
Timecop.freeze(start_of_july + 4.days) { enterprise.update_attribute(:sells, 'own') }
Timecop.freeze(start_of_july + 6.days) { enterprise.update_attribute(:owner, new_owner) }
enterprise.update_attribute(:shop_trial_start_date, start_of_july + 8.days)
Timecop.freeze(start_of_july + 10.days) { enterprise.update_attribute(:owner, original_owner) }
Timecop.freeze(start_of_july + 12.days) { enterprise.update_attribute(:sells, 'any') }
allow(enterprise).to receive(:shop_trial_expiry) { start_of_july + 14.days }
Timecop.freeze(start_of_july + 16.days) { enterprise.update_attribute(:sells, 'own') }
Timecop.freeze(start_of_july + 18.days) { enterprise.update_attribute(:owner, new_owner) }
end
context "where the sells and owner_id properties of the enterprise have not been altered within the current billing period" do
before do
Timecop.travel(start_of_july + 28.days)
end
travel_to(20.days)
after do
Timecop.return
end
context "where no trial information has been set" do
before do
UpdateBillItems.new.perform
end
let(:bill_items) { BillItem.order(:id) }
it "creates a single bill item" do
expect(bill_items.count).to eq 1
expect(bill_items.map(&:sells)).to eq ['any']
end
it "calculates turnover for the whole month to date" do
expect(bill_items.first.turnover).to eq (order1.total + order2.total + order3.total)
end
end
context "where a trial ended during the current billing period" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july - 10.days)
UpdateBillItems.new.perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits out the trial period into a separate bill item" do
expect(bill_items.count).to eq 2
expect(bill_items.map(&:sells)).to eq ['any', 'any']
expect(bill_items.map(&:trial)).to eq [true, false]
end
it "splits out the trial period into a separate bill item" do
expect(bill_items.first.turnover).to eq order1.total + order2.total
expect(bill_items.last.turnover).to eq order3.total
end
end
context "where the trial began part-way through the current billing period" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july + 10.days)
UpdateBillItems.new.perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits out the trial period into a separate bill item" do
expect(bill_items.count).to eq 2
expect(bill_items.map(&:sells)).to eq ['any', 'any']
expect(bill_items.map(&:trial)).to eq [false, true]
end
it "splits the turnover for the month to date" do
expect(bill_items.first.turnover).to eq order1.total
expect(bill_items.last.turnover).to eq order2.total + order3.total
end
end
end
context "where the sells property of the enterprise has been altered within the current billing period" do
before do
Timecop.freeze(start_of_july + 10.days) do
# NOTE: Sells is changed between when order1 and order2 are placed
enterprise.update_attribute(:sells, 'own')
end
Timecop.travel(start_of_july + 28.days)
end
after do
Timecop.return
end
context "where no trial information has been set" do
before do
UpdateBillItems.new.perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits the billing period into a separate item for each sells value" do
expect(bill_items.count).to eq 2
expect(bill_items.map(&:sells)).to eq ['any', 'own']
expect(bill_items.map(&:trial)).to eq [false, false]
end
it "splits the turnover for the month to date" do
expect(bill_items.first.turnover).to eq order1.total
expect(bill_items.last.turnover).to eq order2.total + order3.total
end
end
context "where a trial ended during the current billing period, after sells was changed" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july - 10.days)
UpdateBillItems.new.perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits out the distinct sells periods and trial period into separate bill items" do
expect(bill_items.count).to eq 3
expect(bill_items.map(&:sells)).to eq ['any', 'own', 'own']
expect(bill_items.map(&:trial)).to eq [true, true, false]
end
it "splits out the trial period into a separate bill item" do
expect(bill_items.first.turnover).to eq order1.total
expect(bill_items.second.turnover).to eq order2.total
expect(bill_items.last.turnover).to eq order3.total
end
end
context "where a trial ended during the current billing period, before sells was changed" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july - 22.days)
UpdateBillItems.new.perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits out the distinct sells periods and trial period into separate bill items" do
expect(bill_items.count).to eq 3
expect(bill_items.map(&:sells)).to eq ['any', 'any', 'own']
expect(bill_items.map(&:trial)).to eq [true, false, false]
end
it "splits out the trial period into a separate bill item" do
expect(bill_items.first.turnover).to eq order1.total
expect(bill_items.second.turnover).to eq 0
expect(bill_items.last.turnover).to eq (order2.total + order3.total)
end
end
context "where the trial began part-way through the current billing period, after sells was changed" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july + 18.days)
UpdateBillItems.new.perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits out the distinct sells periods and trial period into separate bill items" do
expect(bill_items.count).to eq 3
expect(bill_items.map(&:sells)).to eq ['any', 'own', 'own']
expect(bill_items.map(&:trial)).to eq [false, false, true]
end
it "splits out the trial period into a separate bill item" do
expect(bill_items.first.turnover).to eq order1.total
expect(bill_items.second.turnover).to eq order2.total
expect(bill_items.last.turnover).to eq order3.total
end
end
context "where the trial began part-way through the current billing period, before sells was changed" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july + 8.days)
UpdateBillItems.new.perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits out the distinct sells periods and trial period into separate bill items" do
expect(bill_items.count).to eq 3
expect(bill_items.map(&:sells)).to eq ['any', 'any', 'own']
expect(bill_items.map(&:trial)).to eq [false, true, true]
end
it "splits out the trial period into a separate bill item" do
expect(bill_items.first.turnover).to eq order1.total
expect(bill_items.second.turnover).to eq 0
expect(bill_items.last.turnover).to eq (order2.total + order3.total)
end
end
end
context "where the owner_id property of the enterprise has been altered within the current billing period" do
let!(:original_owner) { enterprise.owner }
let!(:new_owner) { create(:user) }
before do
Timecop.freeze(start_of_july + 10.days) do
# NOTE: Sells is changed between when order1 and order2 are placed
enterprise.update_attribute(:owner, new_owner)
end
Timecop.travel(start_of_july + 28.days)
end
after do
Timecop.return
end
context "where no trial information has been set" do
before do
UpdateBillItems.new.perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits the billing period into a separate item for each owner" do
expect(bill_items.count).to eq 2
expect(bill_items.map(&:owner_id)).to eq [original_owner.id, new_owner.id]
expect(bill_items.map(&:sells)).to eq ['any', 'any']
expect(bill_items.map(&:trial)).to eq [false, false]
expect(bill_items.map(&:begins_at)).to eq [start_of_july, start_of_july + 10.days]
expect(bill_items.map(&:ends_at)).to eq [start_of_july + 10.days, start_of_july + 28.days]
end
it "splits the turnover for the month to date" do
expect(bill_items.first.turnover).to eq order1.total
expect(bill_items.last.turnover).to eq order2.total + order3.total
end
end
context "where a trial ended during the current billing period, after owner was changed" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july - 10.days)
UpdateBillItems.new.perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits out the distinct ownership periods and trial period into separate bill items" do
expect(bill_items.count).to eq 3
expect(bill_items.map(&:owner_id)).to eq [original_owner.id, new_owner.id, new_owner.id]
expect(bill_items.map(&:sells)).to eq ['any', 'any', 'any']
expect(bill_items.map(&:trial)).to eq [true, true, false]
expect(bill_items.map(&:begins_at)).to eq [start_of_july, start_of_july + 10.days, start_of_july + 20.days]
expect(bill_items.map(&:ends_at)).to eq [start_of_july + 10.days, start_of_july + 20.days, start_of_july + 28.days]
end
it "splits out the trial period into a separate bill item" do
expect(bill_items.first.turnover).to eq order1.total
expect(bill_items.second.turnover).to eq order2.total
expect(bill_items.last.turnover).to eq order3.total
end
end
context "where a trial ended during the current billing period, before owner was changed" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july - 22.days)
UpdateBillItems.new.perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits out the distinct sells periods and trial period into separate bill items" do
expect(bill_items.count).to eq 3
expect(bill_items.map(&:owner_id)).to eq [original_owner.id, original_owner.id, new_owner.id]
expect(bill_items.map(&:sells)).to eq ['any', 'any', 'any']
expect(bill_items.map(&:trial)).to eq [true, false, false]
expect(bill_items.map(&:begins_at)).to eq [start_of_july, start_of_july + 8.days, start_of_july + 10.days]
expect(bill_items.map(&:ends_at)).to eq [start_of_july + 8.days, start_of_july + 10.days, start_of_july + 28.days]
end
it "splits out the trial period into a separate bill item" do
expect(bill_items.first.turnover).to eq order1.total
expect(bill_items.second.turnover).to eq 0
expect(bill_items.last.turnover).to eq (order2.total + order3.total)
end
end
context "where the trial began part-way through the current billing period, after owner was changed" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july + 18.days)
UpdateBillItems.new.perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits out the distinct ownership periods and trial period into separate bill items" do
expect(bill_items.count).to eq 3
expect(bill_items.map(&:owner_id)).to eq [original_owner.id, new_owner.id, new_owner.id]
expect(bill_items.map(&:sells)).to eq ['any', 'any', 'any']
expect(bill_items.map(&:trial)).to eq [false, false, true]
expect(bill_items.map(&:begins_at)).to eq [start_of_july, start_of_july + 10.days, start_of_july + 18.days]
expect(bill_items.map(&:ends_at)).to eq [start_of_july + 10.days, start_of_july + 18.days, start_of_july + 28.days]
end
it "splits out the trial period into a separate bill item" do
expect(bill_items.first.turnover).to eq order1.total
expect(bill_items.second.turnover).to eq order2.total
expect(bill_items.last.turnover).to eq order3.total
end
end
context "where the trial began part-way through the current billing period, before owner was changed" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july + 8.days)
UpdateBillItems.new.perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits out the distinct ownership periods and trial period into separate bill items" do
expect(bill_items.count).to eq 3
expect(bill_items.map(&:owner_id)).to eq [original_owner.id, original_owner.id, new_owner.id]
expect(bill_items.map(&:sells)).to eq ['any', 'any', 'any']
expect(bill_items.map(&:trial)).to eq [false, true, true]
expect(bill_items.map(&:begins_at)).to eq [start_of_july, start_of_july + 8.days, start_of_july + 10.days]
expect(bill_items.map(&:ends_at)).to eq [start_of_july + 8.days, start_of_july + 10.days, start_of_july + 28.days]
end
it "splits out the trial period into a separate bill item" do
expect(bill_items.first.turnover).to eq order1.total
expect(bill_items.second.turnover).to eq 0
expect(bill_items.last.turnover).to eq (order2.total + order3.total)
end
end
end
end
context "where the enterprise was created after the beginning of the current billing period", versioning: true do
before do
enterprise.update_attribute(:created_at, start_of_july + 7.days)
UpdateBillItems.new.perform
end
context "where the sells property of the enterprise has not been altered within the current billing period" do
before do
Timecop.travel(start_of_july + 28.days)
end
let(:bill_items) { BillItem.order(:id) }
after do
Timecop.return
end
it "creates the correct bill items" do
expect(bill_items.count).to eq 9
context "where no trial information has been set" do
before do
UpdateBillItems.new.perform
end
expect(bill_items.map(&:begins_at)).to eq [
start_of_july + 2.days,
start_of_july + 4.days,
start_of_july + 6.days,
start_of_july + 8.days,
start_of_july + 10.days,
start_of_july + 12.days,
start_of_july + 14.days,
start_of_july + 16.days,
start_of_july + 18.days
]
let(:bill_items) { BillItem.order(:id) }
expect(bill_items.map(&:ends_at)).to eq [
start_of_july + 4.days,
start_of_july + 6.days,
start_of_july + 8.days,
start_of_july + 10.days,
start_of_july + 12.days,
start_of_july + 14.days,
start_of_july + 16.days,
start_of_july + 18.days,
start_of_july + 20.days
]
it "creates a single bill item" do
expect(bill_items.count).to eq 1
expect(bill_items.map(&:sells)).to eq ['any']
expect(bill_items.map(&:trial)).to eq [false]
expect(bill_items.map(&:begins_at)).to eq [start_of_july + 7.days]
expect(bill_items.map(&:ends_at)).to eq [start_of_july + 28.days]
end
expect(bill_items.map(&:owner)).to eq [
original_owner,
original_owner,
new_owner,
new_owner,
original_owner,
original_owner,
original_owner,
original_owner,
new_owner
]
it "ignores orders completed before the enterprise was created" do
expect(bill_items.first.turnover).to eq (order2.total + order3.total)
end
end
expect(bill_items.map(&:sells)).to eq [
'any',
'own',
'own',
'own',
'own',
'any',
'any',
'own',
'own'
]
context "where a trial ended during the current billing period" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july - 10.days)
UpdateBillItems.new.perform
end
expect(bill_items.map(&:trial)).to eq [
false,
false,
false,
true,
true,
true,
false,
false,
false
]
let(:bill_items) { BillItem.order(:id) }
it "splits out the trial period into a separate bill item" do
expect(bill_items.count).to eq 2
expect(bill_items.map(&:sells)).to eq ['any', 'any']
expect(bill_items.map(&:trial)).to eq [true, false]
expect(bill_items.map(&:begins_at)).to eq [start_of_july + 7.days, start_of_july + 20.days]
expect(bill_items.map(&:ends_at)).to eq [start_of_july + 20.days, start_of_july + 28.days]
end
it "splits out the trial period into a separate bill item" do
expect(bill_items.first.turnover).to eq order2.total
expect(bill_items.last.turnover).to eq order3.total
end
end
context "where the trial began part-way through the current billing period" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july + 10.days)
UpdateBillItems.new.perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits out the trial period into a separate bill item" do
expect(bill_items.count).to eq 2
expect(bill_items.map(&:sells)).to eq ['any', 'any']
expect(bill_items.map(&:trial)).to eq [false, true]
expect(bill_items.map(&:begins_at)).to eq [start_of_july + 7.days, start_of_july + 10.days]
expect(bill_items.map(&:ends_at)).to eq [start_of_july + 10.days, start_of_july + 28.days]
end
it "splits the turnover for the month to date" do
expect(bill_items.first.turnover).to eq 0
expect(bill_items.last.turnover).to eq order2.total + order3.total
end
end
end
context "where the sells property of the enterprise has been altered within the current billing period" do
before do
Timecop.freeze(start_of_july + 10.days) do
# NOTE: Sells is changed between when order1 and order2 are placed
enterprise.update_attribute(:sells, 'own')
end
Timecop.travel(start_of_july + 28.days)
end
after do
Timecop.return
end
context "where no trial information has been set" do
before do
UpdateBillItems.new.perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits the billing period into a separate item for each sells value" do
expect(bill_items.count).to eq 2
expect(bill_items.map(&:sells)).to eq ['any', 'own']
expect(bill_items.map(&:trial)).to eq [false, false]
expect(bill_items.map(&:begins_at)).to eq [start_of_july + 7.days, start_of_july + 10.days]
expect(bill_items.map(&:ends_at)).to eq [start_of_july + 10.days, start_of_july + 28.days]
end
it "splits the turnover for the month to date" do
expect(bill_items.first.turnover).to eq 0
expect(bill_items.last.turnover).to eq order2.total + order3.total
end
end
context "where a trial ended during the current billing period, after sells was changed" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july - 10.days)
UpdateBillItems.new.perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits out the distinct sells periods and trial period into separate bill items" do
expect(bill_items.count).to eq 3
expect(bill_items.map(&:sells)).to eq ['any', 'own', 'own']
expect(bill_items.map(&:trial)).to eq [true, true, false]
expect(bill_items.map(&:begins_at)).to eq [start_of_july + 7.days, start_of_july + 10.days, start_of_july + 20.days]
expect(bill_items.map(&:ends_at)).to eq [start_of_july + 10.days, start_of_july + 20.days, start_of_july + 28.days]
end
it "splits out the trial period into a separate bill item" do
expect(bill_items.first.turnover).to eq 0
expect(bill_items.second.turnover).to eq order2.total
expect(bill_items.last.turnover).to eq order3.total
end
end
context "where a trial ended during the current billing period, before sells was changed" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july - 22.days)
UpdateBillItems.new.perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits out the distinct sells periods and trial period into separate bill items" do
expect(bill_items.count).to eq 3
expect(bill_items.map(&:sells)).to eq ['any', 'any', 'own']
expect(bill_items.map(&:trial)).to eq [true, false, false]
expect(bill_items.map(&:begins_at)).to eq [start_of_july + 7.days, start_of_july + 8.days, start_of_july + 10.days]
expect(bill_items.map(&:ends_at)).to eq [start_of_july + 8.days, start_of_july + 10.days, start_of_july + 28.days]
end
it "splits out the trial period into a separate bill item" do
expect(bill_items.first.turnover).to eq 0
expect(bill_items.second.turnover).to eq 0
expect(bill_items.last.turnover).to eq (order2.total + order3.total)
end
end
context "where the trial began part-way through the current billing period, after sells was changed" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july + 18.days)
UpdateBillItems.new.perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits out the distinct sells periods and trial period into separate bill items" do
expect(bill_items.count).to eq 3
expect(bill_items.map(&:sells)).to eq ['any', 'own', 'own']
expect(bill_items.map(&:trial)).to eq [false, false, true]
expect(bill_items.map(&:begins_at)).to eq [start_of_july + 7.days, start_of_july + 10.days, start_of_july + 18.days]
expect(bill_items.map(&:ends_at)).to eq [start_of_july + 10.days, start_of_july + 18.days, start_of_july + 28.days]
end
it "splits out the trial period into a separate bill item" do
expect(bill_items.first.turnover).to eq 0
expect(bill_items.second.turnover).to eq order2.total
expect(bill_items.last.turnover).to eq order3.total
end
end
context "where the trial began part-way through the current billing period, before sells was changed" do
before do
enterprise.update_attribute(:shop_trial_start_date, start_of_july + 8.days)
UpdateBillItems.new.perform
end
let(:bill_items) { BillItem.order(:id) }
it "splits out the distinct sells periods and trial period into separate bill items" do
expect(bill_items.count).to eq 3
expect(bill_items.map(&:sells)).to eq ['any', 'any', 'own']
expect(bill_items.map(&:trial)).to eq [false, true, true]
expect(bill_items.map(&:begins_at)).to eq [start_of_july + 7.days, start_of_july + 8.days, start_of_july + 10.days]
expect(bill_items.map(&:ends_at)).to eq [start_of_july + 8.days, start_of_july + 10.days, start_of_july + 28.days]
end
it "splits out the trial period into a separate bill item" do
expect(bill_items.first.turnover).to eq 0
expect(bill_items.second.turnover).to eq 0
expect(bill_items.last.turnover).to eq (order2.total + order3.total)
end
end
expect(bill_items.map(&:turnover)).to eq [
order2.total,
order3.total,
order4.total,
order5.total,
order6.total,
order7.total,
order8.total,
order9.total,
order10.total
]
end
end
end