gocardless_pro 2.20.0 → 2.24.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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +25 -43
  3. data/Gemfile +7 -0
  4. data/gocardless_pro.gemspec +2 -2
  5. data/lib/gocardless_pro.rb +3 -0
  6. data/lib/gocardless_pro/api_service.rb +1 -1
  7. data/lib/gocardless_pro/client.rb +6 -1
  8. data/lib/gocardless_pro/resources/event.rb +12 -0
  9. data/lib/gocardless_pro/resources/payout.rb +2 -0
  10. data/lib/gocardless_pro/resources/payout_item.rb +2 -0
  11. data/lib/gocardless_pro/resources/tax_rate.rb +51 -0
  12. data/lib/gocardless_pro/services/bank_details_lookups_service.rb +0 -10
  13. data/lib/gocardless_pro/services/base_service.rb +11 -0
  14. data/lib/gocardless_pro/services/creditor_bank_accounts_service.rb +0 -10
  15. data/lib/gocardless_pro/services/creditors_service.rb +0 -10
  16. data/lib/gocardless_pro/services/currency_exchange_rates_service.rb +0 -10
  17. data/lib/gocardless_pro/services/customer_bank_accounts_service.rb +0 -10
  18. data/lib/gocardless_pro/services/customer_notifications_service.rb +0 -10
  19. data/lib/gocardless_pro/services/customers_service.rb +0 -10
  20. data/lib/gocardless_pro/services/events_service.rb +0 -10
  21. data/lib/gocardless_pro/services/instalment_schedules_service.rb +0 -10
  22. data/lib/gocardless_pro/services/mandate_import_entries_service.rb +0 -10
  23. data/lib/gocardless_pro/services/mandate_imports_service.rb +0 -10
  24. data/lib/gocardless_pro/services/mandate_pdfs_service.rb +0 -10
  25. data/lib/gocardless_pro/services/mandates_service.rb +0 -10
  26. data/lib/gocardless_pro/services/payments_service.rb +0 -10
  27. data/lib/gocardless_pro/services/payout_items_service.rb +0 -10
  28. data/lib/gocardless_pro/services/payouts_service.rb +0 -10
  29. data/lib/gocardless_pro/services/redirect_flows_service.rb +0 -10
  30. data/lib/gocardless_pro/services/refunds_service.rb +6 -11
  31. data/lib/gocardless_pro/services/subscriptions_service.rb +1 -11
  32. data/lib/gocardless_pro/services/tax_rates_service.rb +74 -0
  33. data/lib/gocardless_pro/version.rb +1 -1
  34. data/spec/resources/payout_item_spec.rb +5 -0
  35. data/spec/resources/payout_spec.rb +8 -0
  36. data/spec/resources/tax_rate_spec.rb +198 -0
  37. data/spec/services/creditor_bank_accounts_service_spec.rb +1 -1
  38. data/spec/services/customer_bank_accounts_service_spec.rb +1 -1
  39. data/spec/services/customer_notifications_service_spec.rb +1 -1
  40. data/spec/services/customers_service_spec.rb +1 -1
  41. data/spec/services/instalment_schedules_service_spec.rb +1 -1
  42. data/spec/services/mandate_imports_service_spec.rb +2 -2
  43. data/spec/services/mandates_service_spec.rb +2 -2
  44. data/spec/services/payments_service_spec.rb +2 -2
  45. data/spec/services/payout_items_service_spec.rb +9 -0
  46. data/spec/services/payouts_service_spec.rb +12 -0
  47. data/spec/services/redirect_flows_service_spec.rb +1 -1
  48. data/spec/services/subscriptions_service_spec.rb +3 -3
  49. data/spec/services/tax_rates_service_spec.rb +381 -0
  50. metadata +13 -7
