diff --git a/app/models/spree/order/checkout.rb b/app/models/spree/order/checkout.rb index 0b70dda37a..ffecf63f23 100644 --- a/app/models/spree/order/checkout.rb +++ b/app/models/spree/order/checkout.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Spree class Order < ActiveRecord::Base module Checkout @@ -38,8 +40,8 @@ module Spree # To avoid multiple occurrences of the same transition being defined # On first definition, state_machines will not be defined state_machines.clear if respond_to?(:state_machines) - state_machine :state, :initial => :cart do - klass.next_event_transitions.each { |t| transition(t.merge(:on => :next)) } + state_machine :state, initial: :cart do + klass.next_event_transitions.each { |t| transition(t.merge(on: :next)) } # Persist the state on the order after_transition do |order| @@ -48,46 +50,46 @@ module Spree end event :cancel do - transition :to => :canceled, :if => :allow_cancel? + transition to: :canceled, if: :allow_cancel? end event :return do - transition :to => :returned, :from => :awaiting_return, :unless => :awaiting_returns? + transition to: :returned, from: :awaiting_return, unless: :awaiting_returns? end event :resume do - transition :to => :resumed, :from => :canceled, :if => :allow_resume? + transition to: :resumed, from: :canceled, if: :allow_resume? end event :authorize_return do - transition :to => :awaiting_return + transition to: :awaiting_return end if states[:payment] - before_transition :to => :complete do |order| + before_transition to: :complete do |order| order.process_payments! if order.payment_required? end end - before_transition :from => :cart, :do => :ensure_line_items_present + before_transition from: :cart, do: :ensure_line_items_present - before_transition :to => :delivery, :do => :create_proposed_shipments - before_transition :to => :delivery, :do => :ensure_available_shipping_rates + before_transition to: :delivery, do: :create_proposed_shipments + before_transition to: :delivery, do: :ensure_available_shipping_rates - after_transition :to => :complete, :do => :finalize! - after_transition :to => :delivery, :do => :create_tax_charge! - after_transition :to => :resumed, :do => :after_resume - after_transition :to => :canceled, :do => :after_cancel + after_transition to: :complete, do: :finalize! + after_transition to: :delivery, do: :create_tax_charge! + after_transition to: :resumed, do: :after_resume + after_transition to: :canceled, do: :after_cancel end end - def self.go_to_state(name, options={}) - self.checkout_steps[name] = options + def self.go_to_state(name, options = {}) + checkout_steps[name] = options previous_states.each do |state| - add_transition({:from => state, :to => name}.merge(options)) + add_transition({ from: state, to: name }.merge(options)) end if options[:if] - self.previous_states << name + previous_states << name else self.previous_states = [name] end @@ -96,43 +98,44 @@ module Spree def self.insert_checkout_step(name, options = {}) before = options.delete(:before) after = options.delete(:after) unless before - after = self.checkout_steps.keys.last unless before || after + after = checkout_steps.keys.last unless before || after - cloned_steps = self.checkout_steps.clone - cloned_removed_transitions = self.removed_transitions.clone - self.checkout_flow do + cloned_steps = checkout_steps.clone + cloned_removed_transitions = removed_transitions.clone + checkout_flow do cloned_steps.each_pair do |key, value| - self.go_to_state(name, options) if key == before - self.go_to_state(key, value) - self.go_to_state(name, options) if key == after + go_to_state(name, options) if key == before + go_to_state(key, value) + go_to_state(name, options) if key == after end cloned_removed_transitions.each do |transition| - self.remove_transition(transition) + remove_transition(transition) end end end def self.remove_checkout_step(name) - cloned_steps = self.checkout_steps.clone - cloned_removed_transitions = self.removed_transitions.clone - self.checkout_flow do + cloned_steps = checkout_steps.clone + cloned_removed_transitions = removed_transitions.clone + checkout_flow do cloned_steps.each_pair do |key, value| - self.go_to_state(key, value) unless key == name + go_to_state(key, value) unless key == name end cloned_removed_transitions.each do |transition| - self.remove_transition(transition) + remove_transition(transition) end end end - def self.remove_transition(options={}) - self.removed_transitions << options - self.next_event_transitions.delete(find_transition(options)) + def self.remove_transition(options = {}) + removed_transitions << options + next_event_transitions.delete(find_transition(options)) end - def self.find_transition(options={}) + def self.find_transition(options = {}) return nil if options.nil? || !options.include?(:from) || !options.include?(:to) - self.next_event_transitions.detect do |transition| + + next_event_transitions.detect do |transition| transition[options[:from].to_sym] == options[:to].to_sym end end @@ -146,12 +149,15 @@ module Spree end def self.add_transition(options) - self.next_event_transitions << { options.delete(:from) => options.delete(:to) }.merge(options) + next_event_transitions << { options.delete(:from) => options.delete(:to) }. + merge(options) end def checkout_steps - steps = self.class.checkout_steps.each_with_object([]) { |(step, options), checkout_steps| + steps = self.class.checkout_steps. + each_with_object([]) { |(step, options), checkout_steps| next if options.include?(:if) && !options[:if].call(self) + checkout_steps << step }.map(&:to_s) # Ensure there is always a complete step @@ -159,12 +165,12 @@ module Spree steps end - def has_checkout_step?(step) - step.present? ? self.checkout_steps.include?(step) : false + def checkout_step?(step) + step.present? ? checkout_steps.include?(step) : false end def checkout_step_index(step) - self.checkout_steps.index(step) + checkout_steps.index(step) end def self.removed_transitions @@ -172,7 +178,10 @@ module Spree end def can_go_to_state?(state) - return false unless self.state.present? && has_checkout_step?(state) && has_checkout_step?(self.state) + return false unless self.state.present? && + checkout_step?(state) && + checkout_step?(self.state) + checkout_step_index(state) > checkout_step_index(self.state) end end diff --git a/spec/models/spree/order/checkout_spec.rb b/spec/models/spree/order/checkout_spec.rb index 4cc9ca5101..75a3ae6a95 100644 --- a/spec/models/spree/order/checkout_spec.rb +++ b/spec/models/spree/order/checkout_spec.rb @@ -6,33 +6,34 @@ describe Spree::Order do context "with default state machine" do let(:transitions) do [ - { :address => :delivery }, - { :delivery => :payment }, - { :payment => :confirm }, - { :confirm => :complete }, - { :payment => :complete }, - { :delivery => :complete } + { address: :delivery }, + { delivery: :payment }, + { payment: :confirm }, + { confirm: :complete }, + { payment: :complete }, + { delivery: :complete } ] end it "has the following transitions" do transitions.each do |transition| - transition = Spree::Order.find_transition(:from => transition.keys.first, :to => transition.values.first) + transition = Spree::Order.find_transition(from: transition.keys.first, + to: transition.values.first) transition.should_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) + transition = Spree::Order.find_transition(from: :delivery, to: :confirm) transition.should be_nil end - + it '.find_transition when contract was broken' do - Spree::Order.find_transition({foo: :bar, baz: :dog}).should be_false + Spree::Order.find_transition({ foo: :bar, baz: :dog }).should be_false end it '.remove_transition' do - options = {:from => transitions.first.keys.first, :to => transitions.first.values.first} + options = { from: transitions.first.keys.first, to: transitions.first.values.first } Spree::Order.stub(:next_event_transition).and_return([options]) Spree::Order.remove_transition(options).should be_true end @@ -44,8 +45,8 @@ describe Spree::Order do context "#checkout_steps" do context "when confirmation not required" do before do - order.stub :confirmation_required? => false - order.stub :payment_required? => true + order.stub confirmation_required?: false + order.stub payment_required?: true end specify do @@ -55,8 +56,8 @@ describe Spree::Order do context "when confirmation required" do before do - order.stub :confirmation_required? => true - order.stub :payment_required? => true + order.stub confirmation_required?: true + order.stub payment_required?: true end specify do @@ -65,14 +66,14 @@ describe Spree::Order do end context "when payment not required" do - before { order.stub :payment_required? => false } + before { order.stub payment_required?: false } specify do order.checkout_steps.should == %w(address delivery complete) end end context "when payment required" do - before { order.stub :payment_required? => true } + before { order.stub payment_required?: true } specify do order.checkout_steps.should == %w(address delivery payment complete) end @@ -92,20 +93,21 @@ describe Spree::Order do it "cannot transition to address without any line items" do order.line_items.should be_blank - lambda { order.next! }.should raise_error(StateMachine::InvalidTransition, /#{Spree.t(:there_are_no_items_for_this_order)}/) + lambda { order.next! }.should raise_error(StateMachine::InvalidTransition, + /#{Spree.t(:there_are_no_items_for_this_order)}/) end context "from address" do before do order.state = 'address' order.stub(:has_available_payment) - shipment = FactoryGirl.create(:shipment, :order => order) + shipment = FactoryGirl.create(:shipment, order: order) order.email = "user@example.com" order.save! end it "transitions to delivery" do - order.stub(:ensure_available_shipping_rates => true) + order.stub(ensure_available_shipping_rates: true) order.next! order.state.should == "delivery" end @@ -114,7 +116,8 @@ describe Spree::Order do context "if there are no shipping rates for any shipment" do specify do transition = lambda { order.next! } - transition.should raise_error(StateMachine::InvalidTransition, /#{Spree.t(:items_cannot_be_shipped)}/) + transition.should raise_error(StateMachine::InvalidTransition, + /#{Spree.t(:items_cannot_be_shipped)}/) end end end @@ -127,7 +130,7 @@ describe Spree::Order do context "with payment required" do before do - order.stub :payment_required? => true + order.stub payment_required?: true end it "transitions to payment" do @@ -138,7 +141,7 @@ describe Spree::Order do context "without payment required" do before do - order.stub :payment_required? => false + order.stub payment_required?: false end it "transitions to complete" do @@ -155,7 +158,7 @@ describe Spree::Order do context "with confirmation required" do before do - order.stub :confirmation_required? => true + order.stub confirmation_required?: true end it "transitions to confirm" do @@ -166,8 +169,8 @@ describe Spree::Order do context "without confirmation required" do before do - order.stub :confirmation_required? => false - order.stub :payment_required? => true + order.stub confirmation_required?: false + order.stub payment_required?: true end it "transitions to complete" do @@ -180,7 +183,7 @@ describe Spree::Order do # Regression test for #2028 context "when payment is not required" do before do - order.stub :payment_required? => false + order.stub payment_required?: false end it "does not call process payments" do @@ -204,7 +207,7 @@ describe Spree::Order do it "should only call default transitions once when checkout_flow is redefined" do order = SubclassedOrder.new - order.stub :payment_required? => true + order.stub payment_required?: true order.should_receive(:process_payments!).once order.state = "payment" order.next! @@ -228,7 +231,7 @@ describe Spree::Order do end it "should not keep old event transitions when checkout_flow is redefined" do - Spree::Order.next_event_transitions.should == [{:cart=>:payment}, {:payment=>:complete}] + Spree::Order.next_event_transitions.should == [{ cart: :payment }, { payment: :complete }] end it "should not keep old events when checkout_flow is redefined" do @@ -262,7 +265,6 @@ describe Spree::Order do order.should_not_receive(:process_payments!) order.next! end - end context "insert checkout step" do @@ -278,7 +280,7 @@ describe Spree::Order do end it "should maintain removed transitions" do - transition = Spree::Order.find_transition(:from => :delivery, :to => :confirm) + transition = Spree::Order.find_transition(from: :delivery, to: :confirm) transition.should be_nil end @@ -322,7 +324,7 @@ describe Spree::Order do end it "should maintain removed transitions" do - transition = Spree::Order.find_transition(:from => :delivery, :to => :confirm) + transition = Spree::Order.find_transition(from: :delivery, to: :confirm) transition.should be_nil end