gocardless_pro 2.15.1 → 2.16.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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