@@ -692,7 +692,7 @@ describe GoCardlessPro::Services::CreditorBankAccountsService do
692
692
  stub = stub_request(:post, /.*api.gocardless.com#{stub_url}/).
693
693
  to_timeout
694
694
 
695
- expect { post_response }.to raise_error(Faraday::TimeoutError)
695
+ expect { post_response }.to raise_error(Faraday::ConnectionFailed)
696
696
  expect(stub).to have_been_requested
697
697
  end
698
698
  end
@@ -754,7 +754,7 @@ describe GoCardlessPro::Services::CustomerBankAccountsService do
754
754
  stub = stub_request(:post, /.*api.gocardless.com#{stub_url}/).
755
755
  to_timeout
756
756
 
757
- expect { post_response }.to raise_error(Faraday::TimeoutError)
757
+ expect { post_response }.to raise_error(Faraday::ConnectionFailed)
758
758
  expect(stub).to have_been_requested
759
759
  end
760
760
  end
@@ -45,7 +45,7 @@ describe GoCardlessPro::Services::CustomerNotificationsService do
45
45
  stub = stub_request(:post, /.*api.gocardless.com#{stub_url}/).
46
46
  to_timeout
47
47
 
48
- expect { post_response }.to raise_error(Faraday::TimeoutError)
48
+ expect { post_response }.to raise_error(Faraday::ConnectionFailed)
49
49
  expect(stub).to have_been_requested
50
50
  end
51
51
  end
@@ -882,7 +882,7 @@ describe GoCardlessPro::Services::CustomersService do
882
882
  stub = stub_request(:delete, /.*api.gocardless.com#{stub_url}/).
883
883
  to_timeout
884
884
 
885
- expect { delete_response }.to raise_error(Faraday::TimeoutError)
885
+ expect { delete_response }.to raise_error(Faraday::ConnectionFailed)
886
886
  expect(stub).to have_been_requested
887
887
  end
888
888
  end
@@ -927,7 +927,7 @@ describe GoCardlessPro::Services::InstalmentSchedulesService do
927
927
  stub = stub_request(:post, /.*api.gocardless.com#{stub_url}/).
928
928
  to_timeout
929
929
 
930
- expect { post_response }.to raise_error(Faraday::TimeoutError)
930
+ expect { post_response }.to raise_error(Faraday::ConnectionFailed)
931
931
  expect(stub).to have_been_requested
932
932
  end
933
933
  end
@@ -363,7 +363,7 @@ describe GoCardlessPro::Services::MandateImportsService do
363
363
  stub = stub_request(:post, /.*api.gocardless.com#{stub_url}/).
364
364
  to_timeout
365
365
 
366
- expect { post_response }.to raise_error(Faraday::TimeoutError)
366
+ expect { post_response }.to raise_error(Faraday::ConnectionFailed)
367
367
  expect(stub).to have_been_requested
368
368
  end
369
369
  end
@@ -432,7 +432,7 @@ describe GoCardlessPro::Services::MandateImportsService do
432
432
  stub = stub_request(:post, /.*api.gocardless.com#{stub_url}/).
433
433
  to_timeout
434
434
 
435
- expect { post_response }.to raise_error(Faraday::TimeoutError)
435
+ expect { post_response }.to raise_error(Faraday::ConnectionFailed)
436
436
  expect(stub).to have_been_requested
437
437
  end
438
438
  end
@@ -718,7 +718,7 @@ describe GoCardlessPro::Services::MandatesService do
718
718
  stub = stub_request(:post, /.*api.gocardless.com#{stub_url}/).
719
719
  to_timeout
720
720
 
721
- expect { post_response }.to raise_error(Faraday::TimeoutError)
721
+ expect { post_response }.to raise_error(Faraday::ConnectionFailed)
722
722
  expect(stub).to have_been_requested
723
723
  end
724
724
  end
@@ -797,7 +797,7 @@ describe GoCardlessPro::Services::MandatesService do
797
797
  stub = stub_request(:post, /.*api.gocardless.com#{stub_url}/).
798
798
  to_timeout
799
799
 
800
- expect { post_response }.to raise_error(Faraday::TimeoutError)
800
+ expect { post_response }.to raise_error(Faraday::ConnectionFailed)
801
801
  expect(stub).to have_been_requested
802
802
  end
803
803
  end
@@ -790,7 +790,7 @@ describe GoCardlessPro::Services::PaymentsService do
790
790
  stub = stub_request(:post, /.*api.gocardless.com#{stub_url}/).
791
791
  to_timeout
792
792
 
793
- expect { post_response }.to raise_error(Faraday::TimeoutError)
793
+ expect { post_response }.to raise_error(Faraday::ConnectionFailed)
794
794
  expect(stub).to have_been_requested
795
795
  end
796
796
  end
@@ -877,7 +877,7 @@ describe GoCardlessPro::Services::PaymentsService do
877
877
  stub = stub_request(:post, /.*api.gocardless.com#{stub_url}/).
878
878
  to_timeout
879
879
 
880
- expect { post_response }.to raise_error(Faraday::TimeoutError)
880
+ expect { post_response }.to raise_error(Faraday::ConnectionFailed)
881
881
  expect(stub).to have_been_requested
882
882
  end
883
883
  end
@@ -19,6 +19,7 @@ describe GoCardlessPro::Services::PayoutItemsService do
19
19
 
20
20
  'amount' => 'amount-input',
21
21
  'links' => 'links-input',
22
+ 'taxes' => 'taxes-input',
22
23
  'type' => 'type-input',
23
24
  }],
24
25
  meta: {
@@ -42,6 +43,8 @@ describe GoCardlessPro::Services::PayoutItemsService do
42
43
 
43
44
  expect(get_list_response.records.first.amount).to eq('amount-input')
44
45
 
46
+ expect(get_list_response.records.first.taxes).to eq('taxes-input')
47
+
45
48
  expect(get_list_response.records.first.type).to eq('type-input')
46
49
  end
47
50
 
@@ -85,6 +88,7 @@ describe GoCardlessPro::Services::PayoutItemsService do
85
88
 
86
89
  'amount' => 'amount-input',
87
90
  'links' => 'links-input',
91
+ 'taxes' => 'taxes-input',
88
92
  'type' => 'type-input',
89
93
  }],
90
94
  meta: {
@@ -103,6 +107,7 @@ describe GoCardlessPro::Services::PayoutItemsService do
103
107
 
104
108
  'amount' => 'amount-input',
105
109
  'links' => 'links-input',
110
+ 'taxes' => 'taxes-input',
106
111
  'type' => 'type-input',
107
112
  }],
108
113
  meta: {
@@ -130,6 +135,7 @@ describe GoCardlessPro::Services::PayoutItemsService do
130
135
 
131
136
  'amount' => 'amount-input',
132
137
  'links' => 'links-input',
138
+ 'taxes' => 'taxes-input',
133
139
  'type' => 'type-input',
134
140
  }],
135
141
  meta: {
@@ -148,6 +154,7 @@ describe GoCardlessPro::Services::PayoutItemsService do
148
154
 
149
155
  'amount' => 'amount-input',
150
156
  'links' => 'links-input',
157
+ 'taxes' => 'taxes-input',
151
158
  'type' => 'type-input',
152
159
  }],
153
160
  meta: {
@@ -171,6 +178,7 @@ describe GoCardlessPro::Services::PayoutItemsService do
171
178
 
172
179
  'amount' => 'amount-input',
173
180
  'links' => 'links-input',
181
+ 'taxes' => 'taxes-input',
174
182
  'type' => 'type-input',
175
183
  }],
176
184
  meta: {
@@ -192,6 +200,7 @@ describe GoCardlessPro::Services::PayoutItemsService do
192
200
 
193
201
  'amount' => 'amount-input',
194
202
  'links' => 'links-input',
203
+ 'taxes' => 'taxes-input',
195
204
  'type' => 'type-input',
196
205
  }],
197
206
  meta: {
@@ -29,6 +29,7 @@ describe GoCardlessPro::Services::PayoutsService do
29
29
  'payout_type' => 'payout_type-input',
30
30
  'reference' => 'reference-input',
31
31
  'status' => 'status-input',
32
+ 'tax_currency' => 'tax_currency-input',
32
33
  }],
33
34
  meta: {
34
35
  cursors: {
@@ -70,6 +71,8 @@ describe GoCardlessPro::Services::PayoutsService do
70
71
  expect(get_list_response.records.first.reference).to eq('reference-input')
71
72
 
72
73
  expect(get_list_response.records.first.status).to eq('status-input')
74
+
75
+ expect(get_list_response.records.first.tax_currency).to eq('tax_currency-input')
73
76
  end
74
77
 
75
78
  it 'exposes the cursors for before and after' do
@@ -122,6 +125,7 @@ describe GoCardlessPro::Services::PayoutsService do
122
125
  'payout_type' => 'payout_type-input',
123
126
  'reference' => 'reference-input',
124
127
  'status' => 'status-input',
128
+ 'tax_currency' => 'tax_currency-input',
125
129
  }],
126
130
  meta: {
127
131
  cursors: { after: 'AB345' },
@@ -149,6 +153,7 @@ describe GoCardlessPro::Services::PayoutsService do
149
153
  'payout_type' => 'payout_type-input',
150
154
  'reference' => 'reference-input',
151
155
  'status' => 'status-input',
156
+ 'tax_currency' => 'tax_currency-input',
152
157
  }],
153
158
  meta: {
154
159
  limit: 2,
@@ -185,6 +190,7 @@ describe GoCardlessPro::Services::PayoutsService do
185
190
  'payout_type' => 'payout_type-input',
186
191
  'reference' => 'reference-input',
187
192
  'status' => 'status-input',
193
+ 'tax_currency' => 'tax_currency-input',
188
194
  }],
