braintree 2.90.0 → 2.91.0

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.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/braintree.gemspec +5 -0
  3. data/lib/braintree/configuration.rb +39 -1
  4. data/lib/braintree/credit_card.rb +1 -0
  5. data/lib/braintree/error_codes.rb +8 -0
  6. data/lib/braintree/graphql_client.rb +28 -0
  7. data/lib/braintree/http.rb +21 -9
  8. data/lib/braintree/local_payment_completed.rb +20 -0
  9. data/lib/braintree/test/credit_card.rb +2 -0
  10. data/lib/braintree/transaction.rb +8 -0
  11. data/lib/braintree/transaction_gateway.rb +4 -0
  12. data/lib/braintree/util.rb +44 -3
  13. data/lib/braintree/validation_error.rb +10 -2
  14. data/lib/braintree/validation_error_collection.rb +2 -1
  15. data/lib/braintree/version.rb +1 -1
  16. data/lib/braintree/webhook_notification.rb +5 -1
  17. data/lib/braintree/webhook_testing_gateway.rb +34 -3
  18. data/lib/braintree.rb +3 -1
  19. data/spec/integration/braintree/credit_card_spec.rb +14 -0
  20. data/spec/integration/braintree/dispute_spec.rb +3 -0
  21. data/spec/integration/braintree/graphql_client_spec.rb +74 -0
  22. data/spec/integration/braintree/http_spec.rb +1 -1
  23. data/spec/integration/braintree/transaction_search_spec.rb +19 -0
  24. data/spec/integration/braintree/transaction_spec.rb +203 -2
  25. data/spec/spec_helper.rb +1 -0
  26. data/spec/unit/braintree/configuration_spec.rb +37 -0
  27. data/spec/unit/braintree/http_spec.rb +65 -0
  28. data/spec/unit/braintree/local_payment_completed_spec.rb +24 -0
  29. data/spec/unit/braintree/transaction_spec.rb +8 -0
  30. data/spec/unit/braintree/util_spec.rb +109 -0
  31. data/spec/unit/braintree/validation_error_collection_spec.rb +335 -132
  32. data/spec/unit/braintree/webhook_notification_spec.rb +31 -0
  33. metadata +10 -3
@@ -2,174 +2,377 @@ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
2
 
3
3
  describe Braintree::ValidationErrorCollection do
4
4
 
5
- describe "initialize" do
6
- it "builds an error object given an array of hashes" do
7
- hash = {:errors => [{ :attribute => "some model attribute", :code => 1, :message => "bad juju" }]}
8
- collection = Braintree::ValidationErrorCollection.new(hash)
9
- error = collection[0]
10
- error.attribute.should == "some model attribute"
11
- error.code.should == 1
12
- error.message.should == "bad juju"
5
+ context "blue response" do
6
+ describe "initialize" do
7
+ it "builds an error object given an array of hashes" do
8
+ hash = {:errors => [{ :attribute => "some model attribute", :code => 1, :message => "bad juju" }]}
9
+ collection = Braintree::ValidationErrorCollection.new(hash)
10
+ error = collection[0]
11
+ error.attribute.should == "some model attribute"
12
+ error.code.should == 1
13
+ error.message.should == "bad juju"
14
+ end
13
15
  end
14
- end
15
16
 
