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,782 @@
1
+ require 'spec_helper'
2
+
3
+ describe GoCardlessPro::Resources::BillingRequest 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.billing_requests.list }
15
+
16
+ before do
17
+ stub_request(:get, %r{.*api.gocardless.com/billing_requests}).to_return(
18
+ body: {
19
+ 'billing_requests' => [{
20
+
21
+ 'actions' => 'actions-input',
22
+ 'created_at' => 'created_at-input',
23
+ 'id' => 'id-input',
24
+ 'links' => 'links-input',
25
+ 'mandate_request' => 'mandate_request-input',
26
+ 'metadata' => 'metadata-input',
27
+ 'payment_request' => 'payment_request-input',
28
+ 'resources' => 'resources-input',
29
+ 'status' => 'status-input',
30
+ }],
31
+ meta: {
32
+ cursors: {
33
+ before: nil,
34
+ after: 'ABC123',
35
+ },
36
+ },
37
+ }.to_json,
38
+ headers: response_headers
39
+ )
40
+ end
41
+
42
+ it 'wraps each item in the resource class' do
43
+ expect(get_list_response.records.map(&:class).uniq.first).to eq(GoCardlessPro::Resources::BillingRequest)
44
+
45
+ expect(get_list_response.records.first.actions).to eq('actions-input')
46
+
47
+ expect(get_list_response.records.first.created_at).to eq('created_at-input')
48
+
49
+ expect(get_list_response.records.first.id).to eq('id-input')
50
+
51
+ expect(get_list_response.records.first.mandate_request).to eq('mandate_request-input')
52
+
53
+ expect(get_list_response.records.first.metadata).to eq('metadata-input')
54
+
55
+ expect(get_list_response.records.first.payment_request).to eq('payment_request-input')
56
+
57
+ expect(get_list_response.records.first.resources).to eq('resources-input')
58
+
59
+ expect(get_list_response.records.first.status).to eq('status-input')
60
+ end
61
+
62
+ it 'exposes the cursors for before and after' do
63
+ expect(get_list_response.before).to eq(nil)
64
+ expect(get_list_response.after).to eq('ABC123')
65
+ end
66
+
67
+ specify { expect(get_list_response.api_response.headers).to eql('content-type' => 'application/json') }
68
+ end
69
+ end
70
+
71
+ describe '#all' do
72
+ let!(:first_response_stub) do
73
+ stub_request(:get, %r{.*api.gocardless.com/billing_requests$}).to_return(
74
+ body: {
75
+ 'billing_requests' => [{
76
+
77
+ 'actions' => 'actions-input',
78
+ 'created_at' => 'created_at-input',
79
+ 'id' => 'id-input',
80
+ 'links' => 'links-input',
81
+ 'mandate_request' => 'mandate_request-input',
82
+ 'metadata' => 'metadata-input',
83
+ 'payment_request' => 'payment_request-input',
84
+ 'resources' => 'resources-input',
85
+ 'status' => 'status-input',
86
+ }],
87
+ meta: {
88
+ cursors: { after: 'AB345' },
89
+ limit: 1,
90
+ },
91
+ }.to_json,
92
+ headers: response_headers
93
+ )
94
+ end
95
+
96
+ let!(:second_response_stub) do
97
+ stub_request(:get, %r{.*api.gocardless.com/billing_requests\?after=AB345}).to_return(
98
+ body: {
99
+ 'billing_requests' => [{
100
+
101
+ 'actions' => 'actions-input',
102
+ 'created_at' => 'created_at-input',
103
+ 'id' => 'id-input',
104
+ 'links' => 'links-input',
105
+ 'mandate_request' => 'mandate_request-input',
106
+ 'metadata' => 'metadata-input',
107
+ 'payment_request' => 'payment_request-input',
108
+ 'resources' => 'resources-input',
109
+ 'status' => 'status-input',
110
+ }],
111
+ meta: {
112
+ limit: 2,
113
+ cursors: {},
114
+ },
115
+ }.to_json,
116
+ headers: response_headers
117
+ )
118
+ end
119
+
120
+ it 'automatically makes the extra requests' do
121
+ expect(client.billing_requests.all.to_a.length).to eq(2)
122
+ expect(first_response_stub).to have_been_requested
123
+ expect(second_response_stub).to have_been_requested
124
+ end
125
+ end
126
+
127
+ describe '#create' do
128
+ subject(:post_create_response) { client.billing_requests.create(params: new_resource) }
129
+ context 'with a valid request' do
130
+ let(:new_resource) do
131
+ {
132
+
133
+ 'actions' => 'actions-input',
134
+ 'created_at' => 'created_at-input',
135
+ 'id' => 'id-input',
136
+ 'links' => 'links-input',
137
+ 'mandate_request' => 'mandate_request-input',
138
+ 'metadata' => 'metadata-input',
139
+ 'payment_request' => 'payment_request-input',
140
+ 'resources' => 'resources-input',
141
+ 'status' => 'status-input',
142
+ }
143
+ end
144
+
145
+ before do
146
+ stub_request(:post, %r{.*api.gocardless.com/billing_requests}).
147
+ with(
148
+ body: {
149
+ 'billing_requests' => {
150
+
151
+ 'actions' => 'actions-input',
152
+ 'created_at' => 'created_at-input',
153
+ 'id' => 'id-input',
154
+ 'links' => 'links-input',
155
+ 'mandate_request' => 'mandate_request-input',
156
+ 'metadata' => 'metadata-input',
157
+ 'payment_request' => 'payment_request-input',
158
+ 'resources' => 'resources-input',
159
+ 'status' => 'status-input',
160
+ },
161
+ }
162
+ ).
163
+ to_return(
164
+ body: {
165
+ 'billing_requests' =>
166
+
167
+ {
168
+
169
+ 'actions' => 'actions-input',
170
+ 'created_at' => 'created_at-input',
171
+ 'id' => 'id-input',
172
+ 'links' => 'links-input',
173
+ 'mandate_request' => 'mandate_request-input',
174
+ 'metadata' => 'metadata-input',
175
+ 'payment_request' => 'payment_request-input',
176
+ 'resources' => 'resources-input',
177
+ 'status' => 'status-input',
178
+ },
179
+
180
+ }.to_json,
181
+ headers: response_headers
182
+ )
183
+ end
184
+
185
+ it 'creates and returns the resource' do
186
+ expect(post_create_response).to be_a(GoCardlessPro::Resources::BillingRequest)
187
+ end
188
+ end
189
+
190
+ context 'with a request that returns a validation error' do
191
+ let(:new_resource) { {} }
192
+
193
+ before do
194
+ stub_request(:post, %r{.*api.gocardless.com/billing_requests}).to_return(
195
+ body: {
196
+ error: {
197
+ type: 'validation_failed',
198
+ code: 422,
199
+ errors: [
200
+ { message: 'test error message', field: 'test_field' },
201
+ ],
202
+ },
203
+ }.to_json,
204
+ headers: response_headers,
205
+ status: 422
206
+ )
207
+ end
208
+
209
+ it 'throws the correct error' do
210
+ expect { post_create_response }.to raise_error(GoCardlessPro::ValidationError)
211
+ end
212
+ end
213
+
214
+ context 'with a request that returns an idempotent creation conflict error' do
215
+ let(:id) { 'ID123' }
216
+
217
+ let(:new_resource) do
218
+ {
219
+
220
+ 'actions' => 'actions-input',
221
+ 'created_at' => 'created_at-input',
222
+ 'id' => 'id-input',
223
+ 'links' => 'links-input',
224
+ 'mandate_request' => 'mandate_request-input',
225
+ 'metadata' => 'metadata-input',
226
+ 'payment_request' => 'payment_request-input',
227
+ 'resources' => 'resources-input',
228
+ 'status' => 'status-input',
229
+ }
230
+ end
231
+
232
+ let!(:post_stub) do
233
+ stub_request(:post, %r{.*api.gocardless.com/billing_requests}).to_return(
234
+ body: {
235
+ error: {
236
+ type: 'invalid_state',
237
+ code: 409,
238
+ errors: [
239
+ {
240
+ message: 'A resource has already been created with this idempotency key',
241
+ reason: 'idempotent_creation_conflict',
242
+ links: {
243
+ conflicting_resource_id: id,
244
+ },
245
+ },
246
+ ],
247
+ },
248
+ }.to_json,
249
+ headers: response_headers,
250
+ status: 409
251
+ )
252
+ end
253
+
254
+ let!(:get_stub) do
255
+ stub_url = "/billing_requests/#{id}"
256
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).
257
+ to_return(
258
+ body: {
259
+ 'billing_requests' => {
260
+
261
+ 'actions' => 'actions-input',
262
+ 'created_at' => 'created_at-input',
263
+ 'id' => 'id-input',
264
+ 'links' => 'links-input',
265
+ 'mandate_request' => 'mandate_request-input',
266
+ 'metadata' => 'metadata-input',
267
+ 'payment_request' => 'payment_request-input',
268
+ 'resources' => 'resources-input',
269
+ 'status' => 'status-input',
270
+ },
271
+ }.to_json,
272
+ headers: response_headers
273
+ )
274
+ end
275
+
276
+ it 'fetches the already-created resource' do
277
+ post_create_response
278
+ expect(post_stub).to have_been_requested
279
+ expect(get_stub).to have_been_requested
280
+ end
281
+ end
282
+ end
283
+
284
+ describe '#get' do
285
+ let(:id) { 'ID123' }
286
+
287
+ subject(:get_response) { client.billing_requests.get(id) }
288
+
289
+ context 'passing in a custom header' do
290
+ let!(:stub) do
291
+ stub_url = '/billing_requests/:identity'.gsub(':identity', id)
292
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).
293
+ with(headers: { 'Foo' => 'Bar' }).
294
+ to_return(
295
+ body: {
296
+ 'billing_requests' => {
297
+
298
+ 'actions' => 'actions-input',
299
+ 'created_at' => 'created_at-input',
300
+ 'id' => 'id-input',
301
+ 'links' => 'links-input',
302
+ 'mandate_request' => 'mandate_request-input',
303
+ 'metadata' => 'metadata-input',
304
+ 'payment_request' => 'payment_request-input',
305
+ 'resources' => 'resources-input',
306
+ 'status' => 'status-input',
307
+ },
308
+ }.to_json,
309
+ headers: response_headers
310
+ )
311
+ end
312
+
313
+ subject(:get_response) do
314
+ client.billing_requests.get(id, headers: {
315
+ 'Foo' => 'Bar',
316
+ })
317
+ end
318
+
319
+ it 'includes the header' do
320
+ get_response
321
+ expect(stub).to have_been_requested
322
+ end
323
+ end
324
+
325
+ context 'when there is a billing_request to return' do
326
+ before do
327
+ stub_url = '/billing_requests/:identity'.gsub(':identity', id)
328
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).to_return(
329
+ body: {
330
+ 'billing_requests' => {
331
+
332
+ 'actions' => 'actions-input',
333
+ 'created_at' => 'created_at-input',
334
+ 'id' => 'id-input',
335
+ 'links' => 'links-input',
336
+ 'mandate_request' => 'mandate_request-input',
337
+ 'metadata' => 'metadata-input',
338
+ 'payment_request' => 'payment_request-input',
339
+ 'resources' => 'resources-input',
340
+ 'status' => 'status-input',
341
+ },
342
+ }.to_json,
343
+ headers: response_headers
344
+ )
345
+ end
346
+
347
+ it 'wraps the response in a resource' do
348
+ expect(get_response).to be_a(GoCardlessPro::Resources::BillingRequest)
349
+ end
350
+ end
351
+
352
+ context 'when nothing is returned' do
353
+ before do
354
+ stub_url = '/billing_requests/:identity'.gsub(':identity', id)
355
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).to_return(
356
+ body: '',
357
+ headers: response_headers
358
+ )
359
+ end
360
+
361
+ it 'returns nil' do
362
+ expect(get_response).to be_nil
363
+ end
364
+ end
365
+
366
+ context "when an ID is specified which can't be included in a valid URI" do
367
+ let(:id) { '`' }
368
+
369
+ it "doesn't raise an error" do
370
+ expect { get_response }.to_not raise_error(/bad URI/)
371
+ end
372
+ end
373
+ end
374
+
375
+ describe '#collect_customer_details' do
376
+ subject(:post_response) { client.billing_requests.collect_customer_details(resource_id) }
377
+
378
+ let(:resource_id) { 'ABC123' }
379
+
380
+ let!(:stub) do
381
+ # /billing_requests/%v/actions/collect_customer_details
382
+ stub_url = '/billing_requests/:identity/actions/collect_customer_details'.gsub(':identity', resource_id)
383
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).to_return(
384
+ body: {
385
+ 'billing_requests' => {
386
+
387
+ 'actions' => 'actions-input',
388
+ 'created_at' => 'created_at-input',
389
+ 'id' => 'id-input',
390
+ 'links' => 'links-input',
391
+ 'mandate_request' => 'mandate_request-input',
392
+ 'metadata' => 'metadata-input',
393
+ 'payment_request' => 'payment_request-input',
394
+ 'resources' => 'resources-input',
395
+ 'status' => 'status-input',
396
+ },
397
+ }.to_json,
398
+ headers: response_headers
399
+ )
400
+ end
401
+
402
+ it 'wraps the response and calls the right endpoint' do
403
+ expect(post_response).to be_a(GoCardlessPro::Resources::BillingRequest)
404
+
405
+ expect(stub).to have_been_requested
406
+ end
407
+
408
+ context 'when the request needs a body and custom header' do
409
+ let(:body) { { foo: 'bar' } }
410
+ let(:headers) { { 'Foo' => 'Bar' } }
411
+ subject(:post_response) { client.billing_requests.collect_customer_details(resource_id, body, headers) }
412
+
413
+ let(:resource_id) { 'ABC123' }
414
+
415
+ let!(:stub) do
416
+ # /billing_requests/%v/actions/collect_customer_details
417
+ stub_url = '/billing_requests/:identity/actions/collect_customer_details'.gsub(':identity', resource_id)
418
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).
419
+ with(
420
+ body: { foo: 'bar' },
421
+ headers: { 'Foo' => 'Bar' }
422
+ ).to_return(
423
+ body: {
424
+ 'billing_requests' => {
425
+
426
+ 'actions' => 'actions-input',
427
+ 'created_at' => 'created_at-input',
428
+ 'id' => 'id-input',
429
+ 'links' => 'links-input',
430
+ 'mandate_request' => 'mandate_request-input',
431
+ 'metadata' => 'metadata-input',
432
+ 'payment_request' => 'payment_request-input',
433
+ 'resources' => 'resources-input',
434
+ 'status' => 'status-input',
435
+ },
436
+ }.to_json,
437
+ headers: response_headers
438
+ )
439
+ end
440
+ end
441
+ end
442
+
443
+ describe '#collect_bank_account' do
444
+ subject(:post_response) { client.billing_requests.collect_bank_account(resource_id) }
445
+
446
+ let(:resource_id) { 'ABC123' }
447
+
448
+ let!(:stub) do
449
+ # /billing_requests/%v/actions/collect_bank_account
450
+ stub_url = '/billing_requests/:identity/actions/collect_bank_account'.gsub(':identity', resource_id)
451
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).to_return(
452
+ body: {
453
+ 'billing_requests' => {
454
+
455
+ 'actions' => 'actions-input',
456
+ 'created_at' => 'created_at-input',
457
+ 'id' => 'id-input',
458
+ 'links' => 'links-input',
459
+ 'mandate_request' => 'mandate_request-input',
460
+ 'metadata' => 'metadata-input',
461
+ 'payment_request' => 'payment_request-input',
462
+ 'resources' => 'resources-input',
463
+ 'status' => 'status-input',
464
+ },
465
+ }.to_json,
466
+ headers: response_headers
467
+ )
468
+ end
469
+
470
+ it 'wraps the response and calls the right endpoint' do
471
+ expect(post_response).to be_a(GoCardlessPro::Resources::BillingRequest)
472
+
473
+ expect(stub).to have_been_requested
474
+ end
475
+
476
+ context 'when the request needs a body and custom header' do
477
+ let(:body) { { foo: 'bar' } }
478
+ let(:headers) { { 'Foo' => 'Bar' } }
479
+ subject(:post_response) { client.billing_requests.collect_bank_account(resource_id, body, headers) }
480
+
481
+ let(:resource_id) { 'ABC123' }
482
+
483
+ let!(:stub) do
484
+ # /billing_requests/%v/actions/collect_bank_account
485
+ stub_url = '/billing_requests/:identity/actions/collect_bank_account'.gsub(':identity', resource_id)
486
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).
487
+ with(
488
+ body: { foo: 'bar' },
489
+ headers: { 'Foo' => 'Bar' }
490
+ ).to_return(
491
+ body: {
492
+ 'billing_requests' => {
493
+
494
+ 'actions' => 'actions-input',
495
+ 'created_at' => 'created_at-input',
496
+ 'id' => 'id-input',
497
+ 'links' => 'links-input',
498
+ 'mandate_request' => 'mandate_request-input',
499
+ 'metadata' => 'metadata-input',
500
+ 'payment_request' => 'payment_request-input',
501
+ 'resources' => 'resources-input',
502
+ 'status' => 'status-input',
503
+ },
504
+ }.to_json,
505
+ headers: response_headers
506
+ )
507
+ end
508
+ end
509
+ end
510
+
511
+ describe '#fulfil' do
512
+ subject(:post_response) { client.billing_requests.fulfil(resource_id) }
513
+
514
+ let(:resource_id) { 'ABC123' }
515
+
516
+ let!(:stub) do
517
+ # /billing_requests/%v/actions/fulfil
518
+ stub_url = '/billing_requests/:identity/actions/fulfil'.gsub(':identity', resource_id)
519
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).to_return(
520
+ body: {
521
+ 'billing_requests' => {
522
+
523
+ 'actions' => 'actions-input',
524
+ 'created_at' => 'created_at-input',
525
+ 'id' => 'id-input',
526
+ 'links' => 'links-input',
527
+ 'mandate_request' => 'mandate_request-input',
528
+ 'metadata' => 'metadata-input',
529
+ 'payment_request' => 'payment_request-input',
530
+ 'resources' => 'resources-input',
531
+ 'status' => 'status-input',
532
+ },
533
+ }.to_json,
534
+ headers: response_headers
535
+ )
536
+ end
537
+
538
+ it 'wraps the response and calls the right endpoint' do
539
+ expect(post_response).to be_a(GoCardlessPro::Resources::BillingRequest)
540
+
541
+ expect(stub).to have_been_requested
542
+ end
543
+
544
+ context 'when the request needs a body and custom header' do
545
+ let(:body) { { foo: 'bar' } }
546
+ let(:headers) { { 'Foo' => 'Bar' } }
547
+ subject(:post_response) { client.billing_requests.fulfil(resource_id, body, headers) }
548
+
549
+ let(:resource_id) { 'ABC123' }
550
+
551
+ let!(:stub) do
552
+ # /billing_requests/%v/actions/fulfil
553
+ stub_url = '/billing_requests/:identity/actions/fulfil'.gsub(':identity', resource_id)
554
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).
555
+ with(
556
+ body: { foo: 'bar' },
557
+ headers: { 'Foo' => 'Bar' }
558
+ ).to_return(
559
+ body: {
560
+ 'billing_requests' => {
561
+
562
+ 'actions' => 'actions-input',
563
+ 'created_at' => 'created_at-input',
564
+ 'id' => 'id-input',
565
+ 'links' => 'links-input',
566
+ 'mandate_request' => 'mandate_request-input',
567
+ 'metadata' => 'metadata-input',
568
+ 'payment_request' => 'payment_request-input',
569
+ 'resources' => 'resources-input',
570
+ 'status' => 'status-input',
571
+ },
572
+ }.to_json,
573
+ headers: response_headers
574
+ )
575
+ end
576
+ end
577
+ end
578
+
579
+ describe '#confirm_payer_details' do
580
+ subject(:post_response) { client.billing_requests.confirm_payer_details(resource_id) }
581
+
582
+ let(:resource_id) { 'ABC123' }
583
+
584
+ let!(:stub) do
585
+ # /billing_requests/%v/actions/confirm_payer_details
586
+ stub_url = '/billing_requests/:identity/actions/confirm_payer_details'.gsub(':identity', resource_id)
587
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).to_return(
588
+ body: {
589
+ 'billing_requests' => {
590
+
591
+ 'actions' => 'actions-input',
592
+ 'created_at' => 'created_at-input',
593
+ 'id' => 'id-input',
594
+ 'links' => 'links-input',
595
+ 'mandate_request' => 'mandate_request-input',
596
+ 'metadata' => 'metadata-input',
597
+ 'payment_request' => 'payment_request-input',
598
+ 'resources' => 'resources-input',
599
+ 'status' => 'status-input',
600
+ },
601
+ }.to_json,
602
+ headers: response_headers
603
+ )
604
+ end
605
+
606
+ it 'wraps the response and calls the right endpoint' do
607
+ expect(post_response).to be_a(GoCardlessPro::Resources::BillingRequest)
608
+
609
+ expect(stub).to have_been_requested
610
+ end
611
+
612
+ context 'when the request needs a body and custom header' do
613
+ let(:body) { { foo: 'bar' } }
614
+ let(:headers) { { 'Foo' => 'Bar' } }
615
+ subject(:post_response) { client.billing_requests.confirm_payer_details(resource_id, body, headers) }
616
+
617
+ let(:resource_id) { 'ABC123' }
618
+
619
+ let!(:stub) do
620
+ # /billing_requests/%v/actions/confirm_payer_details
621
+ stub_url = '/billing_requests/:identity/actions/confirm_payer_details'.gsub(':identity', resource_id)
622
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).
623
+ with(
624
+ body: { foo: 'bar' },
625
+ headers: { 'Foo' => 'Bar' }
626
+ ).to_return(
627
+ body: {
628
+ 'billing_requests' => {
629
+
630
+ 'actions' => 'actions-input',
631
+ 'created_at' => 'created_at-input',
632
+ 'id' => 'id-input',
633
+ 'links' => 'links-input',
634
+ 'mandate_request' => 'mandate_request-input',
635
+ 'metadata' => 'metadata-input',
636
+ 'payment_request' => 'payment_request-input',
637
+ 'resources' => 'resources-input',
638
+ 'status' => 'status-input',
639
+ },
640
+ }.to_json,
641
+ headers: response_headers
642
+ )
643
+ end
644
+ end
645
+ end
646
+
647
+ describe '#cancel' do
648
+ subject(:post_response) { client.billing_requests.cancel(resource_id) }
649
+
650
+ let(:resource_id) { 'ABC123' }
651
+
652
+ let!(:stub) do
653
+ # /billing_requests/%v/actions/cancel
654
+ stub_url = '/billing_requests/:identity/actions/cancel'.gsub(':identity', resource_id)
655
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).to_return(
656
+ body: {
657
+ 'billing_requests' => {
658
+
659
+ 'actions' => 'actions-input',
660
+ 'created_at' => 'created_at-input',
661
+ 'id' => 'id-input',
662
+ 'links' => 'links-input',
663
+ 'mandate_request' => 'mandate_request-input',
664
+ 'metadata' => 'metadata-input',
665
+ 'payment_request' => 'payment_request-input',
666
+ 'resources' => 'resources-input',
667
+ 'status' => 'status-input',
668
+ },
669
+ }.to_json,
670
+ headers: response_headers
671
+ )
672
+ end
673
+
674
+ it 'wraps the response and calls the right endpoint' do
675
+ expect(post_response).to be_a(GoCardlessPro::Resources::BillingRequest)
676
+
677
+ expect(stub).to have_been_requested
678
+ end
679
+
680
+ context 'when the request needs a body and custom header' do
681
+ let(:body) { { foo: 'bar' } }
682
+ let(:headers) { { 'Foo' => 'Bar' } }
683
+ subject(:post_response) { client.billing_requests.cancel(resource_id, body, headers) }
684
+
685
+ let(:resource_id) { 'ABC123' }
686
+
687
+ let!(:stub) do
688
+ # /billing_requests/%v/actions/cancel
689
+ stub_url = '/billing_requests/:identity/actions/cancel'.gsub(':identity', resource_id)
690
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).
691
+ with(
692
+ body: { foo: 'bar' },
693
+ headers: { 'Foo' => 'Bar' }
694
+ ).to_return(
695
+ body: {
696
+ 'billing_requests' => {
697
+
698
+ 'actions' => 'actions-input',
699
+ 'created_at' => 'created_at-input',
700
+ 'id' => 'id-input',
701
+ 'links' => 'links-input',
702
+ 'mandate_request' => 'mandate_request-input',
703
+ 'metadata' => 'metadata-input',
704
+ 'payment_request' => 'payment_request-input',
705
+ 'resources' => 'resources-input',
706
+ 'status' => 'status-input',
707
+ },
708
+ }.to_json,
709
+ headers: response_headers
710
+ )
711
+ end
712
+ end
713
+ end
714
+
715
+ describe '#notify' do
716
+ subject(:post_response) { client.billing_requests.notify(resource_id) }
717
+
718
+ let(:resource_id) { 'ABC123' }
719
+
720
+ let!(:stub) do
721
+ # /billing_requests/%v/actions/notify
722
+ stub_url = '/billing_requests/:identity/actions/notify'.gsub(':identity', resource_id)
723
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).to_return(
724
+ body: {
725
+ 'billing_requests' => {
726
+
727
+ 'actions' => 'actions-input',
728
+ 'created_at' => 'created_at-input',
729
+ 'id' => 'id-input',
730
+ 'links' => 'links-input',
731
+ 'mandate_request' => 'mandate_request-input',
732
+ 'metadata' => 'metadata-input',
733
+ 'payment_request' => 'payment_request-input',
734
+ 'resources' => 'resources-input',
735
+ 'status' => 'status-input',
736
+ },
737
+ }.to_json,
738
+ headers: response_headers
739
+ )
740
+ end
741
+
742
+ it 'wraps the response and calls the right endpoint' do
743
+ expect(post_response).to be_a(GoCardlessPro::Resources::BillingRequest)
744
+
745
+ expect(stub).to have_been_requested
746
+ end
747
+
748
+ context 'when the request needs a body and custom header' do
749
+ let(:body) { { foo: 'bar' } }
750
+ let(:headers) { { 'Foo' => 'Bar' } }
751
+ subject(:post_response) { client.billing_requests.notify(resource_id, body, headers) }
752
+
753
+ let(:resource_id) { 'ABC123' }
754
+
755
+ let!(:stub) do
756
+ # /billing_requests/%v/actions/notify
757
+ stub_url = '/billing_requests/:identity/actions/notify'.gsub(':identity', resource_id)
758
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).
759
+ with(
760
+ body: { foo: 'bar' },
761
+ headers: { 'Foo' => 'Bar' }
762
+ ).to_return(
763
+ body: {
764
+ 'billing_requests' => {
765
+
766
+ 'actions' => 'actions-input',
767
+ 'created_at' => 'created_at-input',
768
+ 'id' => 'id-input',
769
+ 'links' => 'links-input',
770
+ 'mandate_request' => 'mandate_request-input',
771
+ 'metadata' => 'metadata-input',
772
+ 'payment_request' => 'payment_request-input',
773
+ 'resources' => 'resources-input',
774
+ 'status' => 'status-input',
775
+ },
776
+ }.to_json,
777
+ headers: response_headers
778
+ )
779
+ end
780
+ end
781
+ end
782
+ end