gocardless_pro 2.22.1 → 2.27.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +3 -3
  3. data/lib/gocardless_pro.rb +24 -0
  4. data/lib/gocardless_pro/client.rb +41 -1
  5. data/lib/gocardless_pro/resources/bank_authorisation.rb +87 -0
  6. data/lib/gocardless_pro/resources/billing_request.rb +86 -0
  7. data/lib/gocardless_pro/resources/billing_request_flow.rb +62 -0
  8. data/lib/gocardless_pro/resources/creditor.rb +2 -3
  9. data/lib/gocardless_pro/resources/event.rb +12 -0
  10. data/lib/gocardless_pro/resources/institution.rb +45 -0
  11. data/lib/gocardless_pro/resources/payer_authorisation.rb +122 -0
  12. data/lib/gocardless_pro/resources/payout.rb +2 -0
  13. data/lib/gocardless_pro/resources/payout_item.rb +6 -0
  14. data/lib/gocardless_pro/resources/scenario_simulator.rb +42 -0
  15. data/lib/gocardless_pro/resources/tax_rate.rb +51 -0
  16. data/lib/gocardless_pro/resources/webhook.rb +62 -0
  17. data/lib/gocardless_pro/services/bank_authorisations_service.rb +82 -0
  18. data/lib/gocardless_pro/services/billing_request_flows_service.rb +47 -0
  19. data/lib/gocardless_pro/services/billing_requests_service.rb +325 -0
  20. data/lib/gocardless_pro/services/institutions_service.rb +56 -0
  21. data/lib/gocardless_pro/services/payer_authorisations_service.rb +208 -0
  22. data/lib/gocardless_pro/services/scenario_simulators_service.rb +148 -0
  23. data/lib/gocardless_pro/services/subscriptions_service.rb +9 -4
  24. data/lib/gocardless_pro/services/tax_rates_service.rb +74 -0
  25. data/lib/gocardless_pro/services/webhooks_service.rb +113 -0
  26. data/lib/gocardless_pro/version.rb +1 -1
  27. data/spec/resources/bank_authorisation_spec.rb +259 -0
  28. data/spec/resources/billing_request_flow_spec.rb +129 -0
  29. data/spec/resources/billing_request_spec.rb +736 -0
  30. data/spec/resources/institution_spec.rb +103 -0
  31. data/spec/resources/payer_authorisation_spec.rb +418 -0
  32. data/spec/resources/payout_item_spec.rb +5 -0
  33. data/spec/resources/payout_spec.rb +8 -0
  34. data/spec/resources/scenario_simulator_spec.rb +63 -0
  35. data/spec/resources/tax_rate_spec.rb +198 -0
  36. data/spec/resources/webhook_spec.rb +323 -0
  37. data/spec/services/bank_authorisations_service_spec.rb +366 -0
  38. data/spec/services/billing_request_flows_service_spec.rb +152 -0
  39. data/spec/services/billing_requests_service_spec.rb +1042 -0
  40. data/spec/services/institutions_service_spec.rb +223 -0
  41. data/spec/services/payer_authorisations_service_spec.rb +572 -0
  42. data/spec/services/payout_items_service_spec.rb +9 -0
  43. data/spec/services/payouts_service_spec.rb +12 -0
  44. data/spec/services/scenario_simulators_service_spec.rb +74 -0
  45. data/spec/services/tax_rates_service_spec.rb +381 -0
  46. data/spec/services/webhooks_service_spec.rb +545 -0
  47. metadata +51 -3
@@ -20,6 +20,7 @@ describe GoCardlessPro::Resources::PayoutItem do
20
20
 
21
21
  'amount' => 'amount-input',
22
22
  'links' => 'links-input',
23
+ 'taxes' => 'taxes-input',
23
24
  'type' => 'type-input',
24
25
  }],