189
195
  meta: {
190
196
  cursors: { after: 'AB345' },
@@ -212,6 +218,7 @@ describe GoCardlessPro::Services::PayoutsService do
212
218
  'payout_type' => 'payout_type-input',
213
219
  'reference' => 'reference-input',
214
220
  'status' => 'status-input',
221
+ 'tax_currency' => 'tax_currency-input',
215
222
  }],
216
223
  meta: {
217
224
  limit: 2,
@@ -244,6 +251,7 @@ describe GoCardlessPro::Services::PayoutsService do
244
251
  'payout_type' => 'payout_type-input',
245
252
  'reference' => 'reference-input',
246
253
  'status' => 'status-input',
254
+ 'tax_currency' => 'tax_currency-input',
247
255
  }],
248
256
  meta: {
249
257
  cursors: { after: 'AB345' },
@@ -274,6 +282,7 @@ describe GoCardlessPro::Services::PayoutsService do
274
282
  'payout_type' => 'payout_type-input',
275
283
  'reference' => 'reference-input',
276
284
  'status' => 'status-input',
285
+ 'tax_currency' => 'tax_currency-input',
277
286
  }],
278
287
  meta: {
279
288
  limit: 2,
@@ -317,6 +326,7 @@ describe GoCardlessPro::Services::PayoutsService do
317
326
  'payout_type' => 'payout_type-input',
318
327
  'reference' => 'reference-input',
319
328
  'status' => 'status-input',
329
+ 'tax_currency' => 'tax_currency-input',
320
330
  },
