gocardless_pro 2.24.0 → 2.29.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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +23 -4
  3. data/lib/gocardless_pro/api_service.rb +4 -0
  4. data/lib/gocardless_pro/client.rb +46 -1
  5. data/lib/gocardless_pro/error/authentication_error.rb +4 -0
  6. data/lib/gocardless_pro/error/permission_error.rb +4 -0
  7. data/lib/gocardless_pro/error/rate_limit_error.rb +4 -0
  8. data/lib/gocardless_pro/middlewares/raise_gocardless_errors.rb +12 -1
  9. data/lib/gocardless_pro/resources/bank_authorisation.rb +81 -0
  10. data/lib/gocardless_pro/resources/billing_request.rb +108 -0
  11. data/lib/gocardless_pro/resources/billing_request_flow.rb +72 -0
  12. data/lib/gocardless_pro/resources/billing_request_template.rb +68 -0
  13. data/lib/gocardless_pro/resources/block.rb +66 -0
  14. data/lib/gocardless_pro/resources/creditor.rb +2 -3
  15. data/lib/gocardless_pro/resources/event.rb +20 -0
  16. data/lib/gocardless_pro/resources/institution.rb +47 -0
  17. data/lib/gocardless_pro/resources/payer_authorisation.rb +131 -0
  18. data/lib/gocardless_pro/resources/payout_item.rb +4 -0
  19. data/lib/gocardless_pro/resources/redirect_flow.rb +2 -0
  20. data/lib/gocardless_pro/resources/scenario_simulator.rb +42 -0
  21. data/lib/gocardless_pro/resources/webhook.rb +62 -0
  22. data/lib/gocardless_pro/services/bank_authorisations_service.rb +80 -0
  23. data/lib/gocardless_pro/services/billing_request_flows_service.rb +70 -0
  24. data/lib/gocardless_pro/services/billing_request_templates_service.rb +131 -0
  25. data/lib/gocardless_pro/services/billing_requests_service.rb +352 -0
  26. data/lib/gocardless_pro/services/blocks_service.rb +223 -0
  27. data/lib/gocardless_pro/services/creditor_bank_accounts_service.rb +1 -5
  28. data/lib/gocardless_pro/services/creditors_service.rb +1 -3
  29. data/lib/gocardless_pro/services/currency_exchange_rates_service.rb +1 -1
  30. data/lib/gocardless_pro/services/customer_bank_accounts_service.rb +1 -5
  31. data/lib/gocardless_pro/services/customers_service.rb +1 -3
  32. data/lib/gocardless_pro/services/events_service.rb +1 -1
  33. data/lib/gocardless_pro/services/instalment_schedules_service.rb +1 -7
  34. data/lib/gocardless_pro/services/institutions_service.rb +56 -0
  35. data/lib/gocardless_pro/services/mandate_import_entries_service.rb +1 -1
  36. data/lib/gocardless_pro/services/mandate_imports_service.rb +0 -6
  37. data/lib/gocardless_pro/services/mandates_service.rb +1 -7
  38. data/lib/gocardless_pro/services/payer_authorisations_service.rb +202 -0
  39. data/lib/gocardless_pro/services/payments_service.rb +1 -7
  40. data/lib/gocardless_pro/services/payout_items_service.rb +1 -1
  41. data/lib/gocardless_pro/services/payouts_service.rb +1 -1
  42. data/lib/gocardless_pro/services/redirect_flows_service.rb +0 -4
  43. data/lib/gocardless_pro/services/refunds_service.rb +1 -3
  44. data/lib/gocardless_pro/services/scenario_simulators_service.rb +170 -0
  45. data/lib/gocardless_pro/services/subscriptions_service.rb +10 -13
  46. data/lib/gocardless_pro/services/tax_rates_service.rb +1 -1
  47. data/lib/gocardless_pro/services/webhooks_service.rb +111 -0
  48. data/lib/gocardless_pro/version.rb +1 -1
  49. data/lib/gocardless_pro.rb +30 -0
  50. data/spec/api_service_spec.rb +12 -1
  51. data/spec/middlewares/raise_gocardless_errors_spec.rb +30 -0
  52. data/spec/resources/bank_authorisation_spec.rb +259 -0
  53. data/spec/resources/billing_request_flow_spec.rb +219 -0
  54. data/spec/resources/billing_request_spec.rb +782 -0
  55. data/spec/resources/billing_request_template_spec.rb +502 -0
  56. data/spec/resources/block_spec.rb +560 -0
  57. data/spec/resources/institution_spec.rb +108 -0
  58. data/spec/resources/payer_authorisation_spec.rb +418 -0
  59. data/spec/resources/redirect_flow_spec.rb +9 -0
  60. data/spec/resources/scenario_simulator_spec.rb +63 -0
  61. data/spec/resources/webhook_spec.rb +323 -0
  62. data/spec/services/bank_authorisations_service_spec.rb +353 -0
  63. data/spec/services/billing_request_flows_service_spec.rb +253 -0
  64. data/spec/services/billing_request_templates_service_spec.rb +789 -0
  65. data/spec/services/billing_requests_service_spec.rb +1082 -0
  66. data/spec/services/blocks_service_spec.rb +823 -0
  67. data/spec/services/creditor_bank_accounts_service_spec.rb +0 -13
  68. data/spec/services/creditors_service_spec.rb +0 -13
  69. data/spec/services/customer_bank_accounts_service_spec.rb +0 -13
  70. data/spec/services/customers_service_spec.rb +0 -13
  71. data/spec/services/instalment_schedules_service_spec.rb +0 -26
  72. data/spec/services/institutions_service_spec.rb +232 -0
  73. data/spec/services/mandate_imports_service_spec.rb +0 -13
  74. data/spec/services/mandates_service_spec.rb +0 -13
  75. data/spec/services/payer_authorisations_service_spec.rb +559 -0
  76. data/spec/services/payments_service_spec.rb +0 -13
  77. data/spec/services/redirect_flows_service_spec.rb +9 -13
  78. data/spec/services/refunds_service_spec.rb +0 -13
  79. data/spec/services/scenario_simulators_service_spec.rb +74 -0
  80. data/spec/services/subscriptions_service_spec.rb +0 -13
  81. data/spec/services/webhooks_service_spec.rb +545 -0
  82. metadata +64 -7
