gocardless_pro 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -4
  3. data/lib/gocardless_pro.rb +1 -0
  4. data/lib/gocardless_pro/api_service.rb +2 -0
  5. data/lib/gocardless_pro/client.rb +4 -3
  6. data/lib/gocardless_pro/error/invalid_state_error.rb +17 -0
  7. data/lib/gocardless_pro/middlewares/raise_gocardless_errors.rb +50 -0
  8. data/lib/gocardless_pro/request.rb +38 -1
  9. data/lib/gocardless_pro/resources/creditor.rb +2 -2
  10. data/lib/gocardless_pro/resources/creditor_bank_account.rb +11 -11
  11. data/lib/gocardless_pro/resources/customer_bank_account.rb +2 -2
  12. data/lib/gocardless_pro/resources/event.rb +2 -2
  13. data/lib/gocardless_pro/resources/mandate.rb +2 -2
  14. data/lib/gocardless_pro/resources/payment.rb +7 -7
  15. data/lib/gocardless_pro/resources/payout.rb +7 -6
  16. data/lib/gocardless_pro/resources/redirect_flow.rb +2 -2
  17. data/lib/gocardless_pro/resources/refund.rb +2 -2
  18. data/lib/gocardless_pro/resources/subscription.rb +2 -2
  19. data/lib/gocardless_pro/response.rb +2 -54
  20. data/lib/gocardless_pro/services/bank_details_lookups_service.rb +3 -0
  21. data/lib/gocardless_pro/services/creditor_bank_accounts_service.rb +31 -2
  22. data/lib/gocardless_pro/services/creditors_service.rb +21 -1
  23. data/lib/gocardless_pro/services/customer_bank_accounts_service.rb +34 -2
  24. data/lib/gocardless_pro/services/customers_service.rb +21 -1
  25. data/lib/gocardless_pro/services/events_service.rb +5 -0
  26. data/lib/gocardless_pro/services/mandate_pdfs_service.rb +3 -0
  27. data/lib/gocardless_pro/services/mandates_service.rb +47 -3
  28. data/lib/gocardless_pro/services/payments_service.rb +47 -3
  29. data/lib/gocardless_pro/services/payouts_service.rb +5 -0
  30. data/lib/gocardless_pro/services/redirect_flows_service.rb +28 -2
  31. data/lib/gocardless_pro/services/refunds_service.rb +21 -1
  32. data/lib/gocardless_pro/services/subscriptions_service.rb +34 -2
  33. data/lib/gocardless_pro/version.rb +1 -1
  34. data/spec/api_service_spec.rb +106 -0
  35. data/spec/middlewares/raise_gocardless_errors_spec.rb +98 -0
  36. data/spec/resources/bank_details_lookup_spec.rb +102 -19
  37. data/spec/resources/creditor_bank_account_spec.rb +416 -40
  38. data/spec/resources/creditor_spec.rb +414 -53
  39. data/spec/resources/customer_bank_account_spec.rb +452 -40
  40. data/spec/resources/customer_spec.rb +457 -45
  41. data/spec/resources/event_spec.rb +171 -72
  42. data/spec/resources/mandate_pdf_spec.rb +100 -17
  43. data/spec/resources/mandate_spec.rb +501 -44
  44. data/spec/resources/payment_spec.rb +531 -48
  45. data/spec/resources/payout_spec.rb +189 -45
  46. data/spec/resources/redirect_flow_spec.rb +277 -43
  47. data/spec/resources/refund_spec.rb +349 -34
  48. data/spec/resources/subscription_spec.rb +531 -53
  49. data/spec/response_spec.rb +12 -79
  50. data/spec/services/bank_details_lookups_service_spec.rb +67 -2
  51. data/spec/services/creditor_bank_accounts_service_spec.rb +309 -31
  52. data/spec/services/creditors_service_spec.rb +343 -33
  53. data/spec/services/customer_bank_accounts_service_spec.rb +335 -32
  54. data/spec/services/customers_service_spec.rb +364 -36
  55. data/spec/services/events_service_spec.rb +185 -24
  56. data/spec/services/mandate_pdfs_service_spec.rb +66 -2
  57. data/spec/services/mandates_service_spec.rb +341 -33
  58. data/spec/services/payments_service_spec.rb +355 -35
  59. data/spec/services/payouts_service_spec.rb +206 -26
  60. data/spec/services/redirect_flows_service_spec.rb +137 -7
  61. data/spec/services/refunds_service_spec.rb +301 -27
  62. data/spec/services/subscriptions_service_spec.rb +377 -38
  63. metadata +6 -3