16
- describe "for" do
17
- it "provides access to nested errors" do
18
- hash = {
19
- :errors => [{ :attribute => "some model attribute", :code => 1, :message => "bad juju" }],
20
- :nested => {
21
- :errors => [{ :attribute => "number", :code => 2, :message => "badder juju"}]
17
+ describe "for" do
18
+ it "provides access to nested errors" do
19
+ hash = {
20
+ :errors => [{ :attribute => "some model attribute", :code => 1, :message => "bad juju" }],
21
+ :nested => {
22
+ :errors => [{ :attribute => "number", :code => 2, :message => "badder juju"}]
23
+ }
22
24
  }
23
- }
24
- errors = Braintree::ValidationErrorCollection.new(hash)
25
- errors.for(:nested).on(:number)[0].code.should == 2
26
- errors.for(:nested).on(:number)[0].message.should == "badder juju"
27
- errors.for(:nested).on(:number)[0].attribute.should == "number"
25
+ errors = Braintree::ValidationErrorCollection.new(hash)
26
+ errors.for(:nested).on(:number)[0].code.should == 2
27
+ errors.for(:nested).on(:number)[0].message.should == "badder juju"
28
+ errors.for(:nested).on(:number)[0].attribute.should == "number"
29
+ end
28
30
  end
29
- end
30
31
 
31
- describe "inspect" do
32
- it "shows the errors at the current level" do
33
- errors = Braintree::ValidationErrorCollection.new(:errors => [
34
- {:attribute => "name", :code => "code1", :message => "message1"},
35
- {:attribute => "name", :code => "code2", :message => "message2"}
36
- ])
37
- errors.inspect.should == "#<Braintree::ValidationErrorCollection errors:[(code1) message1, (code2) message2]>"
32
+ describe "inspect" do
33
+ it "shows the errors at the current level" do
34
+ errors = Braintree::ValidationErrorCollection.new(:errors => [
35
+ {:attribute => "name", :code => "code1", :message => "message1"},
36
+ {:attribute => "name", :code => "code2", :message => "message2"}
37
+ ])
38
+ errors.inspect.should == "#<Braintree::ValidationErrorCollection errors:[(code1) message1, (code2) message2]>"
39
+ end
40
+
41
+ it "shows errors 1 level deep" do
42
+ errors = Braintree::ValidationErrorCollection.new(
43
+ :errors => [
44
+ {:attribute => "name", :code => "code1", :message => "message1"},
45
+ ],
46
+ :level1 => {
47
+ :errors => [{:attribute => "name", :code => "code2", :message => "message2"}]
48
+ }
49
+ )
50
+ errors.inspect.should == "#<Braintree::ValidationErrorCollection errors:[(code1) message1], level1:[(code2) message2]>"
51
+ end
52
+
53
+ it "shows errors 2 levels deep" do
54
+ errors = Braintree::ValidationErrorCollection.new(
55
+ :errors => [
56
+ {:attribute => "name", :code => "code1", :message => "message1"},
57
+ ],
58
+ :level1 => {
59
+ :errors => [{:attribute => "name", :code => "code2", :message => "message2"}],
60
+ :level2 => {
61
+ :errors => [{:attribute => "name", :code => "code3", :message => "message3"}],
62
+ }
63
+ }
64
+ )
65
+ errors.inspect.should == "#<Braintree::ValidationErrorCollection errors:[(code1) message1], level1:[(code2) message2], level1/level2:[(code3) message3]>"
66
+ end
38
67
  end
39
68
 
40
- it "shows errors 1 level deep" do
41
- errors = Braintree::ValidationErrorCollection.new(
42
- :errors => [
43
- {:attribute => "name", :code => "code1", :message => "message1"},
44
- ],
45
- :level1 => {
46
- :errors => [{:attribute => "name", :code => "code2", :message => "message2"}]
47
- }
48
- )
49
- errors.inspect.should == "#<Braintree::ValidationErrorCollection errors:[(code1) message1], level1:[(code2) message2]>"
69
+ describe "on" do
70
+ it "returns an array of errors on the given attribute" do
71
+ errors = Braintree::ValidationErrorCollection.new(:errors => [
72
+ {:attribute => "name", :code => 1, :message => "is too long"},
73
+ {:attribute => "name", :code => 2, :message => "contains invalid chars"},
74
+ {:attribute => "not name", :code => 3, :message => "is invalid"}
75
+ ])
76
+ errors.on("name").size.should == 2
77
+ errors.on("name").map{ |e| e.code }.should == [1, 2]
78
+ end
79
+
80
+ it "has indifferent access" do
81
+ errors = Braintree::ValidationErrorCollection.new(:errors => [
82
+ { :attribute => "name", :code => 3, :message => "is too long" },
83
+ ])
84
+ errors.on(:name).size.should == 1
85
+ errors.on(:name)[0].code.should == 3
86
+
87
+ end
50
88
  end
51
89
 
52
- it "shows errors 2 levels deep" do
53
- errors = Braintree::ValidationErrorCollection.new(
54
- :errors => [
55
- {:attribute => "name", :code => "code1", :message => "message1"},
56
- ],
57
- :level1 => {
58
- :errors => [{:attribute => "name", :code => "code2", :message => "message2"}],
59
- :level2 => {
60
- :errors => [{:attribute => "name", :code => "code3", :message => "message3"}],
90
+ describe "deep_size" do
91
+ it "returns the size for a non-nested collection" do
92
+ errors = Braintree::ValidationErrorCollection.new(:errors => [
93
+ {:attribute => "one", :code => 1, :message => "is too long"},
94
+ {:attribute => "two", :code => 2, :message => "contains invalid chars"},
95
+ {:attribute => "thr", :code => 3, :message => "is invalid"}
96
+ ])
97
+ errors.deep_size.should == 3
98
+ end
99
+
100
+ it "returns the size of nested errors as well" do
101
+ errors = Braintree::ValidationErrorCollection.new(
102
+ :errors => [{ :attribute => "some model attribute", :code => 1, :message => "bad juju" }],
103
+ :nested => {
104
+ :errors => [{ :attribute => "number", :code => 2, :message => "badder juju"}]
61
105
  }
62
- }
63
- )
64
- errors.inspect.should == "#<Braintree::ValidationErrorCollection errors:[(code1) message1], level1:[(code2) message2], level1/level2:[(code3) message3]>"
106
+ )
107
+ errors.deep_size.should == 2
108
+ end
109
+
110
+ it "returns the size of multiple nestings of errors" do
111
+ errors = Braintree::ValidationErrorCollection.new(
112
+ :errors => [
113
+ { :attribute => "one", :code => 1, :message => "bad juju" },
114
+ { :attribute => "two", :code => 1, :message => "bad juju" }],
115
+ :nested => {
116
+ :errors => [{ :attribute => "three", :code => 2, :message => "badder juju"}],
117
+ :nested_again => {
118
+ :errors => [{ :attribute => "four", :code => 2, :message => "badder juju"}]
119
+ }
120
+ },
121
+ :same_level => {
122
+ :errors => [{ :attribute => "five", :code => 2, :message => "badder juju"}],
123
+ }
124
+ )
125
+ errors.deep_size.should == 5
126
+ end
65
127
  end
66
- end
67
128
 
68
- describe "on" do
69
- it "returns an array of errors on the given attribute" do
70
- errors = Braintree::ValidationErrorCollection.new(:errors => [
71
- {:attribute => "name", :code => 1, :message => "is too long"},
72
- {:attribute => "name", :code => 2, :message => "contains invalid chars"},
73
- {:attribute => "not name", :code => 3, :message => "is invalid"}
74
- ])
75
- errors.on("name").size.should == 2
76
- errors.on("name").map{ |e| e.code }.should == [1, 2]
129
+ describe "deep_errors" do
130
+ it "returns errors from all levels" do
131
+ errors = Braintree::ValidationErrorCollection.new(
132
+ :errors => [
133
+ { :attribute => "one", :code => 1, :message => "bad juju" },
134
+ { :attribute => "two", :code => 2, :message => "bad juju" }],
135
+ :nested => {
136
+ :errors => [{ :attribute => "three", :code => 3, :message => "badder juju"}],
137
+ :nested_again => {
138
+ :errors => [{ :attribute => "four", :code => 4, :message => "badder juju"}]
139
+ }
140
+ },
141
+ :same_level => {
142
+ :errors => [{ :attribute => "five", :code => 5, :message => "badder juju"}],
143
+ }
144
+ )
145
+ errors.deep_errors.map { |e| e.code }.sort.should == [1, 2, 3, 4, 5]
146
+ end
77
147
  end
78
148
 
79
- it "has indifferent access" do
80
- errors = Braintree::ValidationErrorCollection.new(:errors => [
81
- { :attribute => "name", :code => 3, :message => "is too long" },
82
- ])
83
- errors.on(:name).size.should == 1
84
- errors.on(:name)[0].code.should == 3
149
+ describe "shallow_errors" do
150
+ it "returns errors on one level" do
151
+ errors = Braintree::ValidationErrorCollection.new(
152
+ :errors => [
153
+ { :attribute => "one", :code => 1, :message => "bad juju" },
154
+ { :attribute => "two", :code => 2, :message => "bad juju" }],
155
+ :nested => {
156
+ :errors => [{ :attribute => "three", :code => 3, :message => "badder juju"}],
157
+ :nested_again => {
158
+ :errors => [{ :attribute => "four", :code => 4, :message => "badder juju"}]
159
+ }
160
+ }
161
+ )
162
+ errors.shallow_errors.map {|e| e.code}.should == [1, 2]
163
+ errors.for(:nested).shallow_errors.map {|e| e.code}.should == [3]
164
+ end
85
165
 
166
+ it "returns an clone of the real array" do
167
+ errors = Braintree::ValidationErrorCollection.new(
168
+ :errors => [
169
+ { :attribute => "one", :code => 1, :message => "bad juju" },
170
+ { :attribute => "two", :code => 2, :message => "bad juju" }]
171
+ )
172
+ errors.shallow_errors.pop
173
+ errors.shallow_errors.map {|e| e.code}.should == [1, 2]
174
+ end
86
175
  end
87
176
  end
88
177
 
89
- describe "deep_size" do
90
- it "returns the size for a non-nested collection" do
91
- errors = Braintree::ValidationErrorCollection.new(:errors => [
92
- {:attribute => "one", :code => 1, :message => "is too long"},
93
- {:attribute => "two", :code => 2, :message => "contains invalid chars"},
94
- {:attribute => "thr", :code => 3, :message => "is invalid"}
95
- ])
96
- errors.deep_size.should == 3
178
+ context "graphql response" do
179
+ describe "initialize" do
180
+ it "builds an error object given an array of hashes" do
181
+ hash = {:errors => [{
182
+ :message => "bad juju",
183
+ :untracked_param => "don't look",
184
+ :path=>["one", "two"],
185
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"1"}
186
+ }]}
187
+ collection = Braintree::ValidationErrorCollection.new(hash)
188
+ error = collection[0]
189
+ error.attribute.should == "two"
190
+ error.code.should == 1
191
+ error.message.should == "bad juju"
192
+ !error.respond_to? :untracked_param
193
+ end
97
194
  end
98
195
 
99
- it "returns the size of nested errors as well" do
100
- errors = Braintree::ValidationErrorCollection.new(
101
- :errors => [{ :attribute => "some model attribute", :code => 1, :message => "bad juju" }],
102
- :nested => {
103
- :errors => [{ :attribute => "number", :code => 2, :message => "badder juju"}]
196
+ describe "for" do
197
+ it "provides access to nested errors" do
198
+ hash = {
199
+ :errors => [{
200
+ :message => "bad juju",
201
+ :path=>["one", "two"],
202
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"1"}
203
+ }],
204
+ :nested => {
205
+ :errors => [{
206
+ :message => "badder juju",
207
+ :path=>["nested_attribute"],
208
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"2"}
209
+ }]
210
+ }
104
211
  }
105
- )
106
- errors.deep_size.should == 2
212
+ errors = Braintree::ValidationErrorCollection.new(hash)
213
+ errors.for(:nested).on(:nested_attribute)[0].code.should == 2
214
+ errors.for(:nested).on(:nested_attribute)[0].message.should == "badder juju"
215
+ errors.for(:nested).on(:nested_attribute)[0].attribute.should == "nested_attribute"
216
+ end
107
217
  end
