gocardless_pro 2.24.0 → 2.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +23 -4
  3. data/lib/gocardless_pro/api_service.rb +4 -0
  4. data/lib/gocardless_pro/client.rb +46 -1
  5. data/lib/gocardless_pro/error/authentication_error.rb +4 -0
  6. data/lib/gocardless_pro/error/permission_error.rb +4 -0
  7. data/lib/gocardless_pro/error/rate_limit_error.rb +4 -0
  8. data/lib/gocardless_pro/middlewares/raise_gocardless_errors.rb +12 -1
  9. data/lib/gocardless_pro/resources/bank_authorisation.rb +81 -0
  10. data/lib/gocardless_pro/resources/billing_request.rb +108 -0
  11. data/lib/gocardless_pro/resources/billing_request_flow.rb +72 -0
  12. data/lib/gocardless_pro/resources/billing_request_template.rb +68 -0
  13. data/lib/gocardless_pro/resources/block.rb +66 -0
  14. data/lib/gocardless_pro/resources/creditor.rb +2 -3
  15. data/lib/gocardless_pro/resources/event.rb +20 -0
  16. data/lib/gocardless_pro/resources/institution.rb +47 -0
  17. data/lib/gocardless_pro/resources/payer_authorisation.rb +131 -0
  18. data/lib/gocardless_pro/resources/payout_item.rb +4 -0
  19. data/lib/gocardless_pro/resources/redirect_flow.rb +2 -0
  20. data/lib/gocardless_pro/resources/scenario_simulator.rb +42 -0
  21. data/lib/gocardless_pro/resources/webhook.rb +62 -0
  22. data/lib/gocardless_pro/services/bank_authorisations_service.rb +80 -0
  23. data/lib/gocardless_pro/services/billing_request_flows_service.rb +70 -0
  24. data/lib/gocardless_pro/services/billing_request_templates_service.rb +131 -0
  25. data/lib/gocardless_pro/services/billing_requests_service.rb +352 -0
  26. data/lib/gocardless_pro/services/blocks_service.rb +223 -0
  27. data/lib/gocardless_pro/services/creditor_bank_accounts_service.rb +1 -5
  28. data/lib/gocardless_pro/services/creditors_service.rb +1 -3
  29. data/lib/gocardless_pro/services/currency_exchange_rates_service.rb +1 -1
  30. data/lib/gocardless_pro/services/customer_bank_accounts_service.rb +1 -5
  31. data/lib/gocardless_pro/services/customers_service.rb +1 -3
  32. data/lib/gocardless_pro/services/events_service.rb +1 -1
  33. data/lib/gocardless_pro/services/instalment_schedules_service.rb +1 -7
  34. data/lib/gocardless_pro/services/institutions_service.rb +56 -0
  35. data/lib/gocardless_pro/services/mandate_import_entries_service.rb +1 -1
  36. data/lib/gocardless_pro/services/mandate_imports_service.rb +0 -6
  37. data/lib/gocardless_pro/services/mandates_service.rb +1 -7
  38. data/lib/gocardless_pro/services/payer_authorisations_service.rb +202 -0
  39. data/lib/gocardless_pro/services/payments_service.rb +1 -7
  40. data/lib/gocardless_pro/services/payout_items_service.rb +1 -1
  41. data/lib/gocardless_pro/services/payouts_service.rb +1 -1
  42. data/lib/gocardless_pro/services/redirect_flows_service.rb +0 -4
  43. data/lib/gocardless_pro/services/refunds_service.rb +1 -3
  44. data/lib/gocardless_pro/services/scenario_simulators_service.rb +170 -0
  45. data/lib/gocardless_pro/services/subscriptions_service.rb +10 -13
  46. data/lib/gocardless_pro/services/tax_rates_service.rb +1 -1
  47. data/lib/gocardless_pro/services/webhooks_service.rb +111 -0
  48. data/lib/gocardless_pro/version.rb +1 -1
  49. data/lib/gocardless_pro.rb +30 -0
  50. data/spec/api_service_spec.rb +12 -1
  51. data/spec/middlewares/raise_gocardless_errors_spec.rb +30 -0
  52. data/spec/resources/bank_authorisation_spec.rb +259 -0
  53. data/spec/resources/billing_request_flow_spec.rb +219 -0
  54. data/spec/resources/billing_request_spec.rb +782 -0
  55. data/spec/resources/billing_request_template_spec.rb +502 -0
  56. data/spec/resources/block_spec.rb +560 -0
  57. data/spec/resources/institution_spec.rb +108 -0
  58. data/spec/resources/payer_authorisation_spec.rb +418 -0
  59. data/spec/resources/redirect_flow_spec.rb +9 -0
  60. data/spec/resources/scenario_simulator_spec.rb +63 -0
  61. data/spec/resources/webhook_spec.rb +323 -0
  62. data/spec/services/bank_authorisations_service_spec.rb +353 -0
  63. data/spec/services/billing_request_flows_service_spec.rb +253 -0
  64. data/spec/services/billing_request_templates_service_spec.rb +789 -0
  65. data/spec/services/billing_requests_service_spec.rb +1082 -0
  66. data/spec/services/blocks_service_spec.rb +823 -0
  67. data/spec/services/creditor_bank_accounts_service_spec.rb +0 -13
  68. data/spec/services/creditors_service_spec.rb +0 -13
  69. data/spec/services/customer_bank_accounts_service_spec.rb +0 -13
  70. data/spec/services/customers_service_spec.rb +0 -13
  71. data/spec/services/instalment_schedules_service_spec.rb +0 -26
  72. data/spec/services/institutions_service_spec.rb +232 -0
  73. data/spec/services/mandate_imports_service_spec.rb +0 -13
  74. data/spec/services/mandates_service_spec.rb +0 -13
  75. data/spec/services/payer_authorisations_service_spec.rb +559 -0
  76. data/spec/services/payments_service_spec.rb +0 -13
  77. data/spec/services/redirect_flows_service_spec.rb +9 -13
  78. data/spec/services/refunds_service_spec.rb +0 -13
  79. data/spec/services/scenario_simulators_service_spec.rb +74 -0
  80. data/spec/services/subscriptions_service_spec.rb +0 -13
  81. data/spec/services/webhooks_service_spec.rb +545 -0
  82. metadata +64 -7