@@ -1,79 +1,223 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe GoCardlessPro::Resources::Payout do
4
- describe 'initialising' do
5
- let(:data) do
6
- {
4
+ let(:client) do
5
+ GoCardlessPro::Client.new(
6
+ access_token: 'SECRET_TOKEN'
7
+ )
8
+ end
7
9
 
8
- 'amount' => 'amount-input',
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.payouts.list }
15
+
16
+ before do
17
+ stub_request(:get, %r{.*api.gocardless.com/payouts}).to_return(
18
+ body: {
19
+ 'payouts' => [{
20
+
21
+ 'amount' => 'amount-input',
22
+ 'arrival_date' => 'arrival_date-input',
23
+ 'created_at' => 'created_at-input',
24
+ 'currency' => 'currency-input',
25
+ 'deducted_fees' => 'deducted_fees-input',
26
+ 'id' => 'id-input',
27
+ 'links' => 'links-input',
28
+ 'payout_type' => 'payout_type-input',
29
+ 'reference' => 'reference-input',
30
+ 'status' => 'status-input'
31
+ }],
32
+ meta: {
33
+ cursors: {
34
+ before: nil,
35
+ after: 'ABC123'
36
+ }
37
+ }
38
+ }.to_json,
39
+ headers: response_headers
40
+ )
41
+ end
9
42
 
10
- 'arrival_date' => 'arrival_date-input',
43
+ it 'wraps each item in the resource class' do
44
+ expect(get_list_response.records.map(&:class).uniq.first).to eq(GoCardlessPro::Resources::Payout)
11
45
 
12
- 'created_at' => 'created_at-input',
46
+ expect(get_list_response.records.first.amount).to eq('amount-input')
13
47
 
14
- 'currency' => 'currency-input',
48
+ expect(get_list_response.records.first.arrival_date).to eq('arrival_date-input')
15
49
 
16
- 'deducted_fees' => 'deducted_fees-input',
50
+ expect(get_list_response.records.first.created_at).to eq('created_at-input')
17
51
 
18
- 'id' => 'id-input',
52
+ expect(get_list_response.records.first.currency).to eq('currency-input')
19
53
 
20
- 'links' => {
54
+ expect(get_list_response.records.first.deducted_fees).to eq('deducted_fees-input')
21
55
 
22
- 'creditor' => 'creditor-input',
56
+ expect(get_list_response.records.first.id).to eq('id-input')
23
57
 
24
- 'creditor_bank_account' => 'creditor_bank_account-input'
58
+ expect(get_list_response.records.first.payout_type).to eq('payout_type-input')
25
59
 
26
- },
60
+ expect(get_list_response.records.first.reference).to eq('reference-input')
27
61
 
28
- 'reference' => 'reference-input',
62
+ expect(get_list_response.records.first.status).to eq('status-input')
63
+ end
29
64
 
30
- 'status' => 'status-input'
65
+ it 'exposes the cursors for before and after' do
66
+ expect(get_list_response.before).to eq(nil)
67
+ expect(get_list_response.after).to eq('ABC123')
68
+ end
31
69
 
32
- }
70
+ specify { expect(get_list_response.api_response.headers).to eql('content-type' => 'application/json') }
33
71
  end
72
+ end
34
73
 