25
26
  meta: {
@@ -38,6 +39,8 @@ describe GoCardlessPro::Resources::PayoutItem do
38
39
 
39
40
  expect(get_list_response.records.first.amount).to eq('amount-input')
40
41
 
42
+ expect(get_list_response.records.first.taxes).to eq('taxes-input')
43
+
41
44
  expect(get_list_response.records.first.type).to eq('type-input')
42
45
  end
43
46
 
@@ -58,6 +61,7 @@ describe GoCardlessPro::Resources::PayoutItem do
58
61
 
59
62
  'amount' => 'amount-input',
60
63
  'links' => 'links-input',
64
+ 'taxes' => 'taxes-input',
61
65
  'type' => 'type-input',
62
66
  }],
63
67
  meta: {
@@ -76,6 +80,7 @@ describe GoCardlessPro::Resources::PayoutItem do
76
80
 
77
81
  'amount' => 'amount-input',
78
82
  'links' => 'links-input',
83
+ 'taxes' => 'taxes-input',
79
84
  'type' => 'type-input',
80
85
  }],
81
86
  meta: {
@@ -30,6 +30,7 @@ describe GoCardlessPro::Resources::Payout do
30
30
  'payout_type' => 'payout_type-input',
31
31
  'reference' => 'reference-input',
32
32
  'status' => 'status-input',
33
+ 'tax_currency' => 'tax_currency-input',
33
34
  }],
34
35
  meta: {
35
36
  cursors: {
@@ -66,6 +67,8 @@ describe GoCardlessPro::Resources::Payout do
66
67
  expect(get_list_response.records.first.reference).to eq('reference-input')
67
68
 
68
69
  expect(get_list_response.records.first.status).to eq('status-input')
70
+
71
+ expect(get_list_response.records.first.tax_currency).to eq('tax_currency-input')
69
72
  end
70
73
 
71
74
  it 'exposes the cursors for before and after' do
@@ -95,6 +98,7 @@ describe GoCardlessPro::Resources::Payout do
95
98
  'payout_type' => 'payout_type-input',
96
99
  'reference' => 'reference-input',
97
100
  'status' => 'status-input',
101
+ 'tax_currency' => 'tax_currency-input',
98
102
  }],
99
103
  meta: {
100
104
  cursors: { after: 'AB345' },
@@ -122,6 +126,7 @@ describe GoCardlessPro::Resources::Payout do
122
126
  'payout_type' => 'payout_type-input',
123
127
  'reference' => 'reference-input',
124
128
  'status' => 'status-input',
129
+ 'tax_currency' => 'tax_currency-input',
125
130
  }],
126
131
  meta: {
127
132
  limit: 2,
@@ -165,6 +170,7 @@ describe GoCardlessPro::Resources::Payout do
165
170
  'payout_type' => 'payout_type-input',
166
171
  'reference' => 'reference-input',
167
172
  'status' => 'status-input',
173
+ 'tax_currency' => 'tax_currency-input',
168
174
  },
169
175
  }.to_json,
170
176
  headers: response_headers
@@ -202,6 +208,7 @@ describe GoCardlessPro::Resources::Payout do
202
208
  'payout_type' => 'payout_type-input',
203
209
  'reference' => 'reference-input',
204
210
  'status' => 'status-input',
211
+ 'tax_currency' => 'tax_currency-input',
205
212
  },
206
213
  }.to_json,
207
214
  headers: response_headers
@@ -261,6 +268,7 @@ describe GoCardlessPro::Resources::Payout do
261
268
  'payout_type' => 'payout_type-input',
262
269
  'reference' => 'reference-input',
263
270
  'status' => 'status-input',
271
+ 'tax_currency' => 'tax_currency-input',
264
272
  },
265
273
  }.to_json,