108
218
 
109
- it "returns the size of multiple nestings of errors" do
110
- errors = Braintree::ValidationErrorCollection.new(
111
- :errors => [
112
- { :attribute => "one", :code => 1, :message => "bad juju" },
113
- { :attribute => "two", :code => 1, :message => "bad juju" }],
114
- :nested => {
115
- :errors => [{ :attribute => "three", :code => 2, :message => "badder juju"}],
116
- :nested_again => {
117
- :errors => [{ :attribute => "four", :code => 2, :message => "badder juju"}]
219
+ describe "deep_size" do
220
+ it "returns the size for a non-nested collection" do
221
+ hash = {
222
+ :errors => [{
223
+ :message => "bad juju",
224
+ :path=>["one", "two"],
225
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"1"}
226
+ },{
227
+ :message => "bad juju 2",
228
+ :path=>["three", "four"],
229
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"2"}
230
+ },{
231
+ :message => "bad juju 3",
232
+ :path=>["five", "six"],
233
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"2"}
234
+ }],
235
+ }
236
+ errors = Braintree::ValidationErrorCollection.new(hash)
237
+ errors.deep_size.should == 3
238
+ end
239
+
240
+ it "returns the size of nested errors as well" do
241
+ hash = {
242
+ :errors => [{
243
+ :message => "bad juju",
244
+ :path=>["one", "two"],
245
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"1"}
246
+ }],
247
+ :nested => {
248
+ :errors => [{
249
+ :message => "badder juju",
250
+ :path=>["nested_attribute"],
251
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"2"}
252
+ }]
118
253
  }