321
331
  }.to_json,
322
332
  headers: response_headers
@@ -354,6 +364,7 @@ describe GoCardlessPro::Services::PayoutsService do
354
364
  'payout_type' => 'payout_type-input',
355
365
  'reference' => 'reference-input',
356
366
  'status' => 'status-input',
367
+ 'tax_currency' => 'tax_currency-input',
357
368
  },
358
369
  }.to_json,
359
370
  headers: response_headers
@@ -468,6 +479,7 @@ describe GoCardlessPro::Services::PayoutsService do
468
479
  'payout_type' => 'payout_type-input',
469
480
  'reference' => 'reference-input',
470
481
  'status' => 'status-input',
482
+ 'tax_currency' => 'tax_currency-input',
471
483
  },
472
484
  }.to_json,
473
485
  headers: response_headers
@@ -411,7 +411,7 @@ describe GoCardlessPro::Services::RedirectFlowsService do
411
411
  stub = stub_request(:post, /.*api.gocardless.com#{stub_url}/).
412
412
  to_timeout
413
413
 
414
- expect { post_response }.to raise_error(Faraday::TimeoutError)
414
+ expect { post_response }.to raise_error(Faraday::ConnectionFailed)
415
415
  expect(stub).to have_been_requested
416
416
  end
417
417
  end
@@ -916,7 +916,7 @@ describe GoCardlessPro::Services::SubscriptionsService do
916
916
  stub = stub_request(:post, /.*api.gocardless.com#{stub_url}/).
917
917
  to_timeout
918
918
 
919
- expect { post_response }.to raise_error(Faraday::TimeoutError)
919
+ expect { post_response }.to raise_error(Faraday::ConnectionFailed)
920
920
  expect(stub).to have_been_requested
921
921
  end
922
922
  end
@@ -1017,7 +1017,7 @@ describe GoCardlessPro::Services::SubscriptionsService do
1017
1017
  stub = stub_request(:post, /.*api.gocardless.com#{stub_url}/).
1018
1018
  to_timeout
1019
1019
 
1020
- expect { post_response }.to raise_error(Faraday::TimeoutError)
1020
+ expect { post_response }.to raise_error(Faraday::ConnectionFailed)
1021
1021
  expect(stub).to have_been_requested
1022
1022
  end
1023
1023
  end
@@ -1118,7 +1118,7 @@ describe GoCardlessPro::Services::SubscriptionsService do
1118
1118
  stub = stub_request(:post, /.*api.gocardless.com#{stub_url}/).
1119
1119
  to_timeout
1120
1120
 
1121
- expect { post_response }.to raise_error(Faraday::TimeoutError)
1121
+ expect { post_response }.to raise_error(Faraday::ConnectionFailed)
1122
1122
  expect(stub).to have_been_requested
1123
1123
  end
1124
1124
  end
@@ -0,0 +1,381 @@
1
+ require 'spec_helper'
2
+
3
+ describe GoCardlessPro::Services::TaxRatesService 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.tax_rates.list }
15
+
16
+ let(:body) do
17
+ {
18
+ 'tax_rates' => [{
19
+
20
+ 'end_date' => 'end_date-input',
21
+ 'id' => 'id-input',
22
+ 'jurisdiction' => 'jurisdiction-input',
23
+ 'percentage' => 'percentage-input',
24
+ 'start_date' => 'start_date-input',
25
+ 'type' => 'type-input',
26
+ }],
27
+ meta: {
28
+ cursors: {
29
+ before: nil,
30
+ after: 'ABC123',
31
+ },
32
+ },
33
+ }.to_json
34
+ end
35
+
36
+ before do
37
+ stub_request(:get, %r{.*api.gocardless.com/tax_rates}).to_return(
38
+ body: body,
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::TaxRate)
45
+
46
+ expect(get_list_response.records.first.end_date).to eq('end_date-input')
47
+
48
+ expect(get_list_response.records.first.id).to eq('id-input')
49
+
50
+ expect(get_list_response.records.first.jurisdiction).to eq('jurisdiction-input')
51
+
52
+ expect(get_list_response.records.first.percentage).to eq('percentage-input')
53
+
54
+ expect(get_list_response.records.first.start_date).to eq('start_date-input')
55
+
56
+ expect(get_list_response.records.first.type).to eq('type-input')
57
+ end
58
+
59
+ it 'exposes the cursors for before and after' do
60
+ expect(get_list_response.before).to eq(nil)
61
+ expect(get_list_response.after).to eq('ABC123')
62
+ end
63
+
64
+ specify { expect(get_list_response.api_response.headers).to eql('content-type' => 'application/json') }
65
+
66
+ describe 'retry behaviour' do
67
+ before { allow_any_instance_of(GoCardlessPro::Request).to receive(:sleep) }
68
+
69
+ it 'retries timeouts' do
70
+ stub = stub_request(:get, %r{.*api.gocardless.com/tax_rates}).
71
+ to_timeout.then.to_return(status: 200, headers: response_headers, body: body)
72
+
73
+ get_list_response
74
+ expect(stub).to have_been_requested.twice
75
+ end
76
+
77
+ it 'retries 5XX errors' do
78
+ stub = stub_request(:get, %r{.*api.gocardless.com/tax_rates}).
79
+ to_return(status: 502,
80
+ headers: { 'Content-Type' => 'text/html' },
81
+ body: '<html><body>Response from Cloudflare</body></html>').
82
+ then.to_return(status: 200, headers: response_headers, body: body)
83
+
84
+ get_list_response
85
+ expect(stub).to have_been_requested.twice
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ describe '#all' do
92
+ let!(:first_response_stub) do
93
+ stub_request(:get, %r{.*api.gocardless.com/tax_rates$}).to_return(
94
+ body: {
95
+ 'tax_rates' => [{
96
+
97
+ 'end_date' => 'end_date-input',
98
+ 'id' => 'id-input',
99
+ 'jurisdiction' => 'jurisdiction-input',
100
+ 'percentage' => 'percentage-input',
101
+ 'start_date' => 'start_date-input',
102
+ 'type' => 'type-input',
103
+ }],
104
+ meta: {
105
+ cursors: { after: 'AB345' },
106
+ limit: 1,
107
+ },
108
+ }.to_json,
109
+ headers: response_headers
110
+ )
111
+ end
112
+
113
+ let!(:second_response_stub) do
114
+ stub_request(:get, %r{.*api.gocardless.com/tax_rates\?after=AB345}).to_return(
115
+ body: {
116
+ 'tax_rates' => [{
117
+
118
+ 'end_date' => 'end_date-input',
119
+ 'id' => 'id-input',
120
+ 'jurisdiction' => 'jurisdiction-input',
121
+ 'percentage' => 'percentage-input',
122
+ 'start_date' => 'start_date-input',
123
+ 'type' => 'type-input',
124
+ }],
125
+ meta: {
126
+ limit: 2,
127
+ cursors: {},
128
+ },
129
+ }.to_json,
130
+ headers: response_headers
131
+ )
132
+ end
133
+
134
+ it 'automatically makes the extra requests' do
135
+ expect(client.tax_rates.all.to_a.length).to eq(2)
136
+ expect(first_response_stub).to have_been_requested
137
+ expect(second_response_stub).to have_been_requested
138
+ end
139
+
140
+ describe 'retry behaviour' do
141
+ before { allow_any_instance_of(GoCardlessPro::Request).to receive(:sleep) }
142
+
143
+ it 'retries timeouts' do
144
+ first_response_stub = stub_request(:get, %r{.*api.gocardless.com/tax_rates$}).to_return(
145
+ body: {
146
+ 'tax_rates' => [{
147
+
148
+ 'end_date' => 'end_date-input',
149
+ 'id' => 'id-input',
150
+ 'jurisdiction' => 'jurisdiction-input',
151
+ 'percentage' => 'percentage-input',
152
+ 'start_date' => 'start_date-input',
153
+ 'type' => 'type-input',
154
+ }],
155
+ meta: {
156
+ cursors: { after: 'AB345' },
157
+ limit: 1,
158
+ },
159
+ }.to_json,
160
+ headers: response_headers
161
+ )
162
+
163
+ second_response_stub = stub_request(:get, %r{.*api.gocardless.com/tax_rates\?after=AB345}).
164
+ to_timeout.then.
165
+ to_return(
166
+ body: {
167
+ 'tax_rates' => [{
168
+
169
+ 'end_date' => 'end_date-input',
170
+ 'id' => 'id-input',
171
+ 'jurisdiction' => 'jurisdiction-input',
172
+ 'percentage' => 'percentage-input',
173
+ 'start_date' => 'start_date-input',
174
+ 'type' => 'type-input',
175
+ }],
176
+ meta: {
177
+ limit: 2,
178
+ cursors: {},
179
+ },
180
+ }.to_json,
181
+ headers: response_headers
182
+ )
183
+
184
+ client.tax_rates.all.to_a
185
+
186
+ expect(first_response_stub).to have_been_requested
187
+ expect(second_response_stub).to have_been_requested.twice
188
+ end
189
+
190
+ it 'retries 5XX errors' do
191
+ first_response_stub = stub_request(:get, %r{.*api.gocardless.com/tax_rates$}).to_return(
192
+ body: {
193
+ 'tax_rates' => [{
194
+
195
+ 'end_date' => 'end_date-input',
196
+ 'id' => 'id-input',
197
+ 'jurisdiction' => 'jurisdiction-input',
198
+ 'percentage' => 'percentage-input',
199
+ 'start_date' => 'start_date-input',
200
+ 'type' => 'type-input',
201
+ }],
202
+ meta: {
203
+ cursors: { after: 'AB345' },
204
+ limit: 1,
205
+ },
206
+ }.to_json,
207
+ headers: response_headers
208
+ )
209
+
210
+ second_response_stub = stub_request(:get, %r{.*api.gocardless.com/tax_rates\?after=AB345}).
211
+ to_return(
212
+ status: 502,
213
+ body: '<html><body>Response from Cloudflare</body></html>',
214
+ headers: { 'Content-Type' => 'text/html' }
215
+ ).then.to_return(
216
+ body: {
217
+ 'tax_rates' => [{
218
+
219
+ 'end_date' => 'end_date-input',
220
+ 'id' => 'id-input',
221
+ 'jurisdiction' => 'jurisdiction-input',
222
+ 'percentage' => 'percentage-input',
223
+ 'start_date' => 'start_date-input',
224
+ 'type' => 'type-input',
225
+ }],
226
+ meta: {
227
+ limit: 2,
228
+ cursors: {},
229
+ },
230
+ }.to_json,
231
+ headers: response_headers
232
+ )
233
+
234
+ client.tax_rates.all.to_a
235
+
236
+ expect(first_response_stub).to have_been_requested
237
+ expect(second_response_stub).to have_been_requested.twice
238
+ end
239
+ end
240
+ end
241
+
242
+ describe '#get' do
243
+ let(:id) { 'ID123' }
244
+
245
+ subject(:get_response) { client.tax_rates.get(id) }
246
+
247
+ context 'passing in a custom header' do
248
+ let!(:stub) do
249
+ stub_url = '/tax_rates/:identity'.gsub(':identity', id)
250
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).
251
+ with(headers: { 'Foo' => 'Bar' }).
252
+ to_return(
253
+ body: {
254
+ 'tax_rates' => {
255
+
256
+ 'end_date' => 'end_date-input',
257
+ 'id' => 'id-input',
258
+ 'jurisdiction' => 'jurisdiction-input',
259
+ 'percentage' => 'percentage-input',
260
+ 'start_date' => 'start_date-input',
261
+ 'type' => 'type-input',
262
+ },
263
+ }.to_json,
264
+ headers: response_headers
265
+ )
266
+ end
267
+
268
+ subject(:get_response) do
269
+ client.tax_rates.get(id, headers: {
270
+ 'Foo' => 'Bar',
271
+ })
272
+ end
273
+
274
+ it 'includes the header' do
275
+ get_response
276
+ expect(stub).to have_been_requested
277
+ end
278
+ end
279
+
280
+ context 'when there is a tax_rate to return' do
281
+ before do
282
+ stub_url = '/tax_rates/:identity'.gsub(':identity', id)
283
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).to_return(
284
+ body: {
285
+ 'tax_rates' => {
286
+
287
+ 'end_date' => 'end_date-input',
288
+ 'id' => 'id-input',
289
+ 'jurisdiction' => 'jurisdiction-input',
290
+ 'percentage' => 'percentage-input',
291
+ 'start_date' => 'start_date-input',
292
+ 'type' => 'type-input',
293
+ },
294
+ }.to_json,
295
+ headers: response_headers
296
+ )
297
+ end
298
+
299
+ it 'wraps the response in a resource' do
300
+ expect(get_response).to be_a(GoCardlessPro::Resources::TaxRate)
301
+ end
302
+ end
303
+
304
+ context 'when nothing is returned' do
305
+ before do
306
+ stub_url = '/tax_rates/:identity'.gsub(':identity', id)
307
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).to_return(
308
+ body: '',
309
+ headers: response_headers
310
+ )
311
+ end
312
+
313
+ it 'returns nil' do
314
+ expect(get_response).to be_nil
315
+ end
316
+ end
317
+
318
+ context "when an ID is specified which can't be included in a valid URI" do
319
+ let(:id) { '`' }
320
+
321
+ it "doesn't raise an error" do
322
+ expect { get_response }.to_not raise_error(/bad URI/)
323
+ end
324
+ end
325
+
326
+ describe 'retry behaviour' do
327
+ before { allow_any_instance_of(GoCardlessPro::Request).to receive(:sleep) }
328
+
329
+ it 'retries timeouts' do
330
+ stub_url = '/tax_rates/:identity'.gsub(':identity', id)
331
+
332
+ stub = stub_request(:get, /.*api.gocardless.com#{stub_url}/).
333
+ to_timeout.then.to_return(status: 200, headers: response_headers)
334
+
335
+ get_response
336
+ expect(stub).to have_been_requested.twice
337
+ end
338
+
339
+ it 'retries 5XX errors, other than 500s' do
340
+ stub_url = '/tax_rates/:identity'.gsub(':identity', id)
341
+
342
+ stub = stub_request(:get, /.*api.gocardless.com#{stub_url}/).
343
+ to_return(status: 502,
344
+ headers: { 'Content-Type' => 'text/html' },
345
+ body: '<html><body>Response from Cloudflare</body></html>').
346
+ then.to_return(status: 200, headers: response_headers)
347
+
348
+ get_response
349
+ expect(stub).to have_been_requested.twice
350
+ end
351
+
352
+ it 'retries 500 errors returned by the API' do
353
+ stub_url = '/tax_rates/:identity'.gsub(':identity', id)
354
+
355
+ gocardless_error = {
356
+ 'error' => {
357
+ 'message' => 'Internal server error',
358
+ 'documentation_url' => 'https://developer.gocardless.com/#gocardless',
359
+ 'errors' => [{
360
+ 'message' => 'Internal server error',
361
+ 'reason' => 'internal_server_error',
362
+ }],
363
+ 'type' => 'gocardless',
364
+ 'code' => 500,
365
+ 'request_id' => 'dummy_request_id',
366
+ 'id' => 'dummy_exception_id',
367
+ },
368
+ }
369
+
370
+ stub = stub_request(:get, /.*api.gocardless.com#{stub_url}/).
371
+ to_return(status: 500,
372
+ headers: response_headers,
373
+ body: gocardless_error.to_json).
374
+ then.to_return(status: 200, headers: response_headers)
375
+
376
+ get_response
377
+ expect(stub).to have_been_requested.twice
378
+ end
379
+ end
380
+ end
381
+ end