35
- it 'can be initialized from an unenveloped response' do
36
- resource = described_class.new(data)
37
-
38
- expect(resource.amount).to eq('amount-input')
39
-
40
- expect(resource.arrival_date).to eq('arrival_date-input')
41
-
42
- expect(resource.created_at).to eq('created_at-input')
74
+ describe '#all' do
75
+ let!(:first_response_stub) do
76
+ stub_request(:get, %r{.*api.gocardless.com/payouts$}).to_return(
77
+ body: {
78
+ 'payouts' => [{
79
+
80
+ 'amount' => 'amount-input',
81
+ 'arrival_date' => 'arrival_date-input',
82
+ 'created_at' => 'created_at-input',
83
+ 'currency' => 'currency-input',
84
+ 'deducted_fees' => 'deducted_fees-input',
85
+ 'id' => 'id-input',
86
+ 'links' => 'links-input',
87
+ 'payout_type' => 'payout_type-input',
88
+ 'reference' => 'reference-input',
89
+ 'status' => 'status-input'
90
+ }],
91
+ meta: {
92
+ cursors: { after: 'AB345' },
93
+ limit: 1
94
+ }
95
+ }.to_json,
96
+ headers: response_headers
97
+ )
98
+ end
43
99
 
44
- expect(resource.currency).to eq('currency-input')
100
+ let!(:second_response_stub) do
101
+ stub_request(:get, %r{.*api.gocardless.com/payouts\?after=AB345}).to_return(
102
+ body: {
103
+ 'payouts' => [{
104
+
105
+ 'amount' => 'amount-input',
106
+ 'arrival_date' => 'arrival_date-input',
107
+ 'created_at' => 'created_at-input',
108
+ 'currency' => 'currency-input',
109
+ 'deducted_fees' => 'deducted_fees-input',
110
+ 'id' => 'id-input',
111
+ 'links' => 'links-input',
112
+ 'payout_type' => 'payout_type-input',
113
+ 'reference' => 'reference-input',
114
+ 'status' => 'status-input'
115
+ }],
116
+ meta: {
117
+ limit: 2,
118
+ cursors: {}
119
+ }
120
+ }.to_json,
121
+ headers: response_headers
122
+ )
123
+ end
45
124
 
46
- expect(resource.deducted_fees).to eq('deducted_fees-input')
125
+ it 'automatically makes the extra requests' do
126
+ expect(client.payouts.all.to_a.length).to eq(2)
127
+ expect(first_response_stub).to have_been_requested
128
+ expect(second_response_stub).to have_been_requested
129
+ end
130
+ end
47
131
 
48
- expect(resource.id).to eq('id-input')
132
+ describe '#get' do
133
+ let(:id) { 'ID123' }
134
+
135
+ subject(:get_response) { client.payouts.get(id) }
136
+
137
+ context 'passing in a custom header' do
138
+ let!(:stub) do
139
+ stub_url = '/payouts/:identity'.gsub(':identity', id)
140
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/)
141
+ .with(headers: { 'Foo' => 'Bar' })
142
+ .to_return(
143
+ body: {
144
+ 'payouts' => {
145
+
146
+ 'amount' => 'amount-input',
147
+ 'arrival_date' => 'arrival_date-input',
148
+ 'created_at' => 'created_at-input',
149
+ 'currency' => 'currency-input',
150
+ 'deducted_fees' => 'deducted_fees-input',
151
+ 'id' => 'id-input',
152
+ 'links' => 'links-input',
153
+ 'payout_type' => 'payout_type-input',
154
+ 'reference' => 'reference-input',
155
+ 'status' => 'status-input'
156
+ }
157
+ }.to_json,
158
+ headers: response_headers
159
+ )
160
+ end
49
161
 
50
- expect(resource.links.creditor).to eq('creditor-input')
162
+ subject(:get_response) do
163
+ client.payouts.get(id, headers: {
164
+ 'Foo' => 'Bar'
165
+ })
166
+ end
51
167
 
