Let people choose which payment methods are available to customers on order cycles

This commit is contained in:
Cillian O'Ruanaidh
2022-10-07 17:14:11 +01:00
parent 5718f9f00c
commit 4e6d64c0a1
18 changed files with 789 additions and 340 deletions

View File

@@ -276,7 +276,7 @@ describe Enterprise do
expect(Enterprise.ready_for_checkout).not_to include e
end
it "does not show enterprises wchich only have backend shipping methods" do
it "does not show enterprises which only have backend shipping methods" do
create(:shipping_method, distributors: [e],
display_on: Spree::ShippingMethod::DISPLAY_ON_OPTIONS[:back_end])
create(:payment_method, distributors: [e])
@@ -354,6 +354,13 @@ describe Enterprise do
create(:payment_method, distributors: [e])
expect(e.reload).to be_ready_for_checkout
end
it "returns false for enterprises with payment methods that are available but not configured
correctly" do
create(:shipping_method, distributors: [e])
create(:stripe_sca_payment_method, distributors: [e])
expect(e.reload).not_to be_ready_for_checkout
end
end
describe "distributors_with_active_order_cycles" do

View File

@@ -404,7 +404,32 @@ describe OrderCycle do
expect(cloned_exchange_attributes).to match_array original_exchange_attributes
end
context "when it has preferred shipping methods which can longer be applied validly
context "when it has selected payment methods which can longer be applied validly
e.g. payment method is backoffice only" do
it "only attaches the valid ones to the clone" do
distributor = create(:distributor_enterprise)
distributor_payment_method_i = create(
:payment_method,
distributors: [distributor]
).distributor_payment_methods.first
distributor_payment_method_ii = create(
:payment_method,
distributors: [distributor],
display_on: "back_end"
).distributor_payment_methods.first
order_cycle = create(:distributor_order_cycle, distributors: [distributor])
order_cycle.selected_distributor_payment_methods = [
distributor_payment_method_i,
distributor_payment_method_ii
]
cloned_order_cycle = order_cycle.clone!
expect(cloned_order_cycle.distributor_payment_methods).to eq [distributor_payment_method_i]
end
end
context "when it has selected shipping methods which can longer be applied validly
e.g. shipping method is backoffice only" do
it "only attaches the valid ones to the clone" do
distributor = create(:distributor_enterprise)
@@ -637,6 +662,32 @@ describe OrderCycle do
end
end
describe "#attachable_distributor_payment_methods" do
it "includes distributor payment methods from the distributors on the order cycle" do
payment_method = create(:payment_method)
oc = create(:simple_order_cycle, distributors: [payment_method.distributors.first])
distributor_payment_method = payment_method.distributor_payment_methods.first
expect(oc.attachable_distributor_payment_methods).to eq([distributor_payment_method])
end
it "does not include backoffice only distributor payment methods" do
payment_method = create(:payment_method, display_on: "back_end")
enterprise = create(:enterprise, payment_methods: [payment_method])
oc = create(:simple_order_cycle, distributors: [enterprise])
expect(oc.attachable_distributor_payment_methods).to be_empty
end
it "does not include inactive distributor payment methods" do
payment_method = create(:payment_method, active: false)
enterprise = create(:enterprise, payment_methods: [payment_method])
oc = create(:simple_order_cycle, distributors: [enterprise])
expect(oc.attachable_distributor_payment_methods).to be_empty
end
end
describe "#attachable_distributor_shipping_methods" do
it "includes distributor shipping methods from the distributors on the order cycle" do
shipping_method = create(:shipping_method)
@@ -655,6 +706,80 @@ describe OrderCycle do
end
end
describe "#distributor_payment_methods" do
let(:distributor) { create(:distributor_enterprise) }
it "returns all attachable distributor payment methods if the order cycle is simple" do
oc = create(:sells_own_order_cycle, distributors: [distributor])
distributor_payment_method = create(
:payment_method,
distributors: [distributor]
).distributor_payment_methods.first
expect(oc.distributor_payment_methods).to eq [distributor_payment_method]
end
context "distributor order cycle i.e. non-simple" do
let(:oc) { create(:distributor_order_cycle, distributors: [distributor]) }
it "returns all attachable distributor payment methods if no distributor payment methods
have been selected specifically" do
distributor_payment_method = create(
:payment_method,
distributors: [distributor]
).distributor_payment_methods.first
expect(oc.selected_distributor_payment_methods).to be_empty
expect(oc.distributor_payment_methods).to eq [distributor_payment_method]
end
it "returns selected distributor payment methods if they have been specified" do
distributor_payment_method_i = create(
:payment_method,
distributors: [distributor]
).distributor_payment_methods.first
distributor_payment_method_ii = create(
:payment_method,
distributors: [distributor]
).distributor_payment_methods.first
oc.selected_distributor_payment_methods << distributor_payment_method_ii
expect(oc.distributor_payment_methods).to eq [distributor_payment_method_ii]
end
context "with multiple distributors" do
let(:other_distributor) { create(:distributor_enterprise) }
let(:oc) { create(:distributor_order_cycle, distributors: [distributor, other_distributor]) }
it "returns all attachable distributor payment methods for a distributor if no distributor
payment methods have been selected specifically for that distributor, even if
distributor payment methods have been selected specifically for a different distributor
on the order cycle" do
distributor_payment_method = create(
:payment_method,
distributors: [distributor]
).distributor_payment_methods.first
other_distributor_payment_method_i = create(
:payment_method,
distributors: [other_distributor]
).distributor_payment_methods.first
other_distributor_payment_method_ii = create(
:payment_method,
distributors: [other_distributor]
).distributor_payment_methods.first
oc.selected_distributor_payment_methods << other_distributor_payment_method_i
expect(oc.distributor_payment_methods).to eq [
distributor_payment_method,
other_distributor_payment_method_i
]
end
end
end
end
describe "#distributor_shipping_methods" do
let(:distributor) { create(:distributor_enterprise) }

