mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-21 00:47:26 +00:00
It allowed introspection of a dynamic state machine. But the only two usages of this method only referred to the first state which is always the same. Our complicated checkout logic needs more clarity and introducing some hardcoded state names here can only help.
128 lines
3.7 KiB
Ruby
128 lines
3.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'spec_helper'
|
|
|
|
describe Spree::Order::Checkout do
|
|
let(:order) { Spree::Order.new }
|
|
|
|
context "with default state machine" do
|
|
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(StateMachines::InvalidTransition,
|
|
/#{Spree.t(:there_are_no_items_for_this_order)}/)
|
|
end
|
|
|
|
context "from address" do
|
|
before do
|
|
order.state = 'address'
|
|
order.shipments << create(:shipment)
|
|
order.distributor = build(:distributor_enterprise)
|
|
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(StateMachines::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 confirmation" do
|
|
order.next!
|
|
expect(order.state).to eq 'confirmation'
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'event :restart_checkout' do
|
|
let(:order) { build_stubbed(:order) }
|
|
|
|
context 'when the order is not complete' do
|
|
before { allow(order).to receive(:completed?) { false } }
|
|
|
|
it 'transitions 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(
|
|
StateMachines::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_variant) { create(:variant, shipping_category: other_shipping_category) }
|
|
|
|
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:, 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
|