52
- expect(resource.links.creditor_bank_account).to eq('creditor_bank_account-input')
168
+ it 'includes the header' do
169
+ get_response
170
+ expect(stub).to have_been_requested
171
+ end
172
+ end
53
173
 
54
- expect(resource.reference).to eq('reference-input')
174
+ context 'when there is a payout to return' do
175
+ before do
176
+ stub_url = '/payouts/:identity'.gsub(':identity', id)
177
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).to_return(
178
+ body: {
179
+ 'payouts' => {
180
+
181
+ 'amount' => 'amount-input',
182
+ 'arrival_date' => 'arrival_date-input',
183
+ 'created_at' => 'created_at-input',
184
+ 'currency' => 'currency-input',
185
+ 'deducted_fees' => 'deducted_fees-input',
186
+ 'id' => 'id-input',
187
+ 'links' => 'links-input',
188
+ 'payout_type' => 'payout_type-input',
189
+ 'reference' => 'reference-input',
190
+ 'status' => 'status-input'
191
+ }
192
+ }.to_json,
193
+ headers: response_headers
194
+ )
195
+ end
55
196
 
56
- expect(resource.status).to eq('status-input')
197
+ it 'wraps the response in a resource' do
198
+ expect(get_response).to be_a(GoCardlessPro::Resources::Payout)
199
+ end
57
200
  end
58
201
 
59
- it 'can handle new attributes without erroring' do
60
- data['foo'] = 'bar'
61
- expect { described_class.new(data) }.to_not raise_error
62
- end
202
+ context 'when nothing is returned' do
203
+ before do
204
+ stub_url = '/payouts/:identity'.gsub(':identity', id)
205
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).to_return(
206
+ body: '',
207
+ headers: response_headers
208
+ )
209
+ end
63
210
 
64
- it 'can handle new link attributes without erroring' do
65
- data['links']['foo'] = 'bar'
66
- expect { described_class.new(data) }.to_not raise_error
211
+ it 'returns nil' do
212
+ expect(get_response).to be_nil
213
+ end
67
214
  end
68
215
 
69
- it 'can handle a nil links value' do
70
- data['links'] = nil
71
- expect { described_class.new(data).links }.to_not raise_error
72
- end
216
+ context "when an ID is specified which can't be included in a valid URI" do
217
+ let(:id) { '`' }
73
218
 
74
- describe '#to_h' do
75
- it 'returns a hash representing the resource' do
76
- expect(described_class.new(data).to_h).to eq(data)
219
+ it "doesn't raise an error" do
220
+ expect { get_response }.to_not raise_error(/bad URI/)
77
221
  end
78
222
  end
79
223
  end
