spree_braintree_vzero 3.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.codeclimate.yml +15 -0
- data/.gitignore +19 -0
- data/.rspec +1 -0
- data/.travis.yml +63 -0
- data/Appraisals +45 -0
- data/CONTRIBUTING.md +28 -0
- data/Gemfile +14 -0
- data/LICENSE +26 -0
- data/README.md +83 -0
- data/Rakefile +21 -0
- data/app/assets/images/credit_cards/icons/jcb.png +0 -0
- data/app/assets/javascripts/spree/backend/payments.js +19 -0
- data/app/assets/javascripts/spree/backend/spree_braintree_vzero.js +81 -0
- data/app/assets/javascripts/spree/frontend/spree_braintree_vzero.js +68 -0
- data/app/assets/stylesheets/spree/backend/spree_braintree_vzero.css +5 -0
- data/app/controllers/spree/admin/payments_controller_decorator.rb +43 -0
- data/app/controllers/spree/api/v1/braintree_client_token_controller.rb +31 -0
- data/app/controllers/spree/checkout_controller_decorator.rb +38 -0
- data/app/controllers/spree/orders_controller_decorator.rb +62 -0
- data/app/controllers/spree/user_sessions_controller_decorator.rb +15 -0
- data/app/helpers/spree/admin/decorated_navigation_helper.rb +10 -0
- data/app/helpers/spree/admin/payment_methods_helper.rb +101 -0
- data/app/helpers/spree/braintree_helper.rb +27 -0
- data/app/models/braintree/successful_result_decorator.rb +21 -0
- data/app/models/spree/address_decorator.rb +18 -0
- data/app/models/spree/braintree_checkout.rb +105 -0
- data/app/models/spree/gateway/braintree_vzero_base.rb +168 -0
- data/app/models/spree/gateway/braintree_vzero_base/address.rb +33 -0
- data/app/models/spree/gateway/braintree_vzero_base/braintree_user.rb +25 -0
- data/app/models/spree/gateway/braintree_vzero_base/purchase_data.rb +48 -0
- data/app/models/spree/gateway/braintree_vzero_base/transaction.rb +39 -0
- data/app/models/spree/gateway/braintree_vzero_base/utils.rb +108 -0
- data/app/models/spree/gateway/braintree_vzero_drop_in_ui.rb +24 -0
- data/app/models/spree/gateway/braintree_vzero_hosted_fields.rb +28 -0
- data/app/models/spree/gateway/braintree_vzero_paypal_express.rb +36 -0
- data/app/models/spree/order_decorator.rb +153 -0
- data/app/models/spree/payment_decorator.rb +10 -0
- data/app/models/spree/payment_processing_decorator.rb +61 -0
- data/app/models/spree/preferences/preferable_decorator.rb +54 -0
- data/app/overrides/spree/admin/orders/customer_details/_form.rb +8 -0
- data/app/overrides/spree/admin/payment_methods/_form.rb +10 -0
- data/app/overrides/spree/admin/shared/_order_summary.rb +23 -0
- data/app/overrides/spree/admin/shared/_refunds.rb +13 -0
- data/app/overrides/spree/checkout/_new_user.rb +6 -0
- data/app/overrides/spree/checkout/_payment.rb +20 -0
- data/app/overrides/spree/checkout/registration.rb +6 -0
- data/app/overrides/spree/orders/edit.rb +6 -0
- data/app/overrides/spree/shared/_order_details.rb +13 -0
- data/app/overrides/spree/shared/_payment.rb +28 -0
- data/app/views/spree/admin/payment_methods/_braintree_vzero_form.html.erb +83 -0
- data/app/views/spree/admin/payments/source_forms/_braintree_vzero_dropin_ui.html.erb +1 -0
- data/app/views/spree/admin/payments/source_forms/_braintree_vzero_hosted_fields.html.erb +1 -0
- data/app/views/spree/admin/payments/source_forms/_braintree_vzero_paypal_express.html.erb +1 -0
- data/app/views/spree/admin/payments/source_forms/braintree_vzero/_payments.html.erb +87 -0
- data/app/views/spree/admin/payments/source_views/_braintree_vzero_dropin_ui.html.erb +1 -0
- data/app/views/spree/admin/payments/source_views/_braintree_vzero_hosted_fields.html.erb +1 -0
- data/app/views/spree/admin/payments/source_views/_braintree_vzero_paypal_express.html.erb +1 -0
- data/app/views/spree/admin/payments/source_views/braintree_vzero/_payment.html.erb +17 -0
- data/app/views/spree/braintree_vzero/_paypal_checkout.html.erb +87 -0
- data/app/views/spree/checkout/payment/_braintree_vzero_dropin_ui.html.erb +4 -0
- data/app/views/spree/checkout/payment/_braintree_vzero_hosted_fields.html.erb +4 -0
- data/app/views/spree/checkout/payment/_braintree_vzero_paypal_express.html.erb +4 -0
- data/app/views/spree/checkout/payment/braintree_vzero/_buttons.html.erb +11 -0
- data/app/views/spree/checkout/payment/braintree_vzero/_dropin_on_error_callback.js.erb +3 -0
- data/app/views/spree/checkout/payment/braintree_vzero/_dropin_on_ready_callback.js.erb +1 -0
- data/app/views/spree/checkout/payment/braintree_vzero/_hosted_fields_on_field_event_callback.js.erb +12 -0
- data/app/views/spree/checkout/payment/braintree_vzero/_hosted_fields_styles.js.erb +29 -0
- data/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb +84 -0
- data/app/views/spree/checkout/payment/braintree_vzero/_three_d_secure.html.erb +218 -0
- data/app/views/spree/shared/braintree_vzero/_dropin.js.erb +70 -0
- data/app/views/spree/shared/braintree_vzero/_hosted.js.erb +66 -0
- data/app/views/spree/shared/braintree_vzero/_paypal.js.erb +39 -0
- data/bin/rails +7 -0
- data/config/initializers/extend_spree_permitted_checkout_attributes.rb +5 -0
- data/config/initializers/prepend_helpers.rb +1 -0
- data/config/locales/en.yml +79 -0
- data/config/routes.rb +7 -0
- data/db/migrate/20150904143013_create_spree_braintree_checkouts.rb +9 -0
- data/db/migrate/20151002094655_add_braintree_id_to_spree_addresses.rb +5 -0
- data/db/migrate/20151018123907_add_braintree_token_and_nonce_to_spree_payments.rb +6 -0
- data/db/migrate/20151027135109_add_paypal_email_to_spree_braintree_checkout.rb +5 -0
- data/db/migrate/20151028095515_add_advanced_fraud_data_to_spree_braintree_checkout.rb +5 -0
- data/db/migrate/20151202095956_add_risk_id_and_risk_decision_to_spree_braintree_checkouts.rb +6 -0
- data/db/migrate/20151211100203_add_braintree_last_digits_and_braintree_card_type_to_spree_braintree_checkouts.rb +6 -0
- data/db/migrate/20160112153422_add_admin_payment_to_spree_braintree_checkout.rb +5 -0
- data/gemfiles/spree_3_5.gemfile +12 -0
- data/gemfiles/spree_3_5_spree_auth_devise.gemfile +13 -0
- data/gemfiles/spree_3_7.gemfile +12 -0
- data/gemfiles/spree_3_7_spree_auth_devise.gemfile +13 -0
- data/gemfiles/spree_4_0.gemfile +11 -0
- data/gemfiles/spree_4_0_spree_auth_devise.gemfile +12 -0
- data/gemfiles/spree_master.gemfile +11 -0
- data/gemfiles/spree_master_spree_auth_devise.gemfile +12 -0
- data/lib/generators/spree_braintree_vzero/install/install_generator.rb +34 -0
- data/lib/spree_braintree_vzero.rb +6 -0
- data/lib/spree_braintree_vzero/engine.rb +28 -0
- data/lib/spree_braintree_vzero/factories.rb +10 -0
- data/lib/spree_braintree_vzero/railtie.rb +8 -0
- data/lib/spree_braintree_vzero/version.rb +17 -0
- data/lib/tasks/spree_braintree_vzero.rake +6 -0
- data/spec/controllers/spree/api/v1/braintree_client_token_controller_spec.rb +49 -0
- data/spec/controllers/spree/checkout_controller_spec.rb +85 -0
- data/spec/controllers/spree/orders_controller_spec.rb +97 -0
- data/spec/factories/braintree_checkout_factory.rb +7 -0
- data/spec/factories/braintree_gateway_factory.rb +35 -0
- data/spec/factories/payment_factory_decorator.rb +28 -0
- data/spec/features/spree/admin/log_entries_spec.rb +63 -0
- data/spec/models/gateway/braintree_vzero_base/address_spec.rb +28 -0
- data/spec/models/gateway/braintree_vzero_base/purchase_data_spec.rb +57 -0
- data/spec/models/gateway/braintree_vzero_base_spec.rb +346 -0
- data/spec/models/gateway/braintree_vzero_dropin_ui_spec.rb +35 -0
- data/spec/models/gateway/braintree_vzero_hosted_fields_spec.rb +35 -0
- data/spec/models/spree/order_spec.rb +186 -0
- data/spec/spec_helper.rb +100 -0
- data/spec/support/vcr.rb +10 -0
- data/spec/vcr/Log_entries/with_a_failed_log_entry/shows_a_failed_attempt.yml +91 -0
- data/spec/vcr/Log_entries/with_a_successful_log_entry/shows_a_successful_attempt.yml +113 -0
- data/spec/vcr/Spree_Api_V1_BraintreeClientTokenController/POST_create/guest_checkout/returns_proper_json_data_when_gateway_not_specified.yml +90 -0
- data/spec/vcr/Spree_Api_V1_BraintreeClientTokenController/POST_create/guest_checkout/returns_proper_json_data_when_gateway_specified.yml +90 -0
- data/spec/vcr/Spree_Api_V1_BraintreeClientTokenController/POST_create/user_checkout/returns_proper_json_data_when_gateway_not_specified.yml +191 -0
- data/spec/vcr/Spree_Api_V1_BraintreeClientTokenController/POST_create/user_checkout/returns_proper_json_data_when_gateway_specified.yml +191 -0
- data/spec/vcr/Spree_CheckoutController/_update/braintree_payment/advanced_fraud_data_in_source_should_be_updated.yml +71 -0
- data/spec/vcr/Spree_CheckoutController/_update/braintree_payment/when_token_credit_card_data_in_source_should_be_updated_from_Braintree_Vault.yml +139 -0
- data/spec/vcr/Spree_CheckoutController/_update/braintree_paypal_express_payment/amount_in_payment_should_be_updated.yml +280 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_capture/captures_authorized_amount/updates_Payment_state.yml +206 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_credit/with_refundable_state/should_be_a_success.yml +211 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_credit/with_unrefundable_state/should_not_be_a_success.yml +177 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/data_from_admin_panel/should_include_only_essential_data.yml +78 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/does_not_store_Transaction_in_Vault_by_default.yml +111 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/returns_false_with_invalid_nonce.yml +88 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/returns_false_with_invalid_token.yml +88 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/returns_success_with_valid_token.yml +113 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/returns_suceess_with_valid_nonce.yml +111 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/using_Vault/saves_Braintree_Address_id_to_Spree_Address_when_address_is_being_saved.yml +130 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/using_Vault/saves_unique_Braintree_Addresses_ids.yml +143 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/using_Vault/sends_empty_address_id_when_address_is_already_in_vault.yml +553 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/using_Vault/stores_Transaction.yml +181 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/with_3DSecure_option_turned_on/performs_3DSecure_check.yml +112 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/with_3DSecure_option_turned_on/returns_error.yml +112 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/with_advanced_fraud_tool_enabled/returns_fraud_data.yml +111 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/with_advanced_fraud_tool_enabled/returns_success.yml +111 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_settle/settles_authorized_amount/does_not_update_Order_payment_state.yml +204 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_settle/settles_authorized_amount/prepares_Checkout_for_status_updating.yml +204 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_settle/settles_authorized_amount/submits_Transaction_for_settlement.yml +377 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_settle/settles_authorized_amount/updates_Payment_state.yml +203 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_update_states/does_not_update_completed_Checkout_on_subsequent_runs.yml +202 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_update_states/updates_Order_payment_state_when_Checkout_is_updated.yml +202 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_update_states/updates_Payment_state_when_Checkout_is_updated.yml +202 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_update_states/updates_payment_State.yml +202 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_void/with_unvoidable_state/should_not_change_payment_source_state.yml +178 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_void/with_voidable_state/should_change_payment_source_state_to_voided.yml +199 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/generates_token_for_User_registered_in_Braintree.yml +356 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/generates_token_for_new_User.yml +189 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/generates_token_without_User.yml +89 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/with_invalid_credentials/raises_Braintree_error.yml +62 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase_Address/_create/creates_Braintree_Address.yml +84 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase_Address/_create/deletes_Braintree_Address.yml +141 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase_Address/_create/finds_Braintree_Address.yml +148 -0
- data/spec/vcr/Spree_Gateway_BraintreeVzeroBase_Address/_create/updates_Braintree_Address.yml +154 -0
- data/spec/vcr/Spree_Order/complete_with_braintree_vzero_standard_payment/with_auto_capture/should_complete_payment.yml +116 -0
- data/spec/vcr/Spree_Order/complete_with_braintree_vzero_standard_payment/with_auto_capture/should_update_payment_s_response_code.yml +111 -0
- data/spec/vcr/Spree_Order/complete_with_braintree_vzero_standard_payment/with_auto_capture/should_update_payment_s_source_state_and_transaction_id.yml +111 -0
- data/spec/vcr/Spree_Order/complete_with_braintree_vzero_standard_payment/without_auto_capture/should_pend_payment.yml +111 -0
- data/spec/vcr/Spree_Order/complete_with_braintree_vzero_standard_payment/without_auto_capture/should_update_payment_s_response_code.yml +111 -0
- data/spec/vcr/Spree_Order/complete_with_braintree_vzero_standard_payment/without_auto_capture/should_update_payment_s_source_state_and_transaction_id.yml +110 -0
- data/spree_braintree_vzero.gemspec +52 -0
- data/vendor/assets/javascripts/maskedinput/jquery.maskedinput.min.js +7 -0
- metadata +643 -0
@@ -0,0 +1,7 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :braintree_checkout, class: Spree::BraintreeCheckout do
|
3
|
+
factory :braintree_checkout_with_fraud_data, class: Spree::BraintreeCheckout do
|
4
|
+
advanced_fraud_data { '{"device_session_id":"9cc1d185d71768c185c06622b7ca7cfe","fraud_merchant_id":"600000","correlation_id":"7343097f536f584bfded32f9d229ec6d"}' }
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :vzero_gateway, class: Spree::Gateway::BraintreeVzeroDropInUi do
|
3
|
+
name { 'Braintree Vzero DropInUI' }
|
4
|
+
|
5
|
+
# to write new specs please provide proper credentials
|
6
|
+
# either here or in dummy secrets.yml file. Values will
|
7
|
+
# be recorded on VCR, so they can be safely replaced with
|
8
|
+
# placeholder afterwards
|
9
|
+
transient do
|
10
|
+
merchant_id { Rails.application.secrets.merchant_id || 'change me' }
|
11
|
+
public_key { Rails.application.secrets.public_key || 'change me' }
|
12
|
+
private_key { Rails.application.secrets.private_key || 'change me' }
|
13
|
+
end
|
14
|
+
|
15
|
+
before(:create) do |gateway, s|
|
16
|
+
%w(merchant_id private_key public_key).each do |preference|
|
17
|
+
gateway.send "preferred_#{preference}=", s.send(preference)
|
18
|
+
end
|
19
|
+
gateway.send 'preferred_server=', :sandbox
|
20
|
+
gateway.preferences[:currency_merchant_accounts] = { 'EUR' => 'sparksolutions_EUR' }
|
21
|
+
end
|
22
|
+
|
23
|
+
factory :vzero_paypal_gateway, class: Spree::Gateway::BraintreeVzeroPaypalExpress do
|
24
|
+
name { 'Braintree Vzero PayPal Express' }
|
25
|
+
end
|
26
|
+
|
27
|
+
factory :vzero_dropin_ui_gateway, class: Spree::Gateway::BraintreeVzeroDropInUi do
|
28
|
+
name { 'Braintree Vzero DropIn UI' }
|
29
|
+
end
|
30
|
+
|
31
|
+
factory :vzero_hosted_fields_gateway, class: Spree::Gateway::BraintreeVzeroHostedFields do
|
32
|
+
name { 'Braintree Vzero Hosted Fields' }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :braintree_vzero_payment, class: Spree::Payment do
|
3
|
+
amount { 12.73 }
|
4
|
+
association(:payment_method, factory: :vzero_gateway)
|
5
|
+
association(:source, factory: :braintree_checkout)
|
6
|
+
order
|
7
|
+
state { 'checkout' }
|
8
|
+
braintree_nonce { 'fake-valid-nonce' }
|
9
|
+
end
|
10
|
+
|
11
|
+
factory :braintree_vzero_paypal_payment, class: Spree::Payment do
|
12
|
+
amount { 0 }
|
13
|
+
association(:payment_method, factory: :vzero_paypal_gateway)
|
14
|
+
association(:source, factory: :braintree_checkout)
|
15
|
+
order
|
16
|
+
state { 'checkout' }
|
17
|
+
braintree_nonce { 'fake-valid-nonce' }
|
18
|
+
end
|
19
|
+
|
20
|
+
factory :braintree_vzero_failed_paypal_payment, class: Spree::Payment do
|
21
|
+
amount { 0 }
|
22
|
+
association(:payment_method, factory: :vzero_paypal_gateway)
|
23
|
+
association(:source, factory: :braintree_checkout)
|
24
|
+
order
|
25
|
+
state { 'checkout' }
|
26
|
+
braintree_nonce { 'fake-invalid-nonce' }
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Log entries', :vcr, type: :feature do
|
4
|
+
include Spree::BaseHelper
|
5
|
+
|
6
|
+
stub_authorization!
|
7
|
+
|
8
|
+
let(:payment) { order.payments.last }
|
9
|
+
let(:entry) { payment.log_entries.last }
|
10
|
+
let(:message) { entry.parsed_details.message }
|
11
|
+
|
12
|
+
context 'with a successful log entry' do
|
13
|
+
let!(:order) do
|
14
|
+
order = OrderWalkthrough.up_to(:payment)
|
15
|
+
order.payments << create(:braintree_vzero_paypal_payment, order: order)
|
16
|
+
order.next!
|
17
|
+
order.next
|
18
|
+
order
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'shows a successful attempt' do
|
22
|
+
expect(message).to be_blank
|
23
|
+
|
24
|
+
visit spree.admin_order_payments_path(order)
|
25
|
+
if Spree.version.to_f < 4.0
|
26
|
+
find("#payment_#{payment.id} a").click
|
27
|
+
else
|
28
|
+
find_all("#payment_#{payment.id} a")[0].click
|
29
|
+
end
|
30
|
+
|
31
|
+
click_link 'Logs'
|
32
|
+
within('#listing_log_entries') do
|
33
|
+
expect(page).to have_css('.log_entry.success')
|
34
|
+
expect(page).not_to have_css('.log_entry.fail')
|
35
|
+
expect(page).to have_content(pretty_time(entry.created_at).gsub(' ', ' '))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'with a failed log entry' do
|
41
|
+
let!(:order) do
|
42
|
+
order = OrderWalkthrough.up_to(:payment)
|
43
|
+
order.payments << create(:braintree_vzero_failed_paypal_payment, order: order)
|
44
|
+
order.next!
|
45
|
+
order.next
|
46
|
+
order
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'shows a failed attempt' do
|
50
|
+
expect(message).to be_present
|
51
|
+
|
52
|
+
visit spree.admin_order_payments_path(order)
|
53
|
+
find("#payment_#{payment.id} a").click
|
54
|
+
click_link 'Logs'
|
55
|
+
within('#listing_log_entries') do
|
56
|
+
expect(page).not_to have_css('.log_entry.success')
|
57
|
+
expect(page).to have_css('.log_entry.fail')
|
58
|
+
expect(page).to have_content(pretty_time(entry.created_at).gsub(' ', ' '))
|
59
|
+
expect(page).to have_content(message)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Spree::Gateway::BraintreeVzeroBase::Address, :vcr do
|
4
|
+
let(:gateway) { create(:vzero_gateway, auto_capture: true) }
|
5
|
+
let(:user) { create(:user) }
|
6
|
+
let(:order) { create(:order) }
|
7
|
+
let(:braintree_address) { Spree::Gateway::BraintreeVzeroBase::Address.new(gateway.provider, order) }
|
8
|
+
|
9
|
+
context '#create' do
|
10
|
+
it 'creates Braintree Address' do
|
11
|
+
expect(braintree_address.create.address.id).to_not be_nil
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'finds Braintree Address' do
|
15
|
+
expect(braintree_address.find(braintree_address.create.address)).to_not be_nil
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'updates Braintree Address' do
|
19
|
+
result = braintree_address.update(braintree_address.create.address, first_name: 'new_name')
|
20
|
+
expect(result.address.first_name).to eq 'new_name'
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'deletes Braintree Address' do
|
24
|
+
result = braintree_address.create
|
25
|
+
expect(braintree_address.delete(result.address).success?).to be true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Spree::Gateway::BraintreeVzeroBase::PurchaseData do
|
4
|
+
let(:gateway) { create(:vzero_gateway, auto_capture: true) }
|
5
|
+
let(:payment) { create(:braintree_vzero_payment, payment_method: gateway) }
|
6
|
+
let(:payment_source) { payment.payment_source }
|
7
|
+
let(:order) { OrderWalkthrough.up_to(:payment) }
|
8
|
+
let(:identifier_hash) { { payment_method_nonce: '123' } }
|
9
|
+
let(:utils) { Spree::Gateway::BraintreeVzeroBase::Utils.new(gateway, order) }
|
10
|
+
let(:set_data) { gateway.send(:set_purchase_data, identifier_hash, order, 113, payment_source) }
|
11
|
+
|
12
|
+
before do
|
13
|
+
gateway.preferred_3dsecure = true
|
14
|
+
payment.update(braintree_nonce: 'fake-valid-debit-nonce')
|
15
|
+
gateway.preferred_advanced_fraud_tools = true
|
16
|
+
payment.source.update(advanced_fraud_data: '{\"device_session_id\":\"5a0c416f74a6044e4693204b4373b9e1\",\"fraud_merchant_id\":\"abcc\"}')
|
17
|
+
gateway.instance_variable_set(:@utils, utils)
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'data from admin panel' do
|
21
|
+
before { payment_source.update(admin_payment: true) }
|
22
|
+
|
23
|
+
it 'should include only essential data' do
|
24
|
+
data = set_data
|
25
|
+
expect(data[:payment_method_nonce]).to eq identifier_hash[:payment_method_nonce]
|
26
|
+
expect(data[:channel]).to eq 'SpreeCommerceInc_Cart_Braintree'
|
27
|
+
expect(data[:device_data]).to be_blank
|
28
|
+
expect(data[:options][:three_d_secure][:required]).to be_blank
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'data from checkout' do
|
33
|
+
it 'should include all data' do
|
34
|
+
data = set_data
|
35
|
+
expect(data[:payment_method_nonce]).to eq identifier_hash[:payment_method_nonce]
|
36
|
+
expect(data[:channel]).to eq 'SpreeCommerceInc_Cart_Braintree'
|
37
|
+
expect(data[:device_data]).to eq payment.source.advanced_fraud_data
|
38
|
+
expect(data[:options][:three_d_secure][:required]).to be true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'multi-currency' do
|
43
|
+
it 'should not include merchant account when currency
|
44
|
+
is not included in preferred currency merchant accounts' do
|
45
|
+
expect(gateway.preferred_currency_merchant_accounts[order.currency]).to be_nil
|
46
|
+
data = set_data
|
47
|
+
expect(data.include?(:merchant_account_id)).to be false
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should include merchant account id based on order currency' do
|
51
|
+
Spree::Price.first.update currency: 'EUR'
|
52
|
+
order.update currency: 'EUR'
|
53
|
+
data = set_data
|
54
|
+
expect(data[:merchant_account_id]).to eq 'sparksolutions_EUR'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,346 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Spree::Gateway::BraintreeVzeroBase, :vcr do
|
4
|
+
context 'valid credentials' do
|
5
|
+
let(:gateway) { create(:vzero_gateway, auto_capture: true) }
|
6
|
+
let(:payment) { create(:braintree_vzero_payment, payment_method: gateway) }
|
7
|
+
let(:payment_source) { payment.payment_source }
|
8
|
+
let(:order) { OrderWalkthrough.up_to(:payment) }
|
9
|
+
let(:add_payment_to_order!) { order.payments << payment }
|
10
|
+
let(:complete_order!) do
|
11
|
+
add_payment_to_order!
|
12
|
+
until order.completed? do order.next! end
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'generates token without User' do
|
16
|
+
expect(gateway.client_token).to_not be_nil
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'generates token for new User' do
|
20
|
+
expect(gateway.client_token(order, create(:user))).to_not be_nil
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'generates token for User registered in Braintree' do
|
24
|
+
user = create(:user, billing_address: create(:address))
|
25
|
+
Spree::Gateway::BraintreeVzeroBase::BraintreeUser.new(gateway.provider, user, order).register_user
|
26
|
+
expect(gateway.client_token(order, user)).to_not be_nil
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#purchase' do
|
30
|
+
let(:gateway_options) { { order_id: "#{order.number}-#{payment.number}" } }
|
31
|
+
let(:purchase) { gateway.purchase(10_000, payment_source, gateway_options) }
|
32
|
+
let(:other_order) { OrderWalkthrough.up_to(:payment) }
|
33
|
+
|
34
|
+
before do
|
35
|
+
gateway.preferred_3dsecure = false
|
36
|
+
add_payment_to_order!
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'returns suceess with valid nonce' do
|
40
|
+
expect(purchase.success?).to be true
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'returns false with invalid nonce' do
|
44
|
+
payment.update(braintree_nonce: 'fake-invalid-nonce')
|
45
|
+
expect(purchase.success?).to be false
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'does not store Transaction in Vault by default' do
|
49
|
+
expect(purchase.transaction.credit_card_details.token).to be_nil
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'returns success with valid token' do
|
53
|
+
gateway.preferred_store_payments_in_vault = :store_all
|
54
|
+
token = purchase.transaction.credit_card_details.token
|
55
|
+
payment.update(braintree_token: token)
|
56
|
+
|
57
|
+
expect(purchase.success?).to be true
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'returns false when neither nonce nor token is present' do
|
61
|
+
payment.update(braintree_nonce: nil, braintree_token: nil)
|
62
|
+
expect(purchase.success?).to be false
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'returns false with invalid token' do
|
66
|
+
token = 'sometoken'
|
67
|
+
payment.update(braintree_token: token)
|
68
|
+
expect(purchase.success?).to be false
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'with advanced fraud tool enabled' do
|
72
|
+
before do
|
73
|
+
gateway.preferences[:advanced_fraud_data] = true
|
74
|
+
payment_source = create(:braintree_checkout_with_fraud_data)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'returns success' do
|
78
|
+
expect(purchase).to be_success
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'returns fraud data' do
|
82
|
+
risk_data = purchase.transaction.risk_data
|
83
|
+
expect(risk_data.id.present? && risk_data.decision.present?).to be true
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'with 3DSecure option turned on' do
|
88
|
+
before do
|
89
|
+
gateway.preferred_3dsecure = true
|
90
|
+
payment.update(braintree_nonce: 'fake-valid-debit-nonce')
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'performs 3DSecure check' do
|
94
|
+
expect(purchase.success?).to be false
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'returns error' do
|
98
|
+
response = purchase
|
99
|
+
expect(response.errors.size.zero?).to be true
|
100
|
+
expect(response.transaction.try(:gateway_rejection_reason)).to eq 'three_d_secure'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'using Vault' do
|
105
|
+
let(:user) { create(:user) }
|
106
|
+
before do
|
107
|
+
order.user = user
|
108
|
+
gateway.preferred_store_payments_in_vault = :store_all
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'stores Transaction' do
|
112
|
+
card_vault_token = purchase.transaction.credit_card_details.token
|
113
|
+
expect { Braintree::PaymentMethod.find(card_vault_token) }.not_to raise_error
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'saves Braintree::Address id to Spree::Address when address is being saved' do
|
117
|
+
gateway.preferred_pass_billing_and_shipping_address = true
|
118
|
+
address = create(:address)
|
119
|
+
order.ship_address = address
|
120
|
+
order.bill_address = address
|
121
|
+
order.save
|
122
|
+
purchase
|
123
|
+
order.reload
|
124
|
+
|
125
|
+
bill_id = order.billing_address.braintree_id
|
126
|
+
ship_id = order.shipping_address.braintree_id
|
127
|
+
expect(order.billing_address.braintree_id).to_not be_nil
|
128
|
+
expect(order.shipping_address.braintree_id).to_not be_nil
|
129
|
+
expect(bill_id).to eq ship_id
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'saves unique Braintree::Addresses ids' do
|
133
|
+
gateway.preferred_pass_billing_and_shipping_address = true
|
134
|
+
ship_address = create(:address, first_name: 'foo')
|
135
|
+
bill_address = create(:address, first_name: 'bar')
|
136
|
+
order.ship_address = ship_address
|
137
|
+
order.bill_address = bill_address
|
138
|
+
order.save
|
139
|
+
purchase
|
140
|
+
order.reload
|
141
|
+
|
142
|
+
bill_id = order.billing_address.braintree_id
|
143
|
+
ship_id = order.shipping_address.braintree_id
|
144
|
+
expect(bill_id).to_not be_nil
|
145
|
+
expect(ship_id).to_not be_nil
|
146
|
+
expect(bill_id).to_not eq ship_id
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'sends address data when address is new' do
|
150
|
+
gateway.preferred_pass_billing_and_shipping_address = true
|
151
|
+
ship_address = create(:address, first_name: 'foo')
|
152
|
+
bill_address = create(:address, first_name: 'bar')
|
153
|
+
order.ship_address = ship_address
|
154
|
+
order.bill_address = bill_address
|
155
|
+
order.save
|
156
|
+
|
157
|
+
utils = Spree::Gateway::BraintreeVzeroBase::Utils.new(gateway, order)
|
158
|
+
data = gateway.send('set_basic_purchase_data', {}, order, utils, order.total * 100)
|
159
|
+
|
160
|
+
expect(data['billing'][:first_name]).to eq bill_address.first_name
|
161
|
+
expect(data['shipping'][:first_name]).to eq ship_address.first_name
|
162
|
+
expect(data['billing_address_id']).to eq nil
|
163
|
+
expect(data['shipping_address_id']).to eq nil
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'sends empty address id when address is already in vault' do
|
167
|
+
gateway.preferred_pass_billing_and_shipping_address = true
|
168
|
+
old_bill_address = create(:address, first_name: 'bar')
|
169
|
+
old_ship_address = create(:address, first_name: 'foo')
|
170
|
+
user = create(:user, bill_address_id: old_bill_address.id, ship_address_id: old_ship_address.id)
|
171
|
+
order.update(user_id: user.id)
|
172
|
+
order.ship_address = old_ship_address
|
173
|
+
order.bill_address = old_bill_address
|
174
|
+
order.save
|
175
|
+
purchase
|
176
|
+
|
177
|
+
ship_address = create(:address, old_ship_address.attributes.except('id', 'updated_at', 'created_at', 'braintree_id'))
|
178
|
+
bill_address = create(:address, old_bill_address.attributes.except('id', 'updated_at', 'created_at', 'braintree_id'))
|
179
|
+
other_order.ship_address = ship_address
|
180
|
+
other_order.bill_address = bill_address
|
181
|
+
other_order.save
|
182
|
+
user.update(bill_address_id: bill_address.id, ship_address_id: ship_address.id)
|
183
|
+
other_order.update(user_id: user.id)
|
184
|
+
|
185
|
+
utils = Spree::Gateway::BraintreeVzeroBase::Utils.new(gateway, other_order)
|
186
|
+
data = gateway.send('set_basic_purchase_data', {}, other_order, utils, other_order.total * 100)
|
187
|
+
|
188
|
+
expect(data['billing_address_id']).to eq old_bill_address.reload.braintree_id
|
189
|
+
expect(data['shipping_address_id']).to eq old_ship_address.reload.braintree_id
|
190
|
+
expect(data['billing']).to eq nil
|
191
|
+
expect(data['shipping']).to eq nil
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe '#update_states' do
|
197
|
+
before do
|
198
|
+
gateway.preferred_3dsecure = false
|
199
|
+
payment.update(amount: order.reload.total)
|
200
|
+
complete_order!
|
201
|
+
order.payments.first.source.update_attribute(:transaction_id, 'dw49zp') # use already settled transaction
|
202
|
+
end
|
203
|
+
|
204
|
+
let!(:result) { Spree::BraintreeCheckout.update_states }
|
205
|
+
|
206
|
+
it 'updates payment State' do
|
207
|
+
expect(result[:changed]).to eq 1
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'does not update completed Checkout on subsequent runs' do
|
211
|
+
expect(result[:changed]).to eq 1
|
212
|
+
expect(Spree::BraintreeCheckout.update_states[:changed]).to eq 0
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'updates Order payment_state when Checkout is updated' do
|
216
|
+
expect(order.reload.payment_state).to eq 'paid'
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'updates Payment state when Checkout is updated' do
|
220
|
+
expect(order.reload.payments.first.state).to eq 'completed'
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
describe '#void' do
|
225
|
+
let(:void) { gateway.void(payment_source.reload.transaction_id, {}) }
|
226
|
+
let!(:prepare_gateway) { gateway.preferred_3dsecure = false }
|
227
|
+
|
228
|
+
context 'with voidable state' do
|
229
|
+
before do
|
230
|
+
complete_order!
|
231
|
+
void
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'should change payment_source state to voided' do
|
235
|
+
expect(payment_source.reload.state).to eq 'voided'
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'should change payment_source state to voided' do
|
239
|
+
expect(payment.reload.state).to eq 'void'
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
context 'with unvoidable state' do
|
244
|
+
before do
|
245
|
+
payment.update(braintree_nonce: 'fake-paypal-one-time-nonce')
|
246
|
+
complete_order!
|
247
|
+
void
|
248
|
+
end
|
249
|
+
|
250
|
+
it 'should not change payment_source state' do
|
251
|
+
expect(payment_source.reload.state).to eq 'settling'
|
252
|
+
end
|
253
|
+
|
254
|
+
it 'should not change payment_source state' do
|
255
|
+
expect(payment.reload.state).to eq 'completed'
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
describe '#settle' do
|
261
|
+
before do
|
262
|
+
gateway.update(auto_capture: false)
|
263
|
+
complete_order!
|
264
|
+
payment.reload
|
265
|
+
end
|
266
|
+
|
267
|
+
context 'settles authorized amount' do
|
268
|
+
it 'does not update Order payment_state' do
|
269
|
+
expect(order.payment_state).to eq 'balance_due'
|
270
|
+
payment.reload.settle!
|
271
|
+
expect(order.reload.payment_state).to eq 'balance_due'
|
272
|
+
end
|
273
|
+
|
274
|
+
it 'updates Payment state' do
|
275
|
+
expect(payment.state).to eq 'pending'
|
276
|
+
payment.reload.settle!
|
277
|
+
expect(payment.state).to eq 'processing'
|
278
|
+
end
|
279
|
+
|
280
|
+
it 'submits Transaction for settlement' do
|
281
|
+
expect(gateway.provider::Transaction.find(payment.response_code).status).to eq 'authorized'
|
282
|
+
payment.reload.settle!
|
283
|
+
expect(gateway.provider::Transaction.find(payment.response_code).status).to eq 'submitted_for_settlement'
|
284
|
+
end
|
285
|
+
|
286
|
+
it 'prepares Checkout for status updating' do
|
287
|
+
payment.reload.settle!
|
288
|
+
expect(Spree::BraintreeCheckout.not_in_state(Spree::BraintreeCheckout::FINAL_STATES).count).to eq 1
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
describe '#capture' do
|
294
|
+
# for Spree::Config.auto_capture_on_dispatch = true
|
295
|
+
|
296
|
+
before do
|
297
|
+
gateway.update(auto_capture: false)
|
298
|
+
complete_order!
|
299
|
+
payment.reload
|
300
|
+
end
|
301
|
+
|
302
|
+
context 'captures authorized amount' do
|
303
|
+
it 'updates Payment state' do
|
304
|
+
expect(payment).to be_pending
|
305
|
+
payment.reload.capture!
|
306
|
+
expect(payment).to be_completed
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
describe '#credit' do
|
312
|
+
let(:refund) { gateway.credit(1317, payment_source.reload.transaction_id, {}) }
|
313
|
+
let!(:prepare_gateway) { gateway.preferred_3dsecure = false }
|
314
|
+
|
315
|
+
context 'with refundable state' do
|
316
|
+
before do
|
317
|
+
payment.update(braintree_nonce: 'fake-paypal-one-time-nonce')
|
318
|
+
complete_order!
|
319
|
+
end
|
320
|
+
|
321
|
+
it 'should be a success' do
|
322
|
+
expect(refund.success?).to be true
|
323
|
+
expect(refund.transaction.amount).to eq 13.17
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
context 'with unrefundable state' do
|
328
|
+
before do
|
329
|
+
complete_order!
|
330
|
+
end
|
331
|
+
|
332
|
+
it 'should not be a success' do
|
333
|
+
expect(refund.success?).to be false
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
context 'with invalid credentials' do
|
340
|
+
let(:gateway) { create(:vzero_gateway, merchant_id: 'invalid_id') }
|
341
|
+
|
342
|
+
it 'raises Braintree error' do
|
343
|
+
expect { gateway.client_token }.to raise_error('Braintree::AuthenticationError')
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|