gocardless_pro 2.15.1 → 2.16.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.
@@ -0,0 +1,442 @@
1
+ require 'spec_helper'
2
+
3
+ describe GoCardlessPro::Resources::InstalmentSchedule 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.instalment_schedules.create(params: new_resource) }
14
+ context 'with a valid request' do
15
+ let(:new_resource) do
16
+ {
17
+
18
+ 'created_at' => 'created_at-input',
19
+ 'currency' => 'currency-input',
20
+ 'id' => 'id-input',
21
+ 'links' => 'links-input',
22
+ 'metadata' => 'metadata-input',
23
+ 'name' => 'name-input',
24
+ 'payment_errors' => 'payment_errors-input',
25
+ 'status' => 'status-input',
26
+ 'total_amount' => 'total_amount-input',
27
+ }
28
+ end
29
+
30
+ before do
31
+ stub_request(:post, %r{.*api.gocardless.com/instalment_schedules}).
32
+ with(
33
+ body: {
34
+ 'instalment_schedules' => {
35
+
36
+ 'created_at' => 'created_at-input',
37
+ 'currency' => 'currency-input',
38
+ 'id' => 'id-input',
39
+ 'links' => 'links-input',
40
+ 'metadata' => 'metadata-input',
41
+ 'name' => 'name-input',
42
+ 'payment_errors' => 'payment_errors-input',
43
+ 'status' => 'status-input',
44
+ 'total_amount' => 'total_amount-input',
45
+ },
46
+ }
47
+ ).
48
+ to_return(
49
+ body: {
50
+ 'instalment_schedules' =>
51
+
52
+ {
53
+
54
+ 'created_at' => 'created_at-input',
55
+ 'currency' => 'currency-input',
56
+ 'id' => 'id-input',
57
+ 'links' => 'links-input',
58
+ 'metadata' => 'metadata-input',
59
+ 'name' => 'name-input',
60
+ 'payment_errors' => 'payment_errors-input',
61
+ 'status' => 'status-input',
62
+ 'total_amount' => 'total_amount-input',
63
+ },
64
+
65
+ }.to_json,
66
+ headers: response_headers
67
+ )
68
+ end
69
+
70
+ it 'creates and returns the resource' do
71
+ expect(post_create_response).to be_a(GoCardlessPro::Resources::InstalmentSchedule)
72
+ end
73
+ end
74
+
75
+ context 'with a request that returns a validation error' do
76
+ let(:new_resource) { {} }
77
+
78
+ before do
79
+ stub_request(:post, %r{.*api.gocardless.com/instalment_schedules}).to_return(
80
+ body: {
81
+ error: {
82
+ type: 'validation_failed',
83
+ code: 422,
84
+ errors: [
85
+ { message: 'test error message', field: 'test_field' },
86
+ ],
87
+ },
88
+ }.to_json,
89
+ headers: response_headers,
90
+ status: 422
91
+ )
92
+ end
93
+
94
+ it 'throws the correct error' do
95
+ expect { post_create_response }.to raise_error(GoCardlessPro::ValidationError)
96
+ end
97
+ end
98
+
99
+ context 'with a request that returns an idempotent creation conflict error' do
100
+ let(:id) { 'ID123' }
101
+
102
+ let(:new_resource) do
103
+ {
104
+
105
+ 'created_at' => 'created_at-input',
106
+ 'currency' => 'currency-input',
107
+ 'id' => 'id-input',
108
+ 'links' => 'links-input',
109
+ 'metadata' => 'metadata-input',
110
+ 'name' => 'name-input',
111
+ 'payment_errors' => 'payment_errors-input',
112
+ 'status' => 'status-input',
113
+ 'total_amount' => 'total_amount-input',
114
+ }
115
+ end
116
+
117
+ let!(:post_stub) do
118
+ stub_request(:post, %r{.*api.gocardless.com/instalment_schedules}).to_return(
119
+ body: {
120
+ error: {
121
+ type: 'invalid_state',
122
+ code: 409,
123
+ errors: [
124
+ {
125
+ message: 'A resource has already been created with this idempotency key',
126
+ reason: 'idempotent_creation_conflict',
127
+ links: {
128
+ conflicting_resource_id: id,
129
+ },
130
+ },
131
+ ],
132
+ },
133
+ }.to_json,
134
+ headers: response_headers,
135
+ status: 409
136
+ )
137
+ end
138
+
139
+ let!(:get_stub) do
140
+ stub_url = "/instalment_schedules/#{id}"
141
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).
142
+ to_return(
143
+ body: {
144
+ 'instalment_schedules' => {
145
+
146
+ 'created_at' => 'created_at-input',
147
+ 'currency' => 'currency-input',
148
+ 'id' => 'id-input',
149
+ 'links' => 'links-input',
150
+ 'metadata' => 'metadata-input',
151
+ 'name' => 'name-input',
152
+ 'payment_errors' => 'payment_errors-input',
153
+ 'status' => 'status-input',
154
+ 'total_amount' => 'total_amount-input',
155
+ },
156
+ }.to_json,
157
+ headers: response_headers
158
+ )
159
+ end
160
+
161
+ it 'fetches the already-created resource' do
162
+ post_create_response
163
+ expect(post_stub).to have_been_requested
164
+ expect(get_stub).to have_been_requested
165
+ end
166
+ end
167
+ end
168
+
169
+ describe '#list' do
170
+ describe 'with no filters' do
171
+ subject(:get_list_response) { client.instalment_schedules.list }
172
+
173
+ before do
174
+ stub_request(:get, %r{.*api.gocardless.com/instalment_schedules}).to_return(
175
+ body: {
176
+ 'instalment_schedules' => [{
177
+
178
+ 'created_at' => 'created_at-input',
179
+ 'currency' => 'currency-input',
180
+ 'id' => 'id-input',
181
+ 'links' => 'links-input',
182
+ 'metadata' => 'metadata-input',
183
+ 'name' => 'name-input',
184
+ 'payment_errors' => 'payment_errors-input',
185
+ 'status' => 'status-input',
186
+ 'total_amount' => 'total_amount-input',
187
+ }],
188
+ meta: {
189
+ cursors: {
190
+ before: nil,
191
+ after: 'ABC123',
192
+ },
193
+ },
194
+ }.to_json,
195
+ headers: response_headers
196
+ )
197
+ end
198
+
199
+ it 'wraps each item in the resource class' do
200
+ expect(get_list_response.records.map(&:class).uniq.first).to eq(GoCardlessPro::Resources::InstalmentSchedule)
201
+
202
+ expect(get_list_response.records.first.created_at).to eq('created_at-input')
203
+
204
+ expect(get_list_response.records.first.currency).to eq('currency-input')
205
+
206
+ expect(get_list_response.records.first.id).to eq('id-input')
207
+
208
+ expect(get_list_response.records.first.metadata).to eq('metadata-input')
209
+
210
+ expect(get_list_response.records.first.name).to eq('name-input')
211
+
212
+ expect(get_list_response.records.first.payment_errors).to eq('payment_errors-input')
213
+
214
+ expect(get_list_response.records.first.status).to eq('status-input')
215
+
216
+ expect(get_list_response.records.first.total_amount).to eq('total_amount-input')
217
+ end
218
+
219
+ it 'exposes the cursors for before and after' do
220
+ expect(get_list_response.before).to eq(nil)
221
+ expect(get_list_response.after).to eq('ABC123')
222
+ end
223
+
224
+ specify { expect(get_list_response.api_response.headers).to eql('content-type' => 'application/json') }
225
+ end
226
+ end
227
+
228
+ describe '#all' do
229
+ let!(:first_response_stub) do
230
+ stub_request(:get, %r{.*api.gocardless.com/instalment_schedules$}).to_return(
231
+ body: {
232
+ 'instalment_schedules' => [{
233
+
234
+ 'created_at' => 'created_at-input',
235
+ 'currency' => 'currency-input',
236
+ 'id' => 'id-input',
237
+ 'links' => 'links-input',
238
+ 'metadata' => 'metadata-input',
239
+ 'name' => 'name-input',
240
+ 'payment_errors' => 'payment_errors-input',
241
+ 'status' => 'status-input',
242
+ 'total_amount' => 'total_amount-input',
243
+ }],
244
+ meta: {
245
+ cursors: { after: 'AB345' },
246
+ limit: 1,
247
+ },
248
+ }.to_json,
249
+ headers: response_headers
250
+ )
251
+ end
252
+
253
+ let!(:second_response_stub) do
254
+ stub_request(:get, %r{.*api.gocardless.com/instalment_schedules\?after=AB345}).to_return(
255
+ body: {
256
+ 'instalment_schedules' => [{
257
+
258
+ 'created_at' => 'created_at-input',
259
+ 'currency' => 'currency-input',
260
+ 'id' => 'id-input',
261
+ 'links' => 'links-input',
262
+ 'metadata' => 'metadata-input',
263
+ 'name' => 'name-input',
264
+ 'payment_errors' => 'payment_errors-input',
265
+ 'status' => 'status-input',
266
+ 'total_amount' => 'total_amount-input',
267
+ }],
268
+ meta: {
269
+ limit: 2,
270
+ cursors: {},
271
+ },
272
+ }.to_json,
273
+ headers: response_headers
274
+ )
275
+ end
276
+
277
+ it 'automatically makes the extra requests' do
278
+ expect(client.instalment_schedules.all.to_a.length).to eq(2)
279
+ expect(first_response_stub).to have_been_requested
280
+ expect(second_response_stub).to have_been_requested
281
+ end
282
+ end
283
+
284
+ describe '#get' do
285
+ let(:id) { 'ID123' }
286
+
287
+ subject(:get_response) { client.instalment_schedules.get(id) }
288
+
289
+ context 'passing in a custom header' do
290
+ let!(:stub) do
291
+ stub_url = '/instalment_schedules/:identity'.gsub(':identity', id)
292
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).
293
+ with(headers: { 'Foo' => 'Bar' }).
294
+ to_return(
295
+ body: {
296
+ 'instalment_schedules' => {
297
+
298
+ 'created_at' => 'created_at-input',
299
+ 'currency' => 'currency-input',
300
+ 'id' => 'id-input',
301
+ 'links' => 'links-input',
302
+ 'metadata' => 'metadata-input',
303
+ 'name' => 'name-input',
304
+ 'payment_errors' => 'payment_errors-input',
305
+ 'status' => 'status-input',
306
+ 'total_amount' => 'total_amount-input',
307
+ },
308
+ }.to_json,
309
+ headers: response_headers
310
+ )
311
+ end
312
+
313
+ subject(:get_response) do
314
+ client.instalment_schedules.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 instalment_schedule to return' do
326
+ before do
327
+ stub_url = '/instalment_schedules/:identity'.gsub(':identity', id)
328
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).to_return(
329
+ body: {
330
+ 'instalment_schedules' => {
331
+
332
+ 'created_at' => 'created_at-input',
333
+ 'currency' => 'currency-input',
334
+ 'id' => 'id-input',
335
+ 'links' => 'links-input',
336
+ 'metadata' => 'metadata-input',
337
+ 'name' => 'name-input',
338
+ 'payment_errors' => 'payment_errors-input',
339
+ 'status' => 'status-input',
340
+ 'total_amount' => 'total_amount-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::InstalmentSchedule)
349
+ end
350
+ end
351
+
352
+ context 'when nothing is returned' do
353
+ before do
354
+ stub_url = '/instalment_schedules/: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 '#cancel' do
376
+ subject(:post_response) { client.instalment_schedules.cancel(resource_id) }
377
+
378
+ let(:resource_id) { 'ABC123' }
379
+
380
+ let!(:stub) do
381
+ # /instalment_schedules/%v/actions/cancel
382
+ stub_url = '/instalment_schedules/:identity/actions/cancel'.gsub(':identity', resource_id)
383
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).to_return(
384
+ body: {
385
+ 'instalment_schedules' => {
386
+
387
+ 'created_at' => 'created_at-input',
388
+ 'currency' => 'currency-input',
389
+ 'id' => 'id-input',
390
+ 'links' => 'links-input',
391
+ 'metadata' => 'metadata-input',
392
+ 'name' => 'name-input',
393
+ 'payment_errors' => 'payment_errors-input',
394
+ 'status' => 'status-input',
395
+ 'total_amount' => 'total_amount-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::InstalmentSchedule)
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.instalment_schedules.cancel(resource_id, body, headers) }
412
+
413
+ let(:resource_id) { 'ABC123' }
414
+
415
+ let!(:stub) do
416
+ # /instalment_schedules/%v/actions/cancel
417
+ stub_url = '/instalment_schedules/:identity/actions/cancel'.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
+ 'instalment_schedules' => {
425
+
426
+ 'created_at' => 'created_at-input',
427
+ 'currency' => 'currency-input',
428
+ 'id' => 'id-input',
429
+ 'links' => 'links-input',
430
+ 'metadata' => 'metadata-input',
431
+ 'name' => 'name-input',
432
+ 'payment_errors' => 'payment_errors-input',
433
+ 'status' => 'status-input',
434
+ 'total_amount' => 'total_amount-input',
435
+ },
436
+ }.to_json,
437
+ headers: response_headers
438
+ )
439
+ end
440
+ end
441
+ end
442
+ end
@@ -23,6 +23,7 @@ describe GoCardlessPro::Resources::Refund do
23
23
  'links' => 'links-input',
24
24
  'metadata' => 'metadata-input',
25
25
  'reference' => 'reference-input',
26
+ 'status' => 'status-input',
26
27
  }
27
28
  end
28
29
 
@@ -40,6 +41,7 @@ describe GoCardlessPro::Resources::Refund do
40
41
  'links' => 'links-input',
41
42
  'metadata' => 'metadata-input',
42
43
  'reference' => 'reference-input',
44
+ 'status' => 'status-input',
43
45
  },
