From f7b0bb6ab6f2695e1f2c87f0ca437306999059c7 Mon Sep 17 00:00:00 2001 From: Luuk Veenis Date: Wed, 14 Sep 2016 09:26:54 -0700 Subject: [PATCH 1/3] Add transactions controller spec --- .../transactions_controller_spec.rb | 87 +++++++++++ .../transactions_controller/create.yml | 141 ++++++++++++++++++ 2 files changed, 228 insertions(+) create mode 100644 spec/controllers/solidus_paypal_braintree/transactions_controller_spec.rb create mode 100644 spec/fixtures/cassettes/transactions_controller/create.yml diff --git a/spec/controllers/solidus_paypal_braintree/transactions_controller_spec.rb b/spec/controllers/solidus_paypal_braintree/transactions_controller_spec.rb new file mode 100644 index 00000000..c3d63080 --- /dev/null +++ b/spec/controllers/solidus_paypal_braintree/transactions_controller_spec.rb @@ -0,0 +1,87 @@ +require 'spec_helper' + +RSpec.describe SolidusPaypalBraintree::TransactionsController, type: :controller do + include_context "order ready for payment" + + let(:payment_method) { create_gateway } + + before do + allow(controller).to receive(:spree_current_user) { user } + allow(controller).to receive(:current_order) { order } + end + + cassette_options = { cassette_name: "transactions_controller/create" } + describe "POST create", vcr: cassette_options do + subject(:post_create) { post :create, params } + + let(:params) do + { + transaction: { + nonce: "ABC123", + payment_type: "MonopolyMoney", + phone: "1112223333", + email: "batman@example.com", + address_attributes: { + first_name: "Wade", + last_name: "Wilson", + address_line_1: "123 Fake Street", + city: "Seattle", + zip: "98101", + state_code: "WA", + country_code: "US" + } + }, + payment_method_id: payment_method.id + } + end + + context "when the transaction is valid" do + it "imports the payment" do + expect { post_create }.to change { order.payments.count }.by(1) + expect(order.payments.first.amount).to eq 55 + end + + context "and an address is provided" do + it "creates a new address" do + # Creating the order also creates 3 addresses, we want to make sure + # the transaction import only creates 1 new one + order + expect { post_create }.to change { Spree::Address.count }.by(1) + expect(Spree::Address.last.full_name).to eq "Wade Wilson" + end + end + + context "and the transaction does not have an address" do + before { params[:transaction].delete(:address_attributes) } + + it "does not create a new address" do + order + expect { post_create }.to_not change { Spree::Address.count } + end + end + + context "when import! leaves the order in confirm" do + it "redirects the user to the confirm page" do + expect(post_create).to redirect_to spree.checkout_state_path("confirm") + end + end + + context "when import! completes the order" do + before { allow(order).to receive(:complete?).and_return(true) } + + it "displays the order to the user" do + expect(post_create).to redirect_to spree.order_path(order) + end + end + end + + context "when the transaction is invalid" do + before { params[:transaction].delete(:phone) } + + it "displays the errors object" do + subject + expect(response.body).to match(/^#$/) + end + end + end +end diff --git a/spec/fixtures/cassettes/transactions_controller/create.yml b/spec/fixtures/cassettes/transactions_controller/create.yml new file mode 100644 index 00000000..449cab3f --- /dev/null +++ b/spec/fixtures/cassettes/transactions_controller/create.yml @@ -0,0 +1,141 @@ +--- +http_interactions: +- request: + method: post + uri: https://api.sandbox.braintreegateway.com/merchants/7rdg92j7bm7fk5h3/customers + body: + encoding: UTF-8 + string: | + + + + headers: + Accept-Encoding: + - gzip + Accept: + - application/xml + User-Agent: + - Braintree Ruby Gem 2.66.0 + X-Apiversion: + - '4' + Authorization: + - Basic bXdqa2t4d2NwMzJja2huZjphOTI5OGY0M2IzMGM2OTlkYjMwNzJjYzRhMDBmN2Y0OQ== + Content-Type: + - application/xml + response: + status: + code: 201 + message: Created + headers: + Date: + - Wed, 14 Sep 2016 15:56:51 GMT + Content-Type: + - application/xml; charset=utf-8 + Transfer-Encoding: + - chunked + X-Frame-Options: + - SAMEORIGIN + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + X-Content-Type-Options: + - nosniff + X-Authentication: + - basic_auth + X-User: + - 3v249hqtptsg744y + Vary: + - Accept-Encoding + Content-Encoding: + - gzip + Etag: + - W/"cf917cd8f592cf2b13a7c0842a0ccf71" + Cache-Control: + - max-age=0, private, must-revalidate + X-Request-Id: + - dec51a53-1dae-4d14-8769-2ddc9ba6a55a + X-Runtime: + - '0.146172' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + body: + encoding: ASCII-8BIT + string: !binary |- + H4sIAENz2VcAA5SRsXKDMBBEe3+FRr0CwsEEj8Cdv8Bp0p25wyhBgpGEY/4+ + mHjszJAUKXef9m7npHYX07IzOa87W3D5FHNGtupQ21PBXw978cJ35UpVgw+d + IVeuGFMay2Sdx0meJSqaxNWbWNWADWLSmcNTnrxnR5PVH2mzVtFPen1da+eD + sGCIWd0WPLiBeDSjFv4iVWd6sOPCJwO6Xbh909nljBouC++Tjl6HX/Y5gkAo + ILAw9lRwnGTQhniZxHIj4lzI54NMt+lmm8o3FT0Cc37o8X/5R+B7/3xzUWtq + 0d8roQ6iAof+NhScg/HWGBAdeU8LNnW7f+AXAAAA//8DAPq+nqbzAQAA + http_version: + recorded_at: Wed, 14 Sep 2016 15:56:51 GMT +- request: + method: post + uri: https://api.sandbox.braintreegateway.com/merchants/7rdg92j7bm7fk5h3/customers + body: + encoding: UTF-8 + string: | + + + + headers: + Accept-Encoding: + - gzip + Accept: + - application/xml + User-Agent: + - Braintree Ruby Gem 2.66.0 + X-Apiversion: + - '4' + Authorization: + - Basic bXdqa2t4d2NwMzJja2huZjphOTI5OGY0M2IzMGM2OTlkYjMwNzJjYzRhMDBmN2Y0OQ== + Content-Type: + - application/xml + response: + status: + code: 201 + message: Created + headers: + Date: + - Wed, 14 Sep 2016 15:56:51 GMT + Content-Type: + - application/xml; charset=utf-8 + Transfer-Encoding: + - chunked + X-Frame-Options: + - SAMEORIGIN + - SAMEORIGIN + X-Xss-Protection: + - 1; mode=block + X-Content-Type-Options: + - nosniff + X-Authentication: + - basic_auth + X-User: + - 3v249hqtptsg744y + Vary: + - Accept-Encoding + Content-Encoding: + - gzip + Etag: + - W/"78438d21ad2d3cac1e4b98726448afec" + Cache-Control: + - max-age=0, private, must-revalidate + X-Request-Id: + - 55d2c0e5-3748-4001-a629-5ca96af6a894 + X-Runtime: + - '0.169527' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + body: + encoding: ASCII-8BIT + string: !binary |- + H4sIAENz2VcAA5SRzW6DMBCE73kKy3eXn4S/yJBbnyC99LZhl+AWG2SbNrx9 + CY2SSrSHHmc+z+5oLQ8X3bEPsk71puTRU8gZmbpHZc4lfzk+i5wfqo2sR+d7 + TbbaMCYVVukuz4ttHMpgFldvZnULxotZZxbPRfyWnXTWvCftVgY/6fV1o6zz + woAmZlRXcm9H4sGCOviL1L0ewEwrnzSobuUObW/WMxq4rLxPOjnlf9lnCTyh + AM/8NFDJcZZeaeJVHEapCAsR7Y5Rsk/SfRK9yuARWPLjgP/LPwLf+5ebi0ZR + h+5eCZUXNVh0t6FgLUy3xoBoyTlasbnb/QO/AAAA//8DAGrc9TDzAQAA + http_version: + recorded_at: Wed, 14 Sep 2016 15:56:51 GMT +recorded_with: VCR 3.0.3 From 505fe2ff12ebbcc261d89050b750e495dfa1ebad Mon Sep 17 00:00:00 2001 From: Luuk Veenis Date: Wed, 14 Sep 2016 09:27:59 -0700 Subject: [PATCH 2/3] Raise an error when the transaction is invalid Instead of displaying the errors object's to_s, show the actual validation errors. --- .../solidus_paypal_braintree/transactions_controller.rb | 5 ++++- .../transactions_controller_spec.rb | 8 +++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/app/controllers/solidus_paypal_braintree/transactions_controller.rb b/app/controllers/solidus_paypal_braintree/transactions_controller.rb index 2423c7c7..9ed3ce93 100644 --- a/app/controllers/solidus_paypal_braintree/transactions_controller.rb +++ b/app/controllers/solidus_paypal_braintree/transactions_controller.rb @@ -1,4 +1,6 @@ class SolidusPaypalBraintree::TransactionsController < Spree::StoreController + class InvalidTransactionError < StandardError; end + PERMITTED_BRAINTREE_TRANSACTION_PARAMS = [ :nonce, :payment_type, @@ -23,7 +25,8 @@ def create return redirect_to spree.checkout_state_path(import.order.state) end else - render text: transaction.errors + raise InvalidTransactionError, + "Transaction invalid: #{transaction.errors.full_messages.join(', ')}" end end diff --git a/spec/controllers/solidus_paypal_braintree/transactions_controller_spec.rb b/spec/controllers/solidus_paypal_braintree/transactions_controller_spec.rb index c3d63080..140271fa 100644 --- a/spec/controllers/solidus_paypal_braintree/transactions_controller_spec.rb +++ b/spec/controllers/solidus_paypal_braintree/transactions_controller_spec.rb @@ -78,9 +78,11 @@ context "when the transaction is invalid" do before { params[:transaction].delete(:phone) } - it "displays the errors object" do - subject - expect(response.body).to match(/^#$/) + it "raises an error" do + expect { post_create }.to raise_error( + SolidusPaypalBraintree::TransactionsController::InvalidTransactionError, + "Transaction invalid: Phone can't be blank" + ) end end end From bb377c74b1af9c3c924931bf776e0a95d57d7318 Mon Sep 17 00:00:00 2001 From: Luuk Veenis Date: Wed, 14 Sep 2016 10:08:22 -0700 Subject: [PATCH 3/3] Add test for invalid address parameters --- .../transactions_controller_spec.rb | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/spec/controllers/solidus_paypal_braintree/transactions_controller_spec.rb b/spec/controllers/solidus_paypal_braintree/transactions_controller_spec.rb index 140271fa..f7966c49 100644 --- a/spec/controllers/solidus_paypal_braintree/transactions_controller_spec.rb +++ b/spec/controllers/solidus_paypal_braintree/transactions_controller_spec.rb @@ -41,7 +41,7 @@ expect(order.payments.first.amount).to eq 55 end - context "and an address is provided" do + context "and a valid address is provided" do it "creates a new address" do # Creating the order also creates 3 addresses, we want to make sure # the transaction import only creates 1 new one @@ -51,6 +51,19 @@ end end + context "and an invalid address is provided" do + before { params[:transaction][:address_attributes][:city] = nil } + + it "raises a validation error" do + expect { post_create }.to raise_error( + ActiveRecord::RecordInvalid, + "Validation failed: " \ + "Billing address city can't be blank, " \ + "Shipping address city can't be blank" + ) + end + end + context "and the transaction does not have an address" do before { params[:transaction].delete(:address_attributes) }