@@ -212,19 +212,6 @@ describe GoCardlessPro::Services::CreditorBankAccountsService do
212
212
  to raise_error(GoCardlessPro::IdempotencyConflict)
213
213
  end
214
214
  end
215
-
216
- context 'with on_idempotency_conflict: :unknown' do
217
- let(:client) do
218
- GoCardlessPro::Client.new(
219
- access_token: 'SECRET_TOKEN',
220
- on_idempotency_conflict: :unknown
221
- )
222
- end
223
-
224
- it 'raises an ArgumentError' do
225
- expect { post_create_response }.to raise_error(ArgumentError)
226
- end
227
- end
228
215
  end
229
216
  end
230
217
 
@@ -252,19 +252,6 @@ describe GoCardlessPro::Services::CreditorsService do
252
252
  to raise_error(GoCardlessPro::IdempotencyConflict)
253
253
  end
254
254
  end
255
-
256
- context 'with on_idempotency_conflict: :unknown' do
257
- let(:client) do
258
- GoCardlessPro::Client.new(
259
- access_token: 'SECRET_TOKEN',
260
- on_idempotency_conflict: :unknown
261
- )
262
- end
263
-
264
- it 'raises an ArgumentError' do
265
- expect { post_create_response }.to raise_error(ArgumentError)
266
- end
267
- end
268
255
  end
269
256
  end
270
257
 
@@ -212,19 +212,6 @@ describe GoCardlessPro::Services::CustomerBankAccountsService do
212
212
  to raise_error(GoCardlessPro::IdempotencyConflict)