44
46
  }
45
47
  ).
@@ -57,6 +59,7 @@ describe GoCardlessPro::Resources::Refund do
57
59
  'links' => 'links-input',
58
60
  'metadata' => 'metadata-input',
59
61
  'reference' => 'reference-input',
62
+ 'status' => 'status-input',
60
63
  },
61
64
 
62
65
  }.to_json,
@@ -107,6 +110,7 @@ describe GoCardlessPro::Resources::Refund do
107
110
  'links' => 'links-input',
108
111
  'metadata' => 'metadata-input',
109
112
  'reference' => 'reference-input',
113
+ 'status' => 'status-input',
110
114
  }
111
115
  end
112
116
 
@@ -147,6 +151,7 @@ describe GoCardlessPro::Resources::Refund do
147
151
  'links' => 'links-input',
148
152
  'metadata' => 'metadata-input',
149
153
  'reference' => 'reference-input',
154
+ 'status' => 'status-input',
150
155
  },
151
156
  }.to_json,
152
157
  headers: response_headers
@@ -178,6 +183,7 @@ describe GoCardlessPro::Resources::Refund do
178
183
  'links' => 'links-input',
179
184
  'metadata' => 'metadata-input',
180
185
  'reference' => 'reference-input',
186
+ 'status' => 'status-input',
181
187
  }],
