From e2a0a185f5b6875e041b860d6b419e17c5949967 Mon Sep 17 00:00:00 2001 From: Luuk Veenis Date: Mon, 9 Jan 2017 15:48:06 -0800 Subject: [PATCH] Fix error when saving braintree payment method If you try to update the Braintree payment method in the admin it will throw an error due to 2 of the preference types being hashes. Solidus automatically creates a text field for these on the page, which it populates with the default value: "{}". The code inside `Spree::Preferences::Preferable` that handles type conversion throws an error if the input for a preference with type :hash is not a Hash object. This change allows for a well-formed hash to be input as a string and converts it to a Hash before saving the record. --- .../solidus_paypal_braintree/gateway.rb | 11 +++++++ .../solidus_paypal_braintree/gateway_spec.rb | 29 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/app/models/solidus_paypal_braintree/gateway.rb b/app/models/solidus_paypal_braintree/gateway.rb index 0b284e72..5c78cce1 100644 --- a/app/models/solidus_paypal_braintree/gateway.rb +++ b/app/models/solidus_paypal_braintree/gateway.rb @@ -204,6 +204,17 @@ def cents(dollars) dollars.to_money.cents end + def to_hash(preference_string) + JSON.parse(preference_string.gsub("=>", ":")) + end + + def convert_preference_value(value, type) + if type == :hash && value.is_a?(String) + value = to_hash(value) + end + super + end + def transaction_options(source, options, submit_for_settlement = false) params = options.select do |key, _| ALLOWED_BRAINTREE_OPTIONS.include?(key) diff --git a/spec/models/solidus_paypal_braintree/gateway_spec.rb b/spec/models/solidus_paypal_braintree/gateway_spec.rb index 25c57b99..d09d082e 100644 --- a/spec/models/solidus_paypal_braintree/gateway_spec.rb +++ b/spec/models/solidus_paypal_braintree/gateway_spec.rb @@ -20,6 +20,35 @@ end let(:payment_type) { SolidusPaypalBraintree::Source::PAYPAL } + describe "saving preference hashes as strings" do + subject { gateway.update(update_params) } + + context "with valid hash syntax" do + let(:update_params) do + { + preferred_merchant_currency_map: '{"EUR" => "test_merchant_account_id"}', + preferred_paypal_payee_email_map: '{"CAD" => "bruce+wayne@example.com"}' + } + end + + it "successfully updates the preference" do + subject + expect(gateway.preferred_merchant_currency_map).to eq({ "EUR" => "test_merchant_account_id" }) + expect(gateway.preferred_paypal_payee_email_map).to eq({ "CAD" => "bruce+wayne@example.com" }) + end + end + + context "with invalid user input" do + let(:update_params) do + { preferred_merchant_currency_map: '{this_is_not_a_valid_hash}' } + end + + it "raise a JSON parser error" do + expect{ subject }.to raise_error(JSON::ParserError) + end + end + end + describe 'making a payment on an order', vcr: { cassette_name: 'gateway/complete' } do include_context 'order ready for payment'