213
213
  end
214
214
  end
215
-
216
- context 'with on_idempotency_conflict: :unknown' do
217
- let(:client) do
218
- GoCardlessPro::Client.new(
219
- access_token: 'SECRET_TOKEN',
220
- on_idempotency_conflict: :unknown
221
- )
222
- end
223
-
224
- it 'raises an ArgumentError' do
225
- expect { post_create_response }.to raise_error(ArgumentError)
226
- end
227
- end
228
215
  end
229
216
  end
230
217
 
@@ -247,19 +247,6 @@ describe GoCardlessPro::Services::CustomersService do
247
247
  to raise_error(GoCardlessPro::IdempotencyConflict)
248
248
  end
249
249
  end
250
-
251
- context 'with on_idempotency_conflict: :unknown' do
252
- let(:client) do
253
- GoCardlessPro::Client.new(
254
- access_token: 'SECRET_TOKEN',
255
- on_idempotency_conflict: :unknown
256
- )
257
- end
258
-
259
- it 'raises an ArgumentError' do
260
- expect { post_create_response }.to raise_error(ArgumentError)
261
- end
262
- end
263
250
  end
264
251
  end
265
252
 
@@ -202,19 +202,6 @@ describe GoCardlessPro::Services::InstalmentSchedulesService do
202
202
  to raise_error(GoCardlessPro::IdempotencyConflict)
203
203
  end
204
204
  end
205
-
206
- context 'with on_idempotency_conflict: :unknown' do
207
- let(:client) do
208
- GoCardlessPro::Client.new(
209
- access_token: 'SECRET_TOKEN',
210
- on_idempotency_conflict: :unknown
211
- )
212
- end
213
-
214
- it 'raises an ArgumentError' do
215
- expect { post_create_response }.to raise_error(ArgumentError)
216
- end
217
- end
218
205
  end
219
206
  end
220
207
 
@@ -411,19 +398,6 @@ describe GoCardlessPro::Services::InstalmentSchedulesService do
411
398
  to raise_error(GoCardlessPro::IdempotencyConflict)
412
399
  end
413
400
  end
414
-
415
- context 'with on_idempotency_conflict: :unknown' do
416
- let(:client) do
417
- GoCardlessPro::Client.new(
418
- access_token: 'SECRET_TOKEN',
419
- on_idempotency_conflict: :unknown
420
- )
421
- end
422
-
423
- it 'raises an ArgumentError' do
424
- expect { post_create_response }.to raise_error(ArgumentError)
425
- end
426
- end
427
401
  end
428
402
  end
429
403
 