View File

@@ -5,100 +5,166 @@ require 'spec_helper'
class Spree::Gateway::Test < Spree::Gateway
end
module Spree
describe PaymentMethod do
describe "#available" do
let(:enterprise) { create(:enterprise) }
describe Spree::PaymentMethod do
describe "#available" do
let(:enterprise) { create(:enterprise) }
before do
Spree::PaymentMethod.delete_all
[nil, 'both', 'back_end'].each do |display_on|
Spree::Gateway::Test.create(
name: 'Display Both',
display_on: display_on,
active: true,
environment: 'test',
description: 'foofah',
distributors: [enterprise]
)
end
expect(Spree::PaymentMethod.all.size).to eq 3
end
it "should return all methods available to front-end/back-end when no parameter is passed" do
expect(Spree::PaymentMethod.available.size).to eq 2
end
it "should return all methods available to front-end/back-end when display_on = :both" do
expect(Spree::PaymentMethod.available(:both).size).to eq 2
end
it "should return all methods available to back-end when display_on = :back_end" do
expect(Spree::PaymentMethod.available(:back_end).size).to eq 2
end
end
describe "#configured?" do
context "non-Stripe payment method" do
let(:payment_method) { build(:payment_method) }
it "returns true" do
expect(payment_method).to be_configured
end
end
context "Stripe payment method" do
let(:payment_method) { create(:stripe_sca_payment_method) }
around do |example|
original_stripe_connect_enabled = Spree::Config[:stripe_connect_enabled]
example.run
Spree::Config.set(stripe_connect_enabled: original_stripe_connect_enabled)
end
before do
Spree::PaymentMethod.delete_all
Spree::Config.set(stripe_connect_enabled: true)
Stripe.publishable_key = "some_key"
end
[nil, 'both', 'back_end'].each do |display_on|
Spree::Gateway::Test.create(
name: 'Display Both',
display_on: display_on,
active: true,
environment: 'test',
description: 'foofah',
distributors: [enterprise]
)
context "and Stripe Connect is enabled and a Stripe publishable key, account id, account
owner are all present" do
it "returns true" do
expect(payment_method).to be_configured
end
expect(Spree::PaymentMethod.all.size).to eq 3
end
it "should return all methods available to front-end/back-end when no parameter is passed" do
expect(Spree::PaymentMethod.available.size).to eq 2
context "and Stripe Connect is disabled" do
before { Spree::Config.set(stripe_connect_enabled: false) }
it "returns false" do
expect(payment_method).not_to be_configured
end
end
it "should return all methods available to front-end/back-end when display_on = :both" do
expect(Spree::PaymentMethod.available(:both).size).to eq 2
context "and a Stripe publishable key is not present" do
before { Spree::Config.set(stripe_connect_enabled: false) }
it "returns false" do
expect(payment_method).not_to be_configured
end
end
it "should return all methods available to back-end when display_on = :back_end" do
expect(Spree::PaymentMethod.available(:back_end).size).to eq 2
context "and a Stripe account owner is not present" do
before { payment_method.preferred_enterprise_id = nil }
it "returns false" do
expect(payment_method).not_to be_configured
end
end
end
it "orders payment methods by name" do
pm1 = create(:payment_method, name: 'ZZ')
pm2 = create(:payment_method, name: 'AA')
pm3 = create(:payment_method, name: 'BB')
context "and a Stripe account ID is not present" do
before do
StripeAccount.find_by(
enterprise_id: payment_method.preferred_enterprise_id
).update_column(:stripe_user_id, nil)
end
expect(PaymentMethod.by_name).to eq([pm2, pm3, pm1])
end
it "raises errors when required fields are missing" do
pm = PaymentMethod.new
pm.save
expect(pm.errors.to_a).to eq(["Name can't be blank", "At least one hub must be selected"])
end
it "generates a clean name for known Payment Method types" do
expect(Spree::PaymentMethod::Check.clean_name).to eq(I18n.t("spree.admin.payment_methods.providers.check"))
expect(Spree::Gateway::PayPalExpress.clean_name).to eq(I18n.t("spree.admin.payment_methods.providers.paypalexpress"))
expect(Spree::Gateway::StripeSCA.clean_name).to eq(I18n.t("spree.admin.payment_methods.providers.stripesca"))
expect(Spree::Gateway::BogusSimple.clean_name).to eq(I18n.t("spree.admin.payment_methods.providers.bogussimple"))
expect(Spree::Gateway::Bogus.clean_name).to eq(I18n.t("spree.admin.payment_methods.providers.bogus"))
end
it "computes the amount of fees" do
order = create(:order)
free_payment_method = create(:payment_method) # flat rate calculator with preferred_amount of 0
expect(free_payment_method.compute_amount(order)).to eq 0
flat_rate_payment_method = create(:payment_method,
calculator: ::Calculator::FlatRate.new(preferred_amount: 10))
expect(flat_rate_payment_method.compute_amount(order)).to eq 10
flat_percent_payment_method = create(:payment_method,
calculator: ::Calculator::FlatPercentItemTotal.new(preferred_flat_percent: 10))
expect(flat_percent_payment_method.compute_amount(order)).to eq 0
product = create(:product)
order.contents.add(product.variants.first)
expect(flat_percent_payment_method.compute_amount(order)).to eq 2.0
end
describe "scope" do
describe "filtering to specified distributors" do
let!(:distributor_a) { create(:distributor_enterprise) }
let!(:distributor_b) { create(:distributor_enterprise) }
let!(:distributor_c) { create(:distributor_enterprise) }
let!(:payment_method_a) {
create(:payment_method, distributors: [distributor_a, distributor_b])
}
let!(:payment_method_b) { create(:payment_method, distributors: [distributor_b]) }
let!(:payment_method_c) { create(:payment_method, distributors: [distributor_c]) }
it "includes only unique records under specified distributors" do
result = described_class.for_distributors([distributor_a, distributor_b])
expect(result.length).to eq(2)
expect(result).to include(payment_method_a)
expect(result).to include(payment_method_b)
it "returns false" do
expect(payment_method).not_to be_configured
end
end
end
end
it "orders payment methods by name" do
pm1 = create(:payment_method, name: 'ZZ')
pm2 = create(:payment_method, name: 'AA')
pm3 = create(:payment_method, name: 'BB')
expect(Spree::PaymentMethod.by_name).to eq([pm2, pm3, pm1])
end
it "raises errors when required fields are missing" do
pm = Spree::PaymentMethod.new
pm.save
expect(pm.errors.to_a).to eq(["Name can't be blank", "At least one hub must be selected"])
end
it "generates a clean name for known Payment Method types" do
expect(Spree::PaymentMethod::Check.clean_name).to eq(I18n.t("spree.admin.payment_methods.providers.check"))
expect(Spree::Gateway::PayPalExpress.clean_name).to eq(I18n.t("spree.admin.payment_methods.providers.paypalexpress"))
expect(Spree::Gateway::StripeSCA.clean_name).to eq(I18n.t("spree.admin.payment_methods.providers.stripesca"))
expect(Spree::Gateway::BogusSimple.clean_name).to eq(I18n.t("spree.admin.payment_methods.providers.bogussimple"))
expect(Spree::Gateway::Bogus.clean_name).to eq(I18n.t("spree.admin.payment_methods.providers.bogus"))
end
it "computes the amount of fees" do
order = create(:order)
free_payment_method = create(:payment_method) # flat rate calculator with preferred_amount of 0
expect(free_payment_method.compute_amount(order)).to eq 0
flat_rate_payment_method = create(:payment_method,
calculator: ::Calculator::FlatRate.new(preferred_amount: 10))
expect(flat_rate_payment_method.compute_amount(order)).to eq 10
flat_percent_payment_method = create(:payment_method,
calculator: ::Calculator::FlatPercentItemTotal.new(preferred_flat_percent: 10))
expect(flat_percent_payment_method.compute_amount(order)).to eq 0
product = create(:product)
order.contents.add(product.variants.first)
expect(flat_percent_payment_method.compute_amount(order)).to eq 2.0
end
describe "scope" do
describe "filtering to specified distributors" do
let!(:distributor_a) { create(:distributor_enterprise) }
let!(:distributor_b) { create(:distributor_enterprise) }
let!(:distributor_c) { create(:distributor_enterprise) }
let!(:payment_method_a) {
create(:payment_method, distributors: [distributor_a, distributor_b])
}
let!(:payment_method_b) { create(:payment_method, distributors: [distributor_b]) }
let!(:payment_method_c) { create(:payment_method, distributors: [distributor_c]) }
it "includes only unique records under specified distributors" do
result = described_class.for_distributors([distributor_a, distributor_b])
expect(result.length).to eq(2)
expect(result).to include(payment_method_a)
expect(result).to include(payment_method_b)
end
end
end
end