mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Merge pull request #6124 from luisramos0/stripe_specs
Add more checkout feature specs covering stripe SCA cases
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Spree::Admin::PaymentsController, type: :controller do
|
||||
include StripeHelper
|
||||
|
||||
let!(:shop) { create(:enterprise) }
|
||||
let!(:user) { shop.owner }
|
||||
let!(:order) { create(:order, distributor: shop, state: 'complete') }
|
||||
@@ -152,19 +154,13 @@ describe Spree::Admin::PaymentsController, type: :controller do
|
||||
allow(Stripe).to receive(:api_key) { "sk_test_12345" }
|
||||
allow(StripeAccount).to receive(:find_by) { stripe_account }
|
||||
|
||||
# Retrieves payment intent info
|
||||
stub_request(:get, "https://api.stripe.com/v1/payment_intents/pi_123")
|
||||
.with(headers: { 'Stripe-Account' => 'abc123' })
|
||||
.to_return({ status: 200, body: JSON.generate(
|
||||
amount_received: 2000,
|
||||
charges: { data: [{ id: "ch_1a2b3c" }] }
|
||||
) })
|
||||
stub_payment_intent_get_request
|
||||
end
|
||||
|
||||
context "where the request succeeds" do
|
||||
before do
|
||||
# Issues the refund
|
||||
stub_request(:post, "https://api.stripe.com/v1/charges/ch_1a2b3c/refunds").
|
||||
stub_request(:post, "https://api.stripe.com/v1/charges/ch_1234/refunds").
|
||||
with(basic_auth: ["sk_test_12345", ""]).
|
||||
to_return(status: 200,
|
||||
body: JSON.generate(id: 're_123', object: 'refund', status: 'succeeded') )
|
||||
@@ -184,7 +180,7 @@ describe Spree::Admin::PaymentsController, type: :controller do
|
||||
|
||||
context "where the request fails" do
|
||||
before do
|
||||
stub_request(:post, "https://api.stripe.com/v1/charges/ch_1a2b3c/refunds").
|
||||
stub_request(:post, "https://api.stripe.com/v1/charges/ch_1234/refunds").
|
||||
with(basic_auth: ["sk_test_12345", ""]).
|
||||
to_return(status: 200, body: JSON.generate(error: { message: "Bup-bow!" }) )
|
||||
end
|
||||
@@ -220,17 +216,12 @@ describe Spree::Admin::PaymentsController, type: :controller do
|
||||
before do
|
||||
allow(Stripe).to receive(:api_key) { "sk_test_12345" }
|
||||
|
||||
# Retrieves payment intent info
|
||||
stub_request(:get, "https://api.stripe.com/v1/payment_intents/pi_123")
|
||||
.to_return({ status: 200, body: JSON.generate(
|
||||
amount_received: 2000,
|
||||
charges: { data: [{ id: "ch_1a2b3c" }] }
|
||||
) })
|
||||
stub_payment_intent_get_request stripe_account_header: false
|
||||
end
|
||||
|
||||
context "where the request succeeds" do
|
||||
before do
|
||||
stub_request(:post, "https://api.stripe.com/v1/charges/ch_1a2b3c/refunds").
|
||||
stub_request(:post, "https://api.stripe.com/v1/charges/ch_1234/refunds").
|
||||
with(basic_auth: ["sk_test_12345", ""]).
|
||||
to_return(status: 200,
|
||||
body: JSON.generate(id: 're_123', object: 'refund', status: 'succeeded') )
|
||||
@@ -250,7 +241,7 @@ describe Spree::Admin::PaymentsController, type: :controller do
|
||||
|
||||
context "where the request fails" do
|
||||
before do
|
||||
stub_request(:post, "https://api.stripe.com/v1/charges/ch_1a2b3c/refunds").
|
||||
stub_request(:post, "https://api.stripe.com/v1/charges/ch_1234/refunds").
|
||||
with(basic_auth: ["sk_test_12345", ""]).
|
||||
to_return(status: 200, body: JSON.generate(error: { message: "Bup-bow!" }) )
|
||||
end
|
||||
|
||||
@@ -90,31 +90,21 @@ feature "Check out with Stripe", js: true do
|
||||
let!(:shipping_method) { create(:shipping_method) }
|
||||
|
||||
context "with guest checkout" do
|
||||
before do
|
||||
stub_payment_intent_get_request
|
||||
stub_hub_payment_methods_request
|
||||
end
|
||||
|
||||
context "when the card is accepted" do
|
||||
before do
|
||||
stub_payment_intents_post_request order: order
|
||||
stub_payment_intent_get_request
|
||||
stub_hub_payment_methods_request
|
||||
stub_successful_capture_request order: order
|
||||
end
|
||||
|
||||
it "completes checkout successfully" do
|
||||
visit checkout_path
|
||||
|
||||
checkout_as_guest
|
||||
|
||||
fill_out_form(
|
||||
free_shipping.name,
|
||||
stripe_sca_payment_method.name,
|
||||
save_default_addresses: false
|
||||
)
|
||||
|
||||
fill_out_card_details
|
||||
|
||||
place_order
|
||||
checkout_with_stripe
|
||||
|
||||
expect(page).to have_content "Confirmed"
|
||||
|
||||
expect(order.reload.completed?).to eq true
|
||||
expect(order.payments.first.state).to eq "completed"
|
||||
end
|
||||
@@ -125,32 +115,72 @@ feature "Check out with Stripe", js: true do
|
||||
|
||||
before do
|
||||
stub_payment_intents_post_request order: order
|
||||
stub_payment_intent_get_request
|
||||
stub_hub_payment_methods_request
|
||||
stub_failed_capture_request order: order, response: { message: error_message }
|
||||
end
|
||||
|
||||
it "shows an error message from the Stripe response" do
|
||||
visit checkout_path
|
||||
|
||||
checkout_as_guest
|
||||
|
||||
fill_out_form(
|
||||
free_shipping.name,
|
||||
stripe_sca_payment_method.name,
|
||||
save_default_addresses: false
|
||||
)
|
||||
|
||||
fill_out_card_details
|
||||
|
||||
place_order
|
||||
checkout_with_stripe
|
||||
|
||||
expect(page).to have_content error_message
|
||||
|
||||
expect(order.reload.state).to eq "cart"
|
||||
expect(order.payments.first.state).to eq "failed"
|
||||
end
|
||||
end
|
||||
|
||||
context "when the card needs extra SCA authorization", js: true do
|
||||
let(:stripe_redirect_url) { checkout_path(payment_intent: "pi_123") }
|
||||
let(:payment_intent_authorize_response) do
|
||||
{ status: 200, body: JSON.generate(id: "pi_123",
|
||||
object: "payment_intent",
|
||||
next_source_action: {
|
||||
type: "authorize_with_url",
|
||||
authorize_with_url: { url: stripe_redirect_url }
|
||||
},
|
||||
status: "requires_source_action") }
|
||||
end
|
||||
|
||||
before do
|
||||
stub_request(:post, "https://api.stripe.com/v1/payment_intents")
|
||||
.with(basic_auth: ["sk_test_12345", ""], body: /.*#{order.number}/)
|
||||
.to_return(payment_intent_authorize_response)
|
||||
end
|
||||
|
||||
describe "and the authorization succeeds" do
|
||||
before do
|
||||
stub_successful_capture_request order: order
|
||||
end
|
||||
|
||||
it "completes checkout successfully" do
|
||||
checkout_with_stripe
|
||||
|
||||
# We make stripe return stripe_redirect_url (which is already sending the user back to the checkout) as if the authorization was done
|
||||
# We can then control the actual authorization or failure of the payment through the mock stub_successful_capture_request
|
||||
|
||||
expect(page).to have_content "Confirmed"
|
||||
expect(order.reload.completed?).to eq true
|
||||
expect(order.payments.first.state).to eq "completed"
|
||||
end
|
||||
end
|
||||
|
||||
describe "and the authorization fails" do
|
||||
let(:error_message) { "Card was declined: insufficient funds." }
|
||||
|
||||
before do
|
||||
stub_failed_capture_request order: order, response: { message: error_message }
|
||||
end
|
||||
|
||||
it "shows an error message from the Stripe response" do
|
||||
checkout_with_stripe
|
||||
|
||||
# We make stripe return stripe_redirect_url (which is already sending the user back to the checkout) as if the authorization was done
|
||||
# We can then control the actual authorization or failure of the payment through the mock stub_failed_capture_request
|
||||
|
||||
expect(page).to have_content error_message
|
||||
expect(order.reload.state).to eq "cart"
|
||||
expect(order.payments.first.state).to eq "failed"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module StripeHelper
|
||||
def checkout_with_stripe
|
||||
visit checkout_path
|
||||
checkout_as_guest
|
||||
|
||||
fill_out_form(
|
||||
free_shipping.name,
|
||||
stripe_sca_payment_method.name,
|
||||
save_default_addresses: false
|
||||
)
|
||||
fill_out_card_details
|
||||
place_order
|
||||
end
|
||||
|
||||
def fill_out_card_details
|
||||
expect(page).to have_css("input[name='cardnumber']")
|
||||
fill_in 'Card number', with: '4242424242424242'
|
||||
@@ -20,10 +33,10 @@ module StripeHelper
|
||||
.to_return(payment_intent_authorize_response_mock(response))
|
||||
end
|
||||
|
||||
def stub_payment_intent_get_request(response: {})
|
||||
stub_request(:get, "https://api.stripe.com/v1/payment_intents/pi_123")
|
||||
.with(headers: { 'Stripe-Account' => 'abc123' })
|
||||
.to_return(payment_intent_authorize_response_mock(response))
|
||||
def stub_payment_intent_get_request(response: {}, stripe_account_header: true)
|
||||
stub = stub_request(:get, "https://api.stripe.com/v1/payment_intents/pi_123")
|
||||
stub = stub.with(headers: { 'Stripe-Account' => 'abc123' }) if stripe_account_header
|
||||
stub.to_return(payment_intent_authorize_response_mock(response))
|
||||
end
|
||||
|
||||
def stub_hub_payment_methods_request(response: {})
|
||||
@@ -55,6 +68,7 @@ module StripeHelper
|
||||
body: JSON.generate(id: "pi_123",
|
||||
object: "payment_intent",
|
||||
amount: 2000,
|
||||
amount_received: 2000,
|
||||
status: options[:intent_status] || "requires_capture",
|
||||
last_payment_error: nil,
|
||||
charges: { data: [{ id: "ch_1234", amount: 2000 }] }) }
|
||||
|
||||
Reference in New Issue
Block a user