mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-11 18:26:50 +00:00
1408 lines
44 KiB
Ruby
1408 lines
44 KiB
Ruby
# frozen_string_literal: false
|
|
|
|
require 'spec_helper'
|
|
|
|
describe Spree::Order do
|
|
include OpenFoodNetwork::EmailHelper
|
|
|
|
let(:user) { build(:user, email: "spree@example.com") }
|
|
let(:order) { build(:order, user: user) }
|
|
|
|
context "#products" do
|
|
let(:order) { create(:order_with_line_items) }
|
|
|
|
it "should return ordered products" do
|
|
expect(order.products.first).to eq order.line_items.first.product
|
|
end
|
|
|
|
it "contains?" do
|
|
expect(order.contains?(order.line_items.first.variant)).to be_truthy
|
|
end
|
|
|
|
it "can find a line item matching a given variant" do
|
|
expect(order.find_line_item_by_variant(order.line_items.third.variant)).to_not be_nil
|
|
expect(order.find_line_item_by_variant(build(:variant))).to be_nil
|
|
end
|
|
end
|
|
|
|
context "#generate_order_number" do
|
|
it "should generate a random string" do
|
|
expect(order.generate_order_number.is_a?(String)).to be_truthy
|
|
expect(!order.generate_order_number.to_s.empty?).to be_truthy
|
|
end
|
|
end
|
|
|
|
context "#associate_user!" do
|
|
it "should associate a user with a persisted order" do
|
|
order = create(:order_with_line_items, created_by: nil)
|
|
user = create(:user)
|
|
|
|
order.user = nil
|
|
order.email = nil
|
|
order.associate_user!(user)
|
|
expect(order.user).to eq user
|
|
expect(order.email).to eq user.email
|
|
expect(order.created_by).to eq user
|
|
|
|
# verify that the changes we made were persisted
|
|
order.reload
|
|
expect(order.user).to eq user
|
|
expect(order.email).to eq user.email
|
|
expect(order.created_by).to eq user
|
|
end
|
|
|
|
it "should not overwrite the created_by if it already is set" do
|
|
creator = create(:user)
|
|
order = create(:order_with_line_items, created_by: creator)
|
|
user = create(:user)
|
|
|
|
order.user = nil
|
|
order.email = nil
|
|
order.associate_user!(user)
|
|
expect(order.user).to eq user
|
|
expect(order.email).to eq user.email
|
|
expect(order.created_by).to eq creator
|
|
|
|
# verify that the changes we made were persisted
|
|
order.reload
|
|
expect(order.user).to eq user
|
|
expect(order.email).to eq user.email
|
|
expect(order.created_by).to eq creator
|
|
end
|
|
|
|
it "should associate a user with a non-persisted order" do
|
|
order = Spree::Order.new
|
|
|
|
expect do
|
|
order.associate_user!(user)
|
|
end.to change { [order.user, order.email] }.from([nil, nil]).to([user, user.email])
|
|
end
|
|
|
|
it "should not persist an invalid address" do
|
|
address = Spree::Address.new
|
|
order.user = nil
|
|
order.email = nil
|
|
order.ship_address = address
|
|
expect do
|
|
order.associate_user!(user)
|
|
end.not_to change { address.persisted? }.from(false)
|
|
end
|
|
end
|
|
|
|
context "#create" do
|
|
it "should assign an order number" do
|
|
order = Spree::Order.create
|
|
expect(order.number).to_not be_nil
|
|
end
|
|
end
|
|
|
|
context "#can_ship?" do
|
|
let(:order) { Spree::Order.create }
|
|
|
|
it "should be true for order in the 'complete' state" do
|
|
allow(order).to receive_messages(complete?: true)
|
|
expect(order.can_ship?).to be_truthy
|
|
end
|
|
|
|
it "should be true for order in the 'resumed' state" do
|
|
allow(order).to receive_messages(resumed?: true)
|
|
expect(order.can_ship?).to be_truthy
|
|
end
|
|
|
|
it "should be true for an order in the 'awaiting return' state" do
|
|
allow(order).to receive_messages(awaiting_return?: true)
|
|
expect(order.can_ship?).to be_truthy
|
|
end
|
|
|
|
it "should be true for an order in the 'returned' state" do
|
|
allow(order).to receive_messages(returned?: true)
|
|
expect(order.can_ship?).to be_truthy
|
|
end
|
|
|
|
it "should be false if the order is neither in the 'complete' nor 'resumed' state" do
|
|
allow(order).to receive_messages(resumed?: false, complete?: false)
|
|
expect(order.can_ship?).to be_falsy
|
|
end
|
|
end
|
|
|
|
context "checking if order is paid" do
|
|
context "payment_state is paid" do
|
|
before { allow(order).to receive_messages payment_state: 'paid' }
|
|
it { expect(order).to be_paid }
|
|
end
|
|
|
|
context "payment_state is credit_owned" do
|
|
before { allow(order).to receive_messages payment_state: 'credit_owed' }
|
|
it { expect(order).to be_paid }
|
|
end
|
|
end
|
|
|
|
context "#finalize!" do
|
|
let(:order) { Spree::Order.create }
|
|
it "should set completed_at" do
|
|
expect(order).to receive(:touch).with(:completed_at)
|
|
order.finalize!
|
|
end
|
|
|
|
it "should sell inventory units" do
|
|
order.shipments.each do |shipment|
|
|
expect(shipment).to receive(:update!)
|
|
expect(shipment).to receive(:finalize!)
|
|
end
|
|
order.finalize!
|
|
end
|
|
|
|
it "should decrease the stock for each variant in the shipment" do
|
|
order.shipments.each do |shipment|
|
|
expect(shipment.stock_location).to receive(:decrease_stock_for_variant)
|
|
end
|
|
order.finalize!
|
|
end
|
|
|
|
it "should change the shipment state to ready if order is paid" do
|
|
Spree::Shipment.create(order: order)
|
|
order.shipments.reload
|
|
|
|
allow(order).to receive_messages(paid?: true, complete?: true)
|
|
order.finalize!
|
|
order.reload # reload so we're sure the changes are persisted
|
|
expect(order.shipment_state).to eq 'ready'
|
|
end
|
|
|
|
it "sends confirmation emails to both the user and the shop owner" do
|
|
mailer = double(:mailer, deliver_later: true)
|
|
|
|
expect(Spree::OrderMailer).to receive(:confirm_email_for_customer).and_return(mailer)
|
|
expect(Spree::OrderMailer).to receive(:confirm_email_for_shop).and_return(mailer)
|
|
|
|
order.finalize!
|
|
end
|
|
|
|
it "should freeze all adjustments" do
|
|
allow(Spree::OrderMailer).to receive_message_chain :confirm_email, :deliver_later
|
|
adjustments = double
|
|
allow(order).to receive_messages all_adjustments: adjustments
|
|
expect(adjustments).to receive(:update_all).with(state: 'closed')
|
|
order.finalize!
|
|
end
|
|
|
|
it "should log state event" do
|
|
expect(order.state_changes).to receive(:create).exactly(3).times # order, shipment & payment state changes
|
|
order.finalize!
|
|
end
|
|
|
|
it 'calls updater#before_save' do
|
|
expect(order.updater).to receive(:before_save_hook)
|
|
order.finalize!
|
|
end
|
|
end
|
|
|
|
context "#process_payments!" do
|
|
let(:payment) { build(:payment) }
|
|
before { allow(order).to receive_messages pending_payments: [payment], total: 10 }
|
|
|
|
it "should return false if no pending_payments available" do
|
|
allow(order).to receive_messages pending_payments: []
|
|
expect(order.process_payments!).to be_falsy
|
|
end
|
|
|
|
context "when the processing is sucessful" do
|
|
it "should process the payments" do
|
|
expect(payment).to receive(:process!)
|
|
expect(order.process_payments!).to be_truthy
|
|
end
|
|
|
|
it "stores the payment total on the order" do
|
|
allow(payment).to receive(:process!)
|
|
allow(payment).to receive(:completed?).and_return(true)
|
|
|
|
order.process_payments!
|
|
|
|
expect(order.payment_total).to eq(payment.amount)
|
|
end
|
|
end
|
|
|
|
context "when a payment raises a GatewayError" do
|
|
before { expect(payment).to receive(:process!).and_raise(Spree::Core::GatewayError) }
|
|
|
|
it "should return true when configured to allow checkout on gateway failures" do
|
|
Spree::Config.set allow_checkout_on_gateway_error: true
|
|
expect(order.process_payments!).to be_truthy
|
|
end
|
|
|
|
it "should return false when not configured to allow checkout on gateway failures" do
|
|
Spree::Config.set allow_checkout_on_gateway_error: false
|
|
expect(order.process_payments!).to be_falsy
|
|
end
|
|
end
|
|
end
|
|
|
|
context "#completed?" do
|
|
it "should indicate if order is completed" do
|
|
order.completed_at = nil
|
|
expect(order.completed?).to be_falsy
|
|
|
|
order.completed_at = Time.zone.now
|
|
expect(order.completed?).to be_truthy
|
|
end
|
|
end
|
|
|
|
context "#allow_checkout?" do
|
|
it "should be true if there are line_items in the order" do
|
|
allow(order).to receive_message_chain(:line_items, count: 1)
|
|
expect(order.checkout_allowed?).to be_truthy
|
|
end
|
|
it "should be false if there are no line_items in the order" do
|
|
allow(order).to receive_message_chain(:line_items, count: 0)
|
|
expect(order.checkout_allowed?).to be_falsy
|
|
end
|
|
end
|
|
|
|
context "#amount" do
|
|
before do
|
|
@order = create(:order, user: user)
|
|
@order.line_items = [create(:line_item, price: 1.0, quantity: 2),
|
|
create(:line_item, price: 1.0, quantity: 1)]
|
|
end
|
|
it "should return the correct lum sum of items" do
|
|
expect(@order.amount).to eq 3.0
|
|
end
|
|
end
|
|
|
|
context "#can_cancel?" do
|
|
it "should be false for completed order in the canceled state" do
|
|
order.state = 'canceled'
|
|
order.shipment_state = 'ready'
|
|
order.completed_at = Time.zone.now
|
|
expect(order.can_cancel?).to be_falsy
|
|
end
|
|
|
|
it "should be true for completed order with no shipment" do
|
|
order.state = 'complete'
|
|
order.shipment_state = nil
|
|
order.completed_at = Time.zone.now
|
|
expect(order.can_cancel?).to be_truthy
|
|
end
|
|
end
|
|
|
|
context "insufficient_stock_lines" do
|
|
let(:line_item) { build(:line_item) }
|
|
|
|
before do
|
|
allow(order).to receive_messages(line_items: [line_item])
|
|
allow(line_item).to receive(:insufficient_stock?) { true }
|
|
end
|
|
|
|
it "should return line_item that has insufficient stock on hand" do
|
|
expect(order.insufficient_stock_lines.size).to eq 1
|
|
expect(order.insufficient_stock_lines.include?(line_item)).to be_truthy
|
|
end
|
|
end
|
|
|
|
context "empty!" do
|
|
it "should clear out all line items and adjustments" do
|
|
order = build(:order)
|
|
allow(order).to receive_messages(line_items: line_items = [])
|
|
allow(order).to receive_messages(adjustments: adjustments = [])
|
|
expect(order.line_items).to receive(:destroy_all)
|
|
expect(order.adjustments).to receive(:destroy_all)
|
|
|
|
order.empty!
|
|
end
|
|
end
|
|
|
|
context "#display_outstanding_balance" do
|
|
it "returns the value as a spree money" do
|
|
allow(order).to receive(:new_outstanding_balance) { 10.55 }
|
|
expect(order.display_outstanding_balance).to eq Spree::Money.new(10.55)
|
|
end
|
|
end
|
|
|
|
context "#display_item_total" do
|
|
it "returns the value as a spree money" do
|
|
allow(order).to receive(:item_total) { 10.55 }
|
|
expect(order.display_item_total).to eq Spree::Money.new(10.55)
|
|
end
|
|
end
|
|
|
|
context "#display_adjustment_total" do
|
|
it "returns the value as a spree money" do
|
|
order.adjustment_total = 10.55
|
|
expect(order.display_adjustment_total).to eq Spree::Money.new(10.55)
|
|
end
|
|
end
|
|
|
|
context "#display_total" do
|
|
it "returns the value as a spree money" do
|
|
order.total = 10.55
|
|
expect(order.display_total).to eq Spree::Money.new(10.55)
|
|
end
|
|
end
|
|
|
|
context "#currency" do
|
|
context "when object currency is ABC" do
|
|
before { order.currency = "ABC" }
|
|
|
|
it "returns the currency from the object" do
|
|
expect(order.currency).to eq "ABC"
|
|
end
|
|
end
|
|
|
|
context "when object currency is nil" do
|
|
before { order.currency = nil }
|
|
|
|
it "returns the globally configured currency" do
|
|
expect(order.currency).to eq Spree::Config[:currency]
|
|
end
|
|
end
|
|
end
|
|
|
|
# Regression test for Spree #2191
|
|
context "when an order has an adjustment that zeroes the total, but another adjustment for shipping that raises it above zero" do
|
|
let!(:persisted_order) { create(:order) }
|
|
let!(:line_item) { create(:line_item) }
|
|
let!(:shipping_method) do
|
|
sm = create(:shipping_method)
|
|
sm.calculator.preferred_amount = 10
|
|
sm.save
|
|
sm
|
|
end
|
|
|
|
before do
|
|
persisted_order.line_items << line_item
|
|
persisted_order.adjustments.create(amount: -line_item.amount, label: "Promotion")
|
|
persisted_order.state = 'delivery'
|
|
persisted_order.save # To ensure new state_change event
|
|
end
|
|
|
|
it "transitions from delivery to payment" do
|
|
allow(persisted_order).to receive_messages(payment_required?: true)
|
|
persisted_order.next!
|
|
expect(persisted_order.state).to eq "payment"
|
|
end
|
|
end
|
|
|
|
context "payment required?" do
|
|
let(:order) { Spree::Order.new }
|
|
|
|
context "total is zero" do
|
|
it { expect(order.payment_required?).to be_falsy }
|
|
end
|
|
|
|
context "total > zero" do
|
|
before { allow(order).to receive_messages(total: 1) }
|
|
it { expect(order.payment_required?).to be_truthy }
|
|
end
|
|
end
|
|
|
|
describe ".tax_address" do
|
|
before { Spree::Config[:tax_using_ship_address] = tax_using_ship_address }
|
|
subject { order.tax_address }
|
|
|
|
context "when tax_using_ship_address is true" do
|
|
let(:tax_using_ship_address) { true }
|
|
|
|
it 'returns ship_address' do
|
|
expect(subject).to eq order.ship_address
|
|
end
|
|
end
|
|
|
|
context "when tax_using_ship_address is not true" do
|
|
let(:tax_using_ship_address) { false }
|
|
|
|
it "returns bill_address" do
|
|
expect(subject).to eq order.bill_address
|
|
end
|
|
end
|
|
end
|
|
|
|
context '#updater' do
|
|
it 'returns an OrderManagement::Order::Updater' do
|
|
expect(order.updater.class).to eq OrderManagement::Order::Updater
|
|
end
|
|
end
|
|
|
|
describe "email validation" do
|
|
let(:order) { build(:order) }
|
|
|
|
it "has errors if email is blank" do
|
|
allow(order).to receive_messages(require_email: true)
|
|
order.email = ""
|
|
|
|
order.valid?
|
|
expect(order.errors[:email]).to eq ["can't be blank", "is invalid"]
|
|
end
|
|
|
|
it "has errors if email is invalid" do
|
|
allow(order).to receive_messages(require_email: true)
|
|
order.email = "invalid_email"
|
|
|
|
order.valid?
|
|
expect(order.errors[:email]).to eq ["is invalid"]
|
|
end
|
|
|
|
it "has errors if email has invalid domain" do
|
|
allow(order).to receive_messages(require_email: true)
|
|
order.email = "single_letter_tld@domain.z"
|
|
|
|
order.valid?
|
|
expect(order.errors[:email]).to eq ["is invalid"]
|
|
end
|
|
|
|
it "is valid if email is valid" do
|
|
allow(order).to receive_messages(require_email: true)
|
|
order.email = "a@b.ca"
|
|
|
|
order.valid?
|
|
expect(order.errors[:email]).to eq []
|
|
end
|
|
end
|
|
|
|
describe "applying enterprise fees" do
|
|
subject { create(:order) }
|
|
let(:fee_handler) { ::OrderFeesHandler.new(subject) }
|
|
|
|
before do
|
|
allow(subject).to receive(:fee_handler) { fee_handler }
|
|
allow(subject).to receive(:update_order!)
|
|
end
|
|
|
|
it "clears all enterprise fee adjustments on the order" do
|
|
expect(EnterpriseFee).to receive(:clear_all_adjustments).with(subject)
|
|
subject.recreate_all_fees!
|
|
end
|
|
|
|
it "creates line item and order fee adjustments via OrderFeesHandler" do
|
|
expect(fee_handler).to receive(:create_line_item_fees!)
|
|
expect(fee_handler).to receive(:create_order_fees!)
|
|
subject.recreate_all_fees!
|
|
end
|
|
|
|
it "skips order cycle per-order adjustments for orders that don't have an order cycle" do
|
|
allow(EnterpriseFee).to receive(:clear_all_adjustments)
|
|
|
|
allow(subject).to receive(:order_cycle) { nil }
|
|
|
|
subject.recreate_all_fees!
|
|
end
|
|
|
|
it "ensures the correct adjustment(s) are created for order cycles" do
|
|
allow(EnterpriseFee).to receive(:clear_all_adjustments)
|
|
line_item = create(:line_item, order: subject)
|
|
allow(fee_handler).to receive(:provided_by_order_cycle?) { true }
|
|
|
|
order_cycle = double(:order_cycle)
|
|
expect_any_instance_of(OpenFoodNetwork::EnterpriseFeeCalculator).
|
|
to receive(:create_line_item_adjustments_for).
|
|
with(line_item)
|
|
allow_any_instance_of(OpenFoodNetwork::EnterpriseFeeCalculator).to receive(:create_order_adjustments_for)
|
|
allow(subject).to receive(:order_cycle) { order_cycle }
|
|
|
|
subject.recreate_all_fees!
|
|
end
|
|
|
|
it "ensures the correct per-order adjustment(s) are created for order cycles" do
|
|
allow(EnterpriseFee).to receive(:clear_all_adjustments)
|
|
|
|
order_cycle = double(:order_cycle)
|
|
expect_any_instance_of(OpenFoodNetwork::EnterpriseFeeCalculator).
|
|
to receive(:create_order_adjustments_for).
|
|
with(subject)
|
|
|
|
allow(subject).to receive(:order_cycle) { order_cycle }
|
|
|
|
subject.recreate_all_fees!
|
|
end
|
|
end
|
|
|
|
describe "getting the admin and handling charge" do
|
|
let(:o) { create(:order) }
|
|
let(:li) { create(:line_item, order: o) }
|
|
|
|
it "returns the sum of eligible enterprise fee adjustments" do
|
|
ef = create(:enterprise_fee, calculator: Calculator::FlatRate.new )
|
|
ef.calculator.set_preference :amount, 123.45
|
|
a = ef.create_adjustment("adjustment", o, true)
|
|
|
|
expect(o.admin_and_handling_total).to eq(123.45)
|
|
end
|
|
|
|
it "does not include ineligible adjustments" do
|
|
ef = create(:enterprise_fee, calculator: Calculator::FlatRate.new )
|
|
ef.calculator.set_preference :amount, 123.45
|
|
a = ef.create_adjustment("adjustment", o, true)
|
|
|
|
a.update_column :eligible, false
|
|
|
|
expect(o.admin_and_handling_total).to eq(0)
|
|
end
|
|
|
|
it "does not include adjustments that do not originate from enterprise fees" do
|
|
sm = create(:shipping_method, calculator: Calculator::FlatRate.new )
|
|
sm.calculator.set_preference :amount, 123.45
|
|
sm.create_adjustment("adjustment", o, true)
|
|
|
|
expect(o.admin_and_handling_total).to eq(0)
|
|
end
|
|
|
|
it "does not include adjustments whose source is a line item" do
|
|
ef = create(:enterprise_fee, calculator: Calculator::PerItem.new )
|
|
ef.calculator.set_preference :amount, 123.45
|
|
ef.create_adjustment("adjustment", li, true)
|
|
|
|
expect(o.admin_and_handling_total).to eq(0)
|
|
end
|
|
end
|
|
|
|
describe "an order without shipping method" do
|
|
let(:order) { create(:order) }
|
|
|
|
it "cannot be shipped" do
|
|
expect(order.ready_to_ship?).to eq(false)
|
|
end
|
|
end
|
|
|
|
describe "an unpaid order with a shipment" do
|
|
let(:order) { create(:order_with_totals, shipments: [create(:shipment)]) }
|
|
|
|
before do
|
|
order.reload
|
|
order.state = 'complete'
|
|
order.shipment.update!(order)
|
|
end
|
|
|
|
it "cannot be shipped" do
|
|
expect(order.ready_to_ship?).to eq(false)
|
|
end
|
|
end
|
|
|
|
describe "a paid order without a shipment" do
|
|
let(:order) { create(:order) }
|
|
|
|
before do
|
|
order.payment_state = 'paid'
|
|
order.state = 'complete'
|
|
end
|
|
|
|
it "cannot be shipped" do
|
|
expect(order.ready_to_ship?).to eq(false)
|
|
end
|
|
end
|
|
|
|
describe "a paid order with a shipment" do
|
|
let(:order) { create(:order_with_line_items) }
|
|
|
|
before do
|
|
order.payment_state = 'paid'
|
|
order.state = 'complete'
|
|
order.shipment.update!(order)
|
|
end
|
|
|
|
it "can be shipped" do
|
|
expect(order.ready_to_ship?).to eq(true)
|
|
end
|
|
end
|
|
|
|
describe "getting the shipping tax" do
|
|
let(:order) { create(:order) }
|
|
let(:shipping_tax_rate) {
|
|
create(:tax_rate, amount: 0.25, included_in_price: true, zone: create(:zone_with_member))
|
|
}
|
|
let(:shipping_tax_category) { create(:tax_category, tax_rates: [shipping_tax_rate]) }
|
|
let!(:shipping_method) {
|
|
create(:shipping_method_with, :flat_rate, tax_category: shipping_tax_category)
|
|
}
|
|
|
|
context "with a taxed shipment" do
|
|
let!(:shipment) {
|
|
create(:shipment_with, :shipping_method, shipping_method: shipping_method, order: order)
|
|
}
|
|
|
|
before do
|
|
allow(order).to receive(:tax_zone) { shipping_tax_rate.zone }
|
|
order.reload
|
|
order.create_tax_charge!
|
|
end
|
|
|
|
it "returns the shipping tax" do
|
|
expect(order.shipping_tax).to eq(10)
|
|
end
|
|
end
|
|
|
|
context 'when the order has not been shipped' do
|
|
it "returns zero when the order has not been shipped" do
|
|
expect(order.shipping_tax).to eq(0)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#enterprise_fee_tax" do
|
|
let!(:order) { create(:order) }
|
|
let(:enterprise_fee) { create(:enterprise_fee) }
|
|
let!(:fee_adjustment) {
|
|
create(:adjustment, adjustable: order, originator: enterprise_fee,
|
|
amount: 100, order: order, state: "closed")
|
|
}
|
|
let!(:fee_tax1) {
|
|
create(:adjustment, adjustable: fee_adjustment, originator_type: "Spree::TaxRate",
|
|
amount: 12.3, order: order, state: "closed")
|
|
}
|
|
let!(:fee_tax2) {
|
|
create(:adjustment, adjustable: fee_adjustment, originator_type: "Spree::TaxRate",
|
|
amount: 4.5, order: order, state: "closed")
|
|
}
|
|
let!(:admin_adjustment) {
|
|
create(:adjustment, adjustable: order, originator: nil,
|
|
amount: 6.7, order: order, state: "closed")
|
|
}
|
|
|
|
it "returns a sum of all taxes on enterprise fees" do
|
|
expect(order.reload.enterprise_fee_tax).to eq(16.8)
|
|
end
|
|
end
|
|
|
|
describe "getting the total tax" do
|
|
let(:shipping_tax_rate) { create(:tax_rate, amount: 0.25) }
|
|
let(:fee_tax_rate) { create(:tax_rate, amount: 0.10) }
|
|
let(:order) { create(:order) }
|
|
let(:shipping_method) { create(:shipping_method_with, :flat_rate) }
|
|
let!(:shipment) do
|
|
create(:shipment_with, :shipping_method, shipping_method: shipping_method, order: order)
|
|
end
|
|
let(:enterprise_fee) { create(:enterprise_fee) }
|
|
let!(:fee) {
|
|
create(:adjustment, adjustable: order, originator: enterprise_fee, label: "EF", amount: 20,
|
|
order: order)
|
|
}
|
|
let!(:fee_tax) {
|
|
create(:adjustment, adjustable: fee, originator: fee_tax_rate,
|
|
amount: 2, order: order, state: "closed")
|
|
}
|
|
let!(:shipping_tax) {
|
|
create(:adjustment, adjustable: shipment, originator: shipping_tax_rate,
|
|
amount: 10, order: order, state: "closed")
|
|
}
|
|
|
|
before do
|
|
order.update_order!
|
|
end
|
|
|
|
it "returns a sum of all tax on the order" do
|
|
# 12 = 2 (of the enterprise fee adjustment) + 10 (of the shipment adjustment)
|
|
expect(order.total_tax).to eq(12)
|
|
end
|
|
end
|
|
|
|
describe "setting the distributor" do
|
|
it "sets the distributor when no order cycle is set" do
|
|
d = create(:distributor_enterprise)
|
|
subject.set_distributor! d
|
|
expect(subject.distributor).to eq(d)
|
|
end
|
|
|
|
it "keeps the order cycle when it is available at the new distributor" do
|
|
d = create(:distributor_enterprise)
|
|
oc = create(:simple_order_cycle)
|
|
create(:exchange, order_cycle: oc, sender: oc.coordinator, receiver: d, incoming: false)
|
|
|
|
subject.order_cycle = oc
|
|
subject.set_distributor! d
|
|
|
|
expect(subject.distributor).to eq(d)
|
|
expect(subject.order_cycle).to eq(oc)
|
|
end
|
|
|
|
it "clears the order cycle if it is not available at that distributor" do
|
|
d = create(:distributor_enterprise)
|
|
oc = create(:simple_order_cycle)
|
|
|
|
subject.order_cycle = oc
|
|
subject.set_distributor! d
|
|
|
|
expect(subject.distributor).to eq(d)
|
|
expect(subject.order_cycle).to be_nil
|
|
end
|
|
|
|
it "clears the distributor when setting to nil" do
|
|
d = create(:distributor_enterprise)
|
|
subject.set_distributor! d
|
|
subject.set_distributor! nil
|
|
|
|
expect(subject.distributor).to be_nil
|
|
end
|
|
end
|
|
|
|
describe "emptying the order" do
|
|
it "removes shipments" do
|
|
subject.shipments << create(:shipment)
|
|
subject.save!
|
|
subject.empty!
|
|
expect(subject.shipments).to be_empty
|
|
end
|
|
|
|
it "removes payments" do
|
|
subject.payments << create(:payment)
|
|
subject.save!
|
|
subject.empty!
|
|
expect(subject.payments).to be_empty
|
|
end
|
|
end
|
|
|
|
describe "setting the order cycle" do
|
|
let(:oc) { create(:simple_order_cycle) }
|
|
|
|
it "empties the cart when changing the order cycle" do
|
|
expect(subject).to receive(:empty!)
|
|
subject.set_order_cycle! oc
|
|
end
|
|
|
|
it "doesn't empty the cart if the order cycle is not different" do
|
|
expect(subject).not_to receive(:empty!)
|
|
subject.set_order_cycle! subject.order_cycle
|
|
end
|
|
|
|
it "sets the order cycle when no distributor is set" do
|
|
subject.set_order_cycle! oc
|
|
expect(subject.order_cycle).to eq(oc)
|
|
end
|
|
|
|
it "keeps the distributor when it is available in the new order cycle" do
|
|
d = create(:distributor_enterprise)
|
|
create(:exchange, order_cycle: oc, sender: oc.coordinator, receiver: d, incoming: false)
|
|
|
|
subject.distributor = d
|
|
subject.set_order_cycle! oc
|
|
|
|
expect(subject.order_cycle).to eq(oc)
|
|
expect(subject.distributor).to eq(d)
|
|
end
|
|
|
|
it "clears the distributor if it is not available at that order cycle" do
|
|
d = create(:distributor_enterprise)
|
|
|
|
subject.distributor = d
|
|
subject.set_order_cycle! oc
|
|
|
|
expect(subject.order_cycle).to eq(oc)
|
|
expect(subject.distributor).to be_nil
|
|
end
|
|
|
|
it "clears the order cycle when setting to nil" do
|
|
d = create(:distributor_enterprise)
|
|
subject.set_order_cycle! oc
|
|
subject.distributor = d
|
|
|
|
subject.set_order_cycle! nil
|
|
|
|
expect(subject.order_cycle).to be_nil
|
|
expect(subject.distributor).to eq(d)
|
|
end
|
|
end
|
|
|
|
context "change distributor and order cycle" do
|
|
let(:variant1) { create(:product).variants.first }
|
|
let(:variant2) { create(:product).variants.first }
|
|
let(:distributor) { create(:enterprise) }
|
|
|
|
before do
|
|
subject.order_cycle = create(:simple_order_cycle, distributors: [distributor],
|
|
variants: [variant1, variant2])
|
|
subject.distributor = distributor
|
|
|
|
line_item1 = create(:line_item, order: subject, variant: variant1)
|
|
line_item2 = create(:line_item, order: subject, variant: variant2)
|
|
subject.reload
|
|
subject.line_items = [line_item1, line_item2]
|
|
end
|
|
|
|
it "allows the change when all variants in the order are provided by the new distributor in the new order cycle" do
|
|
new_distributor = create(:enterprise)
|
|
new_order_cycle = create(:simple_order_cycle, distributors: [new_distributor],
|
|
variants: [variant1, variant2])
|
|
|
|
subject.distributor = new_distributor
|
|
expect(subject).not_to be_valid
|
|
subject.order_cycle = new_order_cycle
|
|
expect(subject).to be_valid
|
|
end
|
|
|
|
it "does not allow the change when not all variants in the order are provided by the new distributor" do
|
|
new_distributor = create(:enterprise)
|
|
create(:simple_order_cycle, distributors: [new_distributor], variants: [variant1])
|
|
|
|
subject.distributor = new_distributor
|
|
expect(subject).not_to be_valid
|
|
expect(subject.errors.messages).to eq(base: ["Distributor or order cycle cannot supply the products in your cart"])
|
|
end
|
|
end
|
|
|
|
describe "scopes" do
|
|
describe "not_state" do
|
|
before do
|
|
setup_email
|
|
end
|
|
|
|
it "finds only orders not in specified state" do
|
|
o = FactoryBot.create(:completed_order_with_totals,
|
|
distributor: create(:distributor_enterprise))
|
|
o.cancel!
|
|
expect(Spree::Order.not_state(:canceled)).not_to include o
|
|
end
|
|
end
|
|
|
|
describe "not_empty" do
|
|
let!(:order_with_line_items) { create(:order_with_line_items, line_items_count: 1) }
|
|
let!(:order_without_line_items) { create(:order) }
|
|
|
|
it "returns only orders which have line items" do
|
|
expect(Spree::Order.not_empty).to include order_with_line_items
|
|
expect(Spree::Order.not_empty).to_not include order_without_line_items
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "sending confirmation emails" do
|
|
let!(:distributor) { create(:distributor_enterprise) }
|
|
let!(:order) { create(:order, distributor: distributor) }
|
|
|
|
it "sends confirmation emails" do
|
|
mailer = double(:mailer, deliver_later: true)
|
|
expect(Spree::OrderMailer).to receive(:confirm_email_for_customer).and_return(mailer)
|
|
expect(Spree::OrderMailer).to receive(:confirm_email_for_shop).and_return(mailer)
|
|
|
|
order.deliver_order_confirmation_email
|
|
end
|
|
|
|
it "does not send confirmation emails when the order belongs to a subscription" do
|
|
create(:proxy_order, order: order)
|
|
|
|
expect(Spree::OrderMailer).not_to receive(:confirm_email_for_customer)
|
|
expect(Spree::OrderMailer).not_to receive(:confirm_email_for_shop)
|
|
|
|
order.deliver_order_confirmation_email
|
|
end
|
|
end
|
|
|
|
describe "#require_customer?" do
|
|
context "when the record is new" do
|
|
let(:order) { build(:order, state: state) }
|
|
|
|
context "and the state is not cart" do
|
|
let(:state) { "complete" }
|
|
|
|
it "returns false" do
|
|
expect(order.send(:require_customer?)).to eq(false)
|
|
end
|
|
end
|
|
|
|
context "and the state is cart" do
|
|
let(:state) { "cart" }
|
|
|
|
it "returns false" do
|
|
expect(order.send(:require_customer?)).to eq(false)
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when the record is not new" do
|
|
let(:order) { create(:order, state: state) }
|
|
|
|
context "and the state is not cart" do
|
|
let(:state) { "complete" }
|
|
|
|
it "returns true" do
|
|
expect(order.send(:require_customer?)).to eq(true)
|
|
end
|
|
end
|
|
|
|
context "and the state is cart" do
|
|
let(:state) { "cart" }
|
|
|
|
it "returns false" do
|
|
expect(order.send(:require_customer?)).to eq(false)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "associating a customer" do
|
|
let(:distributor) { create(:distributor_enterprise) }
|
|
|
|
context "when creating an order" do
|
|
it "does not create a customer" do
|
|
order = create(:order, distributor: distributor)
|
|
expect(order.customer).to be_nil
|
|
end
|
|
end
|
|
|
|
context "when updating the order" do
|
|
let!(:order) { create(:order, distributor: distributor) }
|
|
|
|
before do
|
|
order.state = "complete"
|
|
order.save!
|
|
end
|
|
|
|
it "creates a customer" do
|
|
expect(order.customer).not_to be_nil
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#associate_customer" do
|
|
let(:distributor) { create(:distributor_enterprise) }
|
|
let!(:order) { create(:order, distributor: distributor) }
|
|
|
|
context "when an email address is available for the order" do
|
|
before { allow(order).to receive(:email_for_customer) { "existing@email.com" } }
|
|
|
|
context "and a customer for order.distributor and order#email_for_customer already exists" do
|
|
let!(:customer) { create(:customer, enterprise: distributor, email: "existing@email.com" ) }
|
|
|
|
it "associates the order with the existing customer, and returns the customer" do
|
|
result = order.send(:associate_customer)
|
|
expect(order.customer).to eq customer
|
|
expect(result).to eq customer
|
|
end
|
|
end
|
|
|
|
context "and a customer for order.distributor and order.user.email does not alread exist" do
|
|
let!(:customer) {
|
|
create(:customer, enterprise: distributor, email: 'some-other-email@email.com')
|
|
}
|
|
|
|
it "does not set the customer and returns nil" do
|
|
result = order.send(:associate_customer)
|
|
expect(order.customer).to be_nil
|
|
expect(result).to be_nil
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when an email address is not available for the order" do
|
|
let!(:customer) { create(:customer, enterprise: distributor) }
|
|
before { allow(order).to receive(:email_for_customer) { nil } }
|
|
|
|
it "does not set the customer and returns nil" do
|
|
result = order.send(:associate_customer)
|
|
expect(order.customer).to be_nil
|
|
expect(result).to be_nil
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "ensuring a customer is linked" do
|
|
let(:distributor) { create(:distributor_enterprise) }
|
|
let!(:order) { create(:order, distributor: distributor) }
|
|
|
|
context "when a customer has already been linked to the order" do
|
|
let!(:customer) { create(:customer, enterprise: distributor, email: "existing@email.com" ) }
|
|
before { order.update_attribute(:customer_id, customer.id) }
|
|
|
|
it "does nothing" do
|
|
order.send(:ensure_customer)
|
|
expect(order.customer).to eq customer
|
|
end
|
|
end
|
|
|
|
context "when a customer not been linked to the order" do
|
|
context "but one matching order#email_for_customer already exists" do
|
|
let!(:customer) {
|
|
create(:customer, enterprise: distributor, email: 'some-other-email@email.com')
|
|
}
|
|
before { allow(order).to receive(:email_for_customer) { 'some-other-email@email.com' } }
|
|
|
|
it "links the customer customer to the order" do
|
|
expect(order.customer).to be_nil
|
|
expect{ order.send(:ensure_customer) }.to_not change{ Customer.count }
|
|
expect(order.customer).to eq customer
|
|
end
|
|
end
|
|
|
|
context "and order#email_for_customer does not match any existing customers" do
|
|
before do
|
|
order.bill_address = create(:address)
|
|
order.ship_address = create(:address)
|
|
end
|
|
|
|
context "and the customer is not valid" do
|
|
before do
|
|
order.distributor = nil
|
|
order.user = nil
|
|
order.email = nil
|
|
end
|
|
|
|
it "sends an error to Bugsnag" do
|
|
expect(Bugsnag)
|
|
.to receive(:notify).with("Email can't be blank, Enterprise can't be blank")
|
|
order.send(:ensure_customer)
|
|
end
|
|
end
|
|
|
|
context "and the customer is valid" do
|
|
it "creates a new customer with defaut name and addresses" do
|
|
expect(order.customer).to be_nil
|
|
expect { order.send(:ensure_customer) }.to change{ Customer.count }.by 1
|
|
|
|
expect(order.customer.name).to eq order.bill_address.full_name
|
|
expect(order.customer.bill_address.same_as?(order.bill_address)).to be true
|
|
expect(order.customer.ship_address.same_as?(order.ship_address)).to be true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "when a guest order is placed with a registered email" do
|
|
let(:order) { create(:order_with_totals_and_distribution, user: user) }
|
|
let(:payment_method) { create(:payment_method, distributors: [order.distributor]) }
|
|
let(:shipping_method) { create(:shipping_method, distributors: [order.distributor]) }
|
|
let(:user) { create(:user, email: 'registered@email.com') }
|
|
|
|
before do
|
|
order.bill_address = create(:address)
|
|
order.ship_address = create(:address)
|
|
order.email = user.email
|
|
order.user = nil
|
|
order.state = 'cart'
|
|
end
|
|
|
|
it "returns a validation error" do
|
|
expect{ order.next }.to change(order.errors, :count).from(0).to(1)
|
|
expect(order.errors.messages[:email]).to eq [I18n.t('devise.failure.already_registered')]
|
|
expect(order.state).to eq 'cart'
|
|
end
|
|
end
|
|
|
|
describe "a completed order with shipping and transaction fees" do
|
|
let(:distributor) { create(:distributor_enterprise_with_tax) }
|
|
let(:zone) { create(:zone_with_member) }
|
|
let(:shipping_tax_rate) { create(:tax_rate, amount: 0.25, included_in_price: true, zone: zone) }
|
|
let(:shipping_tax_category) { create(:tax_category, tax_rates: [shipping_tax_rate]) }
|
|
let(:order) {
|
|
create(:completed_order_with_fees, distributor: distributor, shipping_fee: shipping_fee,
|
|
payment_fee: payment_fee,
|
|
shipping_tax_category: shipping_tax_category)
|
|
}
|
|
let(:shipping_fee) { 3 }
|
|
let(:payment_fee) { 5 }
|
|
let(:item_num) { order.line_items.length }
|
|
let(:expected_fees) { item_num * (shipping_fee + payment_fee) }
|
|
|
|
before do
|
|
order.reload
|
|
order.create_tax_charge!
|
|
|
|
# Sanity check the fees
|
|
expect(order.all_adjustments.length).to eq 3
|
|
expect(order.shipment_adjustments.length).to eq 2
|
|
expect(item_num).to eq 2
|
|
expect(order.adjustment_total).to eq expected_fees
|
|
expect(order.shipment.adjustments.tax.inclusive.sum(:amount)).to eq 1.2
|
|
expect(order.shipment.included_tax_total).to eq 1.2
|
|
end
|
|
|
|
context "removing line_items" do
|
|
it "updates shipping and transaction fees" do
|
|
order.line_items.first.update_attribute(:quantity, 0)
|
|
order.save
|
|
|
|
expect(order.adjustment_total).to eq expected_fees - shipping_fee - payment_fee
|
|
expect(order.shipment.adjustments.tax.inclusive.sum(:amount)).to eq 0.6
|
|
expect(order.shipment.included_tax_total).to eq 0.6
|
|
end
|
|
|
|
context "when finalized fee adjustments exist on the order" do
|
|
before do
|
|
order.all_adjustments.each(&:finalize!)
|
|
order.reload
|
|
end
|
|
|
|
it "does not attempt to update such adjustments" do
|
|
order.update(line_items_attributes: [{ id: order.line_items.first.id, quantity: 0 }])
|
|
|
|
# Check if fees got updated
|
|
order.reload
|
|
|
|
expect(order.adjustment_total).to eq expected_fees
|
|
expect(order.shipment.adjustments.tax.inclusive.sum(:amount)).to eq 1.2
|
|
expect(order.shipment.included_tax_total).to eq 1.2
|
|
end
|
|
end
|
|
end
|
|
|
|
context "changing the shipping method to one without fees" do
|
|
let(:shipping_method) {
|
|
create(:shipping_method, calculator: Calculator::FlatRate.new(preferred_amount: 0))
|
|
}
|
|
|
|
it "updates shipping fees" do
|
|
order.shipments = [create(:shipment_with, :shipping_method,
|
|
shipping_method: shipping_method)]
|
|
order.save
|
|
|
|
expect(order.adjustment_total).to eq expected_fees - (item_num * shipping_fee)
|
|
expect(order.shipment.adjustments.tax.inclusive.sum(:amount)).to eq 0
|
|
expect(order.shipment.included_tax_total).to eq 0
|
|
end
|
|
end
|
|
|
|
context "changing the payment method to one without fees" do
|
|
let(:payment_method) {
|
|
create(:payment_method, calculator: Calculator::FlatRate.new(preferred_amount: 0))
|
|
}
|
|
|
|
it "removes transaction fees" do
|
|
# Change the payment method
|
|
order.payments.first.update(payment_method_id: payment_method.id)
|
|
order.save
|
|
|
|
# Check if fees got updated
|
|
order.reload
|
|
expect(order.adjustment_total).to eq expected_fees - (item_num * payment_fee)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "retrieving previously ordered items" do
|
|
let(:distributor) { create(:distributor_enterprise) }
|
|
let(:order_cycle) { create(:simple_order_cycle) }
|
|
let!(:order) { create(:order, distributor: distributor, order_cycle: order_cycle) }
|
|
|
|
it "returns no items if nothing has been ordered" do
|
|
expect(order.finalised_line_items).to eq []
|
|
end
|
|
|
|
context "when no order has been finalised in this order cycle" do
|
|
let(:product) { create(:product) }
|
|
|
|
before do
|
|
order.contents.update_or_create(product.variants.first, { quantity: 1, max_quantity: 3 })
|
|
end
|
|
|
|
it "returns no items even though the cart contains items" do
|
|
expect(order.finalised_line_items).to eq []
|
|
end
|
|
end
|
|
|
|
context "when an order has been finalised in this order cycle" do
|
|
let!(:prev_order) {
|
|
create(:completed_order_with_totals, distributor: distributor, order_cycle: order_cycle,
|
|
user: order.user)
|
|
}
|
|
let!(:prev_order2) {
|
|
create(:completed_order_with_totals, distributor: distributor, order_cycle: order_cycle,
|
|
user: order.user)
|
|
}
|
|
let(:product) { create(:product) }
|
|
|
|
before do
|
|
prev_order.contents.update_or_create(product.variants.first,
|
|
{ quantity: 1, max_quantity: 3 })
|
|
prev_order2.reload # to get the right response from line_items
|
|
end
|
|
|
|
it "returns previous items" do
|
|
expect(order.finalised_line_items.length).to eq 11
|
|
expect(order.finalised_line_items).to match_array(prev_order.line_items + prev_order2.line_items)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "determining checkout steps for an order" do
|
|
let!(:enterprise) { create(:enterprise) }
|
|
let!(:order) { create(:order, distributor: enterprise) }
|
|
let!(:payment_method) {
|
|
create(:stripe_connect_payment_method, distributor_ids: [enterprise.id])
|
|
}
|
|
let!(:payment) { create(:payment, order: order, payment_method: payment_method) }
|
|
|
|
it "does not include the :confirm step" do
|
|
expect(order.checkout_steps).to_not include "confirm"
|
|
end
|
|
end
|
|
|
|
describe "payments" do
|
|
let(:payment_method) { create(:payment_method) }
|
|
let(:shipping_method) { create(:shipping_method) }
|
|
let(:order) { create(:order_with_totals_and_distribution) }
|
|
|
|
before { order.update_totals }
|
|
|
|
context "when the order is not a subscription" do
|
|
it "it requires a payment" do
|
|
expect(order.payment_required?).to be true
|
|
end
|
|
|
|
it "advances to payment state" do
|
|
advance_to_delivery_state(order)
|
|
|
|
expect { order.next! }.to change { order.state }.from("delivery").to("payment")
|
|
end
|
|
|
|
# Regression test for https://github.com/openfoodfoundation/openfoodnetwork/issues/3924
|
|
it "advances to complete state without error" do
|
|
advance_to_delivery_state(order)
|
|
order.next!
|
|
order.payments << create(:payment, order: order)
|
|
|
|
expect { order.next! }.to change { order.state }.from("payment").to("complete")
|
|
end
|
|
end
|
|
|
|
context "when the order is a subscription" do
|
|
let!(:proxy_order) { create(:proxy_order, order: order) }
|
|
let!(:order_cycle) { proxy_order.order_cycle }
|
|
|
|
context "and order_cycle has no order_close_at set" do
|
|
before { order.order_cycle.update(orders_close_at: nil) }
|
|
|
|
it "requires a payment" do
|
|
expect(order.payment_required?).to be true
|
|
end
|
|
end
|
|
|
|
context "and the order_cycle has closed" do
|
|
before { order.order_cycle.update(orders_close_at: 5.minutes.ago) }
|
|
|
|
it "returns the payments on the order" do
|
|
expect(order.payment_required?).to be true
|
|
end
|
|
end
|
|
|
|
context "and the order_cycle has not yet closed" do
|
|
before { order.order_cycle.update(orders_close_at: 5.minutes.from_now) }
|
|
|
|
it "returns an empty array" do
|
|
expect(order.payment_required?).to be false
|
|
end
|
|
|
|
it "skips the payment state" do
|
|
advance_to_delivery_state(order)
|
|
|
|
expect { order.next! }.to change { order.state }.from("delivery").to("complete")
|
|
end
|
|
end
|
|
end
|
|
|
|
def advance_to_delivery_state(order)
|
|
# advance to address state
|
|
order.ship_address = create(:address)
|
|
order.next!
|
|
expect(order.state).to eq "address"
|
|
|
|
# advance to delivery state
|
|
order.next!
|
|
expect(order.state).to eq "delivery"
|
|
end
|
|
end
|
|
|
|
describe '#restart_checkout!' do
|
|
context 'when the order is complete' do
|
|
let(:order) do
|
|
build_stubbed(
|
|
:order,
|
|
completed_at: Time.zone.now,
|
|
line_items: [build_stubbed(:line_item)]
|
|
)
|
|
end
|
|
|
|
it 'raises' do
|
|
expect { order.restart_checkout! }
|
|
.to raise_error(StateMachines::InvalidTransition)
|
|
end
|
|
end
|
|
|
|
context 'when the order is not complete' do
|
|
let(:order) do
|
|
build(:order, completed_at: nil, line_items: [build(:line_item)])
|
|
end
|
|
|
|
it 'transitions to :cart state' do
|
|
order.restart_checkout!
|
|
expect(order.state).to eq('cart')
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#set_payment_amount!' do
|
|
let(:order) do
|
|
shipment = build(:shipment_with, :shipping_method, shipping_method: build(:shipping_method))
|
|
build(:order, shipments: [shipment])
|
|
end
|
|
|
|
context 'after transitioning to payment' do
|
|
before do
|
|
order.state = 'delivery' # payment's previous state
|
|
|
|
allow(order).to receive(:payment_required?) { true }
|
|
end
|
|
|
|
it 'calls #set_payment_amount! and updates totals' do
|
|
expect(order).to receive(:set_payment_amount!)
|
|
expect(order).to receive(:update_totals).at_least(:once)
|
|
|
|
order.next
|
|
end
|
|
|
|
context "payment's amount" do
|
|
let(:failed_payment) { create(:payment, order: order, state: 'failed', amount: 100) }
|
|
|
|
before do
|
|
allow(order).to receive(:total) { 120 }
|
|
end
|
|
|
|
it 'is not updated for failed payments' do
|
|
failed_payment
|
|
|
|
order.next
|
|
|
|
expect(failed_payment.reload.amount).to eq 100
|
|
end
|
|
|
|
it 'is updated only for pending payments' do
|
|
pending_payment = create(:payment, order: order, state: 'pending', amount: 80)
|
|
failed_payment
|
|
|
|
order.next
|
|
|
|
expect(failed_payment.reload.amount).to eq 100
|
|
expect(pending_payment.reload.amount).to eq 120
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#ensure_updated_shipments" do
|
|
before { Spree::Shipment.create!(order: order) }
|
|
|
|
context "when the order is not completed" do
|
|
it "destroys current shipments" do
|
|
order.ensure_updated_shipments
|
|
expect(order.shipments).to be_empty
|
|
end
|
|
|
|
it "puts order back in address state" do
|
|
order.ensure_updated_shipments
|
|
expect(order.state).to eq "address"
|
|
end
|
|
end
|
|
|
|
context "when the order is completed" do
|
|
before do
|
|
allow(order).to receive(:completed?) { true }
|
|
end
|
|
|
|
it "does not change the shipments" do
|
|
expect {
|
|
order.ensure_updated_shipments
|
|
}.not_to change { order.shipments }
|
|
|
|
expect {
|
|
order.ensure_updated_shipments
|
|
}.not_to change { order.state }
|
|
end
|
|
end
|
|
end
|
|
end
|