266
274
  headers: response_headers
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe GoCardlessPro::Resources::ScenarioSimulator 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 '#run' do
13
+ subject(:post_response) { client.scenario_simulators.run(resource_id) }
14
+
15
+ let(:resource_id) { 'ABC123' }
16
+
17
+ let!(:stub) do
18
+ # /scenario_simulators/%v/actions/run
19
+ stub_url = '/scenario_simulators/:identity/actions/run'.gsub(':identity', resource_id)
20
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).to_return(
21
+ body: {
22
+ 'scenario_simulators' => {
23
+
24
+ 'id' => 'id-input',
25
+ },
26
+ }.to_json,
27
+ headers: response_headers
28
+ )
29
+ end
30
+
31
+ it 'wraps the response and calls the right endpoint' do
32
+ expect(post_response).to be_a(GoCardlessPro::Resources::ScenarioSimulator)
33
+
34
+ expect(stub).to have_been_requested
35
+ end
36
+
37
+ context 'when the request needs a body and custom header' do
38
+ let(:body) { { foo: 'bar' } }
39
+ let(:headers) { { 'Foo' => 'Bar' } }
40
+ subject(:post_response) { client.scenario_simulators.run(resource_id, body, headers) }
41
+
42
+ let(:resource_id) { 'ABC123' }
43
+
44
+ let!(:stub) do
45
+ # /scenario_simulators/%v/actions/run
46
+ stub_url = '/scenario_simulators/:identity/actions/run'.gsub(':identity', resource_id)
47
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).
48
+ with(
49
+ body: { foo: 'bar' },
50
+ headers: { 'Foo' => 'Bar' }
51
+ ).to_return(
52
+ body: {
53
+ 'scenario_simulators' => {
54
+
55
+ 'id' => 'id-input',
56
+ },
57
+ }.to_json,
58
+ headers: response_headers
59
+ )
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,198 @@
1
+ require 'spec_helper'
2
+
3
+ describe GoCardlessPro::Resources::TaxRate 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
+ before do
17
+ stub_request(:get, %r{.*api.gocardless.com/tax_rates}).to_return(
18
+ body: {
19
+ 'tax_rates' => [{
20
+
21
+ 'end_date' => 'end_date-input',
22
+ 'id' => 'id-input',
23
+ 'jurisdiction' => 'jurisdiction-input',
24
+ 'percentage' => 'percentage-input',
25
+ 'start_date' => 'start_date-input',
26
+ 'type' => 'type-input',
27
+ }],
28
+ meta: {
29
+ cursors: {
30
+ before: nil,
31
+ after: 'ABC123',
32
+ },
33
+ },
34
+ }.to_json,
35
+ headers: response_headers
36
+ )
37
+ end
38
+
39
+ it 'wraps each item in the resource class' do
40
+ expect(get_list_response.records.map(&:class).uniq.first).to eq(GoCardlessPro::Resources::TaxRate)
41
+
42
+ expect(get_list_response.records.first.end_date).to eq('end_date-input')
43
+
44
+ expect(get_list_response.records.first.id).to eq('id-input')
45
+
46
+ expect(get_list_response.records.first.jurisdiction).to eq('jurisdiction-input')
47
+
48
+ expect(get_list_response.records.first.percentage).to eq('percentage-input')
49
+
50
+ expect(get_list_response.records.first.start_date).to eq('start_date-input')
51
+
52
+ expect(get_list_response.records.first.type).to eq('type-input')
53
+ end
54
+
55
+ it 'exposes the cursors for before and after' do
56
+ expect(get_list_response.before).to eq(nil)
57
+ expect(get_list_response.after).to eq('ABC123')
58
+ end
59
+
60
+ specify { expect(get_list_response.api_response.headers).to eql('content-type' => 'application/json') }
61
+ end
62
+ end
63
+
64
+ describe '#all' do
65
+ let!(:first_response_stub) do
66
+ stub_request(:get, %r{.*api.gocardless.com/tax_rates$}).to_return(
67
+ body: {
68
+ 'tax_rates' => [{
69
+
70
+ 'end_date' => 'end_date-input',
71
+ 'id' => 'id-input',
72
+ 'jurisdiction' => 'jurisdiction-input',
73
+ 'percentage' => 'percentage-input',
74
+ 'start_date' => 'start_date-input',
75
+ 'type' => 'type-input',
76
+ }],
77
+ meta: {
78
+ cursors: { after: 'AB345' },
79
+ limit: 1,
80
+ },
81
+ }.to_json,
82
+ headers: response_headers
83
+ )
84
+ end
85
+
86
+ let!(:second_response_stub) do
87
+ stub_request(:get, %r{.*api.gocardless.com/tax_rates\?after=AB345}).to_return(
88
+ body: {
89
+ 'tax_rates' => [{
90
+
91
+ 'end_date' => 'end_date-input',
92
+ 'id' => 'id-input',
93
+ 'jurisdiction' => 'jurisdiction-input',
94
+ 'percentage' => 'percentage-input',
95
+ 'start_date' => 'start_date-input',
96
+ 'type' => 'type-input',
97
+ }],
98
+ meta: {
99
+ limit: 2,
100
+ cursors: {},
101
+ },
102
+ }.to_json,
103
+ headers: response_headers
104
+ )
105
+ end
106
+
107
+ it 'automatically makes the extra requests' do
108
+ expect(client.tax_rates.all.to_a.length).to eq(2)
109
+ expect(first_response_stub).to have_been_requested
110
+ expect(second_response_stub).to have_been_requested
111
+ end
112
+ end
113
+
114
+ describe '#get' do
115
+ let(:id) { 'ID123' }
116
+
117
+ subject(:get_response) { client.tax_rates.get(id) }
118
+
119
+ context 'passing in a custom header' do
120
+ let!(:stub) do
121
+ stub_url = '/tax_rates/:identity'.gsub(':identity', id)
122
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).
123
+ with(headers: { 'Foo' => 'Bar' }).
124
+ to_return(
125
+ body: {
126
+ 'tax_rates' => {
127
+
128
+ 'end_date' => 'end_date-input',
129
+ 'id' => 'id-input',
130
+ 'jurisdiction' => 'jurisdiction-input',
131
+ 'percentage' => 'percentage-input',
132
+ 'start_date' => 'start_date-input',
133
+ 'type' => 'type-input',
134
+ },
135
+ }.to_json,
136
+ headers: response_headers
137
+ )
138
+ end
139
+
140
+ subject(:get_response) do
141
+ client.tax_rates.get(id, headers: {
142
+ 'Foo' => 'Bar',
143
+ })
144
+ end
145
+
146
+ it 'includes the header' do
147
+ get_response
148
+ expect(stub).to have_been_requested
149
+ end
150
+ end
151
+
152
+ context 'when there is a tax_rate to return' do
153
+ before do
154
+ stub_url = '/tax_rates/:identity'.gsub(':identity', id)
155
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).to_return(
156
+ body: {
157
+ 'tax_rates' => {
158
+
159
+ 'end_date' => 'end_date-input',
160
+ 'id' => 'id-input',
161
+ 'jurisdiction' => 'jurisdiction-input',
162
+ 'percentage' => 'percentage-input',
163
+ 'start_date' => 'start_date-input',
164
+ 'type' => 'type-input',
165
+ },
166
+ }.to_json,
167
+ headers: response_headers
168
+ )
169
+ end
170
+
171
+ it 'wraps the response in a resource' do
172
+ expect(get_response).to be_a(GoCardlessPro::Resources::TaxRate)
173
+ end
174
+ end
175
+
176
+ context 'when nothing is returned' do
177
+ before do
178
+ stub_url = '/tax_rates/:identity'.gsub(':identity', id)
179
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).to_return(
180
+ body: '',
181
+ headers: response_headers
182
+ )
183
+ end
184
+
185
+ it 'returns nil' do
186
+ expect(get_response).to be_nil
187
+ end
188
+ end
189
+
190
+ context "when an ID is specified which can't be included in a valid URI" do
191
+ let(:id) { '`' }
192
+
193
+ it "doesn't raise an error" do
194
+ expect { get_response }.to_not raise_error(/bad URI/)
195
+ end
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,323 @@
1
+ require 'spec_helper'
2
+
3
+ describe GoCardlessPro::Resources::Webhook 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.webhooks.list }
15
+
16
+ before do
17
+ stub_request(:get, %r{.*api.gocardless.com/webhooks}).to_return(
18
+ body: {
19
+ 'webhooks' => [{
20
+
21
+ 'created_at' => 'created_at-input',
22
+ 'id' => 'id-input',
23
+ 'is_test' => 'is_test-input',
24
+ 'request_body' => 'request_body-input',
25
+ 'request_headers' => 'request_headers-input',
26
+ 'response_body' => 'response_body-input',
27
+ 'response_body_truncated' => 'response_body_truncated-input',
28
+ 'response_code' => 'response_code-input',
29
+ 'response_headers' => 'response_headers-input',
30
+ 'response_headers_content_truncated' => 'response_headers_content_truncated-input',
31
+ 'response_headers_count_truncated' => 'response_headers_count_truncated-input',
32
+ 'successful' => 'successful-input',
33
+ 'url' => 'url-input',
34
+ }],
35
+ meta: {
36
+ cursors: {
37
+ before: nil,
38
+ after: 'ABC123',
39
+ },
40
+ },
41
+ }.to_json,
42
+ headers: response_headers
43
+ )
44
+ end
45
+
46
+ it 'wraps each item in the resource class' do
47
+ expect(get_list_response.records.map(&:class).uniq.first).to eq(GoCardlessPro::Resources::Webhook)
48
+
49
+ expect(get_list_response.records.first.created_at).to eq('created_at-input')
50
+
51
+ expect(get_list_response.records.first.id).to eq('id-input')
52
+
53
+ expect(get_list_response.records.first.is_test).to eq('is_test-input')
54
+
55
+ expect(get_list_response.records.first.request_body).to eq('request_body-input')
56
+
57
+ expect(get_list_response.records.first.request_headers).to eq('request_headers-input')
58
+
59
+ expect(get_list_response.records.first.response_body).to eq('response_body-input')
60
+
61
+ expect(get_list_response.records.first.response_body_truncated).to eq('response_body_truncated-input')
62
+
63
+ expect(get_list_response.records.first.response_code).to eq('response_code-input')
64
+
65
+ expect(get_list_response.records.first.response_headers).to eq('response_headers-input')
66
+
67
+ expect(get_list_response.records.first.response_headers_content_truncated).to eq('response_headers_content_truncated-input')
68
+
69
+ expect(get_list_response.records.first.response_headers_count_truncated).to eq('response_headers_count_truncated-input')
70
+
71
+ expect(get_list_response.records.first.successful).to eq('successful-input')
72
+
73
+ expect(get_list_response.records.first.url).to eq('url-input')
74
+ end
75
+
76
+ it 'exposes the cursors for before and after' do
77
+ expect(get_list_response.before).to eq(nil)
78
+ expect(get_list_response.after).to eq('ABC123')
79
+ end
80
+
81
+ specify { expect(get_list_response.api_response.headers).to eql('content-type' => 'application/json') }
82
+ end
83
+ end
84
+
85
+ describe '#all' do
86
+ let!(:first_response_stub) do
87
+ stub_request(:get, %r{.*api.gocardless.com/webhooks$}).to_return(
88
+ body: {
89
+ 'webhooks' => [{
90
+
91
+ 'created_at' => 'created_at-input',
92
+ 'id' => 'id-input',
93
+ 'is_test' => 'is_test-input',
94
+ 'request_body' => 'request_body-input',
95
+ 'request_headers' => 'request_headers-input',
96
+ 'response_body' => 'response_body-input',
97
+ 'response_body_truncated' => 'response_body_truncated-input',
98
+ 'response_code' => 'response_code-input',
99
+ 'response_headers' => 'response_headers-input',
100
+ 'response_headers_content_truncated' => 'response_headers_content_truncated-input',
101
+ 'response_headers_count_truncated' => 'response_headers_count_truncated-input',
102
+ 'successful' => 'successful-input',
103
+ 'url' => 'url-input',
104
+ }],
105
+ meta: {
106
+ cursors: { after: 'AB345' },
107
+ limit: 1,
108
+ },
109
+ }.to_json,
110
+ headers: response_headers
111
+ )
112
+ end
113
+
114
+ let!(:second_response_stub) do
115
+ stub_request(:get, %r{.*api.gocardless.com/webhooks\?after=AB345}).to_return(
116
+ body: {
117
+ 'webhooks' => [{
118
+
119
+ 'created_at' => 'created_at-input',
120
+ 'id' => 'id-input',
121
+ 'is_test' => 'is_test-input',
122
+ 'request_body' => 'request_body-input',
123
+ 'request_headers' => 'request_headers-input',
124
+ 'response_body' => 'response_body-input',
125
+ 'response_body_truncated' => 'response_body_truncated-input',
126
+ 'response_code' => 'response_code-input',
127
+ 'response_headers' => 'response_headers-input',
128
+ 'response_headers_content_truncated' => 'response_headers_content_truncated-input',
129
+ 'response_headers_count_truncated' => 'response_headers_count_truncated-input',
130
+ 'successful' => 'successful-input',
131
+ 'url' => 'url-input',
132
+ }],
133
+ meta: {
134
+ limit: 2,
135
+ cursors: {},
136
+ },
137
+ }.to_json,
138
+ headers: response_headers
139
+ )
140
+ end
141
+
142
+ it 'automatically makes the extra requests' do
143
+ expect(client.webhooks.all.to_a.length).to eq(2)
144
+ expect(first_response_stub).to have_been_requested
145
+ expect(second_response_stub).to have_been_requested
146
+ end
147
+ end
148
+
149
+ describe '#get' do
150
+ let(:id) { 'ID123' }
151
+
152
+ subject(:get_response) { client.webhooks.get(id) }
153
+
154
+ context 'passing in a custom header' do
155
+ let!(:stub) do
156
+ stub_url = '/webhooks/:identity'.gsub(':identity', id)
157
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).
158
+ with(headers: { 'Foo' => 'Bar' }).
159
+ to_return(
160
+ body: {
161
+ 'webhooks' => {
162
+
163
+ 'created_at' => 'created_at-input',
164
+ 'id' => 'id-input',
165
+ 'is_test' => 'is_test-input',
166
+ 'request_body' => 'request_body-input',
167
+ 'request_headers' => 'request_headers-input',
168
+ 'response_body' => 'response_body-input',
169
+ 'response_body_truncated' => 'response_body_truncated-input',
170
+ 'response_code' => 'response_code-input',
171
+ 'response_headers' => 'response_headers-input',
172
+ 'response_headers_content_truncated' => 'response_headers_content_truncated-input',
173
+ 'response_headers_count_truncated' => 'response_headers_count_truncated-input',
174
+ 'successful' => 'successful-input',
175
+ 'url' => 'url-input',
176
+ },
177
+ }.to_json,
178
+ headers: response_headers
179
+ )
180
+ end
181
+
182
+ subject(:get_response) do
183
+ client.webhooks.get(id, headers: {
184
+ 'Foo' => 'Bar',
185
+ })
186
+ end
187
+
188
+ it 'includes the header' do
189
+ get_response
190
+ expect(stub).to have_been_requested
191
+ end
192
+ end
193
+
194
+ context 'when there is a webhook to return' do
195
+ before do
196
+ stub_url = '/webhooks/:identity'.gsub(':identity', id)
197
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).to_return(
198
+ body: {
199
+ 'webhooks' => {
200
+
201
+ 'created_at' => 'created_at-input',
202
+ 'id' => 'id-input',
203
+ 'is_test' => 'is_test-input',
204
+ 'request_body' => 'request_body-input',
205
+ 'request_headers' => 'request_headers-input',
206
+ 'response_body' => 'response_body-input',
207
+ 'response_body_truncated' => 'response_body_truncated-input',
208
+ 'response_code' => 'response_code-input',
209
+ 'response_headers' => 'response_headers-input',
210
+ 'response_headers_content_truncated' => 'response_headers_content_truncated-input',
211
+ 'response_headers_count_truncated' => 'response_headers_count_truncated-input',
212
+ 'successful' => 'successful-input',
213
+ 'url' => 'url-input',
214
+ },
215
+ }.to_json,
216
+ headers: response_headers
217
+ )
218
+ end
219
+
220
+ it 'wraps the response in a resource' do
221
+ expect(get_response).to be_a(GoCardlessPro::Resources::Webhook)
222
+ end
223
+ end
224
+
225
+ context 'when nothing is returned' do
226
+ before do
227
+ stub_url = '/webhooks/:identity'.gsub(':identity', id)
228
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).to_return(
229
+ body: '',
230
+ headers: response_headers
231
+ )
232
+ end
233
+
234
+ it 'returns nil' do
235
+ expect(get_response).to be_nil
236
+ end
237
+ end
238
+
239
+ context "when an ID is specified which can't be included in a valid URI" do
240
+ let(:id) { '`' }
241
+
242
+ it "doesn't raise an error" do
243
+ expect { get_response }.to_not raise_error(/bad URI/)
244
+ end
245
+ end
246
+ end
247
+
248
+ describe '#retry' do
249
+ subject(:post_response) { client.webhooks.retry(resource_id) }
250
+
251
+ let(:resource_id) { 'ABC123' }
252
+
253
+ let!(:stub) do
254
+ # /webhooks/%v/actions/retry
255
+ stub_url = '/webhooks/:identity/actions/retry'.gsub(':identity', resource_id)
256
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).to_return(
257
+ body: {
258
+ 'webhooks' => {
259
+
260
+ 'created_at' => 'created_at-input',
261
+ 'id' => 'id-input',
262
+ 'is_test' => 'is_test-input',
263
+ 'request_body' => 'request_body-input',
264
+ 'request_headers' => 'request_headers-input',
265
+ 'response_body' => 'response_body-input',
266
+ 'response_body_truncated' => 'response_body_truncated-input',
267
+ 'response_code' => 'response_code-input',
268
+ 'response_headers' => 'response_headers-input',
269
+ 'response_headers_content_truncated' => 'response_headers_content_truncated-input',
270
+ 'response_headers_count_truncated' => 'response_headers_count_truncated-input',
271
+ 'successful' => 'successful-input',
272
+ 'url' => 'url-input',
273
+ },
274
+ }.to_json,
275
+ headers: response_headers
276
+ )
277
+ end
278
+
279
+ it 'wraps the response and calls the right endpoint' do
280
+ expect(post_response).to be_a(GoCardlessPro::Resources::Webhook)
281
+
282
+ expect(stub).to have_been_requested
283
+ end
284
+
285
+ context 'when the request needs a body and custom header' do
286
+ let(:body) { { foo: 'bar' } }
287
+ let(:headers) { { 'Foo' => 'Bar' } }
288
+ subject(:post_response) { client.webhooks.retry(resource_id, body, headers) }
289
+
290
+ let(:resource_id) { 'ABC123' }
291
+
292
+ let!(:stub) do
293
+ # /webhooks/%v/actions/retry
294
+ stub_url = '/webhooks/:identity/actions/retry'.gsub(':identity', resource_id)
295
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).
296
+ with(
297
+ body: { foo: 'bar' },
298
+ headers: { 'Foo' => 'Bar' }
299
+ ).to_return(
300
+ body: {
301
+ 'webhooks' => {
302
+
303
+ 'created_at' => 'created_at-input',
304
+ 'id' => 'id-input',
305
+ 'is_test' => 'is_test-input',
306
+ 'request_body' => 'request_body-input',
307
+ 'request_headers' => 'request_headers-input',
308
+ 'response_body' => 'response_body-input',
309
+ 'response_body_truncated' => 'response_body_truncated-input',
310
+ 'response_code' => 'response_code-input',
311
+ 'response_headers' => 'response_headers-input',
312
+ 'response_headers_content_truncated' => 'response_headers_content_truncated-input',
313
+ 'response_headers_count_truncated' => 'response_headers_count_truncated-input',
314
+ 'successful' => 'successful-input',
315
+ 'url' => 'url-input',
316
+ },
317
+ }.to_json,
318
+ headers: response_headers
319
+ )
320
+ end
321
+ end
322
+ end
323
+ end