@@ -0,0 +1,560 @@
1
+ require 'spec_helper'
2
+
3
+ describe GoCardlessPro::Resources::Block do
4
+ let(:client) do
5
+ GoCardlessPro::Client.new(
6
+ access_token: 'SECRET_TOKEN'
7
+ )
8
+ end
9
+
10
+ let(:response_headers) { { 'Content-Type' => 'application/json' } }
11
+
12
+ describe '#create' do
13
+ subject(:post_create_response) { client.blocks.create(params: new_resource) }
14
+ context 'with a valid request' do
15
+ let(:new_resource) do
16
+ {
17
+
18
+ 'active' => 'active-input',
19
+ 'block_type' => 'block_type-input',
20
+ 'created_at' => 'created_at-input',
21
+ 'id' => 'id-input',
22
+ 'reason_description' => 'reason_description-input',
23
+ 'reason_type' => 'reason_type-input',
24
+ 'resource_reference' => 'resource_reference-input',
25
+ 'updated_at' => 'updated_at-input',
26
+ }
27
+ end
28
+
29
+ before do
30
+ stub_request(:post, %r{.*api.gocardless.com/blocks}).
31
+ with(
32
+ body: {
33
+ 'blocks' => {
34
+
35
+ 'active' => 'active-input',
36
+ 'block_type' => 'block_type-input',
37
+ 'created_at' => 'created_at-input',
38
+ 'id' => 'id-input',
39
+ 'reason_description' => 'reason_description-input',
40
+ 'reason_type' => 'reason_type-input',
41
+ 'resource_reference' => 'resource_reference-input',
42
+ 'updated_at' => 'updated_at-input',
43
+ },
44
+ }
45
+ ).
46
+ to_return(
47
+ body: {
48
+ 'blocks' =>
49
+
50
+ {
51
+
52
+ 'active' => 'active-input',
53
+ 'block_type' => 'block_type-input',
54
+ 'created_at' => 'created_at-input',
55
+ 'id' => 'id-input',
56
+ 'reason_description' => 'reason_description-input',
57
+ 'reason_type' => 'reason_type-input',
58
+ 'resource_reference' => 'resource_reference-input',
59
+ 'updated_at' => 'updated_at-input',
60
+ },
61
+
62
+ }.to_json,
63
+ headers: response_headers
64
+ )
65
+ end
66
+
67
+ it 'creates and returns the resource' do
68
+ expect(post_create_response).to be_a(GoCardlessPro::Resources::Block)
69
+ end
70
+ end
71
+
72
+ context 'with a request that returns a validation error' do
73
+ let(:new_resource) { {} }
74
+
75
+ before do
76
+ stub_request(:post, %r{.*api.gocardless.com/blocks}).to_return(
77
+ body: {
78
+ error: {
79
+ type: 'validation_failed',
80
+ code: 422,
81
+ errors: [
82
+ { message: 'test error message', field: 'test_field' },
83
+ ],
84
+ },
85
+ }.to_json,
86
+ headers: response_headers,
87
+ status: 422
88
+ )
89
+ end
90
+
91
+ it 'throws the correct error' do
92
+ expect { post_create_response }.to raise_error(GoCardlessPro::ValidationError)
93
+ end
94
+ end
95
+
96
+ context 'with a request that returns an idempotent creation conflict error' do
97
+ let(:id) { 'ID123' }
98
+
99
+ let(:new_resource) do
100
+ {
101
+
102
+ 'active' => 'active-input',
103
+ 'block_type' => 'block_type-input',
104
+ 'created_at' => 'created_at-input',
105
+ 'id' => 'id-input',
106
+ 'reason_description' => 'reason_description-input',
107
+ 'reason_type' => 'reason_type-input',
108
+ 'resource_reference' => 'resource_reference-input',
109
+ 'updated_at' => 'updated_at-input',
110
+ }
111
+ end
112
+
113
+ let!(:post_stub) do
114
+ stub_request(:post, %r{.*api.gocardless.com/blocks}).to_return(
115
+ body: {
116
+ error: {
117
+ type: 'invalid_state',
118
+ code: 409,
119
+ errors: [
120
+ {
121
+ message: 'A resource has already been created with this idempotency key',
122
+ reason: 'idempotent_creation_conflict',
123
+ links: {
124
+ conflicting_resource_id: id,
125
+ },
126
+ },
127
+ ],
128
+ },
129
+ }.to_json,
130
+ headers: response_headers,
131
+ status: 409
132
+ )
133
+ end
134
+
135
+ let!(:get_stub) do
136
+ stub_url = "/blocks/#{id}"
137
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).
138
+ to_return(
139
+ body: {
140
+ 'blocks' => {
141
+
142
+ 'active' => 'active-input',
143
+ 'block_type' => 'block_type-input',
144
+ 'created_at' => 'created_at-input',
145
+ 'id' => 'id-input',
146
+ 'reason_description' => 'reason_description-input',
147
+ 'reason_type' => 'reason_type-input',
148
+ 'resource_reference' => 'resource_reference-input',
149
+ 'updated_at' => 'updated_at-input',
150
+ },
151
+ }.to_json,
152
+ headers: response_headers
153
+ )
154
+ end
155
+
156
+ it 'fetches the already-created resource' do
157
+ post_create_response
158
+ expect(post_stub).to have_been_requested
159
+ expect(get_stub).to have_been_requested
160
+ end
161
+ end
162
+ end
163
+
164
+ describe '#get' do
165
+ let(:id) { 'ID123' }
166
+
167
+ subject(:get_response) { client.blocks.get(id) }
168
+
169
+ context 'passing in a custom header' do
170
+ let!(:stub) do
171
+ stub_url = '/blocks/:identity'.gsub(':identity', id)
172
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).
173
+ with(headers: { 'Foo' => 'Bar' }).
174
+ to_return(
175
+ body: {
176
+ 'blocks' => {
177
+
178
+ 'active' => 'active-input',
179
+ 'block_type' => 'block_type-input',
180
+ 'created_at' => 'created_at-input',
181
+ 'id' => 'id-input',
182
+ 'reason_description' => 'reason_description-input',
183
+ 'reason_type' => 'reason_type-input',
184
+ 'resource_reference' => 'resource_reference-input',
185
+ 'updated_at' => 'updated_at-input',
186
+ },
187
+ }.to_json,
188
+ headers: response_headers
189
+ )
190
+ end
191
+
192
+ subject(:get_response) do
193
+ client.blocks.get(id, headers: {
194
+ 'Foo' => 'Bar',
195
+ })
196
+ end
197
+
198
+ it 'includes the header' do
199
+ get_response
200
+ expect(stub).to have_been_requested
201
+ end
202
+ end
203
+
204
+ context 'when there is a block to return' do
205
+ before do
206
+ stub_url = '/blocks/:identity'.gsub(':identity', id)
207
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).to_return(
208
+ body: {
209
+ 'blocks' => {
210
+
211
+ 'active' => 'active-input',
212
+ 'block_type' => 'block_type-input',
213
+ 'created_at' => 'created_at-input',
214
+ 'id' => 'id-input',
215
+ 'reason_description' => 'reason_description-input',
216
+ 'reason_type' => 'reason_type-input',
217
+ 'resource_reference' => 'resource_reference-input',
218
+ 'updated_at' => 'updated_at-input',
219
+ },
220
+ }.to_json,
221
+ headers: response_headers
222
+ )
223
+ end
224
+
225
+ it 'wraps the response in a resource' do
226
+ expect(get_response).to be_a(GoCardlessPro::Resources::Block)
227
+ end
228
+ end
229
+
230
+ context 'when nothing is returned' do
231
+ before do
232
+ stub_url = '/blocks/:identity'.gsub(':identity', id)
233
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).to_return(
234
+ body: '',
235
+ headers: response_headers
236
+ )
237
+ end
238
+
239
+ it 'returns nil' do
240
+ expect(get_response).to be_nil
241
+ end
242
+ end
243
+
244
+ context "when an ID is specified which can't be included in a valid URI" do
245
+ let(:id) { '`' }
246
+
247
+ it "doesn't raise an error" do
248
+ expect { get_response }.to_not raise_error(/bad URI/)
249
+ end
250
+ end
251
+ end
252
+
253
+ describe '#list' do
254
+ describe 'with no filters' do
255
+ subject(:get_list_response) { client.blocks.list }
256
+
257
+ before do
258
+ stub_request(:get, %r{.*api.gocardless.com/blocks}).to_return(
259
+ body: {
260
+ 'blocks' => [{
261
+
262
+ 'active' => 'active-input',
263
+ 'block_type' => 'block_type-input',
264
+ 'created_at' => 'created_at-input',
265
+ 'id' => 'id-input',
266
+ 'reason_description' => 'reason_description-input',
267
+ 'reason_type' => 'reason_type-input',
268
+ 'resource_reference' => 'resource_reference-input',
269
+ 'updated_at' => 'updated_at-input',
270
+ }],
271
+ meta: {
272
+ cursors: {
273
+ before: nil,
274
+ after: 'ABC123',
275
+ },
276
+ },
277
+ }.to_json,
278
+ headers: response_headers
279
+ )
280
+ end
281
+
282
+ it 'wraps each item in the resource class' do
283
+ expect(get_list_response.records.map(&:class).uniq.first).to eq(GoCardlessPro::Resources::Block)
284
+
285
+ expect(get_list_response.records.first.active).to eq('active-input')
286
+
287
+ expect(get_list_response.records.first.block_type).to eq('block_type-input')
288
+
289
+ expect(get_list_response.records.first.created_at).to eq('created_at-input')
290
+
291
+ expect(get_list_response.records.first.id).to eq('id-input')
292
+
293
+ expect(get_list_response.records.first.reason_description).to eq('reason_description-input')
294
+
295
+ expect(get_list_response.records.first.reason_type).to eq('reason_type-input')
296
+
297
+ expect(get_list_response.records.first.resource_reference).to eq('resource_reference-input')
298
+
299
+ expect(get_list_response.records.first.updated_at).to eq('updated_at-input')
300
+ end
301
+
302
+ it 'exposes the cursors for before and after' do
303
+ expect(get_list_response.before).to eq(nil)
304
+ expect(get_list_response.after).to eq('ABC123')
305
+ end
306
+
307
+ specify { expect(get_list_response.api_response.headers).to eql('content-type' => 'application/json') }
308
+ end
309
+ end
310
+
311
+ describe '#all' do
312
+ let!(:first_response_stub) do
313
+ stub_request(:get, %r{.*api.gocardless.com/blocks$}).to_return(
314
+ body: {
315
+ 'blocks' => [{
316
+
317
+ 'active' => 'active-input',
318
+ 'block_type' => 'block_type-input',
319
+ 'created_at' => 'created_at-input',
320
+ 'id' => 'id-input',
321
+ 'reason_description' => 'reason_description-input',
322
+ 'reason_type' => 'reason_type-input',
323
+ 'resource_reference' => 'resource_reference-input',
324
+ 'updated_at' => 'updated_at-input',
325
+ }],
326
+ meta: {
327
+ cursors: { after: 'AB345' },
328
+ limit: 1,
329
+ },
330
+ }.to_json,
331
+ headers: response_headers
332
+ )
333
+ end
334
+
335
+ let!(:second_response_stub) do
336
+ stub_request(:get, %r{.*api.gocardless.com/blocks\?after=AB345}).to_return(
337
+ body: {
338
+ 'blocks' => [{
339
+
340
+ 'active' => 'active-input',
341
+ 'block_type' => 'block_type-input',
342
+ 'created_at' => 'created_at-input',
343
+ 'id' => 'id-input',
344
+ 'reason_description' => 'reason_description-input',
345
+ 'reason_type' => 'reason_type-input',
346
+ 'resource_reference' => 'resource_reference-input',
347
+ 'updated_at' => 'updated_at-input',
348
+ }],
349
+ meta: {
350
+ limit: 2,
351
+ cursors: {},
352
+ },
353
+ }.to_json,
354
+ headers: response_headers
355
+ )
356
+ end
357
+
358
+ it 'automatically makes the extra requests' do
359
+ expect(client.blocks.all.to_a.length).to eq(2)
360
+ expect(first_response_stub).to have_been_requested
361
+ expect(second_response_stub).to have_been_requested
362
+ end
363
+ end
364
+
365
+ describe '#disable' do
366
+ subject(:post_response) { client.blocks.disable(resource_id) }
367
+
368
+ let(:resource_id) { 'ABC123' }
369
+
370
+ let!(:stub) do
371
+ # /blocks/%v/actions/disable
372
+ stub_url = '/blocks/:identity/actions/disable'.gsub(':identity', resource_id)
373
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).to_return(
374
+ body: {
375
+ 'blocks' => {
376
+
377
+ 'active' => 'active-input',
378
+ 'block_type' => 'block_type-input',
379
+ 'created_at' => 'created_at-input',
380
+ 'id' => 'id-input',
381
+ 'reason_description' => 'reason_description-input',
382
+ 'reason_type' => 'reason_type-input',
383
+ 'resource_reference' => 'resource_reference-input',
384
+ 'updated_at' => 'updated_at-input',
385
+ },
386
+ }.to_json,
387
+ headers: response_headers
388
+ )
389
+ end
390
+
391
+ it 'wraps the response and calls the right endpoint' do
392
+ expect(post_response).to be_a(GoCardlessPro::Resources::Block)
393
+
394
+ expect(stub).to have_been_requested
395
+ end
396
+
397
+ context 'when the request needs a body and custom header' do
398
+ let(:body) { { foo: 'bar' } }
399
+ let(:headers) { { 'Foo' => 'Bar' } }
400
+ subject(:post_response) { client.blocks.disable(resource_id, body, headers) }
401
+
402
+ let(:resource_id) { 'ABC123' }
403
+
404
+ let!(:stub) do
405
+ # /blocks/%v/actions/disable
406
+ stub_url = '/blocks/:identity/actions/disable'.gsub(':identity', resource_id)
407
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).
408
+ with(
409
+ body: { foo: 'bar' },
410
+ headers: { 'Foo' => 'Bar' }
411
+ ).to_return(
412
+ body: {
413
+ 'blocks' => {
414
+
415
+ 'active' => 'active-input',
416
+ 'block_type' => 'block_type-input',
417
+ 'created_at' => 'created_at-input',
418
+ 'id' => 'id-input',
419
+ 'reason_description' => 'reason_description-input',
420
+ 'reason_type' => 'reason_type-input',
421
+ 'resource_reference' => 'resource_reference-input',
422
+ 'updated_at' => 'updated_at-input',
423
+ },
424
+ }.to_json,
425
+ headers: response_headers
426
+ )
427
+ end
428
+ end
429
+ end
430
+
431
+ describe '#enable' do
432
+ subject(:post_response) { client.blocks.enable(resource_id) }
433
+
434
+ let(:resource_id) { 'ABC123' }
435
+
436
+ let!(:stub) do
437
+ # /blocks/%v/actions/enable
438
+ stub_url = '/blocks/:identity/actions/enable'.gsub(':identity', resource_id)
439
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).to_return(
440
+ body: {
441
+ 'blocks' => {
442
+
443
+ 'active' => 'active-input',
444
+ 'block_type' => 'block_type-input',
445
+ 'created_at' => 'created_at-input',
446
+ 'id' => 'id-input',
447
+ 'reason_description' => 'reason_description-input',
448
+ 'reason_type' => 'reason_type-input',
449
+ 'resource_reference' => 'resource_reference-input',
450
+ 'updated_at' => 'updated_at-input',
451
+ },
452
+ }.to_json,
453
+ headers: response_headers
454
+ )
455
+ end
456
+
457
+ it 'wraps the response and calls the right endpoint' do
458
+ expect(post_response).to be_a(GoCardlessPro::Resources::Block)
459
+
460
+ expect(stub).to have_been_requested
461
+ end
462
+
463
+ context 'when the request needs a body and custom header' do
464
+ let(:body) { { foo: 'bar' } }
465
+ let(:headers) { { 'Foo' => 'Bar' } }
466
+ subject(:post_response) { client.blocks.enable(resource_id, body, headers) }
467
+
468
+ let(:resource_id) { 'ABC123' }
469
+
470
+ let!(:stub) do
471
+ # /blocks/%v/actions/enable
472
+ stub_url = '/blocks/:identity/actions/enable'.gsub(':identity', resource_id)
473
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).
474
+ with(
475
+ body: { foo: 'bar' },
476
+ headers: { 'Foo' => 'Bar' }
477
+ ).to_return(
478
+ body: {
479
+ 'blocks' => {
480
+
481
+ 'active' => 'active-input',
482
+ 'block_type' => 'block_type-input',
483
+ 'created_at' => 'created_at-input',
484
+ 'id' => 'id-input',
485
+ 'reason_description' => 'reason_description-input',
486
+ 'reason_type' => 'reason_type-input',
487
+ 'resource_reference' => 'resource_reference-input',
488
+ 'updated_at' => 'updated_at-input',
489
+ },
490
+ }.to_json,
491
+ headers: response_headers
492
+ )
493
+ end
494
+ end
495
+ end
496
+
497
+ describe '#block_by_ref' do
498
+ subject(:post_response) { client.blocks.block_by_ref }
499
+
500
+ let(:resource_id) { 'ABC123' }
501
+
502
+ let!(:stub) do
503
+ # /block_by_ref
504
+ stub_url = '/block_by_ref'.gsub(':identity', resource_id)
505
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).to_return(
506
+ body: {
507
+ 'blocks' => [{
508
+
509
+ 'active' => 'active-input',
510
+ 'block_type' => 'block_type-input',
511
+ 'created_at' => 'created_at-input',
512
+ 'id' => 'id-input',
513
+ 'reason_description' => 'reason_description-input',
514
+ 'reason_type' => 'reason_type-input',
515
+ 'resource_reference' => 'resource_reference-input',
516
+ 'updated_at' => 'updated_at-input',
517
+ }],
518
+ }.to_json,
519
+ headers: response_headers
520
+ )
521
+ end
522
+
523
+ it 'wraps the response and calls the right endpoint' do
524
+ expect(post_response.records.map(&:class).uniq.first).to eq(GoCardlessPro::Resources::Block)
525
+
526
+ expect(stub).to have_been_requested
527
+ end
528
+
529
+ context 'when the request needs a body and custom header' do
530
+ subject(:post_response) { client.blocks.block_by_ref(body, headers) }
531
+
532
+ let(:resource_id) { 'ABC123' }
533
+
534
+ let!(:stub) do
535
+ # /block_by_ref
536
+ stub_url = '/block_by_ref'.gsub(':identity', resource_id)
537
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).
538
+ with(
539
+ body: { foo: 'bar' },
540
+ headers: { 'Foo' => 'Bar' }
541
+ ).to_return(
542
+ body: {
543
+ 'blocks' => {
544
+
545
+ 'active' => 'active-input',
546
+ 'block_type' => 'block_type-input',
547
+ 'created_at' => 'created_at-input',
548
+ 'id' => 'id-input',
549
+ 'reason_description' => 'reason_description-input',
550
+ 'reason_type' => 'reason_type-input',
551
+ 'resource_reference' => 'resource_reference-input',
552
+ 'updated_at' => 'updated_at-input',
553
+ },
554
+ }.to_json,
555
+ headers: response_headers
556
+ )
557
+ end
558
+ end
559
+ end
560
+ end
@@ -0,0 +1,108 @@
1
+ require 'spec_helper'
2
+
3
+ describe GoCardlessPro::Resources::Institution do
4
+ let(:client) do
5
+ GoCardlessPro::Client.new(
6
+ access_token: 'SECRET_TOKEN'
7
+ )
8
+ end
9
+
10
+ let(:response_headers) { { 'Content-Type' => 'application/json' } }
11
+
12
+ describe '#list' do
13
+ describe 'with no filters' do
14
+ subject(:get_list_response) { client.institutions.list }
15
+
16
+ before do
17
+ stub_request(:get, %r{.*api.gocardless.com/institutions}).to_return(
18
+ body: {
19
+ 'institutions' => [{
20
+
21
+ 'country_code' => 'country_code-input',
22
+ 'icon_url' => 'icon_url-input',
23
+ 'id' => 'id-input',
24
+ 'logo_url' => 'logo_url-input',
25
+ 'name' => 'name-input',
26
+ }],
27
+ meta: {
28
+ cursors: {
29
+ before: nil,
30
+ after: 'ABC123',
31
+ },
32
+ },
33
+ }.to_json,
34
+ headers: response_headers
35
+ )
36
+ end
37
+
38
+ it 'wraps each item in the resource class' do
39
+ expect(get_list_response.records.map(&:class).uniq.first).to eq(GoCardlessPro::Resources::Institution)
40
+
41
+ expect(get_list_response.records.first.country_code).to eq('country_code-input')
42
+
43
+ expect(get_list_response.records.first.icon_url).to eq('icon_url-input')
44
+
45
+ expect(get_list_response.records.first.id).to eq('id-input')
46
+
47
+ expect(get_list_response.records.first.logo_url).to eq('logo_url-input')
48
+
49
+ expect(get_list_response.records.first.name).to eq('name-input')
50
+ end
51
+
52
+ it 'exposes the cursors for before and after' do
53
+ expect(get_list_response.before).to eq(nil)
54
+ expect(get_list_response.after).to eq('ABC123')
55
+ end
56
+
57
+ specify { expect(get_list_response.api_response.headers).to eql('content-type' => 'application/json') }
58
+ end
59
+ end
60
+
61
+ describe '#all' do
62
+ let!(:first_response_stub) do
63
+ stub_request(:get, %r{.*api.gocardless.com/institutions$}).to_return(
64
+ body: {
65
+ 'institutions' => [{
66
+
67
+ 'country_code' => 'country_code-input',
68
+ 'icon_url' => 'icon_url-input',
69
+ 'id' => 'id-input',
70
+ 'logo_url' => 'logo_url-input',
71
+ 'name' => 'name-input',
72
+ }],
73
+ meta: {
74
+ cursors: { after: 'AB345' },
75
+ limit: 1,
76
+ },
77
+ }.to_json,
78
+ headers: response_headers
79
+ )
80
+ end
81
+
82
+ let!(:second_response_stub) do
83
+ stub_request(:get, %r{.*api.gocardless.com/institutions\?after=AB345}).to_return(
84
+ body: {
85
+ 'institutions' => [{
86
+
87
+ 'country_code' => 'country_code-input',
88
+ 'icon_url' => 'icon_url-input',
89
+ 'id' => 'id-input',
90
+ 'logo_url' => 'logo_url-input',
91
+ 'name' => 'name-input',
92
+ }],
93
+ meta: {
94
+ limit: 2,
95
+ cursors: {},
96
+ },
97
+ }.to_json,
98
+ headers: response_headers
99
+ )
100
+ end
101
+
102
+ it 'automatically makes the extra requests' do
103
+ expect(client.institutions.all.to_a.length).to eq(2)
104
+ expect(first_response_stub).to have_been_requested
105
+ expect(second_response_stub).to have_been_requested
106
+ end
107
+ end
108
+ end