From 7efc52075e52e7eba4e332c748873715465cc5bf Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Thu, 8 Oct 2020 17:36:47 +0100 Subject: [PATCH 1/7] 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 From 7e80ddf1e50413756c448eb026bc2c66306393f6 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 16 Oct 2020 10:24:49 +0100 Subject: [PATCH 2/7] Add step to checkout with the previously saved card --- .../consumer/shopping/checkout_stripe_spec.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/spec/features/consumer/shopping/checkout_stripe_spec.rb b/spec/features/consumer/shopping/checkout_stripe_spec.rb index 934d1b8f5c..c8f69e52f0 100644 --- a/spec/features/consumer/shopping/checkout_stripe_spec.rb +++ b/spec/features/consumer/shopping/checkout_stripe_spec.rb @@ -241,9 +241,23 @@ feature "Check out with Stripe", js: true do expect(order.reload.completed?).to eq true expect(order.payments.first.state).to eq "completed" + # Verify card has been saved with correct stripe IDs 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" + + # Prepare a second order + new_order = create(:order, user: user, order_cycle: order_cycle, distributor: distributor, bill_address_id: nil, ship_address_id: nil) + set_order(new_order) + add_product_to_cart(new_order, product, quantity: 10) + + # Checkout with saved card + visit checkout_path + choose free_shipping.name + choose stripe_sca_payment_method.name + expect(page).to have_content "Use a saved card" + expect(page).to have_select 'selected_card', selected: "Visa x-4242 Exp:10/2050" + place_order end end end From f13ebf8f214abf642de910c3125f08d801c839ee Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 16 Oct 2020 11:00:26 +0100 Subject: [PATCH 3/7] DRY StripeHelper --- .../consumer/shopping/checkout_stripe_spec.rb | 2 +- spec/support/request/stripe_helper.rb | 11 ++--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/spec/features/consumer/shopping/checkout_stripe_spec.rb b/spec/features/consumer/shopping/checkout_stripe_spec.rb index c8f69e52f0..6203d3163d 100644 --- a/spec/features/consumer/shopping/checkout_stripe_spec.rb +++ b/spec/features/consumer/shopping/checkout_stripe_spec.rb @@ -217,7 +217,7 @@ feature "Check out with Stripe", js: true do end before do - stub_payment_methods_post_request_with_customer response: { pm_id: "pm_123" } + stub_payment_methods_post_request request: { payment_method: "pm_123", customer: "cus_A123" }, response: { pm_id: "pm_123" } stub_payment_intents_post_request order: order stub_successful_capture_request order: order diff --git a/spec/support/request/stripe_helper.rb b/spec/support/request/stripe_helper.rb index cd64426e96..cd82b40b22 100644 --- a/spec/support/request/stripe_helper.rb +++ b/spec/support/request/stripe_helper.rb @@ -54,16 +54,9 @@ module StripeHelper stub.to_return(payment_intent_authorize_response_mock(response)) end - def stub_payment_methods_post_request(response: {}) + def stub_payment_methods_post_request(request: { payment_method: "pm_123" }, response: {}) stub_request(:post, "https://api.stripe.com/v1/payment_methods") - .with(body: { payment_method: "pm_123" }, - headers: { 'Stripe-Account' => 'abc123' }) - .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" }, + .with(body: request, headers: { 'Stripe-Account' => 'abc123' }) .to_return(hub_payment_method_response_mock(response)) end From 487aaf486211b1b413232dcd798436518a0c9128 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 16 Oct 2020 11:12:44 +0100 Subject: [PATCH 4/7] Extract stub to StripeHelper --- .../consumer/shopping/checkout_stripe_spec.rb | 13 +------------ spec/support/request/stripe_helper.rb | 8 ++++++++ 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/spec/features/consumer/shopping/checkout_stripe_spec.rb b/spec/features/consumer/shopping/checkout_stripe_spec.rb index 6203d3163d..528a8d9e81 100644 --- a/spec/features/consumer/shopping/checkout_stripe_spec.rb +++ b/spec/features/consumer/shopping/checkout_stripe_spec.rb @@ -209,13 +209,6 @@ feature "Check out with Stripe", js: true do 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 request: { payment_method: "pm_123", customer: "cus_A123" }, response: { pm_id: "pm_123" } stub_payment_intents_post_request order: order @@ -227,11 +220,7 @@ feature "Check out with Stripe", js: true do .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) + stub_payment_method_attach_request end it "allows saving a card and re-using it" do diff --git a/spec/support/request/stripe_helper.rb b/spec/support/request/stripe_helper.rb index cd82b40b22..a3e9475e80 100644 --- a/spec/support/request/stripe_helper.rb +++ b/spec/support/request/stripe_helper.rb @@ -61,6 +61,14 @@ module StripeHelper .to_return(hub_payment_method_response_mock(response)) end + # Attaches the payment method to the customer in the hub's stripe account + def stub_payment_method_attach_request + stub_request(:post, + "https://api.stripe.com/v1/payment_methods/pm_123/attach") + .with(body: { customer: "cus_A123" }) + .to_return(hub_payment_method_response_mock({ pm_id: "pm_123" })) + end + def stub_successful_capture_request(order:, response: {}) stub_capture_request(order, payment_successful_capture_mock(response)) end From f5f9a733fb6ab31f305ea366c9da69772d2481c8 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 16 Oct 2020 11:16:49 +0100 Subject: [PATCH 5/7] Fix rubocop issue, long module, by extracting StripeStubs to a separate helper module --- .rubocop_manual_todo.yml | 1 - .../payments_controller_refunds_spec.rb | 1 + spec/features/admin/payments_stripe_spec.rb | 1 + .../consumer/shopping/checkout_stripe_spec.rb | 1 + spec/support/request/stripe_helper.rb | 104 ----------------- spec/support/request/stripe_stubs.rb | 107 ++++++++++++++++++ 6 files changed, 110 insertions(+), 105 deletions(-) create mode 100644 spec/support/request/stripe_stubs.rb diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index 5c55f6ef9e..3e32bf9faf 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -848,7 +848,6 @@ Metrics/ModuleLength: - spec/models/spree/variant_spec.rb - spec/services/permissions/order_spec.rb - spec/services/variant_units/option_value_namer_spec.rb - - spec/support/request/stripe_helper.rb Metrics/ParameterLists: Max: 5 diff --git a/spec/controllers/spree/admin/orders/payments/payments_controller_refunds_spec.rb b/spec/controllers/spree/admin/orders/payments/payments_controller_refunds_spec.rb index 1b97a6fcd2..24decb1b9b 100644 --- a/spec/controllers/spree/admin/orders/payments/payments_controller_refunds_spec.rb +++ b/spec/controllers/spree/admin/orders/payments/payments_controller_refunds_spec.rb @@ -5,6 +5,7 @@ require 'spree/core/gateway_error' describe Spree::Admin::PaymentsController, type: :controller do include StripeHelper + include StripeStubs let!(:shop) { create(:enterprise) } let!(:user) { shop.owner } diff --git a/spec/features/admin/payments_stripe_spec.rb b/spec/features/admin/payments_stripe_spec.rb index b296d0fc32..1a3d6047bf 100644 --- a/spec/features/admin/payments_stripe_spec.rb +++ b/spec/features/admin/payments_stripe_spec.rb @@ -8,6 +8,7 @@ feature ' ' do include AuthenticationHelper include StripeHelper + include StripeStubs let!(:order) { create(:completed_order_with_fees) } let!(:stripe_payment_method) do diff --git a/spec/features/consumer/shopping/checkout_stripe_spec.rb b/spec/features/consumer/shopping/checkout_stripe_spec.rb index 528a8d9e81..cf7800225e 100644 --- a/spec/features/consumer/shopping/checkout_stripe_spec.rb +++ b/spec/features/consumer/shopping/checkout_stripe_spec.rb @@ -7,6 +7,7 @@ feature "Check out with Stripe", js: true do include ShopWorkflow include CheckoutHelper include StripeHelper + include StripeStubs let(:distributor) { create(:distributor_enterprise) } let!(:order_cycle) { create(:simple_order_cycle, distributors: [distributor], variants: [variant]) } diff --git a/spec/support/request/stripe_helper.rb b/spec/support/request/stripe_helper.rb index a3e9475e80..ef552a0586 100644 --- a/spec/support/request/stripe_helper.rb +++ b/spec/support/request/stripe_helper.rb @@ -34,108 +34,4 @@ module StripeHelper allow(Stripe).to receive(:publishable_key) { "pk_test_12345" } Spree::Config.set(stripe_connect_enabled: true) end - - def stub_payment_intents_post_request(order:, response: {}, stripe_account_header: true) - stub = stub_request(:post, "https://api.stripe.com/v1/payment_intents") - .with(basic_auth: ["sk_test_12345", ""], body: /.*#{order.number}/) - stub = stub.with(headers: { 'Stripe-Account' => 'abc123' }) if stripe_account_header - stub.to_return(payment_intent_authorize_response_mock(response)) - end - - def stub_payment_intents_post_request_with_redirect(order:, redirect_url:) - stub_request(:post, "https://api.stripe.com/v1/payment_intents") - .with(basic_auth: ["sk_test_12345", ""], body: /.*#{order.number}/) - .to_return(payment_intent_redirect_response_mock(redirect_url)) - end - - 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_payment_methods_post_request(request: { payment_method: "pm_123" }, response: {}) - stub_request(:post, "https://api.stripe.com/v1/payment_methods") - .with(body: request, - headers: { 'Stripe-Account' => 'abc123' }) - .to_return(hub_payment_method_response_mock(response)) - end - - # Attaches the payment method to the customer in the hub's stripe account - def stub_payment_method_attach_request - stub_request(:post, - "https://api.stripe.com/v1/payment_methods/pm_123/attach") - .with(body: { customer: "cus_A123" }) - .to_return(hub_payment_method_response_mock({ pm_id: "pm_123" })) - end - - def stub_successful_capture_request(order:, response: {}) - stub_capture_request(order, payment_successful_capture_mock(response)) - end - - def stub_failed_capture_request(order:, response: {}) - stub_capture_request(order, payment_failed_capture_mock(response)) - end - - def stub_capture_request(order, response_mock) - stub_request(:post, "https://api.stripe.com/v1/payment_intents/pi_123/capture") - .with(body: { amount_to_capture: Spree::Money.new(order.total).cents }, - headers: { 'Stripe-Account' => 'abc123' }) - .to_return(response_mock) - end - - def stub_refund_request - stub_request(:post, "https://api.stripe.com/v1/charges/ch_1234/refunds") - .with(body: { amount: 2000, expand: ["charge"] }, - headers: { 'Stripe-Account' => 'abc123' }) - .to_return(payment_successful_refund_mock) - end - - private - - def payment_intent_authorize_response_mock(options) - { status: options[:code] || 200, - 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 }] }) } - end - - def payment_intent_redirect_response_mock(redirect_url) - { status: 200, body: JSON.generate(id: "pi_123", - object: "payment_intent", - next_source_action: { - type: "authorize_with_url", - authorize_with_url: { url: redirect_url } - }, - status: "requires_source_action") } - end - - def payment_successful_capture_mock(options) - { status: options[:code] || 200, - body: JSON.generate(object: "payment_intent", - amount: 2000, - charges: { data: [{ id: "ch_1234", amount: 2000 }] }) } - end - - def payment_failed_capture_mock(options) - { status: options[:code] || 402, - body: JSON.generate(error: { message: - options[:message] || "payment-method-failure" }) } - end - - def hub_payment_method_response_mock(options) - { status: options[:code] || 200, - body: JSON.generate(id: options[:pm_id] || "pm_456", customer: "cus_A123") } - end - - def payment_successful_refund_mock - { status: 200, - body: JSON.generate(object: "refund", - amount: 2000, - charge: "ch_1234") } - end end diff --git a/spec/support/request/stripe_stubs.rb b/spec/support/request/stripe_stubs.rb new file mode 100644 index 0000000000..af441577cd --- /dev/null +++ b/spec/support/request/stripe_stubs.rb @@ -0,0 +1,107 @@ +# frozen_string_literal: true + +module StripeStubs + def stub_payment_intents_post_request(order:, response: {}, stripe_account_header: true) + stub = stub_request(:post, "https://api.stripe.com/v1/payment_intents") + .with(basic_auth: ["sk_test_12345", ""], body: /.*#{order.number}/) + stub = stub.with(headers: { 'Stripe-Account' => 'abc123' }) if stripe_account_header + stub.to_return(payment_intent_authorize_response_mock(response)) + end + + def stub_payment_intents_post_request_with_redirect(order:, redirect_url:) + stub_request(:post, "https://api.stripe.com/v1/payment_intents") + .with(basic_auth: ["sk_test_12345", ""], body: /.*#{order.number}/) + .to_return(payment_intent_redirect_response_mock(redirect_url)) + end + + 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_payment_methods_post_request(request: { payment_method: "pm_123" }, response: {}) + stub_request(:post, "https://api.stripe.com/v1/payment_methods") + .with(body: request, + headers: { 'Stripe-Account' => 'abc123' }) + .to_return(hub_payment_method_response_mock(response)) + end + + # Attaches the payment method to the customer in the hub's stripe account + def stub_payment_method_attach_request + stub_request(:post, + "https://api.stripe.com/v1/payment_methods/pm_123/attach") + .with(body: { customer: "cus_A123" }) + .to_return(hub_payment_method_response_mock({ pm_id: "pm_123" })) + end + + def stub_successful_capture_request(order:, response: {}) + stub_capture_request(order, payment_successful_capture_mock(response)) + end + + def stub_failed_capture_request(order:, response: {}) + stub_capture_request(order, payment_failed_capture_mock(response)) + end + + def stub_capture_request(order, response_mock) + stub_request(:post, "https://api.stripe.com/v1/payment_intents/pi_123/capture") + .with(body: { amount_to_capture: Spree::Money.new(order.total).cents }, + headers: { 'Stripe-Account' => 'abc123' }) + .to_return(response_mock) + end + + def stub_refund_request + stub_request(:post, "https://api.stripe.com/v1/charges/ch_1234/refunds") + .with(body: { amount: 2000, expand: ["charge"] }, + headers: { 'Stripe-Account' => 'abc123' }) + .to_return(payment_successful_refund_mock) + end + + private + + def payment_intent_authorize_response_mock(options) + { status: options[:code] || 200, + 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 }] }) } + end + + def payment_intent_redirect_response_mock(redirect_url) + { status: 200, body: JSON.generate(id: "pi_123", + object: "payment_intent", + next_source_action: { + type: "authorize_with_url", + authorize_with_url: { url: redirect_url } + }, + status: "requires_source_action") } + end + + def payment_successful_capture_mock(options) + { status: options[:code] || 200, + body: JSON.generate(object: "payment_intent", + amount: 2000, + charges: { data: [{ id: "ch_1234", amount: 2000 }] }) } + end + + def payment_failed_capture_mock(options) + { status: options[:code] || 402, + body: JSON.generate(error: { message: + options[:message] || "payment-method-failure" }) } + end + + def hub_payment_method_response_mock(options) + { status: options[:code] || 200, + body: JSON.generate(id: options[:pm_id] || "pm_456", customer: "cus_A123") } + end + + def payment_successful_refund_mock + { status: 200, + body: JSON.generate(object: "refund", + amount: 2000, + charge: "ch_1234") } + end +end From cf319d3f057be6d32f4dc20cc869f6b834dc40d8 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 16 Oct 2020 11:33:19 +0100 Subject: [PATCH 6/7] Extract customers stripe stub to StripeStubs helper --- .../consumer/shopping/checkout_stripe_spec.rb | 14 +------------- spec/support/request/stripe_stubs.rb | 13 +++++++++++++ 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/spec/features/consumer/shopping/checkout_stripe_spec.rb b/spec/features/consumer/shopping/checkout_stripe_spec.rb index cf7800225e..dcd262ae97 100644 --- a/spec/features/consumer/shopping/checkout_stripe_spec.rb +++ b/spec/features/consumer/shopping/checkout_stripe_spec.rb @@ -204,23 +204,11 @@ feature "Check out with Stripe", js: true do 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 - before do stub_payment_methods_post_request request: { payment_method: "pm_123", customer: "cus_A123" }, 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) - + stub_customer_post_request email: user.email stub_payment_method_attach_request end diff --git a/spec/support/request/stripe_stubs.rb b/spec/support/request/stripe_stubs.rb index af441577cd..d7f209a67c 100644 --- a/spec/support/request/stripe_stubs.rb +++ b/spec/support/request/stripe_stubs.rb @@ -35,6 +35,13 @@ module StripeStubs .to_return(hub_payment_method_response_mock({ pm_id: "pm_123" })) end + # Stubs the customers call to both the main stripe account and the connected account + def stub_customer_post_request(email:) + stub_request(:post, "https://api.stripe.com/v1/customers") + .with(body: { email: email }) + .to_return(customers_response_mock) + end + def stub_successful_capture_request(order:, response: {}) stub_capture_request(order, payment_successful_capture_mock(response)) end @@ -98,6 +105,12 @@ module StripeStubs body: JSON.generate(id: options[:pm_id] || "pm_456", customer: "cus_A123") } end + def customers_response_mock + { status: 200, + body: JSON.generate(id: "cus_A123", + sources: { data: [id: "cus_A123"] }) } + end + def payment_successful_refund_mock { status: 200, body: JSON.generate(object: "refund", From 27111394202baf6520cfc4f0b1aedc8918bd6847 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 16 Oct 2020 11:43:45 +0100 Subject: [PATCH 7/7] Re-use existing stripe stub --- .../consumer/shopping/checkout_stripe_spec.rb | 2 +- spec/lib/stripe/credit_card_cloner_spec.rb | 14 +++++--------- spec/support/request/stripe_stubs.rb | 14 ++++++++------ 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/spec/features/consumer/shopping/checkout_stripe_spec.rb b/spec/features/consumer/shopping/checkout_stripe_spec.rb index dcd262ae97..e3a32718aa 100644 --- a/spec/features/consumer/shopping/checkout_stripe_spec.rb +++ b/spec/features/consumer/shopping/checkout_stripe_spec.rb @@ -208,7 +208,7 @@ feature "Check out with Stripe", js: true do stub_payment_methods_post_request request: { payment_method: "pm_123", customer: "cus_A123" }, response: { pm_id: "pm_123" } stub_payment_intents_post_request order: order stub_successful_capture_request order: order - stub_customer_post_request email: user.email + stub_customers_post_request email: user.email stub_payment_method_attach_request end diff --git a/spec/lib/stripe/credit_card_cloner_spec.rb b/spec/lib/stripe/credit_card_cloner_spec.rb index 40854560d6..432d707676 100644 --- a/spec/lib/stripe/credit_card_cloner_spec.rb +++ b/spec/lib/stripe/credit_card_cloner_spec.rb @@ -6,6 +6,8 @@ require 'stripe/credit_card_cloner' module Stripe describe CreditCardCloner do describe "#clone" do + include StripeStubs + let(:cloner) { Stripe::CreditCardCloner.new } let(:customer_id) { "cus_A123" } @@ -13,7 +15,6 @@ module Stripe let(:new_customer_id) { "cus_A456" } let(:new_payment_method_id) { "pm_456" } let(:stripe_account_id) { "acct_456" } - let(:customer_response_mock) { { status: 200, body: customer_response_body } } let(:payment_method_response_mock) { { status: 200, body: payment_method_response_body } } let(:credit_card) { create(:credit_card, user: create(:user)) } @@ -21,18 +22,13 @@ module Stripe let(:payment_method_response_body) { JSON.generate(id: new_payment_method_id) } - let(:customer_response_body) { - JSON.generate(id: new_customer_id) - } before do allow(Stripe).to receive(:api_key) { "sk_test_12345" } - stub_request(:post, "https://api.stripe.com/v1/customers") - .with(body: { email: credit_card.user.email }, - headers: { 'Stripe-Account' => stripe_account_id }) - .to_return(customer_response_mock) - + stub_customers_post_request email: credit_card.user.email, + response: { customer_id: new_customer_id }, + stripe_account_header: true stub_request(:post, "https://api.stripe.com/v1/payment_methods/#{new_payment_method_id}/attach") .with(body: { customer: new_customer_id }, diff --git a/spec/support/request/stripe_stubs.rb b/spec/support/request/stripe_stubs.rb index d7f209a67c..909604b9ae 100644 --- a/spec/support/request/stripe_stubs.rb +++ b/spec/support/request/stripe_stubs.rb @@ -36,10 +36,11 @@ module StripeStubs end # Stubs the customers call to both the main stripe account and the connected account - def stub_customer_post_request(email:) - stub_request(:post, "https://api.stripe.com/v1/customers") + def stub_customers_post_request(email:, response: {}, stripe_account_header: false) + stub = stub_request(:post, "https://api.stripe.com/v1/customers") .with(body: { email: email }) - .to_return(customers_response_mock) + stub = stub.with(headers: { 'Stripe-Account' => 'acct_456' }) if stripe_account_header + stub.to_return(customers_response_mock(response)) end def stub_successful_capture_request(order:, response: {}) @@ -105,10 +106,11 @@ module StripeStubs body: JSON.generate(id: options[:pm_id] || "pm_456", customer: "cus_A123") } end - def customers_response_mock + def customers_response_mock(options) + customer_id = options[:customer_id] || "cus_A123" { status: 200, - body: JSON.generate(id: "cus_A123", - sources: { data: [id: "cus_A123"] }) } + body: JSON.generate(id: customer_id, + sources: { data: [id: customer_id] }) } end def payment_successful_refund_mock