@@ -1,83 +1,317 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe GoCardlessPro::Resources::RedirectFlow do
4
- describe 'initialising' do
5
- let(:data) do
6
- {
4
+ let(:client) do
5
+ GoCardlessPro::Client.new(
6
+ access_token: 'SECRET_TOKEN'
7
+ )
8
+ end
7
9
 
8
- 'created_at' => 'created_at-input',
10
+ let(:response_headers) { { 'Content-Type' => 'application/json' } }
9
11
 
10
- 'description' => 'description-input',
12
+ describe '#create' do
13
+ subject(:post_create_response) { client.redirect_flows.create(params: new_resource) }
14
+ context 'with a valid request' do
15
+ let(:new_resource) do
16
+ {
11
17
 
12
- 'id' => 'id-input',
18
+ 'created_at' => 'created_at-input',
19
+ 'description' => 'description-input',
20
+ 'id' => 'id-input',
21
+ 'links' => 'links-input',
22
+ 'redirect_url' => 'redirect_url-input',
23
+ 'scheme' => 'scheme-input',
24
+ 'session_token' => 'session_token-input',
25
+ 'success_redirect_url' => 'success_redirect_url-input'
26
+ }
27
+ end
13
28
 
14
- 'links' => {
29
+ before do
30
+ stub_request(:post, %r{.*api.gocardless.com/redirect_flows})
31
+ .with(
32
+ body: {
33
+ 'redirect_flows' => {
15
34
 
16
- 'creditor' => 'creditor-input',
35
+ 'created_at' => 'created_at-input',
36
+ 'description' => 'description-input',
37
+ 'id' => 'id-input',
38
+ 'links' => 'links-input',
39
+ 'redirect_url' => 'redirect_url-input',
40
+ 'scheme' => 'scheme-input',
41
+ 'session_token' => 'session_token-input',
42
+ 'success_redirect_url' => 'success_redirect_url-input'
43
+ }
44
+ }
45
+ )
46
+ .to_return(
47
+ body: {
48
+ 'redirect_flows' =>
17
49
 
18
- 'customer' => 'customer-input',
50
+ {
19
51
 
20
- 'customer_bank_account' => 'customer_bank_account-input',
52
+ 'created_at' => 'created_at-input',
53
+ 'description' => 'description-input',
54
+ 'id' => 'id-input',
55
+ 'links' => 'links-input',
56
+ 'redirect_url' => 'redirect_url-input',
57
+ 'scheme' => 'scheme-input',
58
+ 'session_token' => 'session_token-input',
59
+ 'success_redirect_url' => 'success_redirect_url-input'
60
+ }
21
61
 
22
- 'mandate' => 'mandate-input'
62
+ }.to_json,
63
+ headers: response_headers
64
+ )
65
+ end
23
66
 
24
- },
67
+ it 'creates and returns the resource' do
68
+ expect(post_create_response).to be_a(GoCardlessPro::Resources::RedirectFlow)
69
+ end
70
+ end
25
71
 
26
- 'redirect_url' => 'redirect_url-input',
72
+ context 'with a request that returns a validation error' do
73
+ let(:new_resource) { {} }
27
74
 
28
- 'scheme' => 'scheme-input',
75
+ before do
76
+ stub_request(:post, %r{.*api.gocardless.com/redirect_flows}).to_return(
77
+ body: {
78
+ error: {
79
+ type: 'validation_failed',
80
+ code: 422,
81
+ errors: [
82
+ { message: 'test error message', field: 'test_field' }
83
+ ]
84
+ }
85
+ }.to_json,
86
+ headers: response_headers,
87
+ status: 422
88
+ )
89
+ end
29
90
 
30
- 'session_token' => 'session_token-input',
91
+ it 'throws the correct error' do
92
+ expect { post_create_response }.to raise_error(GoCardlessPro::ValidationError)
93
+ end
94
+ end
31
95
 
32
- 'success_redirect_url' => 'success_redirect_url-input'
96
+ context 'with a request that returns an idempotent creation conflict error' do
97
+ let(:id) { 'ID123' }
33
98
 
34
- }
35
- end
99
+ let(:new_resource) do
100
+ {
36
101
 
37
- it 'can be initialized from an unenveloped response' do
38
- resource = described_class.new(data)
102
+ 'created_at' => 'created_at-input',
103
+ 'description' => 'description-input',
104
+ 'id' => 'id-input',
105
+ 'links' => 'links-input',
106
+ 'redirect_url' => 'redirect_url-input',
107
+ 'scheme' => 'scheme-input',
108
+ 'session_token' => 'session_token-input',
109
+ 'success_redirect_url' => 'success_redirect_url-input'
110
+ }
111
+ end
112
+
113
+ let!(:post_stub) do
114
+ stub_request(:post, %r{.*api.gocardless.com/redirect_flows}).to_return(
115
+ body: {
116
+ error: {
117
+ type: 'invalid_state',
118
+ code: 409,
119
+ errors: [
120
+ {
121
+ message: 'A resource has already been created with this idempotency key',
122
+ reason: 'idempotent_creation_conflict',
123
+ links: {
124
+ conflicting_resource_id: id
125
+ }
126
+ }
127
+ ]
128
+ }
129
+ }.to_json,
130
+ headers: response_headers,
131
+ status: 409
132
+ )
133
+ end
134
+
135
+ let!(:get_stub) do
136
+ stub_url = "/redirect_flows/#{id}"
137
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/)
138
+ .to_return(
139
+ body: {
140
+ 'redirect_flows' => {
141
+
142
+ 'created_at' => 'created_at-input',
143
+ 'description' => 'description-input',
144
+ 'id' => 'id-input',
145
+ 'links' => 'links-input',
146
+ 'redirect_url' => 'redirect_url-input',
147
+ 'scheme' => 'scheme-input',
148
+ 'session_token' => 'session_token-input',
149
+ 'success_redirect_url' => 'success_redirect_url-input'
150
+ }
151
+ }.to_json,
152
+ headers: response_headers
153
+ )
154
+ end
155
+
156
+ it 'fetches the already-created resource' do
157
+ post_create_response
158
+ expect(post_stub).to have_been_requested
159
+ expect(get_stub).to have_been_requested
160
+ end
161
+ end
162
+ end
39
163
 