119
- },
120
- :same_level => {
121
- :errors => [{ :attribute => "five", :code => 2, :message => "badder juju"}],
122
254
  }
123
- )
124
- errors.deep_size.should == 5
125
- end
126
- end
255
+ errors = Braintree::ValidationErrorCollection.new(hash)
256
+ errors.deep_size.should == 2
257
+ end
127
258
 
128
- describe "deep_errors" do
129
- it "returns errors from all levels" do
130
- errors = Braintree::ValidationErrorCollection.new(
131
- :errors => [
132
- { :attribute => "one", :code => 1, :message => "bad juju" },
133
- { :attribute => "two", :code => 2, :message => "bad juju" }],
134
- :nested => {
135
- :errors => [{ :attribute => "three", :code => 3, :message => "badder juju"}],
259
+ it "returns the size of multiple nestings of errors" do
260
+ hash = {
261
+ :errors => [{
262
+ :message => "bad juju",
263
+ :path=>["attribute1"],
264
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"1"}
265
+ }],
266
+ :nested => {
267
+ :errors => [{
268
+ :message => "bad juju",
269
+ :path=>["attribute2"],
270
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"2"}
271
+ },{
272
+ :message => "bad juju",
273
+ :path=>["attribute3"],
274
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"3"}
275
+ }],
276
+ :deeply_nested => {
277
+ :errors => [{
278
+ :message => "bad juju",
279
+ :path=>["attribute4"],
280
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"4"}
281
+ }]
282
+ }
283
+ },
136
284
  :nested_again => {
137
- :errors => [{ :attribute => "four", :code => 4, :message => "badder juju"}]
285
+ :errors => [{
286
+ :message => "bad juju",
287
+ :path=>["attribute5"],
288
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"5"}
289
+ }]
138
290
  }