@@ -0,0 +1,232 @@
1
+ require 'spec_helper'
2
+
3
+ describe GoCardlessPro::Services::InstitutionsService 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.institutions.list }
15
+
16
+ let(:body) do
17
+ {
18
+ 'institutions' => [{
19
+
20
+ 'country_code' => 'country_code-input',
21
+ 'icon_url' => 'icon_url-input',
22
+ 'id' => 'id-input',
23
+ 'logo_url' => 'logo_url-input',
24
+ 'name' => 'name-input',
25
+ }],
26
+ meta: {
27
+ cursors: {
28
+ before: nil,
29
+ after: 'ABC123',
30
+ },
31
+ },
32
+ }.to_json
33
+ end
34
+
35
+ before do
36
+ stub_request(:get, %r{.*api.gocardless.com/institutions}).to_return(
37
+ body: body,
38
+ headers: response_headers
39
+ )
40
+ end
41
+
42
+ it 'wraps each item in the resource class' do
43
+ expect(get_list_response.records.map(&:class).uniq.first).to eq(GoCardlessPro::Resources::Institution)
44
+
45
+ expect(get_list_response.records.first.country_code).to eq('country_code-input')
46
+
47
+ expect(get_list_response.records.first.icon_url).to eq('icon_url-input')
48
+
49
+ expect(get_list_response.records.first.id).to eq('id-input')
50
+
51
+ expect(get_list_response.records.first.logo_url).to eq('logo_url-input')
52
+
53
+ expect(get_list_response.records.first.name).to eq('name-input')
54
+ end
55
+
56
+ it 'exposes the cursors for before and after' do
57
+ expect(get_list_response.before).to eq(nil)
58
+ expect(get_list_response.after).to eq('ABC123')
59
+ end
60
+
61
+ specify { expect(get_list_response.api_response.headers).to eql('content-type' => 'application/json') }
62
+
63
+ describe 'retry behaviour' do
64
+ before { allow_any_instance_of(GoCardlessPro::Request).to receive(:sleep) }
65
+
66
+ it 'retries timeouts' do
67
+ stub = stub_request(:get, %r{.*api.gocardless.com/institutions}).
68
+ to_timeout.then.to_return(status: 200, headers: response_headers, body: body)
69
+
70
+ get_list_response
71
+ expect(stub).to have_been_requested.twice
72
+ end
73
+
74
+ it 'retries 5XX errors' do
75
+ stub = stub_request(:get, %r{.*api.gocardless.com/institutions}).
76
+ to_return(status: 502,
77
+ headers: { 'Content-Type' => 'text/html' },
78
+ body: '<html><body>Response from Cloudflare</body></html>').
79
+ then.to_return(status: 200, headers: response_headers, body: body)
80
+
81
+ get_list_response
82
+ expect(stub).to have_been_requested.twice
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ describe '#all' do
89
+ let!(:first_response_stub) do
90
+ stub_request(:get, %r{.*api.gocardless.com/institutions$}).to_return(
91
+ body: {
92
+ 'institutions' => [{
93
+
94
+ 'country_code' => 'country_code-input',
95
+ 'icon_url' => 'icon_url-input',
96
+ 'id' => 'id-input',
97
+ 'logo_url' => 'logo_url-input',
98
+ 'name' => 'name-input',
99
+ }],
100
+ meta: {
101
+ cursors: { after: 'AB345' },
102
+ limit: 1,
103
+ },
104
+ }.to_json,
105
+ headers: response_headers
106
+ )
107
+ end
108
+
109
+ let!(:second_response_stub) do
110
+ stub_request(:get, %r{.*api.gocardless.com/institutions\?after=AB345}).to_return(
111
+ body: {
112
+ 'institutions' => [{
113
+
114
+ 'country_code' => 'country_code-input',
115
+ 'icon_url' => 'icon_url-input',
116
+ 'id' => 'id-input',
117
+ 'logo_url' => 'logo_url-input',
118
+ 'name' => 'name-input',
119
+ }],
120
+ meta: {
121
+ limit: 2,
122
+ cursors: {},
123
+ },
124
+ }.to_json,
125
+ headers: response_headers
126
+ )
127
+ end
128
+
129
+ it 'automatically makes the extra requests' do
130
+ expect(client.institutions.all.to_a.length).to eq(2)
131
+ expect(first_response_stub).to have_been_requested
132
+ expect(second_response_stub).to have_been_requested
133
+ end
134
+
135
+ describe 'retry behaviour' do
136
+ before { allow_any_instance_of(GoCardlessPro::Request).to receive(:sleep) }
137
+
138
+ it 'retries timeouts' do
139
+ first_response_stub = stub_request(:get, %r{.*api.gocardless.com/institutions$}).to_return(
140
+ body: {
141
+ 'institutions' => [{
142
+
143
+ 'country_code' => 'country_code-input',
144
+ 'icon_url' => 'icon_url-input',
145
+ 'id' => 'id-input',
146
+ 'logo_url' => 'logo_url-input',
147
+ 'name' => 'name-input',
148
+ }],
149
+ meta: {
150
+ cursors: { after: 'AB345' },
151
+ limit: 1,
152
+ },
153
+ }.to_json,
154
+ headers: response_headers
155
+ )
156
+
157
+ second_response_stub = stub_request(:get, %r{.*api.gocardless.com/institutions\?after=AB345}).
158
+ to_timeout.then.
159
+ to_return(
160
+ body: {
161
+ 'institutions' => [{
162
+
163
+ 'country_code' => 'country_code-input',
164
+ 'icon_url' => 'icon_url-input',
165
+ 'id' => 'id-input',
166
+ 'logo_url' => 'logo_url-input',
167
+ 'name' => 'name-input',
168
+ }],
169
+ meta: {
170
+ limit: 2,
171
+ cursors: {},
172
+ },
173
+ }.to_json,
174
+ headers: response_headers
175
+ )
176
+
177
+ client.institutions.all.to_a
178
+
179
+ expect(first_response_stub).to have_been_requested
180
+ expect(second_response_stub).to have_been_requested.twice
181
+ end
182
+
183
+ it 'retries 5XX errors' do
184
+ first_response_stub = stub_request(:get, %r{.*api.gocardless.com/institutions$}).to_return(
185
+ body: {
186
+ 'institutions' => [{
187
+
188
+ 'country_code' => 'country_code-input',
189
+ 'icon_url' => 'icon_url-input',
190
+ 'id' => 'id-input',
191
+ 'logo_url' => 'logo_url-input',
192
+ 'name' => 'name-input',
193
+ }],
194
+ meta: {
195
+ cursors: { after: 'AB345' },
196
+ limit: 1,
197
+ },
198
+ }.to_json,
199
+ headers: response_headers
200
+ )
201
+
202
+ second_response_stub = stub_request(:get, %r{.*api.gocardless.com/institutions\?after=AB345}).
203
+ to_return(
204
+ status: 502,
205
+ body: '<html><body>Response from Cloudflare</body></html>',
206
+ headers: { 'Content-Type' => 'text/html' }
207
+ ).then.to_return(
208
+ body: {
209
+ 'institutions' => [{
210
+
211
+ 'country_code' => 'country_code-input',
212
+ 'icon_url' => 'icon_url-input',
213
+ 'id' => 'id-input',
214
+ 'logo_url' => 'logo_url-input',
215
+ 'name' => 'name-input',
216
+ }],
217
+ meta: {
218
+ limit: 2,
219
+ cursors: {},
220
+ },
221
+ }.to_json,
222
+ headers: response_headers
223
+ )
224
+
225
+ client.institutions.all.to_a
226
+
227
+ expect(first_response_stub).to have_been_requested
228
+ expect(second_response_stub).to have_been_requested.twice
229
+ end
230
+ end
231
+ end
232
+ end
@@ -177,19 +177,6 @@ describe GoCardlessPro::Services::MandateImportsService do
177
177
  to raise_error(GoCardlessPro::IdempotencyConflict)
178
178
  end
179
179
  end
180
-
181
- context 'with on_idempotency_conflict: :unknown' do
182
- let(:client) do
183
- GoCardlessPro::Client.new(
184
- access_token: 'SECRET_TOKEN',
185
- on_idempotency_conflict: :unknown
186
- )
187
- end
188
-
189
- it 'raises an ArgumentError' do
190
- expect { post_create_response }.to raise_error(ArgumentError)
191
- end
192
- end
193
180
  end
194
181
  end
195
182
 
@@ -202,19 +202,6 @@ describe GoCardlessPro::Services::MandatesService do
202
202
  to raise_error(GoCardlessPro::IdempotencyConflict)
203
203
  end
204
204
  end
205
-
206
- context 'with on_idempotency_conflict: :unknown' do
207
- let(:client) do
208
- GoCardlessPro::Client.new(
209
- access_token: 'SECRET_TOKEN',
210
- on_idempotency_conflict: :unknown
211
- )
212
- end
213
-
214
- it 'raises an ArgumentError' do
215
- expect { post_create_response }.to raise_error(ArgumentError)
216
- end
217
- end
218
205
  end
219
206
  end
220
207