mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Merge pull request #3130 from coopdevs/extract-restart-checkout
Extract restart checkout
This commit is contained in:
@@ -18,7 +18,7 @@ class CheckoutController < Spree::CheckoutController
|
||||
# This is only required because of spree_paypal_express. If we implement
|
||||
# a version of paypal that uses this controller, and more specifically
|
||||
# the #update_failed method, then we can remove this call
|
||||
restart_checkout
|
||||
RestartCheckout.new(@order).call
|
||||
end
|
||||
|
||||
def update
|
||||
@@ -139,7 +139,8 @@ class CheckoutController < Spree::CheckoutController
|
||||
|
||||
def update_failed
|
||||
clear_ship_address
|
||||
restart_checkout
|
||||
RestartCheckout.new(@order).call
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
render :edit
|
||||
@@ -158,15 +159,6 @@ class CheckoutController < Spree::CheckoutController
|
||||
end
|
||||
end
|
||||
|
||||
def restart_checkout
|
||||
return if @order.state == 'cart'
|
||||
@order.restart_checkout! # resets state to 'cart'
|
||||
@order.update_attributes!(shipping_method_id: nil)
|
||||
@order.shipments.with_state(:pending).destroy_all
|
||||
@order.payments.with_state(:checkout).destroy_all
|
||||
@order.reload
|
||||
end
|
||||
|
||||
def skip_state_validation?
|
||||
true
|
||||
end
|
||||
|
||||
33
app/services/restart_checkout.rb
Normal file
33
app/services/restart_checkout.rb
Normal file
@@ -0,0 +1,33 @@
|
||||
# Resets the passed order to cart state while clearing associated payments and shipments
|
||||
class RestartCheckout
|
||||
def initialize(order)
|
||||
@order = order
|
||||
end
|
||||
|
||||
def call
|
||||
return if order.cart?
|
||||
|
||||
reset_state_to_cart
|
||||
clear_shipments
|
||||
clear_payments
|
||||
|
||||
order.reload
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :order
|
||||
|
||||
def reset_state_to_cart
|
||||
order.restart_checkout!
|
||||
end
|
||||
|
||||
def clear_shipments
|
||||
order.update_attributes!(shipping_method_id: nil)
|
||||
order.shipments.with_state(:pending).destroy_all
|
||||
end
|
||||
|
||||
def clear_payments
|
||||
order.payments.with_state(:checkout).destroy_all
|
||||
end
|
||||
end
|
||||
@@ -189,11 +189,14 @@ describe CheckoutController, type: :controller do
|
||||
|
||||
describe "Paypal routing" do
|
||||
let(:payment_method) { create(:payment_method, type: "Spree::Gateway::PayPalExpress") }
|
||||
let(:restart_checkout) { instance_double(RestartCheckout, call: true) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:current_distributor) { distributor }
|
||||
allow(controller).to receive(:current_order_cycle) { order_cycle }
|
||||
allow(controller).to receive(:current_order) { order }
|
||||
allow(controller).to receive(:restart_checkout)
|
||||
|
||||
allow(RestartCheckout).to receive(:new) { restart_checkout }
|
||||
end
|
||||
|
||||
it "should check the payment method for Paypalness if we've selected one" do
|
||||
@@ -205,57 +208,19 @@ describe CheckoutController, type: :controller do
|
||||
end
|
||||
|
||||
describe "#update_failed" do
|
||||
let(:restart_checkout) { instance_double(RestartCheckout, call: true) }
|
||||
|
||||
before do
|
||||
controller.instance_variable_set(:@order, order)
|
||||
allow(RestartCheckout).to receive(:new) { restart_checkout }
|
||||
end
|
||||
|
||||
it "clears the shipping address and restarts the checkout" do
|
||||
expect(controller).to receive(:clear_ship_address)
|
||||
expect(controller).to receive(:restart_checkout)
|
||||
expect(restart_checkout).to receive(:call)
|
||||
expect(controller).to receive(:respond_to)
|
||||
|
||||
controller.send(:update_failed)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#restart_checkout" do
|
||||
let!(:shipment_pending) { create(:shipment, order: order, state: 'pending') }
|
||||
let!(:payment_checkout) { create(:payment, order: order, state: 'checkout') }
|
||||
let!(:payment_failed) { create(:payment, order: order, state: 'failed') }
|
||||
|
||||
before do
|
||||
order.update_attribute(:shipping_method_id, shipment_pending.shipping_method_id)
|
||||
controller.instance_variable_set(:@order, order.reload)
|
||||
end
|
||||
|
||||
context "when the order is already in the 'cart' state" do
|
||||
it "does nothing" do
|
||||
expect(order).to_not receive(:restart_checkout!)
|
||||
controller.send(:restart_checkout)
|
||||
end
|
||||
end
|
||||
|
||||
context "when the order is in a subsequent state" do
|
||||
before do
|
||||
order.update_attribute(:state, "payment")
|
||||
end
|
||||
|
||||
# NOTE: at the time of writing, it was not possible to create a shipment with a state other than
|
||||
# 'pending' when the order has not been completed, so this is not a case that requires testing.
|
||||
it "resets the order state, and clears incomplete shipments and payments" do
|
||||
expect(order).to receive(:restart_checkout!).and_call_original
|
||||
expect(order.shipping_method_id).to_not be nil
|
||||
expect(order.shipments.count).to be 1
|
||||
expect(order.adjustments.shipping.count).to be 1
|
||||
expect(order.payments.count).to be 2
|
||||
expect(order.adjustments.payment_fee.count).to be 2
|
||||
controller.send(:restart_checkout)
|
||||
expect(order.reload.state).to eq 'cart'
|
||||
expect(order.shipping_method_id).to be nil
|
||||
expect(order.shipments.count).to be 0
|
||||
expect(order.adjustments.shipping.count).to be 0
|
||||
expect(order.payments.count).to be 1
|
||||
expect(order.adjustments.payment_fee.count).to be 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
39
spec/services/restart_checkout_spec.rb
Normal file
39
spec/services/restart_checkout_spec.rb
Normal file
@@ -0,0 +1,39 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe RestartCheckout do
|
||||
let(:order) { create(:order) }
|
||||
|
||||
describe "#call" do
|
||||
context "when the order is already in the 'cart' state" do
|
||||
it "does nothing" do
|
||||
expect(order).to_not receive(:restart_checkout!)
|
||||
RestartCheckout.new(order).call
|
||||
end
|
||||
end
|
||||
|
||||
context "when the order is in a subsequent state" do
|
||||
let!(:shipment_pending) { create(:shipment, order: order, state: 'pending') }
|
||||
let!(:payment_checkout) { create(:payment, order: order, state: 'checkout') }
|
||||
let!(:payment_failed) { create(:payment, order: order, state: 'failed') }
|
||||
|
||||
before do
|
||||
order.shipping_method_id = shipment_pending.shipping_method_id
|
||||
order.update_attribute(:state, "payment")
|
||||
end
|
||||
|
||||
# NOTE: at the time of writing, it was not possible to create a shipment
|
||||
# with a state other than 'pending' when the order has not been
|
||||
# completed, so this is not a case that requires testing.
|
||||
it "resets the order state, and clears incomplete shipments and payments" do
|
||||
RestartCheckout.new(order).call
|
||||
|
||||
expect(order.state).to eq 'cart'
|
||||
expect(order.shipping_method_id).to eq nil
|
||||
expect(order.shipments.count).to eq 0
|
||||
expect(order.adjustments.shipping.count).to eq 0
|
||||
expect(order.payments.count).to eq 1
|
||||
expect(order.adjustments.payment_fee.count).to eq 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user