braintree-rails 1.4.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +11 -0
- data/lib/braintree_rails/address_details.rb +4 -0
- data/lib/braintree_rails/business_details.rb +5 -1
- data/lib/braintree_rails/credit_card.rb +1 -1
- data/lib/braintree_rails/funding_details.rb +4 -0
- data/lib/braintree_rails/individual_details.rb +5 -1
- data/lib/braintree_rails/merchant_account.rb +3 -3
- data/lib/braintree_rails/persistence.rb +9 -5
- data/lib/braintree_rails/transaction.rb +6 -6
- data/lib/braintree_rails/version.rb +1 -1
- data/spec/config/braintree_auth.yml.example +2 -1
- data/spec/fixtures/gateway_rejected.xml +147 -0
- data/spec/integration/braintree_rails/credit_card_integration_spec.rb +1 -0
- data/spec/integration/braintree_rails/customer_integration_spec.rb +2 -1
- data/spec/integration/braintree_rails/merchant_account_integration_spec.rb +22 -3
- data/spec/support/helper.rb +13 -3
- data/spec/unit/braintree_rails/credit_card_spec.rb +2 -1
- data/spec/unit/braintree_rails/funding_details_spec.rb +5 -5
- data/spec/unit/braintree_rails/transaction_spec.rb +12 -2
- metadata +28 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 51d3059b858bb2192c5a21e6fe99da5b79ce2dbd
|
4
|
+
data.tar.gz: 51a3f9d66af180e42bbc0e5beea380a8fe3e3853
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48a8b5c76024facbfe7b091d804b072ed91a4d18f68bacb565d46bc0a7f13d704ceda99d0fd55e646c104db4a2ee1f96e8c7790e10e0d77cae9a56fd456e527a
|
7
|
+
data.tar.gz: eb131427147d9b22525738f4e9b04f93598f6d6e9c7fd0c7eae24c5f6b9e3261aacdac89bf28934d898b6f60f1658393dec412c4e5ad45c51970619978f38601
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,12 @@
|
|
1
1
|
## Unreleased (master)
|
2
|
+
### Enhancements
|
3
|
+
* Added image_url to credit card readonly attributes. (Thanks, @maxkaplan)
|
4
|
+
|
5
|
+
### Bug Fixes
|
6
|
+
* Fix propagation of braintree reported errors to associations in merchant accounts. (Thanks, @twalpole)
|
7
|
+
* Do not raise exception on gateway rejected transactions. (Thanks, @murtyk)
|
8
|
+
|
9
|
+
## v1.4.0 (0830c14), Dec 12 2014
|
2
10
|
### Enhancements
|
3
11
|
* Added `service_fee_amount` to `BraintreeRails::Transaction`. (Thanks, @KELiON)
|
4
12
|
* Enhanced validation error parsing so that they can be customized/i18n-ed
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -14,6 +14,7 @@ GEM
|
|
14
14
|
braintree (2.38.0)
|
15
15
|
builder (>= 2.0.0)
|
16
16
|
builder (3.2.2)
|
17
|
+
coderay (1.1.0)
|
17
18
|
coveralls (0.7.2)
|
18
19
|
multi_json (~> 1.3)
|
19
20
|
rest-client (= 1.6.7)
|
@@ -26,9 +27,14 @@ GEM
|
|
26
27
|
docile (1.1.5)
|
27
28
|
i18n (0.6.11)
|
28
29
|
json (1.8.1)
|
30
|
+
method_source (0.8.2)
|
29
31
|
mime-types (2.4.3)
|
30
32
|
minitest (5.4.3)
|
31
33
|
multi_json (1.10.1)
|
34
|
+
pry (0.10.3)
|
35
|
+
coderay (~> 1.1.0)
|
36
|
+
method_source (~> 0.8.1)
|
37
|
+
slop (~> 3.4)
|
32
38
|
rake (10.4.2)
|
33
39
|
rest-client (1.6.7)
|
34
40
|
mime-types (>= 1.16)
|
@@ -50,6 +56,7 @@ GEM
|
|
50
56
|
multi_json (~> 1.0)
|
51
57
|
simplecov-html (~> 0.8.0)
|
52
58
|
simplecov-html (0.8.0)
|
59
|
+
slop (3.6.0)
|
53
60
|
term-ansicolor (1.2.2)
|
54
61
|
tins (~> 0.8)
|
55
62
|
thor (0.18.1)
|
@@ -69,6 +76,10 @@ DEPENDENCIES
|
|
69
76
|
activesupport (>= 3.0)
|
70
77
|
braintree (>= 2.28.0)
|
71
78
|
coveralls
|
79
|
+
pry
|
72
80
|
rake
|
73
81
|
rspec
|
74
82
|
webmock
|
83
|
+
|
84
|
+
BUNDLED WITH
|
85
|
+
1.10.6
|
@@ -14,7 +14,7 @@ module BraintreeRails
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def add_errors(validation_errors)
|
17
|
-
address.add_errors(validation_errors) if address
|
17
|
+
address.add_errors(extract_errors(validation_errors)) if address
|
18
18
|
super(validation_errors)
|
19
19
|
end
|
20
20
|
|
@@ -25,5 +25,9 @@ module BraintreeRails
|
|
25
25
|
def address_attributes
|
26
26
|
address.present? ? {:address => address.attributes_for(:as_association)} : {}
|
27
27
|
end
|
28
|
+
|
29
|
+
def extract_errors(errors)
|
30
|
+
errors.for(:business)
|
31
|
+
end
|
28
32
|
end
|
29
33
|
end
|
@@ -6,7 +6,7 @@ module BraintreeRails
|
|
6
6
|
:update => [:billing_address, :cardholder_name, :expiration_date, :expiration_month, :expiration_year, :options, :number, :cvv, :device_data],
|
7
7
|
:readonly => [
|
8
8
|
:bin, :card_type, :commercial, :country_of_issuance, :created_at, :debit, :durbin_regulated, :default,
|
9
|
-
:expired, :healthcare, :issuing_bank, :last_4, :payroll, :prepaid, :unique_number_identifier, :updated_at
|
9
|
+
:expired, :healthcare, :issuing_bank, :image_url, :last_4, :payroll, :prepaid, :unique_number_identifier, :updated_at
|
10
10
|
],
|
11
11
|
:as_association => [:cardholder_name, :cvv, :expiration_date, :expiration_month, :expiration_year, :number]
|
12
12
|
)
|
@@ -17,7 +17,7 @@ module BraintreeRails
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def add_errors(validation_errors)
|
20
|
-
address.add_errors(validation_errors) if address
|
20
|
+
address.add_errors(extract_errors(validation_errors)) if address
|
21
21
|
super(validation_errors)
|
22
22
|
end
|
23
23
|
|
@@ -28,5 +28,9 @@ module BraintreeRails
|
|
28
28
|
def address_attributes
|
29
29
|
address.present? ? {:address => address.attributes_for(:as_association)} : {}
|
30
30
|
end
|
31
|
+
|
32
|
+
def extract_errors(errors)
|
33
|
+
errors.for(:individual)
|
34
|
+
end
|
31
35
|
end
|
32
36
|
end
|
@@ -20,13 +20,13 @@ module BraintreeRails
|
|
20
20
|
after_create :reload, :if => :persisted?
|
21
21
|
|
22
22
|
def add_errors(validation_errors)
|
23
|
-
|
23
|
+
propagate_errors_to_associations(extract_errors(validation_errors))
|
24
24
|
super(validation_errors)
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
27
|
+
def propagate_errors_to_associations(validation_errors)
|
28
28
|
[individual, business, funding].each do |association|
|
29
|
-
association.add_errors(validation_errors) if association
|
29
|
+
association.add_errors(validation_errors) if association && errors
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -114,13 +114,17 @@ module BraintreeRails
|
|
114
114
|
def with_update_braintree(context)
|
115
115
|
raise RecordInvalid.new(self) unless valid?(context)
|
116
116
|
run_callbacks context do
|
117
|
-
result = yield
|
118
|
-
|
117
|
+
case result = yield
|
118
|
+
when Braintree::ErrorResult
|
119
|
+
if result.respond_to?(self.class.braintree_model_name) && result.send(self.class.braintree_model_name)
|
120
|
+
init(result.send(self.class.braintree_model_name))
|
121
|
+
end
|
119
122
|
add_errors(result.errors)
|
120
123
|
false
|
124
|
+
when Braintree::SuccessfulResult
|
125
|
+
init(result.send(self.class.braintree_model_name))
|
121
126
|
else
|
122
|
-
|
123
|
-
init(new_record)
|
127
|
+
init(result)
|
124
128
|
end
|
125
129
|
end
|
126
130
|
end
|
@@ -136,4 +140,4 @@ module BraintreeRails
|
|
136
140
|
end
|
137
141
|
end
|
138
142
|
end
|
139
|
-
end
|
143
|
+
end
|
@@ -13,8 +13,8 @@ module BraintreeRails
|
|
13
13
|
:readonly => [
|
14
14
|
:avs_error_response_code, :avs_postal_code_response_code, :avs_street_address_response_code, :billing_details,
|
15
15
|
:channel, :created_at, :credit_card, :credit_card_details, :currency_iso_code, :customer, :customer_details,
|
16
|
-
:cvv_response_code, :id, :plan_id, :purchase_order_number, :refund_ids, :refunded_transaction_id,
|
17
|
-
:shipping_details, :status, :status_history, :subscription_details, :updated_at
|
16
|
+
:cvv_response_code, :gateway_rejection_reason, :id, :plan_id, :purchase_order_number, :refund_ids, :refunded_transaction_id,
|
17
|
+
:settlement_batch_id, :shipping_details, :status, :status_history, :subscription_details, :updated_at
|
18
18
|
]
|
19
19
|
)
|
20
20
|
|
@@ -64,7 +64,7 @@ module BraintreeRails
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def add_errors(validation_errors)
|
67
|
-
|
67
|
+
propagate_errors_to_associations(extract_errors(validation_errors))
|
68
68
|
super(validation_errors)
|
69
69
|
end
|
70
70
|
|
@@ -80,9 +80,9 @@ module BraintreeRails
|
|
80
80
|
|
81
81
|
protected
|
82
82
|
|
83
|
-
def
|
83
|
+
def propagate_errors_to_associations(errors)
|
84
84
|
[customer, credit_card, billing, shipping].each do |association|
|
85
|
-
association.add_errors(errors) if association
|
85
|
+
association.add_errors(errors) if association && errors
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
@@ -116,4 +116,4 @@ module BraintreeRails
|
|
116
116
|
end
|
117
117
|
end
|
118
118
|
end
|
119
|
-
end
|
119
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<api-error-response>
|
3
|
+
<errors>
|
4
|
+
<errors type="array"/>
|
5
|
+
</errors>
|
6
|
+
<params>
|
7
|
+
<transaction>
|
8
|
+
<amount>5001</amount>
|
9
|
+
<type>sale</type>
|
10
|
+
<customer-id>customer_id</customer-id>
|
11
|
+
<payment-method-token>credit_card_id</payment-method-token>
|
12
|
+
</transaction>
|
13
|
+
</params>
|
14
|
+
<message>Gateway Rejected: application_incomplete</message>
|
15
|
+
<transaction>
|
16
|
+
<id>transactionid</id>
|
17
|
+
<status>gateway_rejected</status>
|
18
|
+
<type>sale</type>
|
19
|
+
<currency-iso-code>USD</currency-iso-code>
|
20
|
+
<amount>5001.00</amount>
|
21
|
+
<merchant-account-id>merchant_id</merchant-account-id>
|
22
|
+
<order-id nil="true"/>
|
23
|
+
<created-at type="datetime">2015-11-21T22:23:51Z</created-at>
|
24
|
+
<updated-at type="datetime">2015-11-21T22:23:51Z</updated-at>
|
25
|
+
<customer>
|
26
|
+
<id>customer_id</id>
|
27
|
+
<first-name>Brain47</first-name>
|
28
|
+
<last-name>Tree17</last-name>
|
29
|
+
<company nil="true"/>
|
30
|
+
<email nil="true"/>
|
31
|
+
<website nil="true"/>
|
32
|
+
<phone nil="true"/>
|
33
|
+
<fax nil="true"/>
|
34
|
+
</customer>
|
35
|
+
<billing>
|
36
|
+
<id>ff</id>
|
37
|
+
<first-name>Brain</first-name>
|
38
|
+
<last-name>Tree</last-name>
|
39
|
+
<company>Braintree</company>
|
40
|
+
<street-address>8711 Crane Avenue</street-address>
|
41
|
+
<extended-address>Suite 629</extended-address>
|
42
|
+
<locality>Menlo Park</locality>
|
43
|
+
<region>CA</region>
|
44
|
+
<postal-code>82875</postal-code>
|
45
|
+
<country-name>United States of America</country-name>
|
46
|
+
<country-code-alpha2>US</country-code-alpha2>
|
47
|
+
<country-code-alpha3>USA</country-code-alpha3>
|
48
|
+
<country-code-numeric>840</country-code-numeric>
|
49
|
+
</billing>
|
50
|
+
<refund-id nil="true"/>
|
51
|
+
<refund-ids type="array"/>
|
52
|
+
<refunded-transaction-id nil="true"/>
|
53
|
+
<partial-settlement-transaction-ids type="array"/>
|
54
|
+
<authorized-transaction-id nil="true"/>
|
55
|
+
<settlement-batch-id nil="true"/>
|
56
|
+
<shipping>
|
57
|
+
<id nil="true"/>
|
58
|
+
<first-name nil="true"/>
|
59
|
+
<last-name nil="true"/>
|
60
|
+
<company nil="true"/>
|
61
|
+
<street-address nil="true"/>
|
62
|
+
<extended-address nil="true"/>
|
63
|
+
<locality nil="true"/>
|
64
|
+
<region nil="true"/>
|
65
|
+
<postal-code nil="true"/>
|
66
|
+
<country-name nil="true"/>
|
67
|
+
<country-code-alpha2 nil="true"/>
|
68
|
+
<country-code-alpha3 nil="true"/>
|
69
|
+
<country-code-numeric nil="true"/>
|
70
|
+
</shipping>
|
71
|
+
<custom-fields/>
|
72
|
+
<avs-error-response-code nil="true"/>
|
73
|
+
<avs-postal-code-response-code nil="true"/>
|
74
|
+
<avs-street-address-response-code nil="true"/>
|
75
|
+
<cvv-response-code nil="true"/>
|
76
|
+
<gateway-rejection-reason>application_incomplete</gateway-rejection-reason>
|
77
|
+
<processor-authorization-code nil="true"/>
|
78
|
+
<processor-response-code></processor-response-code>
|
79
|
+
<processor-response-text>Unknown ()</processor-response-text>
|
80
|
+
<additional-processor-response nil="true"/>
|
81
|
+
<voice-referral-number nil="true"/>
|
82
|
+
<purchase-order-number nil="true"/>
|
83
|
+
<tax-amount nil="true"/>
|
84
|
+
<tax-exempt type="boolean">false</tax-exempt>
|
85
|
+
<credit-card>
|
86
|
+
<token>credit_card_id</token>
|
87
|
+
<bin>400011</bin>
|
88
|
+
<last-4>1115</last-4>
|
89
|
+
<card-type>Visa</card-type>
|
90
|
+
<expiration-month>11</expiration-month>
|
91
|
+
<expiration-year>2017</expiration-year>
|
92
|
+
<customer-location>US</customer-location>
|
93
|
+
<cardholder-name>Brain Tree</cardholder-name>
|
94
|
+
<image-url>https://assets.braintreegateway.com/payment_method_logo/visa.png?environment=sandbox</image-url>
|
95
|
+
<prepaid>Unknown</prepaid>
|
96
|
+
<healthcare>Unknown</healthcare>
|
97
|
+
<debit>Unknown</debit>
|
98
|
+
<durbin-regulated>Unknown</durbin-regulated>
|
99
|
+
<commercial>Unknown</commercial>
|
100
|
+
<payroll>Unknown</payroll>
|
101
|
+
<issuing-bank>Unknown</issuing-bank>
|
102
|
+
<country-of-issuance>Unknown</country-of-issuance>
|
103
|
+
<product-id>Unknown</product-id>
|
104
|
+
<unique-number-identifier>26f8b913bb2a574089777f07d48cc590</unique-number-identifier>
|
105
|
+
<venmo-sdk type="boolean">false</venmo-sdk>
|
106
|
+
</credit-card>
|
107
|
+
<status-history type="array">
|
108
|
+
<status-event>
|
109
|
+
<timestamp type="datetime">2015-11-21T22:23:51Z</timestamp>
|
110
|
+
<status>gateway_rejected</status>
|
111
|
+
<amount>5001.00</amount>
|
112
|
+
<user>braintree-rails-integration-test</user>
|
113
|
+
<transaction-source>api</transaction-source>
|
114
|
+
</status-event>
|
115
|
+
</status-history>
|
116
|
+
<plan-id nil="true"/>
|
117
|
+
<subscription-id nil="true"/>
|
118
|
+
<subscription>
|
119
|
+
<billing-period-end-date nil="true"/>
|
120
|
+
<billing-period-start-date nil="true"/>
|
121
|
+
</subscription>
|
122
|
+
<add-ons type="array"/>
|
123
|
+
<discounts type="array"/>
|
124
|
+
<descriptor>
|
125
|
+
<name nil="true"/>
|
126
|
+
<phone nil="true"/>
|
127
|
+
<url nil="true"/>
|
128
|
+
</descriptor>
|
129
|
+
<recurring type="boolean">false</recurring>
|
130
|
+
<channel nil="true"/>
|
131
|
+
<service-fee-amount nil="true"/>
|
132
|
+
<escrow-status nil="true"/>
|
133
|
+
<disbursement-details>
|
134
|
+
<disbursement-date nil="true"/>
|
135
|
+
<settlement-amount nil="true"/>
|
136
|
+
<settlement-currency-iso-code nil="true"/>
|
137
|
+
<settlement-currency-exchange-rate nil="true"/>
|
138
|
+
<funds-held nil="true"/>
|
139
|
+
<success nil="true"/>
|
140
|
+
</disbursement-details>
|
141
|
+
<disputes type="array"/>
|
142
|
+
<payment-instrument-type>credit_card</payment-instrument-type>
|
143
|
+
<processor-settlement-response-code></processor-settlement-response-code>
|
144
|
+
<processor-settlement-response-text></processor-settlement-response-text>
|
145
|
+
<three-d-secure-info nil="true"/>
|
146
|
+
</transaction>
|
147
|
+
</api-error-response>
|
@@ -29,6 +29,7 @@ describe 'Credit Card Integration' do
|
|
29
29
|
attributes.except(:number, :cvv, :billing_address).each do |key, value|
|
30
30
|
expect(braintree_credit_card.send(key)).to eq(value)
|
31
31
|
end
|
32
|
+
expect(credit_card.image_url).to eq(braintree_credit_card.image_url)
|
32
33
|
|
33
34
|
braintree_address = braintree_credit_card.billing_address
|
34
35
|
attributes[:billing_address].each do |key, value|
|
@@ -42,7 +42,8 @@ describe 'Customer Integration' do
|
|
42
42
|
customer.update_attributes!(:first_name => 'Foo', :last_name => 'Bar', :credit_card => credit_card_hash.merge(:cardholder_name => "FooBar"))
|
43
43
|
|
44
44
|
braintree_customer = Braintree::Customer.find(customer.id)
|
45
|
-
expect(braintree_customer.credit_cards.
|
45
|
+
expect(braintree_customer.credit_cards.size).to eq(2)
|
46
|
+
expect(braintree_customer.credit_cards.map(&:cardholder_name)).to include("FooBar")
|
46
47
|
end
|
47
48
|
|
48
49
|
it 'should be able to destroy existing customer' do
|
@@ -8,8 +8,13 @@ describe 'MerchantAccount Integration' do
|
|
8
8
|
expect(merchant_account.status).to eq(braintree_merchant_account.status)
|
9
9
|
end
|
10
10
|
|
11
|
-
it 'can create sub merchant account' do
|
12
|
-
merchant_account = BraintreeRails::MerchantAccount.create(merchant_account_hash)
|
11
|
+
it 'can create sub merchant account paid via email' do
|
12
|
+
merchant_account = BraintreeRails::MerchantAccount.create(merchant_account_hash(:email))
|
13
|
+
expect(merchant_account).to be_persisted
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'can create sub merchant account paid via bank account' do
|
17
|
+
merchant_account = BraintreeRails::MerchantAccount.create(merchant_account_hash(:bank))
|
13
18
|
expect(merchant_account).to be_persisted
|
14
19
|
end
|
15
20
|
|
@@ -18,7 +23,7 @@ describe 'MerchantAccount Integration' do
|
|
18
23
|
expect(merchant_account).to_not be_persisted
|
19
24
|
end
|
20
25
|
|
21
|
-
it 'sets validation errors properly to its associations' do
|
26
|
+
it 'sets internal validation errors properly to its associations' do
|
22
27
|
merchant_account = BraintreeRails::MerchantAccount.create(merchant_account_hash.merge(:individual => {}, :funding => {}, :business => {:legal_name => "foo"}))
|
23
28
|
expect(merchant_account).to_not be_persisted
|
24
29
|
expect(merchant_account.individual.errors).to_not be_empty
|
@@ -26,6 +31,20 @@ describe 'MerchantAccount Integration' do
|
|
26
31
|
expect(merchant_account.business.errors).to_not be_empty
|
27
32
|
end
|
28
33
|
|
34
|
+
it 'sets validation errors reported by Braintree properly to its associations' do
|
35
|
+
mah = merchant_account_hash(:bank)
|
36
|
+
mah[:funding][:routing_number]='22222222' #invalid routing number
|
37
|
+
mah[:individual][:address][:postal_code] = '1234' #invalid postal code
|
38
|
+
mah[:individual][:ssn]='111-11-111' #invalid ssn
|
39
|
+
mah[:business][:tax_id]='1' #invlaid tax id
|
40
|
+
merchant_account = BraintreeRails::MerchantAccount.create(mah)
|
41
|
+
expect(merchant_account).to_not be_persisted
|
42
|
+
expect(merchant_account.funding.errors).to_not be_empty
|
43
|
+
expect(merchant_account.business.errors).to_not be_empty
|
44
|
+
expect(merchant_account.individual.errors).to_not be_empty
|
45
|
+
expect(merchant_account.individual.address.errors).to_not be_empty
|
46
|
+
end
|
47
|
+
|
29
48
|
it 'can update the submerchant account' do
|
30
49
|
individual = merchant_account_hash[:individual].merge(:first_name => "foo")
|
31
50
|
merchant_account = BraintreeRails::MerchantAccount.create(merchant_account_hash.merge(:individual => individual))
|
data/spec/support/helper.rb
CHANGED
@@ -65,12 +65,12 @@ module Helper
|
|
65
65
|
}
|
66
66
|
end
|
67
67
|
|
68
|
-
def merchant_account_hash
|
68
|
+
def merchant_account_hash(kind = :email)
|
69
69
|
{
|
70
70
|
:master_merchant_account_id => BraintreeRails::Configuration.default_merchant_account_id,
|
71
71
|
:tos_accepted => true,
|
72
72
|
:individual => individual_details_hash,
|
73
|
-
:funding =>
|
73
|
+
:funding => send("#{kind.to_s}_funding_details_hash"),
|
74
74
|
:business => business_details_hash,
|
75
75
|
}
|
76
76
|
end
|
@@ -93,13 +93,23 @@ module Helper
|
|
93
93
|
}
|
94
94
|
end
|
95
95
|
|
96
|
-
def
|
96
|
+
def email_funding_details_hash
|
97
97
|
{
|
98
98
|
:destination => Braintree::MerchantAccount::FundingDestination::Email,
|
99
99
|
:email => "braintree-rails@exameple.com"
|
100
100
|
}
|
101
101
|
end
|
102
102
|
|
103
|
+
def bank_funding_details_hash
|
104
|
+
{
|
105
|
+
:destination => Braintree::MerchantAccount::FundingDestination::Bank,
|
106
|
+
:email => "braintree-rails@example.com",
|
107
|
+
:mobile_phone => '2015551212',
|
108
|
+
:account_number => '1234567890',
|
109
|
+
:routing_number => '071101307'
|
110
|
+
}
|
111
|
+
end
|
112
|
+
|
103
113
|
def address_details_hash
|
104
114
|
{
|
105
115
|
:street_address => "#{(1000..9999).to_a.sample} Crane Avenue",
|
@@ -14,6 +14,7 @@ describe BraintreeRails::CreditCard do
|
|
14
14
|
expect(credit_card.default?).to eq(braintree_credit_card.default?)
|
15
15
|
expect(credit_card.expired?).to eq(braintree_credit_card.expired?)
|
16
16
|
expect(credit_card.masked_number).to eq(braintree_credit_card.masked_number)
|
17
|
+
expect(credit_card.image_url).to eq(braintree_credit_card.image_url)
|
17
18
|
BraintreeRails::CreditCard.attributes.each do |attribute|
|
18
19
|
next if BraintreeRails::CreditCard.associations.include?(attribute)
|
19
20
|
if braintree_credit_card.respond_to?(attribute)
|
@@ -350,4 +351,4 @@ describe BraintreeRails::CreditCard do
|
|
350
351
|
expect(BraintreeRails::CreditCard.delete('credit_card_id')).to eq(true)
|
351
352
|
end
|
352
353
|
end
|
353
|
-
end
|
354
|
+
end
|
@@ -3,31 +3,31 @@ require File.expand_path(File.join(File.dirname(__FILE__), '../unit_spec_helper'
|
|
3
3
|
describe BraintreeRails::FundingDetails do
|
4
4
|
describe 'validations' do
|
5
5
|
it "requries destination" do
|
6
|
-
funding = BraintreeRails::FundingDetails.new(
|
6
|
+
funding = BraintreeRails::FundingDetails.new(email_funding_details_hash.merge(:destination => nil))
|
7
7
|
expect(funding).to be_invalid
|
8
8
|
expect(funding.errors[:destination]).to eq(["can't be blank", "is not included in the list"])
|
9
9
|
end
|
10
10
|
|
11
11
|
it "cannot be trash destination" do
|
12
|
-
funding = BraintreeRails::FundingDetails.new(
|
12
|
+
funding = BraintreeRails::FundingDetails.new(email_funding_details_hash.merge(:destination => "foo"))
|
13
13
|
expect(funding).to be_invalid
|
14
14
|
expect(funding.errors[:destination]).to eq(["is not included in the list"])
|
15
15
|
end
|
16
16
|
|
17
17
|
it "requries email if destination is Email" do
|
18
|
-
funding = BraintreeRails::FundingDetails.new(
|
18
|
+
funding = BraintreeRails::FundingDetails.new(email_funding_details_hash.merge(:destination => Braintree::MerchantAccount::FundingDestination::Email, :email => nil))
|
19
19
|
expect(funding).to be_invalid
|
20
20
|
expect(funding.errors[:email]).to eq(["can't be blank"])
|
21
21
|
end
|
22
22
|
|
23
23
|
it "requries mobile_phone if destination is MobilePhone" do
|
24
|
-
funding = BraintreeRails::FundingDetails.new(
|
24
|
+
funding = BraintreeRails::FundingDetails.new(email_funding_details_hash.merge(:destination => Braintree::MerchantAccount::FundingDestination::MobilePhone, :mobile_phone => nil))
|
25
25
|
expect(funding).to be_invalid
|
26
26
|
expect(funding.errors[:mobile_phone]).to eq(["can't be blank"])
|
27
27
|
end
|
28
28
|
|
29
29
|
it "requries account_number and routing_number if destination is Bank" do
|
30
|
-
funding = BraintreeRails::FundingDetails.new(
|
30
|
+
funding = BraintreeRails::FundingDetails.new(email_funding_details_hash.merge(:destination => Braintree::MerchantAccount::FundingDestination::Bank, :account_number => nil, :routing_number => nil))
|
31
31
|
expect(funding).to be_invalid
|
32
32
|
expect(funding.errors[:account_number]).to eq(["can't be blank"])
|
33
33
|
expect(funding.errors[:routing_number]).to eq(["can't be blank"])
|
@@ -218,7 +218,7 @@ describe BraintreeRails::Transaction do
|
|
218
218
|
expect {transaction.submit_for_settlement!}.to raise_error(BraintreeRails::RecordInvalid)
|
219
219
|
end
|
220
220
|
|
221
|
-
it 'should
|
221
|
+
it 'should propagate api errors to associations if any' do
|
222
222
|
customer = BraintreeRails::Customer.find('customer_id')
|
223
223
|
credit_card = BraintreeRails::CreditCard.find('credit_card_id')
|
224
224
|
transaction = BraintreeRails::Transaction.new(:amount => '10.00', :customer => customer, :credit_card => credit_card, :billing => address_hash, :shipping => address_hash)
|
@@ -243,9 +243,19 @@ describe BraintreeRails::Transaction do
|
|
243
243
|
expect(transaction.shipping.errors.full_messages.map(&:to_s)).to eq(["Postal code Postal code may contain no more than 9 letter or number characters."])
|
244
244
|
end
|
245
245
|
|
246
|
+
it 'should be able to handle gateway rejected transactions' do
|
247
|
+
customer = BraintreeRails::Customer.find('customer_id')
|
248
|
+
credit_card = BraintreeRails::CreditCard.find('credit_card_id')
|
249
|
+
transaction = BraintreeRails::Transaction.new(:amount => '10.00', :customer => customer, :credit_card => credit_card, :billing => address_hash, :shipping => address_hash)
|
250
|
+
stub_braintree_request(:post, '/transactions', :status => 422, :body => fixture('gateway_rejected.xml'))
|
251
|
+
expect {transaction.save}.to_not raise_error
|
252
|
+
expect(transaction.status).to eq(Braintree::Transaction::Status::GatewayRejected)
|
253
|
+
expect(transaction.gateway_rejection_reason).to eq("application_incomplete")
|
254
|
+
end
|
255
|
+
|
246
256
|
it 'does not support update or destroy' do
|
247
257
|
expect {BraintreeRails::Transaction.find('transactionid').update_attributes(:amount => 1)}.to raise_error(BraintreeRails::NotSupportedApiException)
|
248
258
|
expect {BraintreeRails::Transaction.find('transactionid').destroy!}.to raise_error(BraintreeRails::NotSupportedApiException)
|
249
259
|
end
|
250
260
|
end
|
251
|
-
end
|
261
|
+
end
|
metadata
CHANGED
@@ -1,129 +1,129 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: braintree-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lin Yang
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: braintree
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 2.28.0
|
20
|
-
- - <
|
20
|
+
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: '3'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: 2.28.0
|
30
|
-
- - <
|
30
|
+
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '3'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: activemodel
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
|
-
- -
|
37
|
+
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
39
|
version: '3.0'
|
40
|
-
- - <
|
40
|
+
- - "<"
|
41
41
|
- !ruby/object:Gem::Version
|
42
42
|
version: '5'
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
|
-
- -
|
47
|
+
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
49
|
version: '3.0'
|
50
|
-
- - <
|
50
|
+
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: '5'
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
54
|
name: activesupport
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
56
56
|
requirements:
|
57
|
-
- -
|
57
|
+
- - ">="
|
58
58
|
- !ruby/object:Gem::Version
|
59
59
|
version: '3.0'
|
60
|
-
- - <
|
60
|
+
- - "<"
|
61
61
|
- !ruby/object:Gem::Version
|
62
62
|
version: '5'
|
63
63
|
type: :runtime
|
64
64
|
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
|
-
- -
|
67
|
+
- - ">="
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '3.0'
|
70
|
-
- - <
|
70
|
+
- - "<"
|
71
71
|
- !ruby/object:Gem::Version
|
72
72
|
version: '5'
|
73
73
|
- !ruby/object:Gem::Dependency
|
74
74
|
name: rake
|
75
75
|
requirement: !ruby/object:Gem::Requirement
|
76
76
|
requirements:
|
77
|
-
- - ~>
|
77
|
+
- - "~>"
|
78
78
|
- !ruby/object:Gem::Version
|
79
79
|
version: '10'
|
80
80
|
type: :development
|
81
81
|
prerelease: false
|
82
82
|
version_requirements: !ruby/object:Gem::Requirement
|
83
83
|
requirements:
|
84
|
-
- - ~>
|
84
|
+
- - "~>"
|
85
85
|
- !ruby/object:Gem::Version
|
86
86
|
version: '10'
|
87
87
|
- !ruby/object:Gem::Dependency
|
88
88
|
name: rspec
|
89
89
|
requirement: !ruby/object:Gem::Requirement
|
90
90
|
requirements:
|
91
|
-
- - ~>
|
91
|
+
- - "~>"
|
92
92
|
- !ruby/object:Gem::Version
|
93
93
|
version: '3'
|
94
94
|
type: :development
|
95
95
|
prerelease: false
|
96
96
|
version_requirements: !ruby/object:Gem::Requirement
|
97
97
|
requirements:
|
98
|
-
- - ~>
|
98
|
+
- - "~>"
|
99
99
|
- !ruby/object:Gem::Version
|
100
100
|
version: '3'
|
101
101
|
- !ruby/object:Gem::Dependency
|
102
102
|
name: webmock
|
103
103
|
requirement: !ruby/object:Gem::Requirement
|
104
104
|
requirements:
|
105
|
-
- - ~>
|
105
|
+
- - "~>"
|
106
106
|
- !ruby/object:Gem::Version
|
107
107
|
version: '1'
|
108
108
|
type: :development
|
109
109
|
prerelease: false
|
110
110
|
version_requirements: !ruby/object:Gem::Requirement
|
111
111
|
requirements:
|
112
|
-
- - ~>
|
112
|
+
- - "~>"
|
113
113
|
- !ruby/object:Gem::Version
|
114
114
|
version: '1'
|
115
115
|
- !ruby/object:Gem::Dependency
|
116
116
|
name: coveralls
|
117
117
|
requirement: !ruby/object:Gem::Requirement
|
118
118
|
requirements:
|
119
|
-
- - ~>
|
119
|
+
- - "~>"
|
120
120
|
- !ruby/object:Gem::Version
|
121
121
|
version: '0'
|
122
122
|
type: :development
|
123
123
|
prerelease: false
|
124
124
|
version_requirements: !ruby/object:Gem::Requirement
|
125
125
|
requirements:
|
126
|
-
- - ~>
|
126
|
+
- - "~>"
|
127
127
|
- !ruby/object:Gem::Version
|
128
128
|
version: '0'
|
129
129
|
description: Provides ActiveModel compatible wrappers for Braintree models and more.
|
@@ -132,8 +132,8 @@ executables: []
|
|
132
132
|
extensions: []
|
133
133
|
extra_rdoc_files: []
|
134
134
|
files:
|
135
|
-
- .gitignore
|
136
|
-
- .travis.yml
|
135
|
+
- ".gitignore"
|
136
|
+
- ".travis.yml"
|
137
137
|
- CHANGELOG.md
|
138
138
|
- Gemfile
|
139
139
|
- Gemfile.lock
|
@@ -207,6 +207,7 @@ files:
|
|
207
207
|
- spec/fixtures/credit_card_validation_error.xml
|
208
208
|
- spec/fixtures/customer.xml
|
209
209
|
- spec/fixtures/discounts.xml
|
210
|
+
- spec/fixtures/gateway_rejected.xml
|
210
211
|
- spec/fixtures/merchant_account.xml
|
211
212
|
- spec/fixtures/plans.xml
|
212
213
|
- spec/fixtures/subscription.xml
|
@@ -259,17 +260,17 @@ require_paths:
|
|
259
260
|
- lib
|
260
261
|
required_ruby_version: !ruby/object:Gem::Requirement
|
261
262
|
requirements:
|
262
|
-
- -
|
263
|
+
- - ">="
|
263
264
|
- !ruby/object:Gem::Version
|
264
265
|
version: 1.9.2
|
265
266
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
266
267
|
requirements:
|
267
|
-
- -
|
268
|
+
- - ">="
|
268
269
|
- !ruby/object:Gem::Version
|
269
270
|
version: '0'
|
270
271
|
requirements: []
|
271
272
|
rubyforge_project:
|
272
|
-
rubygems_version: 2.
|
273
|
+
rubygems_version: 2.4.6
|
273
274
|
signing_key:
|
274
275
|
specification_version: 4
|
275
276
|
summary: Provides ActiveModel compatible wrappers for Braintree models.
|