139
- },
140
- :same_level => {
141
- :errors => [{ :attribute => "five", :code => 5, :message => "badder juju"}],
142
291
  }
143
- )
144
- errors.deep_errors.map { |e| e.code }.sort.should == [1, 2, 3, 4, 5]
292
+ errors = Braintree::ValidationErrorCollection.new(hash)
293
+ errors.deep_size.should == 5
294
+ end
145
295
  end
146
- end
147
296
 
148
- describe "shallow_errors" do
149
- it "returns errors on one level" do
150
- errors = Braintree::ValidationErrorCollection.new(
151
- :errors => [
152
- { :attribute => "one", :code => 1, :message => "bad juju" },
153
- { :attribute => "two", :code => 2, :message => "bad juju" }],
154
- :nested => {
155
- :errors => [{ :attribute => "three", :code => 3, :message => "badder juju"}],
297
+ describe "deep_errors" do
298
+ it "returns errors from all levels" do
299
+ hash = {
300
+ :errors => [{
301
+ :message => "bad juju",
302
+ :path=>["attribute1"],
303
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"1"}
304
+ }],
305
+ :nested => {
306
+ :errors => [{
307
+ :message => "bad juju",
308
+ :path=>["attribute2"],
309
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"2"}
310
+ },{
311
+ :message => "bad juju",
312
+ :path=>["attribute3"],
313
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"3"}
314
+ }],
315
+ :deeply_nested => {
316
+ :errors => [{
317
+ :message => "bad juju",
318
+ :path=>["attribute4"],
319
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"4"}
320
+ }]
321
+ }
322
+ },
156
323
  :nested_again => {
157
- :errors => [{ :attribute => "four", :code => 4, :message => "badder juju"}]
324
+ :errors => [{
325
+ :message => "bad juju",
326
+ :path=>["attribute5"],
327
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"5"}
328
+ }]
158
329
  }