40
- expect(resource.created_at).to eq('created_at-input')
164
+ describe '#get' do
165
+ let(:id) { 'ID123' }
41
166
 
42
- expect(resource.description).to eq('description-input')
167
+ subject(:get_response) { client.redirect_flows.get(id) }
43
168
 
44
- expect(resource.id).to eq('id-input')
169
+ context 'passing in a custom header' do
170
+ let!(:stub) do
171
+ stub_url = '/redirect_flows/:identity'.gsub(':identity', id)
172
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/)
173
+ .with(headers: { 'Foo' => 'Bar' })
174
+ .to_return(
175
+ body: {
176
+ 'redirect_flows' => {
45
177
 
46
- expect(resource.links.creditor).to eq('creditor-input')
178
+ 'created_at' => 'created_at-input',
179
+ 'description' => 'description-input',
180
+ 'id' => 'id-input',
181
+ 'links' => 'links-input',
182
+ 'redirect_url' => 'redirect_url-input',
183
+ 'scheme' => 'scheme-input',
184
+ 'session_token' => 'session_token-input',
185
+ 'success_redirect_url' => 'success_redirect_url-input'
186
+ }
187
+ }.to_json,
188
+ headers: response_headers
189
+ )
190
+ end
47
191
 
48
- expect(resource.links.customer).to eq('customer-input')
192
+ subject(:get_response) do
193
+ client.redirect_flows.get(id, headers: {
194
+ 'Foo' => 'Bar'
195
+ })
196
+ end
49
197
 
50
- expect(resource.links.customer_bank_account).to eq('customer_bank_account-input')
198
+ it 'includes the header' do
199
+ get_response
200
+ expect(stub).to have_been_requested
201
+ end
202
+ end
51
203
 
52
- expect(resource.links.mandate).to eq('mandate-input')
204
+ context 'when there is a redirect_flow to return' do
205
+ before do
206
+ stub_url = '/redirect_flows/:identity'.gsub(':identity', id)
207
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).to_return(
208
+ body: {
209
+ 'redirect_flows' => {
53
210
 
54
- expect(resource.redirect_url).to eq('redirect_url-input')
211
+ 'created_at' => 'created_at-input',
212
+ 'description' => 'description-input',
213
+ 'id' => 'id-input',
214
+ 'links' => 'links-input',
215
+ 'redirect_url' => 'redirect_url-input',
216
+ 'scheme' => 'scheme-input',
217
+ 'session_token' => 'session_token-input',
218
+ 'success_redirect_url' => 'success_redirect_url-input'
219
+ }
220
+ }.to_json,
221
+ headers: response_headers
222
+ )
223
+ end
55
224
 