182
188
  meta: {
183
189
  cursors: {
@@ -206,6 +212,8 @@ describe GoCardlessPro::Resources::Refund do
206
212
  expect(get_list_response.records.first.metadata).to eq('metadata-input')
207
213
 
208
214
  expect(get_list_response.records.first.reference).to eq('reference-input')
215
+
216
+ expect(get_list_response.records.first.status).to eq('status-input')
209
217
  end
210
218
 
211
219
  it 'exposes the cursors for before and after' do
@@ -231,6 +239,7 @@ describe GoCardlessPro::Resources::Refund do
231
239
  'links' => 'links-input',
232
240
  'metadata' => 'metadata-input',
233
241
  'reference' => 'reference-input',
242
+ 'status' => 'status-input',
234
243
  }],
235
244
  meta: {
236
245
  cursors: { after: 'AB345' },
@@ -254,6 +263,7 @@ describe GoCardlessPro::Resources::Refund do
254
263
  'links' => 'links-input',
255
264
  'metadata' => 'metadata-input',
256
265
  'reference' => 'reference-input',
266
+ 'status' => 'status-input',
257
267
  }],
258
268
  meta: {
259
269
  limit: 2,
@@ -293,6 +303,7 @@ describe GoCardlessPro::Resources::Refund do
293
303
  'links' => 'links-input',
294
304
  'metadata' => 'metadata-input',
295
305
  'reference' => 'reference-input',
306
+ 'status' => 'status-input',
296
307
  },
297
308
  }.to_json,
298
309
  headers: response_headers
@@ -326,6 +337,7 @@ describe GoCardlessPro::Resources::Refund do
326
337
  'links' => 'links-input',
327
338
  'metadata' => 'metadata-input',
328
339
  'reference' => 'reference-input',
340
+ 'status' => 'status-input',
329
341
  },
330
342
  }.to_json,
331
343
  headers: response_headers
@@ -381,6 +393,7 @@ describe GoCardlessPro::Resources::Refund do
381
393
  'links' => 'links-input',
382
394
  'metadata' => 'metadata-input',
383
395
  'reference' => 'reference-input',
396
+ 'status' => 'status-input',
384
397
  },
385
398
  }.to_json,
386
399
  headers: response_headers