mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-31 21:37:16 +00:00
258 lines
8.9 KiB
Ruby
258 lines
8.9 KiB
Ruby
require 'spec_helper'
|
|
|
|
module Spree
|
|
describe OrderUpdater do
|
|
let(:order) { build(:order) }
|
|
let(:updater) { Spree::OrderUpdater.new(order) }
|
|
|
|
before { allow(order).to receive(:backordered?) { false } }
|
|
|
|
it "updates totals" do
|
|
payments = [double(:amount => 5), double(:amount => 5)]
|
|
allow(order).to receive_message_chain(:payments, :completed).and_return(payments)
|
|
|
|
line_items = [double(:amount => 10), double(:amount => 20)]
|
|
allow(order).to receive_messages :line_items => line_items
|
|
|
|
adjustments = [double(:amount => 10), double(:amount => -20)]
|
|
allow(order).to receive_message_chain(:adjustments, :eligible).and_return(adjustments)
|
|
|
|
updater.update_totals
|
|
expect(order.payment_total).to eq 10
|
|
expect(order.item_total).to eq 30
|
|
expect(order.adjustment_total).to eq -10
|
|
expect(order.total).to eq 20
|
|
end
|
|
|
|
context "updating shipment state" do
|
|
before do
|
|
allow(order).to receive_message_chain(:shipments, :shipped, :count).and_return(0)
|
|
allow(order).to receive_message_chain(:shipments, :ready, :count).and_return(0)
|
|
allow(order).to receive_message_chain(:shipments, :pending, :count).and_return(0)
|
|
end
|
|
|
|
it "is backordered" do
|
|
allow(order).to receive(:backordered?) { true }
|
|
updater.update_shipment_state
|
|
|
|
expect(order.shipment_state).to eq 'backorder'
|
|
end
|
|
|
|
it "is nil" do
|
|
allow(order).to receive_message_chain(:shipments, :states).and_return([])
|
|
allow(order).to receive_message_chain(:shipments, :count).and_return(0)
|
|
|
|
updater.update_shipment_state
|
|
expect(order.shipment_state).to be_nil
|
|
end
|
|
|
|
|
|
["shipped", "ready", "pending"].each do |state|
|
|
it "is #{state}" do
|
|
allow(order).to receive_message_chain(:shipments, :states).and_return([state])
|
|
updater.update_shipment_state
|
|
expect(order.shipment_state).to eq state.to_s
|
|
end
|
|
end
|
|
|
|
it "is partial" do
|
|
allow(order).to receive_message_chain(:shipments, :states).and_return(["pending", "ready"])
|
|
updater.update_shipment_state
|
|
expect(order.shipment_state).to eq 'partial'
|
|
end
|
|
end
|
|
|
|
context "updating payment state" do
|
|
it "is failed if last payment failed" do
|
|
allow(order).to receive_message_chain(:payments, :last, :state).and_return('failed')
|
|
|
|
updater.update_payment_state
|
|
expect(order.payment_state).to eq 'failed'
|
|
end
|
|
|
|
it "is balance due with no line items" do
|
|
allow(order).to receive_message_chain(:line_items, :empty?).and_return(true)
|
|
|
|
updater.update_payment_state
|
|
expect(order.payment_state).to eq 'balance_due'
|
|
end
|
|
|
|
it "is credit owed if payment is above total" do
|
|
allow(order).to receive_message_chain(:line_items, :empty?).and_return(false)
|
|
allow(order).to receive_messages :payment_total => 31
|
|
allow(order).to receive_messages :total => 30
|
|
|
|
updater.update_payment_state
|
|
expect(order.payment_state).to eq 'credit_owed'
|
|
end
|
|
|
|
it "is paid if order is paid in full" do
|
|
allow(order).to receive_message_chain(:line_items, :empty?).and_return(false)
|
|
allow(order).to receive_messages :payment_total => 30
|
|
allow(order).to receive_messages :total => 30
|
|
|
|
updater.update_payment_state
|
|
expect(order.payment_state).to eq 'paid'
|
|
end
|
|
end
|
|
|
|
it "state change" do
|
|
order = create(:order)
|
|
order.shipment_state = 'shipped'
|
|
state_changes = double
|
|
allow(order).to receive(:state_changes) { state_changes }
|
|
expect(state_changes).to receive(:create).with(
|
|
:previous_state => nil,
|
|
:next_state => 'shipped',
|
|
:name => 'shipment',
|
|
:user_id => order.user_id
|
|
)
|
|
|
|
order.state_changed('shipment')
|
|
end
|
|
|
|
context "completed order" do
|
|
before { allow(order).to receive(:completed?) { true } }
|
|
|
|
it "updates payment state" do
|
|
expect(updater).to receive(:update_payment_state)
|
|
updater.update
|
|
end
|
|
|
|
it "updates shipment state" do
|
|
expect(updater).to receive(:update_shipment_state)
|
|
updater.update
|
|
end
|
|
|
|
it "updates each shipment" do
|
|
shipment = build(:shipment)
|
|
shipments = [shipment]
|
|
allow(order).to receive_messages :shipments => shipments
|
|
allow(shipments).to receive_messages :states => []
|
|
allow(shipments).to receive_messages :ready => []
|
|
allow(shipments).to receive_messages :pending => []
|
|
allow(shipments).to receive_messages :shipped => []
|
|
|
|
expect(shipment).to receive(:update!).with(order)
|
|
updater.update
|
|
end
|
|
end
|
|
|
|
context "incompleted order" do
|
|
before { allow(order).to receive_messages completed?: false }
|
|
|
|
it "doesnt update payment state" do
|
|
expect(updater).not_to receive(:update_payment_state)
|
|
updater.update
|
|
end
|
|
|
|
it "doesnt update shipment state" do
|
|
expect(updater).not_to receive(:update_shipment_state)
|
|
updater.update
|
|
end
|
|
|
|
it "doesnt update each shipment" do
|
|
shipment = build(:shipment)
|
|
shipments = [shipment]
|
|
allow(order).to receive_messages :shipments => shipments
|
|
allow(shipments).to receive_messages :states => []
|
|
allow(shipments).to receive_messages :ready => []
|
|
allow(shipments).to receive_messages :pending => []
|
|
allow(shipments).to receive_messages :shipped => []
|
|
|
|
expect(shipment).not_to receive(:update!).with(order)
|
|
updater.update
|
|
end
|
|
end
|
|
|
|
it "updates totals twice" do
|
|
expect(updater).to receive(:update_totals).twice
|
|
updater.update
|
|
end
|
|
|
|
context "update adjustments" do
|
|
context "shipments" do
|
|
it "updates" do
|
|
expect(updater).to receive(:update_shipping_adjustments)
|
|
updater.update
|
|
end
|
|
end
|
|
|
|
context "promotions" do
|
|
let(:originator) do
|
|
originator = Spree::Promotion::Actions::CreateAdjustment.create
|
|
calculator = Spree::Calculator::PerItem.create(:calculable => originator)
|
|
originator.calculator = calculator
|
|
originator.save
|
|
originator
|
|
end
|
|
|
|
def create_adjustment(label, amount)
|
|
create(:adjustment, :adjustable => order,
|
|
:originator => originator,
|
|
:amount => amount,
|
|
:state => "closed",
|
|
:label => label,
|
|
:mandatory => false)
|
|
end
|
|
|
|
it "should make all but the most valuable promotion adjustment ineligible, leaving non promotion adjustments alone" do
|
|
create_adjustment("Promotion A", -100)
|
|
create_adjustment("Promotion B", -200)
|
|
create_adjustment("Promotion C", -300)
|
|
create(:adjustment, :adjustable => order,
|
|
:originator => nil,
|
|
:amount => -500,
|
|
:state => "closed",
|
|
:label => "Some other credit")
|
|
order.adjustments.each {|a| a.update_column(:eligible, true)}
|
|
|
|
updater.update_promotion_adjustments
|
|
|
|
expect(order.adjustments.eligible.promotion.count).to eq 1
|
|
expect(order.adjustments.eligible.promotion.first.label).to eq 'Promotion C'
|
|
end
|
|
|
|
context "multiple adjustments and the best one is not eligible" do
|
|
let!(:promo_a) { create_adjustment("Promotion A", -100) }
|
|
let!(:promo_c) { create_adjustment("Promotion C", -300) }
|
|
|
|
before do
|
|
promo_a.update_column(:eligible, true)
|
|
promo_c.update_column(:eligible, false)
|
|
end
|
|
|
|
# regression for #3274
|
|
it "still makes the previous best eligible adjustment valid" do
|
|
updater.update_promotion_adjustments
|
|
expect(order.adjustments.eligible.promotion.first.label).to eq 'Promotion A'
|
|
end
|
|
end
|
|
|
|
it "should only leave one adjustment even if 2 have the same amount" do
|
|
create_adjustment("Promotion A", -100)
|
|
create_adjustment("Promotion B", -200)
|
|
create_adjustment("Promotion C", -200)
|
|
|
|
updater.update_promotion_adjustments
|
|
|
|
expect(order.adjustments.eligible.promotion.count).to eq 1
|
|
expect(order.adjustments.eligible.promotion.first.amount.to_i).to eq -200
|
|
end
|
|
|
|
it "should only include eligible adjustments in promo_total" do
|
|
create_adjustment("Promotion A", -100)
|
|
create(:adjustment, :adjustable => order,
|
|
:originator => nil,
|
|
:amount => -1000,
|
|
:state => "closed",
|
|
:eligible => false,
|
|
:label => 'Bad promo')
|
|
|
|
expect(order.promo_total.to_f).to eq -100.to_f
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|