159
330
  }
160
- )
161
- errors.shallow_errors.map {|e| e.code}.should == [1, 2]
162
- errors.for(:nested).shallow_errors.map {|e| e.code}.should == [3]
331
+ errors = Braintree::ValidationErrorCollection.new(hash)
332
+ errors.deep_errors.map { |e| e.code }.sort.should == [1, 2, 3, 4, 5]
333
+ end
163
334
  end
164
335
 
165
- it "returns an clone of the real array" do
166
- errors = Braintree::ValidationErrorCollection.new(
167
- :errors => [
168
- { :attribute => "one", :code => 1, :message => "bad juju" },
169
- { :attribute => "two", :code => 2, :message => "bad juju" }]
170
- )
171
- errors.shallow_errors.pop
172
- errors.shallow_errors.map {|e| e.code}.should == [1, 2]
336
+ describe "shallow_errors" do
337
+ it "returns errors on one level" do
338
+ hash = {
339
+ :errors => [{
340
+ :message => "bad juju",
341
+ :path=>["attribute1"],
342
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"1"}
343
+ }],
344
+ :nested => {
345
+ :errors => [{
346
+ :message => "bad juju",
347
+ :path=>["attribute2"],
348
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"2"}
349
+ },{
350
+ :message => "bad juju",
351
+ :path=>["attribute3"],
352
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"3"}
353
+ }],
354
+ :deeply_nested => {
355
+ :errors => [{
356
+ :message => "bad juju",
357
+ :path=>["attribute4"],
358
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"4"}
359
+ }]
360
+ }
361
+ },
362
+ :nested_again => {
363
+ :errors => [{
364
+ :message => "bad juju",
365
+ :path=>["attribute5"],
366
+ :extensions=> {:errorClass=>"VALIDATION", :legacyCode=>"5"}
367
+ }]
368
+ }
369
+ }
370
+ errors = Braintree::ValidationErrorCollection.new(hash)
371
+ errors.shallow_errors.map {|e| e.code}.should == [1]
372
+ errors.for(:nested).shallow_errors.map {|e| e.code}.should == [2,3]
373
+ errors.for(:nested).for(:deeply_nested).shallow_errors.map {|e| e.code}.should == [4]
374
+ errors.for(:nested_again).shallow_errors.map {|e| e.code}.should == [5]
375
+ end
173
376
  end
174
377
  end
175
378
  end
@@ -392,6 +392,21 @@ describe Braintree::WebhookNotification do
392
392
  notification.subscription.transactions.first.status.should == Braintree::Transaction::Status::SubmittedForSettlement
393
393
  notification.subscription.transactions.first.amount.should == BigDecimal("49.99")
394
394
  end
