gocardless_pro 1.1.0 → 2.0.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.
- checksums.yaml +4 -4
- data/README.md +13 -4
- data/lib/gocardless_pro.rb +1 -0
- data/lib/gocardless_pro/api_service.rb +2 -0
- data/lib/gocardless_pro/client.rb +4 -3
- data/lib/gocardless_pro/error/invalid_state_error.rb +17 -0
- data/lib/gocardless_pro/middlewares/raise_gocardless_errors.rb +50 -0
- data/lib/gocardless_pro/request.rb +38 -1
- data/lib/gocardless_pro/resources/creditor.rb +2 -2
- data/lib/gocardless_pro/resources/creditor_bank_account.rb +11 -11
- data/lib/gocardless_pro/resources/customer_bank_account.rb +2 -2
- data/lib/gocardless_pro/resources/event.rb +2 -2
- data/lib/gocardless_pro/resources/mandate.rb +2 -2
- data/lib/gocardless_pro/resources/payment.rb +7 -7
- data/lib/gocardless_pro/resources/payout.rb +7 -6
- data/lib/gocardless_pro/resources/redirect_flow.rb +2 -2
- data/lib/gocardless_pro/resources/refund.rb +2 -2
- data/lib/gocardless_pro/resources/subscription.rb +2 -2
- data/lib/gocardless_pro/response.rb +2 -54
- data/lib/gocardless_pro/services/bank_details_lookups_service.rb +3 -0
- data/lib/gocardless_pro/services/creditor_bank_accounts_service.rb +31 -2
- data/lib/gocardless_pro/services/creditors_service.rb +21 -1
- data/lib/gocardless_pro/services/customer_bank_accounts_service.rb +34 -2
- data/lib/gocardless_pro/services/customers_service.rb +21 -1
- data/lib/gocardless_pro/services/events_service.rb +5 -0
- data/lib/gocardless_pro/services/mandate_pdfs_service.rb +3 -0
- data/lib/gocardless_pro/services/mandates_service.rb +47 -3
- data/lib/gocardless_pro/services/payments_service.rb +47 -3
- data/lib/gocardless_pro/services/payouts_service.rb +5 -0
- data/lib/gocardless_pro/services/redirect_flows_service.rb +28 -2
- data/lib/gocardless_pro/services/refunds_service.rb +21 -1
- data/lib/gocardless_pro/services/subscriptions_service.rb +34 -2
- data/lib/gocardless_pro/version.rb +1 -1
- data/spec/api_service_spec.rb +106 -0
- data/spec/middlewares/raise_gocardless_errors_spec.rb +98 -0
- data/spec/resources/bank_details_lookup_spec.rb +102 -19
- data/spec/resources/creditor_bank_account_spec.rb +416 -40
- data/spec/resources/creditor_spec.rb +414 -53
- data/spec/resources/customer_bank_account_spec.rb +452 -40
- data/spec/resources/customer_spec.rb +457 -45
- data/spec/resources/event_spec.rb +171 -72
- data/spec/resources/mandate_pdf_spec.rb +100 -17
- data/spec/resources/mandate_spec.rb +501 -44
- data/spec/resources/payment_spec.rb +531 -48
- data/spec/resources/payout_spec.rb +189 -45
- data/spec/resources/redirect_flow_spec.rb +277 -43
- data/spec/resources/refund_spec.rb +349 -34
- data/spec/resources/subscription_spec.rb +531 -53
- data/spec/response_spec.rb +12 -79
- data/spec/services/bank_details_lookups_service_spec.rb +67 -2
- data/spec/services/creditor_bank_accounts_service_spec.rb +309 -31
- data/spec/services/creditors_service_spec.rb +343 -33
- data/spec/services/customer_bank_accounts_service_spec.rb +335 -32
- data/spec/services/customers_service_spec.rb +364 -36
- data/spec/services/events_service_spec.rb +185 -24
- data/spec/services/mandate_pdfs_service_spec.rb +66 -2
- data/spec/services/mandates_service_spec.rb +341 -33
- data/spec/services/payments_service_spec.rb +355 -35
- data/spec/services/payouts_service_spec.rb +206 -26
- data/spec/services/redirect_flows_service_spec.rb +137 -7
- data/spec/services/refunds_service_spec.rb +301 -27
- data/spec/services/subscriptions_service_spec.rb +377 -38
- metadata +6 -3
@@ -7,31 +7,37 @@ describe GoCardlessPro::Services::EventsService do
|
|
7
7
|
)
|
8
8
|
end
|
9
9
|
|
10
|
+
let(:response_headers) { { 'Content-Type' => 'application/json' } }
|
11
|
+
|
10
12
|
describe '#list' do
|
11
13
|
describe 'with no filters' do
|
12
14
|
subject(:get_list_response) { client.events.list }
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
'events' => [{
|
16
|
+
let(:body) do
|
17
|
+
{
|
18
|
+
'events' => [{
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
}
|
20
|
+
'action' => 'action-input',
|
21
|
+
'created_at' => 'created_at-input',
|
22
|
+
'details' => 'details-input',
|
23
|
+
'id' => 'id-input',
|
24
|
+
'links' => 'links-input',
|
25
|
+
'metadata' => 'metadata-input',
|
26
|
+
'resource_type' => 'resource_type-input'
|
27
|
+
}],
|
28
|
+
meta: {
|
29
|
+
cursors: {
|
30
|
+
before: nil,
|
31
|
+
after: 'ABC123'
|
32
32
|
}
|
33
|
-
}
|
34
|
-
|
33
|
+
}
|
34
|
+
}.to_json
|
35
|
+
end
|
36
|
+
|
37
|
+
before do
|
38
|
+
stub_request(:get, %r{.*api.gocardless.com/events}).to_return(
|
39
|
+
body: body,
|
40
|
+
headers: response_headers
|
35
41
|
)
|
36
42
|
end
|
37
43
|
|
@@ -57,6 +63,29 @@ describe GoCardlessPro::Services::EventsService do
|
|
57
63
|
end
|
58
64
|
|
59
65
|
specify { expect(get_list_response.api_response.headers).to eql('content-type' => 'application/json') }
|
66
|
+
|
67
|
+
describe 'retry behaviour' do
|
68
|
+
before { allow_any_instance_of(GoCardlessPro::Request).to receive(:sleep) }
|
69
|
+
|
70
|
+
it 'retries timeouts' do
|
71
|
+
stub = stub_request(:get, %r{.*api.gocardless.com/events})
|
72
|
+
.to_timeout.then.to_return(status: 200, headers: response_headers, body: body)
|
73
|
+
|
74
|
+
get_list_response
|
75
|
+
expect(stub).to have_been_requested.twice
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'retries 5XX errors' do
|
79
|
+
stub = stub_request(:get, %r{.*api.gocardless.com/events})
|
80
|
+
.to_return(status: 502,
|
81
|
+
headers: { 'Content-Type' => 'text/html' },
|
82
|
+
body: '<html><body>Response from Cloudflare</body></html>')
|
83
|
+
.then.to_return(status: 200, headers: response_headers, body: body)
|
84
|
+
|
85
|
+
get_list_response
|
86
|
+
expect(stub).to have_been_requested.twice
|
87
|
+
end
|
88
|
+
end
|
60
89
|
end
|
61
90
|
end
|
62
91
|
|
@@ -79,7 +108,7 @@ describe GoCardlessPro::Services::EventsService do
|
|
79
108
|
limit: 1
|
80
109
|
}
|
81
110
|
}.to_json,
|
82
|
-
headers:
|
111
|
+
headers: response_headers
|
83
112
|
)
|
84
113
|
end
|
85
114
|
|
@@ -101,7 +130,7 @@ describe GoCardlessPro::Services::EventsService do
|
|
101
130
|
cursors: {}
|
102
131
|
}
|
103
132
|
}.to_json,
|
104
|
-
headers:
|
133
|
+
headers: response_headers
|
105
134
|
)
|
106
135
|
end
|
107
136
|
|
@@ -110,6 +139,111 @@ describe GoCardlessPro::Services::EventsService do
|
|
110
139
|
expect(first_response_stub).to have_been_requested
|
111
140
|
expect(second_response_stub).to have_been_requested
|
112
141
|
end
|
142
|
+
|
143
|
+
describe 'retry behaviour' do
|
144
|
+
before { allow_any_instance_of(GoCardlessPro::Request).to receive(:sleep) }
|
145
|
+
|
146
|
+
it 'retries timeouts' do
|
147
|
+
first_response_stub = stub_request(:get, %r{.*api.gocardless.com/events$}).to_return(
|
148
|
+
body: {
|
149
|
+
'events' => [{
|
150
|
+
|
151
|
+
'action' => 'action-input',
|
152
|
+
'created_at' => 'created_at-input',
|
153
|
+
'details' => 'details-input',
|
154
|
+
'id' => 'id-input',
|
155
|
+
'links' => 'links-input',
|
156
|
+
'metadata' => 'metadata-input',
|
157
|
+
'resource_type' => 'resource_type-input'
|
158
|
+
}],
|
159
|
+
meta: {
|
160
|
+
cursors: { after: 'AB345' },
|
161
|
+
limit: 1
|
162
|
+
}
|
163
|
+
}.to_json,
|
164
|
+
headers: response_headers
|
165
|
+
)
|
166
|
+
|
167
|
+
second_response_stub = stub_request(:get, %r{.*api.gocardless.com/events\?after=AB345})
|
168
|
+
.to_timeout.then
|
169
|
+
.to_return(
|
170
|
+
body: {
|
171
|
+
'events' => [{
|
172
|
+
|
173
|
+
'action' => 'action-input',
|
174
|
+
'created_at' => 'created_at-input',
|
175
|
+
'details' => 'details-input',
|
176
|
+
'id' => 'id-input',
|
177
|
+
'links' => 'links-input',
|
178
|
+
'metadata' => 'metadata-input',
|
179
|
+
'resource_type' => 'resource_type-input'
|
180
|
+
}],
|
181
|
+
meta: {
|
182
|
+
limit: 2,
|
183
|
+
cursors: {}
|
184
|
+
}
|
185
|
+
}.to_json,
|
186
|
+
headers: response_headers
|
187
|
+
)
|
188
|
+
|
189
|
+
client.events.all.to_a
|
190
|
+
|
191
|
+
expect(first_response_stub).to have_been_requested
|
192
|
+
expect(second_response_stub).to have_been_requested.twice
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'retries 5XX errors' do
|
196
|
+
first_response_stub = stub_request(:get, %r{.*api.gocardless.com/events$}).to_return(
|
197
|
+
body: {
|
198
|
+
'events' => [{
|
199
|
+
|
200
|
+
'action' => 'action-input',
|
201
|
+
'created_at' => 'created_at-input',
|
202
|
+
'details' => 'details-input',
|
203
|
+
'id' => 'id-input',
|
204
|
+
'links' => 'links-input',
|
205
|
+
'metadata' => 'metadata-input',
|
206
|
+
'resource_type' => 'resource_type-input'
|
207
|
+
}],
|
208
|
+
meta: {
|
209
|
+
cursors: { after: 'AB345' },
|
210
|
+
limit: 1
|
211
|
+
}
|
212
|
+
}.to_json,
|
213
|
+
headers: response_headers
|
214
|
+
)
|
215
|
+
|
216
|
+
second_response_stub = stub_request(:get, %r{.*api.gocardless.com/events\?after=AB345})
|
217
|
+
.to_return(
|
218
|
+
status: 502,
|
219
|
+
body: '<html><body>Response from Cloudflare</body></html>',
|
220
|
+
headers: { 'Content-Type' => 'text/html' }
|
221
|
+
).then.to_return(
|
222
|
+
body: {
|
223
|
+
'events' => [{
|
224
|
+
|
225
|
+
'action' => 'action-input',
|
226
|
+
'created_at' => 'created_at-input',
|
227
|
+
'details' => 'details-input',
|
228
|
+
'id' => 'id-input',
|
229
|
+
'links' => 'links-input',
|
230
|
+
'metadata' => 'metadata-input',
|
231
|
+
'resource_type' => 'resource_type-input'
|
232
|
+
}],
|
233
|
+
meta: {
|
234
|
+
limit: 2,
|
235
|
+
cursors: {}
|
236
|
+
}
|
237
|
+
}.to_json,
|
238
|
+
headers: response_headers
|
239
|
+
)
|
240
|
+
|
241
|
+
client.events.all.to_a
|
242
|
+
|
243
|
+
expect(first_response_stub).to have_been_requested
|
244
|
+
expect(second_response_stub).to have_been_requested.twice
|
245
|
+
end
|
246
|
+
end
|
113
247
|
end
|
114
248
|
|
115
249
|
describe '#get' do
|
@@ -135,7 +269,7 @@ describe GoCardlessPro::Services::EventsService do
|
|
135
269
|
'resource_type' => 'resource_type-input'
|
136
270
|
}
|
137
271
|
}.to_json,
|
138
|
-
headers:
|
272
|
+
headers: response_headers
|
139
273
|
)
|
140
274
|
end
|
141
275
|
|
@@ -167,7 +301,7 @@ describe GoCardlessPro::Services::EventsService do
|
|
167
301
|
'resource_type' => 'resource_type-input'
|
168
302
|
}
|
169
303
|
}.to_json,
|
170
|
-
headers:
|
304
|
+
headers: response_headers
|
171
305
|
)
|
172
306
|
end
|
173
307
|
|
@@ -181,7 +315,7 @@ describe GoCardlessPro::Services::EventsService do
|
|
181
315
|
stub_url = '/events/:identity'.gsub(':identity', id)
|
182
316
|
stub_request(:get, /.*api.gocardless.com#{stub_url}/).to_return(
|
183
317
|
body: '',
|
184
|
-
headers:
|
318
|
+
headers: response_headers
|
185
319
|
)
|
186
320
|
end
|
187
321
|
|
@@ -197,5 +331,32 @@ describe GoCardlessPro::Services::EventsService do
|
|
197
331
|
expect { get_response }.to_not raise_error(/bad URI/)
|
198
332
|
end
|
199
333
|
end
|
334
|
+
|
335
|
+
describe 'retry behaviour' do
|
336
|
+
before { allow_any_instance_of(GoCardlessPro::Request).to receive(:sleep) }
|
337
|
+
|
338
|
+
it 'retries timeouts' do
|
339
|
+
stub_url = '/events/:identity'.gsub(':identity', id)
|
340
|
+
|
341
|
+
stub = stub_request(:get, /.*api.gocardless.com#{stub_url}/)
|
342
|
+
.to_timeout.then.to_return(status: 200, headers: response_headers)
|
343
|
+
|
344
|
+
get_response
|
345
|
+
expect(stub).to have_been_requested.twice
|
346
|
+
end
|
347
|
+
|
348
|
+
it 'retries 5XX errors' do
|
349
|
+
stub_url = '/events/:identity'.gsub(':identity', id)
|
350
|
+
|
351
|
+
stub = stub_request(:get, /.*api.gocardless.com#{stub_url}/)
|
352
|
+
.to_return(status: 502,
|
353
|
+
headers: { 'Content-Type' => 'text/html' },
|
354
|
+
body: '<html><body>Response from Cloudflare</body></html>')
|
355
|
+
.then.to_return(status: 200, headers: response_headers)
|
356
|
+
|
357
|
+
get_response
|
358
|
+
expect(stub).to have_been_requested.twice
|
359
|
+
end
|
360
|
+
end
|
200
361
|
end
|
201
362
|
end
|
@@ -7,6 +7,8 @@ describe GoCardlessPro::Services::MandatePdfsService do
|
|
7
7
|
)
|
8
8
|
end
|
9
9
|
|
10
|
+
let(:response_headers) { { 'Content-Type' => 'application/json' } }
|
11
|
+
|
10
12
|
describe '#create' do
|
11
13
|
subject(:post_create_response) { client.mandate_pdfs.create(params: new_resource) }
|
12
14
|
context 'with a valid request' do
|
@@ -40,13 +42,36 @@ describe GoCardlessPro::Services::MandatePdfsService do
|
|
40
42
|
}
|
41
43
|
|
42
44
|
}.to_json,
|
43
|
-
headers:
|
45
|
+
headers: response_headers
|
44
46
|
)
|
45
47
|
end
|
46
48
|
|
47
49
|
it 'creates and returns the resource' do
|
48
50
|
expect(post_create_response).to be_a(GoCardlessPro::Resources::MandatePdf)
|
49
51
|
end
|
52
|
+
|
53
|
+
describe 'retry behaviour' do
|
54
|
+
before { allow_any_instance_of(GoCardlessPro::Request).to receive(:sleep) }
|
55
|
+
|
56
|
+
it 'retries timeouts' do
|
57
|
+
stub = stub_request(:post, %r{.*api.gocardless.com/mandate_pdfs})
|
58
|
+
.to_timeout.then.to_return(status: 200, headers: response_headers)
|
59
|
+
|
60
|
+
post_create_response
|
61
|
+
expect(stub).to have_been_requested.twice
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'retries 5XX errors' do
|
65
|
+
stub = stub_request(:post, %r{.*api.gocardless.com/mandate_pdfs})
|
66
|
+
.to_return(status: 502,
|
67
|
+
headers: { 'Content-Type' => 'text/html' },
|
68
|
+
body: '<html><body>Response from Cloudflare</body></html>')
|
69
|
+
.then.to_return(status: 200, headers: response_headers)
|
70
|
+
|
71
|
+
post_create_response
|
72
|
+
expect(stub).to have_been_requested.twice
|
73
|
+
end
|
74
|
+
end
|
50
75
|
end
|
51
76
|
|
52
77
|
context 'with a request that returns a validation error' do
|
@@ -63,7 +88,7 @@ describe GoCardlessPro::Services::MandatePdfsService do
|
|
63
88
|
]
|
64
89
|
}
|
65
90
|
}.to_json,
|
66
|
-
headers:
|
91
|
+
headers: response_headers,
|
67
92
|
status: 422
|
68
93
|
)
|
69
94
|
end
|
@@ -72,5 +97,44 @@ describe GoCardlessPro::Services::MandatePdfsService do
|
|
72
97
|
expect { post_create_response }.to raise_error(GoCardlessPro::ValidationError)
|
73
98
|
end
|
74
99
|
end
|
100
|
+
|
101
|
+
context 'with a request that returns an idempotent creation conflict error' do
|
102
|
+
let(:id) { 'ID123' }
|
103
|
+
|
104
|
+
let(:new_resource) do
|
105
|
+
{
|
106
|
+
|
107
|
+
'expires_at' => 'expires_at-input',
|
108
|
+
'url' => 'url-input'
|
109
|
+
}
|
110
|
+
end
|
111
|
+
|
112
|
+
let!(:post_stub) do
|
113
|
+
stub_request(:post, %r{.*api.gocardless.com/mandate_pdfs}).to_return(
|
114
|
+
body: {
|
115
|
+
error: {
|
116
|
+
type: 'invalid_state',
|
117
|
+
code: 409,
|
118
|
+
errors: [
|
119
|
+
{
|
120
|
+
message: 'A resource has already been created with this idempotency key',
|
121
|
+
reason: 'idempotent_creation_conflict',
|
122
|
+
links: {
|
123
|
+
conflicting_resource_id: id
|
124
|
+
}
|
125
|
+
}
|
126
|
+
]
|
127
|
+
}
|
128
|
+
}.to_json,
|
129
|
+
headers: response_headers,
|
130
|
+
status: 409
|
131
|
+
)
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'raises an InvalidStateError' do
|
135
|
+
expect { post_create_response }.to raise_error(GoCardlessPro::InvalidStateError)
|
136
|
+
expect(post_stub).to have_been_requested
|
137
|
+
end
|
138
|
+
end
|
75
139
|
end
|
76
140
|
end
|
@@ -7,6 +7,8 @@ describe GoCardlessPro::Services::MandatesService do
|
|
7
7
|
)
|
8
8
|
end
|
9
9
|
|
10
|
+
let(:response_headers) { { 'Content-Type' => 'application/json' } }
|
11
|
+
|
10
12
|
describe '#create' do
|
11
13
|
subject(:post_create_response) { client.mandates.create(params: new_resource) }
|
12
14
|
context 'with a valid request' do
|
@@ -61,13 +63,36 @@ describe GoCardlessPro::Services::MandatesService do
|
|
61
63
|
}
|
62
64
|
|
63
65
|
}.to_json,
|
64
|
-
headers:
|
66
|
+
headers: response_headers
|
65
67
|
)
|
66
68
|
end
|
67
69
|
|
68
70
|
it 'creates and returns the resource' do
|
69
71
|
expect(post_create_response).to be_a(GoCardlessPro::Resources::Mandate)
|
70
72
|
end
|
73
|
+
|
74
|
+
describe 'retry behaviour' do
|
75
|
+
before { allow_any_instance_of(GoCardlessPro::Request).to receive(:sleep) }
|
76
|
+
|
77
|
+
it 'retries timeouts' do
|
78
|
+
stub = stub_request(:post, %r{.*api.gocardless.com/mandates})
|
79
|
+
.to_timeout.then.to_return(status: 200, headers: response_headers)
|
80
|
+
|
81
|
+
post_create_response
|
82
|
+
expect(stub).to have_been_requested.twice
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'retries 5XX errors' do
|
86
|
+
stub = stub_request(:post, %r{.*api.gocardless.com/mandates})
|
87
|
+
.to_return(status: 502,
|
88
|
+
headers: { 'Content-Type' => 'text/html' },
|
89
|
+
body: '<html><body>Response from Cloudflare</body></html>')
|
90
|
+
.then.to_return(status: 200, headers: response_headers)
|
91
|
+
|
92
|
+
post_create_response
|
93
|
+
expect(stub).to have_been_requested.twice
|
94
|
+
end
|
95
|
+
end
|
71
96
|
end
|
72
97
|
|
73
98
|
context 'with a request that returns a validation error' do
|
@@ -84,7 +109,7 @@ describe GoCardlessPro::Services::MandatesService do
|
|
84
109
|
]
|
85
110
|
}
|
86
111
|
}.to_json,
|
87
|
-
headers:
|
112
|
+
headers: response_headers,
|
88
113
|
status: 422
|
89
114
|
)
|
90
115
|
end
|
@@ -93,35 +118,108 @@ describe GoCardlessPro::Services::MandatesService do
|
|
93
118
|
expect { post_create_response }.to raise_error(GoCardlessPro::ValidationError)
|
94
119
|
end
|
95
120
|
end
|
121
|
+
|
122
|
+
context 'with a request that returns an idempotent creation conflict error' do
|
123
|
+
let(:id) { 'ID123' }
|
124
|
+
|
125
|
+
let(:new_resource) do
|
126
|
+
{
|
127
|
+
|
128
|
+
'created_at' => 'created_at-input',
|
129
|
+
'id' => 'id-input',
|
130
|
+
'links' => 'links-input',
|
131
|
+
'metadata' => 'metadata-input',
|
132
|
+
'next_possible_charge_date' => 'next_possible_charge_date-input',
|
133
|
+
'payments_require_approval' => 'payments_require_approval-input',
|
134
|
+
'reference' => 'reference-input',
|
135
|
+
'scheme' => 'scheme-input',
|
136
|
+
'status' => 'status-input'
|
137
|
+
}
|
138
|
+
end
|
139
|
+
|
140
|
+
let!(:post_stub) do
|
141
|
+
stub_request(:post, %r{.*api.gocardless.com/mandates}).to_return(
|
142
|
+
body: {
|
143
|
+
error: {
|
144
|
+
type: 'invalid_state',
|
145
|
+
code: 409,
|
146
|
+
errors: [
|
147
|
+
{
|
148
|
+
message: 'A resource has already been created with this idempotency key',
|
149
|
+
reason: 'idempotent_creation_conflict',
|
150
|
+
links: {
|
151
|
+
conflicting_resource_id: id
|
152
|
+
}
|
153
|
+
}
|
154
|
+
]
|
155
|
+
}
|
156
|
+
}.to_json,
|
157
|
+
headers: response_headers,
|
158
|
+
status: 409
|
159
|
+
)
|
160
|
+
end
|
161
|
+
|
162
|
+
let!(:get_stub) do
|
163
|
+
stub_url = "/mandates/#{id}"
|
164
|
+
stub_request(:get, /.*api.gocardless.com#{stub_url}/)
|
165
|
+
.to_return(
|
166
|
+
body: {
|
167
|
+
'mandates' => {
|
168
|
+
|
169
|
+
'created_at' => 'created_at-input',
|
170
|
+
'id' => 'id-input',
|
171
|
+
'links' => 'links-input',
|
172
|
+
'metadata' => 'metadata-input',
|
173
|
+
'next_possible_charge_date' => 'next_possible_charge_date-input',
|
174
|
+
'payments_require_approval' => 'payments_require_approval-input',
|
175
|
+
'reference' => 'reference-input',
|
176
|
+
'scheme' => 'scheme-input',
|
177
|
+
'status' => 'status-input'
|
178
|
+
}
|
179
|
+
}.to_json,
|
180
|
+
headers: response_headers
|
181
|
+
)
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'fetches the already-created resource' do
|
185
|
+
post_create_response
|
186
|
+
expect(post_stub).to have_been_requested
|
187
|
+
expect(get_stub).to have_been_requested
|
188
|
+
end
|
189
|
+
end
|
96
190
|
end
|
97
191
|
|
98
192
|
describe '#list' do
|
99
193
|
describe 'with no filters' do
|
100
194
|
subject(:get_list_response) { client.mandates.list }
|
101
195
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
'mandates' => [{
|
196
|
+
let(:body) do
|
197
|
+
{
|
198
|
+
'mandates' => [{
|
106
199
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
}
|
200
|
+
'created_at' => 'created_at-input',
|
201
|
+
'id' => 'id-input',
|
202
|
+
'links' => 'links-input',
|
203
|
+
'metadata' => 'metadata-input',
|
204
|
+
'next_possible_charge_date' => 'next_possible_charge_date-input',
|
205
|
+
'payments_require_approval' => 'payments_require_approval-input',
|
206
|
+
'reference' => 'reference-input',
|
207
|
+
'scheme' => 'scheme-input',
|
208
|
+
'status' => 'status-input'
|
209
|
+
}],
|
210
|
+
meta: {
|
211
|
+
cursors: {
|
212
|
+
before: nil,
|
213
|
+
after: 'ABC123'
|
122
214
|
}
|
123
|
-
}
|
124
|
-
|
215
|
+
}
|
216
|
+
}.to_json
|
217
|
+
end
|
218
|
+
|
219
|
+
before do
|
220
|
+
stub_request(:get, %r{.*api.gocardless.com/mandates}).to_return(
|
221
|
+
body: body,
|
222
|
+
headers: response_headers
|
125
223
|
)
|
126
224
|
end
|
127
225
|
|
@@ -151,6 +249,29 @@ describe GoCardlessPro::Services::MandatesService do
|
|
151
249
|
end
|
152
250
|
|
153
251
|
specify { expect(get_list_response.api_response.headers).to eql('content-type' => 'application/json') }
|
252
|
+
|
253
|
+
describe 'retry behaviour' do
|
254
|
+
before { allow_any_instance_of(GoCardlessPro::Request).to receive(:sleep) }
|
255
|
+
|
256
|
+
it 'retries timeouts' do
|
257
|
+
stub = stub_request(:get, %r{.*api.gocardless.com/mandates})
|
258
|
+
.to_timeout.then.to_return(status: 200, headers: response_headers, body: body)
|
259
|
+
|
260
|
+
get_list_response
|
261
|
+
expect(stub).to have_been_requested.twice
|
262
|
+
end
|
263
|
+
|
264
|
+
it 'retries 5XX errors' do
|
265
|
+
stub = stub_request(:get, %r{.*api.gocardless.com/mandates})
|
266
|
+
.to_return(status: 502,
|
267
|
+
headers: { 'Content-Type' => 'text/html' },
|
268
|
+
body: '<html><body>Response from Cloudflare</body></html>')
|
269
|
+
.then.to_return(status: 200, headers: response_headers, body: body)
|
270
|
+
|
271
|
+
get_list_response
|
272
|
+
expect(stub).to have_been_requested.twice
|
273
|
+
end
|
274
|
+
end
|
154
275
|
end
|
155
276
|
end
|
156
277
|
|
@@ -175,7 +296,7 @@ describe GoCardlessPro::Services::MandatesService do
|
|
175
296
|
limit: 1
|
176
297
|
}
|
177
298
|
}.to_json,
|
178
|
-
headers:
|
299
|
+
headers: response_headers
|
179
300
|
)
|
180
301
|
end
|
181
302
|
|
@@ -199,7 +320,7 @@ describe GoCardlessPro::Services::MandatesService do
|
|
199
320
|
cursors: {}
|
200
321
|
}
|
201
322
|
}.to_json,
|
202
|
-
headers:
|
323
|
+
headers: response_headers
|
203
324
|
)
|
204
325
|
end
|
205
326
|
|
@@ -208,6 +329,119 @@ describe GoCardlessPro::Services::MandatesService do
|
|
208
329
|
expect(first_response_stub).to have_been_requested
|
209
330
|
expect(second_response_stub).to have_been_requested
|
210
331
|
end
|
332
|
+
|
333
|
+
describe 'retry behaviour' do
|
334
|
+
before { allow_any_instance_of(GoCardlessPro::Request).to receive(:sleep) }
|
335
|
+
|
336
|
+
it 'retries timeouts' do
|
337
|
+
first_response_stub = stub_request(:get, %r{.*api.gocardless.com/mandates$}).to_return(
|
338
|
+
body: {
|
339
|
+
'mandates' => [{
|
340
|
+
|
341
|
+
'created_at' => 'created_at-input',
|
342
|
+
'id' => 'id-input',
|
343
|
+
'links' => 'links-input',
|
344
|
+
'metadata' => 'metadata-input',
|
345
|
+
'next_possible_charge_date' => 'next_possible_charge_date-input',
|
346
|
+
'payments_require_approval' => 'payments_require_approval-input',
|
347
|
+
'reference' => 'reference-input',
|
348
|
+
'scheme' => 'scheme-input',
|
349
|
+
'status' => 'status-input'
|
350
|
+
}],
|
351
|
+
meta: {
|
352
|
+
cursors: { after: 'AB345' },
|
353
|
+
limit: 1
|
354
|
+
}
|
355
|
+
}.to_json,
|
356
|
+
headers: response_headers
|
357
|
+
)
|
358
|
+
|
359
|
+
second_response_stub = stub_request(:get, %r{.*api.gocardless.com/mandates\?after=AB345})
|
360
|
+
.to_timeout.then
|
361
|
+
.to_return(
|
362
|
+
body: {
|
363
|
+
'mandates' => [{
|
364
|
+
|
365
|
+
'created_at' => 'created_at-input',
|
366
|
+
'id' => 'id-input',
|
367
|
+
'links' => 'links-input',
|
368
|
+
'metadata' => 'metadata-input',
|
369
|
+
'next_possible_charge_date' => 'next_possible_charge_date-input',
|
370
|
+
'payments_require_approval' => 'payments_require_approval-input',
|
371
|
+
'reference' => 'reference-input',
|
372
|
+
'scheme' => 'scheme-input',
|
373
|
+
'status' => 'status-input'
|
374
|
+
}],
|
375
|
+
meta: {
|
376
|
+
limit: 2,
|
377
|
+
cursors: {}
|
378
|
+
}
|
379
|
+
}.to_json,
|
380
|
+
headers: response_headers
|
381
|
+
)
|
382
|
+
|
383
|
+
client.mandates.all.to_a
|
384
|
+
|
385
|
+
expect(first_response_stub).to have_been_requested
|
386
|
+
expect(second_response_stub).to have_been_requested.twice
|
387
|
+
end
|
388
|
+
|
389
|
+
it 'retries 5XX errors' do
|
390
|
+
first_response_stub = stub_request(:get, %r{.*api.gocardless.com/mandates$}).to_return(
|
391
|
+
body: {
|
392
|
+
'mandates' => [{
|
393
|
+
|
394
|
+
'created_at' => 'created_at-input',
|
395
|
+
'id' => 'id-input',
|
396
|
+
'links' => 'links-input',
|
397
|
+
'metadata' => 'metadata-input',
|
398
|
+
'next_possible_charge_date' => 'next_possible_charge_date-input',
|
399
|
+
'payments_require_approval' => 'payments_require_approval-input',
|
400
|
+
'reference' => 'reference-input',
|
401
|
+
'scheme' => 'scheme-input',
|
402
|
+
'status' => 'status-input'
|
403
|
+
}],
|
404
|
+
meta: {
|
405
|
+
cursors: { after: 'AB345' },
|
406
|
+
limit: 1
|
407
|
+
}
|
408
|
+
}.to_json,
|
409
|
+
headers: response_headers
|
410
|
+
)
|
411
|
+
|
412
|
+
second_response_stub = stub_request(:get, %r{.*api.gocardless.com/mandates\?after=AB345})
|
413
|
+
.to_return(
|
414
|
+
status: 502,
|
415
|
+
body: '<html><body>Response from Cloudflare</body></html>',
|
416
|
+
headers: { 'Content-Type' => 'text/html' }
|
417
|
+
).then.to_return(
|
418
|
+
body: {
|
419
|
+
'mandates' => [{
|
420
|
+
|
421
|
+
'created_at' => 'created_at-input',
|
422
|
+
'id' => 'id-input',
|
423
|
+
'links' => 'links-input',
|
424
|
+
'metadata' => 'metadata-input',
|
425
|
+
'next_possible_charge_date' => 'next_possible_charge_date-input',
|
426
|
+
'payments_require_approval' => 'payments_require_approval-input',
|
427
|
+
'reference' => 'reference-input',
|
428
|
+
'scheme' => 'scheme-input',
|
429
|
+
'status' => 'status-input'
|
430
|
+
}],
|
431
|
+
meta: {
|
432
|
+
limit: 2,
|
433
|
+
cursors: {}
|
434
|
+
}
|
435
|
+
}.to_json,
|
436
|
+
headers: response_headers
|
437
|
+
)
|
438
|
+
|
439
|
+
client.mandates.all.to_a
|
440
|
+
|
441
|
+
expect(first_response_stub).to have_been_requested
|
442
|
+
expect(second_response_stub).to have_been_requested.twice
|
443
|
+
end
|
444
|
+
end
|
211
445
|
end
|
212
446
|
|
213
447
|
describe '#get' do
|
@@ -235,7 +469,7 @@ describe GoCardlessPro::Services::MandatesService do
|
|
235
469
|
'status' => 'status-input'
|
236
470
|
}
|
237
471
|
}.to_json,
|
238
|
-
headers:
|
472
|
+
headers: response_headers
|
239
473
|
)
|
240
474
|
end
|
241
475
|
|
@@ -269,7 +503,7 @@ describe GoCardlessPro::Services::MandatesService do
|
|
269
503
|
'status' => 'status-input'
|
270
504
|
}
|
271
505
|
}.to_json,
|
272
|
-
headers:
|
506
|
+
headers: response_headers
|
273
507
|
)
|
274
508
|
end
|
275
509
|
|
@@ -283,7 +517,7 @@ describe GoCardlessPro::Services::MandatesService do
|
|
283
517
|
stub_url = '/mandates/:identity'.gsub(':identity', id)
|
284
518
|
stub_request(:get, /.*api.gocardless.com#{stub_url}/).to_return(
|
285
519
|
body: '',
|
286
|
-
headers:
|
520
|
+
headers: response_headers
|
287
521
|
)
|
288
522
|
end
|
289
523
|
|
@@ -299,6 +533,33 @@ describe GoCardlessPro::Services::MandatesService do
|
|
299
533
|
expect { get_response }.to_not raise_error(/bad URI/)
|
300
534
|
end
|
301
535
|
end
|
536
|
+
|
537
|
+
describe 'retry behaviour' do
|
538
|
+
before { allow_any_instance_of(GoCardlessPro::Request).to receive(:sleep) }
|
539
|
+
|
540
|
+
it 'retries timeouts' do
|
541
|
+
stub_url = '/mandates/:identity'.gsub(':identity', id)
|
542
|
+
|
543
|
+
stub = stub_request(:get, /.*api.gocardless.com#{stub_url}/)
|
544
|
+
.to_timeout.then.to_return(status: 200, headers: response_headers)
|
545
|
+
|
546
|
+
get_response
|
547
|
+
expect(stub).to have_been_requested.twice
|
548
|
+
end
|
549
|
+
|
550
|
+
it 'retries 5XX errors' do
|
551
|
+
stub_url = '/mandates/:identity'.gsub(':identity', id)
|
552
|
+
|
553
|
+
stub = stub_request(:get, /.*api.gocardless.com#{stub_url}/)
|
554
|
+
.to_return(status: 502,
|
555
|
+
headers: { 'Content-Type' => 'text/html' },
|
556
|
+
body: '<html><body>Response from Cloudflare</body></html>')
|
557
|
+
.then.to_return(status: 200, headers: response_headers)
|
558
|
+
|
559
|
+
get_response
|
560
|
+
expect(stub).to have_been_requested.twice
|
561
|
+
end
|
562
|
+
end
|
302
563
|
end
|
303
564
|
|
304
565
|
describe '#update' do
|
@@ -325,7 +586,7 @@ describe GoCardlessPro::Services::MandatesService do
|
|
325
586
|
'status' => 'status-input'
|
326
587
|
}
|
327
588
|
}.to_json,
|
328
|
-
headers:
|
589
|
+
headers: response_headers
|
329
590
|
)
|
330
591
|
end
|
331
592
|
|
@@ -333,6 +594,31 @@ describe GoCardlessPro::Services::MandatesService do
|
|
333
594
|
expect(put_update_response).to be_a(GoCardlessPro::Resources::Mandate)
|
334
595
|
expect(stub).to have_been_requested
|
335
596
|
end
|
597
|
+
|
598
|
+
describe 'retry behaviour' do
|
599
|
+
before { allow_any_instance_of(GoCardlessPro::Request).to receive(:sleep) }
|
600
|
+
|
601
|
+
it 'retries timeouts' do
|
602
|
+
stub_url = '/mandates/:identity'.gsub(':identity', id)
|
603
|
+
stub = stub_request(:put, /.*api.gocardless.com#{stub_url}/)
|
604
|
+
.to_timeout.then.to_return(status: 200, headers: response_headers)
|
605
|
+
|
606
|
+
put_update_response
|
607
|
+
expect(stub).to have_been_requested.twice
|
608
|
+
end
|
609
|
+
|
610
|
+
it 'retries 5XX errors' do
|
611
|
+
stub_url = '/mandates/:identity'.gsub(':identity', id)
|
612
|
+
stub = stub_request(:put, /.*api.gocardless.com#{stub_url}/)
|
613
|
+
.to_return(status: 502,
|
614
|
+
headers: { 'Content-Type' => 'text/html' },
|
615
|
+
body: '<html><body>Response from Cloudflare</body></html>')
|
616
|
+
.then.to_return(status: 200, headers: response_headers)
|
617
|
+
|
618
|
+
put_update_response
|
619
|
+
expect(stub).to have_been_requested.twice
|
620
|
+
end
|
621
|
+
end
|
336
622
|
end
|
337
623
|
end
|
338
624
|
|
@@ -359,7 +645,7 @@ describe GoCardlessPro::Services::MandatesService do
|
|
359
645
|
'status' => 'status-input'
|
360
646
|
}
|
361
647
|
}.to_json,
|
362
|
-
headers:
|
648
|
+
headers: response_headers
|
363
649
|
)
|
364
650
|
end
|
365
651
|
|
@@ -369,6 +655,17 @@ describe GoCardlessPro::Services::MandatesService do
|
|
369
655
|
expect(stub).to have_been_requested
|
370
656
|
end
|
371
657
|
|
658
|
+
describe 'retry behaviour' do
|
659
|
+
it "doesn't retry errors" do
|
660
|
+
stub_url = '/mandates/:identity/actions/cancel'.gsub(':identity', resource_id)
|
661
|
+
stub = stub_request(:post, /.*api.gocardless.com#{stub_url}/)
|
662
|
+
.to_timeout
|
663
|
+
|
664
|
+
expect { post_response }.to raise_error(Faraday::TimeoutError)
|
665
|
+
expect(stub).to have_been_requested
|
666
|
+
end
|
667
|
+
end
|
668
|
+
|
372
669
|
context 'when the request needs a body and custom header' do
|
373
670
|
let(:body) { { foo: 'bar' } }
|
374
671
|
let(:headers) { { 'Foo' => 'Bar' } }
|
@@ -398,7 +695,7 @@ describe GoCardlessPro::Services::MandatesService do
|
|
398
695
|
'status' => 'status-input'
|
399
696
|
}
|
400
697
|
}.to_json,
|
401
|
-
headers:
|
698
|
+
headers: response_headers
|
402
699
|
)
|
403
700
|
end
|
404
701
|
end
|
@@ -427,7 +724,7 @@ describe GoCardlessPro::Services::MandatesService do
|
|
427
724
|
'status' => 'status-input'
|
428
725
|
}
|
429
726
|
}.to_json,
|
430
|
-
headers:
|
727
|
+
headers: response_headers
|
431
728
|
)
|
432
729
|
end
|
433
730
|
|
@@ -437,6 +734,17 @@ describe GoCardlessPro::Services::MandatesService do
|
|
437
734
|
expect(stub).to have_been_requested
|
438
735
|
end
|
439
736
|
|
737
|
+
describe 'retry behaviour' do
|
738
|
+
it "doesn't retry errors" do
|
739
|
+
stub_url = '/mandates/:identity/actions/reinstate'.gsub(':identity', resource_id)
|
740
|
+
stub = stub_request(:post, /.*api.gocardless.com#{stub_url}/)
|
741
|
+
.to_timeout
|
742
|
+
|
743
|
+
expect { post_response }.to raise_error(Faraday::TimeoutError)
|
744
|
+
expect(stub).to have_been_requested
|
745
|
+
end
|
746
|
+
end
|
747
|
+
|
440
748
|
context 'when the request needs a body and custom header' do
|
441
749
|
let(:body) { { foo: 'bar' } }
|
442
750
|
let(:headers) { { 'Foo' => 'Bar' } }
|
@@ -466,7 +774,7 @@ describe GoCardlessPro::Services::MandatesService do
|
|
466
774
|
'status' => 'status-input'
|
467
775
|
}
|
468
776
|
}.to_json,
|
469
|
-
headers:
|
777
|
+
headers: response_headers
|
470
778
|
)
|
471
779
|
end
|
472
780
|
end
|