mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-27 21:06:49 +00:00
351 lines
10 KiB
Ruby
351 lines
10 KiB
Ruby
require 'spec_helper'
|
|
|
|
describe Spree::Order do
|
|
let(:order) { Spree::Order.new }
|
|
|
|
context "with default state machine" do
|
|
let(:transitions) do
|
|
[
|
|
{ address: :delivery },
|
|
{ delivery: :payment },
|
|
{ payment: :complete },
|
|
{ delivery: :complete }
|
|
]
|
|
end
|
|
|
|
it "has the following transitions" do
|
|
transitions.each do |transition|
|
|
puts transition.keys.first
|
|
puts transition.values.first
|
|
transition = Spree::Order.find_transition(from: transition.keys.first,
|
|
to: transition.values.first)
|
|
expect(transition).to_not be_nil
|
|
end
|
|
end
|
|
|
|
it "does not have a transition from delivery to confirm" do
|
|
transition = Spree::Order.find_transition(from: :delivery, to: :confirm)
|
|
expect(transition).to be_nil
|
|
end
|
|
|
|
it '.find_transition when contract was broken' do
|
|
expect(Spree::Order.find_transition({ foo: :bar, baz: :dog })).to be_falsy
|
|
end
|
|
|
|
it '.remove_transition' do
|
|
options = { from: transitions.first.keys.first, to: transitions.first.values.first }
|
|
allow(Spree::Order).to receive(:next_event_transition).and_return([options])
|
|
expect(Spree::Order.remove_transition(options)).to be_truthy
|
|
end
|
|
|
|
it '.remove_transition when contract was broken' do
|
|
expect(Spree::Order.remove_transition(nil)).to be_falsy
|
|
end
|
|
|
|
context "#checkout_steps" do
|
|
context "when payment not required" do
|
|
before { allow(order).to receive_messages payment_required?: false }
|
|
specify do
|
|
expect(order.checkout_steps).to eq %w(address delivery complete)
|
|
end
|
|
end
|
|
|
|
context "when payment required" do
|
|
before { allow(order).to receive_messages payment_required?: true }
|
|
specify do
|
|
expect(order.checkout_steps).to eq %w(address delivery payment complete)
|
|
end
|
|
end
|
|
end
|
|
|
|
it "starts out at cart" do
|
|
expect(order.state).to eq "cart"
|
|
end
|
|
|
|
it "transitions to address" do
|
|
order.line_items << FactoryBot.create(:line_item)
|
|
order.email = "user@example.com"
|
|
order.next!
|
|
expect(order.state).to eq "address"
|
|
end
|
|
|
|
it "cannot transition to address without any line items" do
|
|
expect(order.line_items).to be_blank
|
|
expect(lambda { order.next! }).to raise_error(StateMachine::InvalidTransition,
|
|
/#{Spree.t(:there_are_no_items_for_this_order)}/)
|
|
end
|
|
|
|
context "from address" do
|
|
before do
|
|
order.state = 'address'
|
|
allow(order).to receive(:has_available_payment)
|
|
order.shipments << create(:shipment)
|
|
order.email = "user@example.com"
|
|
order.save!
|
|
end
|
|
|
|
it "transitions to delivery" do
|
|
allow(order).to receive_messages(ensure_available_shipping_rates: true)
|
|
order.next!
|
|
expect(order.state).to eq "delivery"
|
|
end
|
|
|
|
context "cannot transition to delivery" do
|
|
context "if there are no shipping rates for any shipment" do
|
|
specify do
|
|
transition = lambda { order.next! }
|
|
expect(transition).to raise_error(StateMachine::InvalidTransition,
|
|
/#{Spree.t(:items_cannot_be_shipped)}/)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context "from delivery" do
|
|
before do
|
|
order.state = 'delivery'
|
|
end
|
|
|
|
context "with payment required" do
|
|
before do
|
|
allow(order).to receive_messages payment_required?: true
|
|
end
|
|
|
|
it "transitions to payment" do
|
|
order.next!
|
|
expect(order.state).to eq 'payment'
|
|
end
|
|
end
|
|
|
|
context "without payment required" do
|
|
before do
|
|
allow(order).to receive_messages payment_required?: false
|
|
end
|
|
|
|
it "transitions to complete" do
|
|
order.next!
|
|
expect(order.state).to eq "complete"
|
|
end
|
|
end
|
|
end
|
|
|
|
context "from payment" do
|
|
before do
|
|
order.state = 'payment'
|
|
end
|
|
|
|
context "when payment is required" do
|
|
before do
|
|
allow(order).to receive_messages confirmation_required?: false
|
|
allow(order).to receive_messages payment_required?: true
|
|
end
|
|
|
|
it "transitions to complete" do
|
|
expect(order).to receive(:process_payments!).once.and_return true
|
|
order.next!
|
|
expect(order.state).to eq "complete"
|
|
end
|
|
end
|
|
|
|
# Regression test for #2028
|
|
context "when payment is not required" do
|
|
before do
|
|
allow(order).to receive_messages payment_required?: false
|
|
end
|
|
|
|
it "does not call process payments" do
|
|
expect(order).to_not receive(:process_payments!)
|
|
order.next!
|
|
expect(order.state).to eq "complete"
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context "subclassed order" do
|
|
# This causes another test above to fail, but fixing this test should make
|
|
# the other test pass
|
|
class SubclassedOrder < Spree::Order
|
|
checkout_flow do
|
|
go_to_state :payment
|
|
go_to_state :complete
|
|
end
|
|
end
|
|
|
|
it "should only call default transitions once when checkout_flow is redefined" do
|
|
order = SubclassedOrder.new
|
|
allow(order).to receive_messages payment_required?: true
|
|
expect(order).to receive(:process_payments!).once
|
|
order.state = "payment"
|
|
order.next!
|
|
expect(order.state).to eq "complete"
|
|
end
|
|
end
|
|
|
|
context "re-define checkout flow" do
|
|
before do
|
|
@old_checkout_flow = Spree::Order.checkout_flow
|
|
Spree::Order.class_eval do
|
|
checkout_flow do
|
|
go_to_state :payment
|
|
go_to_state :complete
|
|
end
|
|
end
|
|
end
|
|
|
|
after do
|
|
Spree::Order.checkout_flow(&@old_checkout_flow)
|
|
end
|
|
|
|
it "should not keep old event transitions when checkout_flow is redefined" do
|
|
expect(Spree::Order.next_event_transitions).to eq [{ cart: :payment }, { payment: :complete }]
|
|
end
|
|
|
|
it "should not keep old events when checkout_flow is redefined" do
|
|
state_machine = Spree::Order.state_machine
|
|
expect(state_machine.states.any? { |s| s.name == :address }).to be_falsy
|
|
known_states = state_machine.events[:next].branches.map(&:known_states).flatten
|
|
expect(known_states).to_not include(:address)
|
|
expect(known_states).to_not include(:delivery)
|
|
expect(known_states).to_not include(:confirm)
|
|
end
|
|
end
|
|
|
|
# Regression test for #3665
|
|
context "with only a complete step" do
|
|
before do
|
|
@old_checkout_flow = Spree::Order.checkout_flow
|
|
Spree::Order.class_eval do
|
|
checkout_flow do
|
|
go_to_state :complete
|
|
end
|
|
end
|
|
end
|
|
|
|
after do
|
|
Spree::Order.checkout_flow(&@old_checkout_flow)
|
|
end
|
|
|
|
it "does not attempt to process payments" do
|
|
allow(order).to receive_message_chain(:line_items, :present?).and_return(true)
|
|
expect(order).to_not receive(:payment_required?)
|
|
expect(order).to_not receive(:process_payments!)
|
|
order.next!
|
|
end
|
|
end
|
|
|
|
context "insert checkout step" do
|
|
before do
|
|
@old_checkout_flow = Spree::Order.checkout_flow
|
|
Spree::Order.class_eval do
|
|
insert_checkout_step :new_step, before: :address
|
|
end
|
|
end
|
|
|
|
after do
|
|
Spree::Order.checkout_flow(&@old_checkout_flow)
|
|
end
|
|
|
|
it "should maintain removed transitions" do
|
|
transition = Spree::Order.find_transition(from: :delivery, to: :confirm)
|
|
expect(transition).to be_nil
|
|
end
|
|
|
|
context "before" do
|
|
before do
|
|
Spree::Order.class_eval do
|
|
insert_checkout_step :before_address, before: :address
|
|
end
|
|
end
|
|
|
|
specify do
|
|
order = Spree::Order.new
|
|
expect(order.checkout_steps).to eq %w(new_step before_address address delivery complete)
|
|
end
|
|
end
|
|
|
|
context "after" do
|
|
before do
|
|
Spree::Order.class_eval do
|
|
insert_checkout_step :after_address, after: :address
|
|
end
|
|
end
|
|
|
|
specify do
|
|
order = Spree::Order.new
|
|
expect(order.checkout_steps).to eq %w(new_step address after_address delivery complete)
|
|
end
|
|
end
|
|
end
|
|
|
|
context "remove checkout step" do
|
|
before do
|
|
@old_checkout_flow = Spree::Order.checkout_flow
|
|
Spree::Order.class_eval do
|
|
remove_checkout_step :address
|
|
end
|
|
end
|
|
|
|
after do
|
|
Spree::Order.checkout_flow(&@old_checkout_flow)
|
|
end
|
|
|
|
it "should maintain removed transitions" do
|
|
transition = Spree::Order.find_transition(from: :delivery, to: :confirm)
|
|
expect(transition).to be_nil
|
|
end
|
|
|
|
specify do
|
|
order = Spree::Order.new
|
|
expect(order.checkout_steps).to eq %w(delivery complete)
|
|
end
|
|
end
|
|
|
|
describe 'event :restart_checkout' do
|
|
let(:order) { create(:order) }
|
|
|
|
context 'when the order is not complete' do
|
|
before { allow(order).to receive(:completed?) { false } }
|
|
|
|
it 'does transition to cart state' do
|
|
expect(order.state).to eq('cart')
|
|
end
|
|
end
|
|
|
|
context 'when the order is complete' do
|
|
before { allow(order).to receive(:completed?) { true } }
|
|
|
|
it 'raises' do
|
|
expect { order.restart_checkout! }
|
|
.to raise_error(
|
|
StateMachine::InvalidTransition,
|
|
/Cannot transition state via :restart_checkout/
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "order with products with different shipping categories" do
|
|
let(:order) { create(:order_with_totals_and_distribution, ship_address: create(:address) ) }
|
|
let(:shipping_method) { create(:shipping_method, distributors: [order.distributor]) }
|
|
let(:other_shipping_category) { create(:shipping_category) }
|
|
let(:other_product) { create(:product, shipping_category: other_shipping_category ) }
|
|
let(:other_variant) { other_product.variants.first }
|
|
|
|
before do
|
|
order.order_cycle = create(:simple_order_cycle,
|
|
distributors: [order.distributor],
|
|
variants: [order.line_items.first.variant, other_variant])
|
|
order.line_items << create(:line_item, order: order, variant: other_variant)
|
|
end
|
|
|
|
it "can progress to delivery" do
|
|
shipping_method.shipping_categories << other_shipping_category
|
|
|
|
order.next
|
|
order.next
|
|
expect(order.state).to eq "delivery"
|
|
end
|
|
end
|
|
end
|