Merge pull request #6124 from luisramos0/stripe_specs

Add more checkout feature specs covering stripe SCA cases
This commit is contained in:
Matt-Yorkley
2020-10-03 18:24:06 +02:00
committed by GitHub
3 changed files with 88 additions and 53 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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 }] }) }