395
+
396
+ it "builds a sample notification for a subscription charged unsuccessfully webhook" do
397
+ sample_notification = Braintree::WebhookTesting.sample_notification(
398
+ Braintree::WebhookNotification::Kind::SubscriptionChargedUnsuccessfully,
399
+ "my_id"
400
+ )
401
+
402
+ notification = Braintree::WebhookNotification.parse(sample_notification[:bt_signature], sample_notification[:bt_payload])
403
+
404
+ notification.kind.should == Braintree::WebhookNotification::Kind::SubscriptionChargedUnsuccessfully
405
+ notification.subscription.id.should == "my_id"
406
+ notification.subscription.transactions.size.should == 1
407
+ notification.subscription.transactions.first.status.should == Braintree::Transaction::Status::Failed
408
+ notification.subscription.transactions.first.amount.should == BigDecimal("49.99")
409
+ end
395
410
  end
396
411
 
397
412
  it "includes a valid signature" do
@@ -439,6 +454,22 @@ describe Braintree::WebhookNotification do
439
454
  end
440
455
  end
441
456
 
457
+ context "local_payment_completed" do
458
+ it "builds a sample notification for a local_payment webhook" do
459
+ sample_notification = Braintree::WebhookTesting.sample_notification(
460
+ Braintree::WebhookNotification::Kind::LocalPaymentCompleted,
461
+ "my_id"
462
+ )
463
+
464
+ notification = Braintree::WebhookNotification.parse(sample_notification[:bt_signature], sample_notification[:bt_payload])
465
+ notification.kind.should == Braintree::WebhookNotification::Kind::LocalPaymentCompleted
466
+
467
+ local_payment_completed = notification.local_payment_completed
468
+ local_payment_completed.payment_id.should == 'PAY-XYZ123'
469
+ local_payment_completed.payer_id.should == 'ABCPAYER'
470
+ end
471
+ end
472
+
442
473
  describe "parse" do
443
474
  it "raises InvalidSignature error when the signature is nil" do
444
475
  expect do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: braintree
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.90.0
4
+ version: 2.91.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Braintree
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-25 00:00:00.000000000 Z
11
+ date: 2018-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: builder
@@ -89,9 +89,11 @@ files:
89
89
  - lib/braintree/facilitator_details.rb
90
90
  - lib/braintree/gateway.rb
91
91
  - lib/braintree/granted_payment_instrument_update.rb
92
+ - lib/braintree/graphql_client.rb
92
93
  - lib/braintree/http.rb
93
94
  - lib/braintree/ideal_payment.rb
94
95
  - lib/braintree/ideal_payment_gateway.rb
96
+ - lib/braintree/local_payment_completed.rb
95
97
  - lib/braintree/masterpass_card.rb
96
98
  - lib/braintree/merchant.rb
97
99
  - lib/braintree/merchant_account.rb
@@ -205,6 +207,7 @@ files:
205
207
  - spec/integration/braintree/dispute_spec.rb
206
208
  - spec/integration/braintree/document_upload_spec.rb
207
209
  - spec/integration/braintree/error_codes_spec.rb
210
+ - spec/integration/braintree/graphql_client_spec.rb
208
211
  - spec/integration/braintree/http_spec.rb
209
212
  - spec/integration/braintree/ideal_payment_spec.rb
210
213
  - spec/integration/braintree/masterpass_card_spec.rb
@@ -256,6 +259,7 @@ files:
256
259
  - spec/unit/braintree/error_result_spec.rb
257
260
  - spec/unit/braintree/errors_spec.rb
258
261
  - spec/unit/braintree/http_spec.rb
262
+ - spec/unit/braintree/local_payment_completed_spec.rb
259
263
  - spec/unit/braintree/merchant_account_spec.rb
260
264
  - spec/unit/braintree/modification_spec.rb
261
265
  - spec/unit/braintree/payment_method_spec.rb
@@ -291,7 +295,10 @@ files:
291
295
  homepage: https://www.braintreepayments.com/
292
296
  licenses:
293
297
  - MIT
294
- metadata: {}
298
+ metadata:
299
+ bug_tracker_uri: https://github.com/braintree/braintree_ruby/issues
300
+ changelog_uri: https://github.com/braintree/braintree_ruby/blob/master/CHANGELOG.md
301
+ source_code_uri: https://github.com/braintree/braintree_ruby
295
302
  post_install_message:
296
303
  rdoc_options: []
297
304
  require_paths: