From 7efc52075e52e7eba4e332c748873715465cc5bf Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 8 Oct 2020 17:36:47 +0100 Subject: [PATCH] First attempt at adding a spec to checkout and save a credit card --- .../consumer/shopping/checkout_stripe_spec.rb | 65 +++++++++++++++++-- spec/support/request/stripe_helper.rb | 15 +++-- 2 files changed, 70 insertions(+), 10 deletions(-) diff --git a/spec/features/consumer/shopping/checkout_stripe_spec.rb b/spec/features/consumer/shopping/checkout_stripe_spec.rb index 6c99489013..934d1b8f5c 100644 --- a/spec/features/consumer/shopping/checkout_stripe_spec.rb +++ b/spec/features/consumer/shopping/checkout_stripe_spec.rb @@ -90,12 +90,12 @@ feature "Check out with Stripe", js: true do let!(:shipping_method) { create(:shipping_method) } let(:error_message) { "Card was declined: insufficient funds." } - context "with guest checkout" do - before do - stub_payment_intent_get_request - stub_payment_methods_post_request - end + before do + stub_payment_intent_get_request + stub_payment_methods_post_request + end + context "with guest checkout" do context "when the card is accepted" do before do stub_payment_intents_post_request order: order @@ -126,7 +126,7 @@ feature "Check out with Stripe", js: true do end end - context "when the card needs extra SCA authorization", js: true do + context "when the card needs extra SCA authorization" do before do stripe_redirect_url = checkout_path(payment_intent: "pi_123") stub_payment_intents_post_request_with_redirect order: order, @@ -194,5 +194,58 @@ feature "Check out with Stripe", js: true do end end end + + context "with a logged in user" do + let(:user) { order.user } + + before do + login_as user + end + + context "saving a card and re-using it" do + let(:customers_response_mock) do + { status: 200, + body: JSON.generate(id: "cus_A123", + sources: { data: [id: "cus_A123"] }) } + end + + let(:hubs_payment_method_response_mock) do + { + status: 200, + body: JSON.generate(id: "pm_123", customer: "cus_A123") + } + end + + before do + stub_payment_methods_post_request_with_customer response: { pm_id: "pm_123" } + stub_payment_intents_post_request order: order + stub_successful_capture_request order: order + + # Creates a customer + # This stubs the customers call to both the main stripe account and the connected account + stub_request(:post, "https://api.stripe.com/v1/customers") + .with(body: { email: user.email }) + .to_return(customers_response_mock) + + # Attaches the payment method to the customer in the hub's stripe account + stub_request(:post, + "https://api.stripe.com/v1/payment_methods/pm_123/attach") + .with(body: { customer: "cus_A123" }) + .to_return(hubs_payment_method_response_mock) + end + + it "allows saving a card and re-using it" do + checkout_with_stripe guest_checkout: false, remember_card: true + + expect(page).to have_content "Confirmed" + expect(order.reload.completed?).to eq true + expect(order.payments.first.state).to eq "completed" + + user_credit_card = order.reload.user.credit_cards.first + expect(user_credit_card.gateway_payment_profile_id).to eq "pm_123" + expect(user_credit_card.gateway_customer_profile_id).to eq "cus_A123" + end + end + end end end diff --git a/spec/support/request/stripe_helper.rb b/spec/support/request/stripe_helper.rb index ef71652b1a..cd64426e96 100644 --- a/spec/support/request/stripe_helper.rb +++ b/spec/support/request/stripe_helper.rb @@ -1,16 +1,16 @@ # frozen_string_literal: true module StripeHelper - def checkout_with_stripe + def checkout_with_stripe(guest_checkout: true, remember_card: false) visit checkout_path - checkout_as_guest - + checkout_as_guest if guest_checkout fill_out_form( free_shipping.name, stripe_sca_payment_method.name, save_default_addresses: false ) fill_out_card_details + check "Remember this card?" if remember_card place_order end @@ -61,6 +61,13 @@ module StripeHelper .to_return(hub_payment_method_response_mock(response)) end + def stub_payment_methods_post_request_with_customer(response: {}) + stub_request(:post, "https://api.stripe.com/v1/payment_methods") + .with(body: { payment_method: "pm_123", customer: "cus_A123" }, + headers: { 'Stripe-Account' => 'abc123' }) + .to_return(hub_payment_method_response_mock(response)) + end + def stub_successful_capture_request(order:, response: {}) stub_capture_request(order, payment_successful_capture_mock(response)) end @@ -121,7 +128,7 @@ module StripeHelper def hub_payment_method_response_mock(options) { status: options[:code] || 200, - body: JSON.generate(id: "pm_456", customer: "cus_A123") } + body: JSON.generate(id: options[:pm_id] || "pm_456", customer: "cus_A123") } end def payment_successful_refund_mock