diff --git a/spec/jobs/update_bill_items_spec.rb b/spec/jobs/update_bill_items_spec.rb index 828a5b706e..671e04ce6a 100644 --- a/spec/jobs/update_bill_items_spec.rb +++ b/spec/jobs/update_bill_items_spec.rb @@ -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