56
- expect(resource.scheme).to eq('scheme-input')
225
+ it 'wraps the response in a resource' do
226
+ expect(get_response).to be_a(GoCardlessPro::Resources::RedirectFlow)
227
+ end
228
+ end
57
229
 
58
- expect(resource.session_token).to eq('session_token-input')
230
+ context 'when nothing is returned' do
231
+ before do
232
+ stub_url = '/redirect_flows/:identity'.gsub(':identity', id)
233
+ stub_request(:get, /.*api.gocardless.com#{stub_url}/).to_return(
234
+ body: '',
235
+ headers: response_headers
236
+ )
237
+ end
59
238
 
60
- expect(resource.success_redirect_url).to eq('success_redirect_url-input')
239
+ it 'returns nil' do
240
+ expect(get_response).to be_nil
241
+ end
61
242
  end
62
243
 
63
- it 'can handle new attributes without erroring' do
64
- data['foo'] = 'bar'
65
- expect { described_class.new(data) }.to_not raise_error
244
+ context "when an ID is specified which can't be included in a valid URI" do
245
+ let(:id) { '`' }
246
+
247
+ it "doesn't raise an error" do
248
+ expect { get_response }.to_not raise_error(/bad URI/)
249
+ end
66
250
  end
251
+ end
252
+
253
+ describe '#complete' do
254
+ subject(:post_response) { client.redirect_flows.complete(resource_id) }
255
+
256
+ let(:resource_id) { 'ABC123' }
257
+
258
+ let!(:stub) do
259
+ # /redirect_flows/%v/actions/complete
260
+ stub_url = '/redirect_flows/:identity/actions/complete'.gsub(':identity', resource_id)
261
+ stub_request(:post, /.*api.gocardless.com#{stub_url}/).to_return(
262
+ body: {
263
+ 'redirect_flows' => {
67
264
 
68
- it 'can handle new link attributes without erroring' do
69
- data['links']['foo'] = 'bar'
70
- expect { described_class.new(data) }.to_not raise_error
265
+ 'created_at' => 'created_at-input',
266
+ 'description' => 'description-input',
267
+ 'id' => 'id-input',
268
+ 'links' => 'links-input',
269
+ 'redirect_url' => 'redirect_url-input',
270
+ 'scheme' => 'scheme-input',
271
+ 'session_token' => 'session_token-input',
272
+ 'success_redirect_url' => 'success_redirect_url-input'
273
+ }
274
+ }.to_json,
275
+ headers: response_headers
276
+ )
71
277
  end
72
278
 
73
- it 'can handle a nil links value' do
74
- data['links'] = nil
75
- expect { described_class.new(data).links }.to_not raise_error
279
+ it 'wraps the response and calls the right endpoint' do
280
+ expect(post_response).to be_a(GoCardlessPro::Resources::RedirectFlow)
281
+
282
+ expect(stub).to have_been_requested
76
283
  end
77
284
 
78
- describe '#to_h' do
79
- it 'returns a hash representing the resource' do
80
- expect(described_class.new(data).to_h).to eq(data)
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.redirect_flows.complete(resource_id, body, headers) }
289
+
290
+ let(:resource_id) { 'ABC123' }
291
+
292
+ let!(:stub) do
293
+ # /redirect_flows/%v/actions/complete
294
+ stub_url = '/redirect_flows/:identity/actions/complete'.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
+ 'redirect_flows' => {
302
+
303
+ 'created_at' => 'created_at-input',
304
+ 'description' => 'description-input',
305
+ 'id' => 'id-input',
306
+ 'links' => 'links-input',
307
+ 'redirect_url' => 'redirect_url-input',
308
+ 'scheme' => 'scheme-input',
309
+ 'session_token' => 'session_token-input',
310
+ 'success_redirect_url' => 'success_redirect_url-input'
311
+ }
312
+ }.to_json,
313
+ headers: response_headers
314
+ )
81
315
  end
82
316
  end
83
317
  end