gocardless_pro 2.25.0 → 2.27.0

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