gocardless_pro 2.25.0 → 2.27.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +3 -3
- data/lib/gocardless_pro.rb +18 -0
- data/lib/gocardless_pro/client.rb +31 -1
- data/lib/gocardless_pro/resources/bank_authorisation.rb +87 -0
- data/lib/gocardless_pro/resources/billing_request.rb +86 -0
- data/lib/gocardless_pro/resources/billing_request_flow.rb +62 -0
- data/lib/gocardless_pro/resources/creditor.rb +2 -3
- data/lib/gocardless_pro/resources/institution.rb +45 -0
- data/lib/gocardless_pro/resources/payer_authorisation.rb +3 -0
- data/lib/gocardless_pro/resources/scenario_simulator.rb +42 -0
- data/lib/gocardless_pro/resources/webhook.rb +62 -0
- data/lib/gocardless_pro/services/bank_authorisations_service.rb +82 -0
- data/lib/gocardless_pro/services/billing_request_flows_service.rb +47 -0
- data/lib/gocardless_pro/services/billing_requests_service.rb +325 -0
- data/lib/gocardless_pro/services/institutions_service.rb +56 -0
- data/lib/gocardless_pro/services/payer_authorisations_service.rb +5 -5
- data/lib/gocardless_pro/services/scenario_simulators_service.rb +148 -0
- data/lib/gocardless_pro/services/subscriptions_service.rb +8 -3
- data/lib/gocardless_pro/services/webhooks_service.rb +113 -0
- data/lib/gocardless_pro/version.rb +1 -1
- data/spec/resources/bank_authorisation_spec.rb +259 -0
- data/spec/resources/billing_request_flow_spec.rb +129 -0
- data/spec/resources/billing_request_spec.rb +736 -0
- data/spec/resources/institution_spec.rb +103 -0
- data/spec/resources/scenario_simulator_spec.rb +63 -0
- data/spec/resources/webhook_spec.rb +323 -0
- data/spec/services/bank_authorisations_service_spec.rb +366 -0
- data/spec/services/billing_request_flows_service_spec.rb +152 -0
- data/spec/services/billing_requests_service_spec.rb +1042 -0
- data/spec/services/institutions_service_spec.rb +223 -0
- data/spec/services/scenario_simulators_service_spec.rb +74 -0
- data/spec/services/webhooks_service_spec.rb +545 -0
- metadata +39 -3
@@ -0,0 +1,56 @@
|
|
1
|
+
require_relative './base_service'
|
2
|
+
|
3
|
+
# encoding: utf-8
|
4
|
+
#
|
5
|
+
# This client is automatically generated from a template and JSON schema definition.
|
6
|
+
# See https://github.com/gocardless/gocardless-pro-ruby#contributing before editing.
|
7
|
+
#
|
8
|
+
|
9
|
+
module GoCardlessPro
|
10
|
+
module Services
|
11
|
+
# Service for making requests to the Institution endpoints
|
12
|
+
class InstitutionsService < BaseService
|
13
|
+
# Returns a list of all supported institutions.
|
14
|
+
# Example URL: /institutions
|
15
|
+
# @param options [Hash] parameters as a hash, under a params key.
|
16
|
+
def list(options = {})
|
17
|
+
path = '/institutions'
|
18
|
+
|
19
|
+
options[:retry_failures] = true
|
20
|
+
|
21
|
+
response = make_request(:get, path, options)
|
22
|
+
|
23
|
+
ListResponse.new(
|
24
|
+
response: response,
|
25
|
+
unenveloped_body: unenvelope_body(response.body),
|
26
|
+
resource_class: Resources::Institution
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Get a lazily enumerated list of all the items returned. This is simmilar to the `list` method but will paginate for you automatically.
|
31
|
+
#
|
32
|
+
# @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
|
33
|
+
# Otherwise they will be the body of the request.
|
34
|
+
def all(options = {})
|
35
|
+
Paginator.new(
|
36
|
+
service: self,
|
37
|
+
options: options
|
38
|
+
).enumerator
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
# Unenvelope the response of the body using the service's `envelope_key`
|
44
|
+
#
|
45
|
+
# @param body [Hash]
|
46
|
+
def unenvelope_body(body)
|
47
|
+
body[envelope_key] || body['data']
|
48
|
+
end
|
49
|
+
|
50
|
+
# return the key which API responses will envelope data under
|
51
|
+
def envelope_key
|
52
|
+
'institutions'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -71,7 +71,7 @@ module GoCardlessPro
|
|
71
71
|
end
|
72
72
|
|
73
73
|
# Updates a Payer Authorisation. Updates the Payer Authorisation with the
|
74
|
-
# request data.Can be invoked as many times as needed. Only fields present in
|
74
|
+
# request data. Can be invoked as many times as needed. Only fields present in
|
75
75
|
# the request will be modified. An empty array of incomplete_fields means that
|
76
76
|
# the resource is valid. This endpoint has been designed this way so you do not
|
77
77
|
# need to save any payer data on your servers or the browser while still being
|
@@ -100,8 +100,8 @@ module GoCardlessPro
|
|
100
100
|
end
|
101
101
|
|
102
102
|
# Submits all the data previously pushed to this PayerAuthorisation for
|
103
|
-
# verification.This time, a 200 HTTP status is returned if the resource is
|
104
|
-
# and a 422 error response in case of validation errors. After it is
|
103
|
+
# verification. This time, a 200 HTTP status is returned if the resource is
|
104
|
+
# valid and a 422 error response in case of validation errors. After it is
|
105
105
|
# successfully submitted, the Payer Authorisation can no longer be edited.
|
106
106
|
# Example URL: /payer_authorisations/:identity/actions/submit
|
107
107
|
#
|
@@ -149,8 +149,8 @@ module GoCardlessPro
|
|
149
149
|
# The main use of the confirm endpoint is to enable integrators to acknowledge
|
150
150
|
# the end of the setup process.
|
151
151
|
# They might want to make the payers go through some other steps after they go
|
152
|
-
# through our flow or make them go through the necessary verification
|
153
|
-
#
|
152
|
+
# through our flow or make them go through the necessary verification mechanism
|
153
|
+
# (upcoming feature).
|
154
154
|
# </p>
|
155
155
|
# Example URL: /payer_authorisations/:identity/actions/confirm
|
156
156
|
#
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require_relative './base_service'
|
2
|
+
|
3
|
+
# encoding: utf-8
|
4
|
+
#
|
5
|
+
# This client is automatically generated from a template and JSON schema definition.
|
6
|
+
# See https://github.com/gocardless/gocardless-pro-ruby#contributing before editing.
|
7
|
+
#
|
8
|
+
|
9
|
+
module GoCardlessPro
|
10
|
+
module Services
|
11
|
+
# Service for making requests to the ScenarioSimulator endpoints
|
12
|
+
class ScenarioSimulatorsService < BaseService
|
13
|
+
# Runs the specific scenario simulator against the specific resource
|
14
|
+
# Example URL: /scenario_simulators/:identity/actions/run
|
15
|
+
#
|
16
|
+
# @param identity # The unique identifier of the simulator, used to initiate simulations.
|
17
|
+
# One of:
|
18
|
+
# <ul>
|
19
|
+
# <li>`creditor_verification_status_action_required`: Sets a creditor's
|
20
|
+
# `verification status` to `action required`, meaning that the creditor
|
21
|
+
# must provide further information to GoCardless in order to verify their
|
22
|
+
# account to receive payouts.</li>
|
23
|
+
# <li>`creditor_verification_status_in_review`: Sets a creditor's
|
24
|
+
# `verification status` to `in review`, meaning that the creditor has
|
25
|
+
# provided all of the information requested by GoCardless to verify their
|
26
|
+
# account, and is now awaiting review.</li>
|
27
|
+
# <li>`creditor_verification_status_successful`: Sets a creditor's
|
28
|
+
# `verification status` to `successful`, meaning that the creditor is
|
29
|
+
# fully verified and can receive payouts.</li>
|
30
|
+
# <li>`payment_paid_out`: Transitions a payment through to `paid_out`,
|
31
|
+
# having been collected successfully and paid out to you. It must start in
|
32
|
+
# the `pending_submission` state, and its mandate must be in the
|
33
|
+
# `activated` state (unless it is a payment for ACH, BECS, BECS_NZ or
|
34
|
+
# SEPA, in which cases the mandate may be `pending_submission`, since
|
35
|
+
# their mandates are submitted with their first payment).</li>
|
36
|
+
# <li>`payment_failed`: Transitions a payment through to `failed`. It must
|
37
|
+
# start in the `pending_submission` state, and its mandate must be in the
|
38
|
+
# `activated` state (unless it is a payment for ACH, BECS, BECS_NZ or
|
39
|
+
# SEPA, in which cases the mandate may be `pending_submission`, since
|
40
|
+
# their mandates are submitted with their first payment).</li>
|
41
|
+
# <li>`payment_charged_back`: Behaves the same as the `payout_paid_out`
|
42
|
+
# simulator, except that the payment is transitioned to `charged_back`
|
43
|
+
# after it is paid out, having been charged back by the customer.</li>
|
44
|
+
# <li>`payment_chargeback_settled`: Behaves the same as the
|
45
|
+
# `payment_charged_back` simulator, except that the charged back payment
|
46
|
+
# is additionally included as a debit item in a payout, thereby settling
|
47
|
+
# the charged back payment.</li>
|
48
|
+
# <li>`payment_late_failure`: Transitions a payment through to
|
49
|
+
# `late_failure`, having been apparently collected successfully
|
50
|
+
# beforehand. It must start in the `pending_submission` state, and its
|
51
|
+
# mandate must be in the `activated` state (unless it is a payment for
|
52
|
+
# ACH, BECS, BECS_NZ or SEPA, in which cases the mandate may be
|
53
|
+
# `pending_submission`, since their mandates are submitted with their
|
54
|
+
# first payment). Not compatible with Autogiro mandates.</li>
|
55
|
+
# <li>`payment_late_failure_settled`: Behaves the same as the
|
56
|
+
# `payment_late_failure` simulator, except that the late failure is
|
57
|
+
# additionally included as a debit item in a payout, thereby settling the
|
58
|
+
# late failure.</li>
|
59
|
+
# <li>`payment_submitted`: Transitions a payment to `submitted`, without
|
60
|
+
# proceeding any further. It must start in the `pending_submission`
|
61
|
+
# state.</li>
|
62
|
+
# <li>`mandate_activated`: Transitions a mandate through to `activated`,
|
63
|
+
# having been submitted to the banks and set up successfully. It must
|
64
|
+
# start in the `pending_submission` state. Not compatible with ACH, BECS,
|
65
|
+
# BECS_NZ and SEPA mandates, which are submitted and activated with their
|
66
|
+
# first payment.</li>
|
67
|
+
# <li>`mandate_customer_approval_granted`: Transitions a mandate through
|
68
|
+
# to `pending_submission`, as if the customer approved the mandate
|
69
|
+
# creation. It must start in the `pending_customer_approval` state.
|
70
|
+
# Compatible only with Bacs and SEPA mandates, which support customer
|
71
|
+
# signatures on the mandate. All payments associated with the mandate will
|
72
|
+
# be transitioned to `pending_submission`. All subscriptions associated
|
73
|
+
# with the mandate will become `active`.</li>
|
74
|
+
# <li>`mandate_customer_approval_skipped`: Transitions a mandate through
|
75
|
+
# to `pending_submission`, as if the customer skipped the mandate approval
|
76
|
+
# during the mandate creation process. It must start in the
|
77
|
+
# `pending_customer_approval` state. Compatible only with Bacs and SEPA
|
78
|
+
# mandates, which support customer signatures on the mandate. All payments
|
79
|
+
# associated with the mandate will be transitioned to
|
80
|
+
# `pending_submission`. All subscriptions associated with the mandate will
|
81
|
+
# become `active`.</li>
|
82
|
+
# <li>`mandate_failed`: Transitions a mandate through to `failed`, having
|
83
|
+
# been submitted to the banks but found to be invalid (for example due to
|
84
|
+
# invalid bank details). It must start in the `pending_submission` or
|
85
|
+
# `submitted` states. Not compatible with ACH, BECS, BECS_NZ and SEPA
|
86
|
+
# mandates, which are submitted with their first payment.</li>
|
87
|
+
# <li>`mandate_expired`: Transitions a mandate through to `expired`,
|
88
|
+
# having been submitted to the banks, set up successfully and then expired
|
89
|
+
# because no collection attempts were made against it for longer than the
|
90
|
+
# scheme's dormancy period (13 months for Bacs, 3 years for SEPA, 15
|
91
|
+
# months for ACH, Betalingsservice, and BECS). It must start in the
|
92
|
+
# `pending_submission` state. Not compatible with Autogiro, BECS NZ, and
|
93
|
+
# PAD mandates, which do not expire.</li>
|
94
|
+
# <li>`mandate_transferred`: Transitions a mandate through to
|
95
|
+
# `transferred`, having been submitted to the banks, set up successfully
|
96
|
+
# and then moved to a new bank account due to the customer using the UK's
|
97
|
+
# Current Account Switching Service (CASS). It must start in the
|
98
|
+
# `pending_submission` state. Only compatible with Bacs mandates.</li>
|
99
|
+
# <li>`mandate_transferred_with_resubmission`: Transitions a mandate
|
100
|
+
# through `transferred` and resubmits it to the banks, can be caused be
|
101
|
+
# the UK's Current Account Switching Service (CASS) or when a customer
|
102
|
+
# contacts GoCardless to change their bank details. It must start in the
|
103
|
+
# `pending_submission` state. Only compatible with Bacs, SEPA and Autogiro
|
104
|
+
# mandates.</li>
|
105
|
+
# <li>`refund_paid`: Transitions a refund to `paid`. It must start in
|
106
|
+
# either the `pending_submission` or `submitted` state.</li>
|
107
|
+
# <li>`refund_bounced`: Transitions a refund to `bounced`. It must start
|
108
|
+
# in either the `pending_submission`, `submitted`, or `paid` state.</li>
|
109
|
+
# <li>`payout_bounced`: Transitions a payout to `bounced`. It must start
|
110
|
+
# in the `paid` state.</li>
|
111
|
+
# <li>`payout_create`: Creates a payout containing payments in
|
112
|
+
# `confirmed`, `failed` & `charged_back` states; refunds in `submitted` &
|
113
|
+
# `bounced`; and all related fees. Can only be used with a positive total
|
114
|
+
# payout balance and when some eligible items exist.</li>
|
115
|
+
# </ul>
|
116
|
+
# @param options [Hash] parameters as a hash, under a params key.
|
117
|
+
def run(identity, options = {})
|
118
|
+
path = sub_url('/scenario_simulators/:identity/actions/run', 'identity' => identity)
|
119
|
+
|
120
|
+
params = options.delete(:params) || {}
|
121
|
+
options[:params] = {}
|
122
|
+
options[:params]['data'] = params
|
123
|
+
|
124
|
+
options[:retry_failures] = false
|
125
|
+
|
126
|
+
response = make_request(:post, path, options)
|
127
|
+
|
128
|
+
return if response.body.nil?
|
129
|
+
|
130
|
+
Resources::ScenarioSimulator.new(unenvelope_body(response.body), response)
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
# Unenvelope the response of the body using the service's `envelope_key`
|
136
|
+
#
|
137
|
+
# @param body [Hash]
|
138
|
+
def unenvelope_body(body)
|
139
|
+
body[envelope_key] || body['data']
|
140
|
+
end
|
141
|
+
|
142
|
+
# return the key which API responses will envelope data under
|
143
|
+
def envelope_key
|
144
|
+
'scenario_simulators'
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -141,8 +141,9 @@ module GoCardlessPro
|
|
141
141
|
# No payments will be created until it is resumed.
|
142
142
|
#
|
143
143
|
# This can only be used when a subscription collecting a fixed number of
|
144
|
-
# payments (created using `count`)
|
145
|
-
#
|
144
|
+
# payments (created using `count`),
|
145
|
+
# when they continue forever (created without `count` or `end_date`) or
|
146
|
+
# the subscription is paused for a number of cycles.
|
146
147
|
#
|
147
148
|
# When `pause_cycles` is omitted the subscription is paused until the [resume
|
148
149
|
# endpoint](#subscriptions-resume-a-subscription) is called.
|
@@ -166,7 +167,11 @@ module GoCardlessPro
|
|
166
167
|
# - `validation_failed` if invalid data is provided when attempting to pause a
|
167
168
|
# subscription.
|
168
169
|
#
|
169
|
-
# - `
|
170
|
+
# - `subscription_paused_cannot_update_cycles` if the subscription is already
|
171
|
+
# paused for a number of cycles and the request provides a value for
|
172
|
+
# `pause_cycle`.
|
173
|
+
#
|
174
|
+
# - `subscription_cannot_be_paused` if the subscription cannot be paused.
|
170
175
|
#
|
171
176
|
# - `subscription_already_ended` if the subscription has taken all payments.
|
172
177
|
#
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require_relative './base_service'
|
2
|
+
|
3
|
+
# encoding: utf-8
|
4
|
+
#
|
5
|
+
# This client is automatically generated from a template and JSON schema definition.
|
6
|
+
# See https://github.com/gocardless/gocardless-pro-ruby#contributing before editing.
|
7
|
+
#
|
8
|
+
|
9
|
+
module GoCardlessPro
|
10
|
+
module Services
|
11
|
+
# Service for making requests to the Webhook endpoints
|
12
|
+
class WebhooksService < BaseService
|
13
|
+
# Returns a [cursor-paginated](#api-usage-cursor-pagination) list of your
|
14
|
+
# webhooks.
|
15
|
+
# Example URL: /webhooks
|
16
|
+
# @param options [Hash] parameters as a hash, under a params key.
|
17
|
+
def list(options = {})
|
18
|
+
path = '/webhooks'
|
19
|
+
|
20
|
+
options[:retry_failures] = true
|
21
|
+
|
22
|
+
response = make_request(:get, path, options)
|
23
|
+
|
24
|
+
ListResponse.new(
|
25
|
+
response: response,
|
26
|
+
unenveloped_body: unenvelope_body(response.body),
|
27
|
+
resource_class: Resources::Webhook
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Get a lazily enumerated list of all the items returned. This is simmilar to the `list` method but will paginate for you automatically.
|
32
|
+
#
|
33
|
+
# @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
|
34
|
+
# Otherwise they will be the body of the request.
|
35
|
+
def all(options = {})
|
36
|
+
Paginator.new(
|
37
|
+
service: self,
|
38
|
+
options: options
|
39
|
+
).enumerator
|
40
|
+
end
|
41
|
+
|
42
|
+
# Retrieves the details of an existing webhook.
|
43
|
+
# Example URL: /webhooks/:identity
|
44
|
+
#
|
45
|
+
# @param identity # Unique identifier, beginning with "WB".
|
46
|
+
# @param options [Hash] parameters as a hash, under a params key.
|
47
|
+
def get(identity, options = {})
|
48
|
+
path = sub_url('/webhooks/:identity', 'identity' => identity)
|
49
|
+
|
50
|
+
options[:retry_failures] = true
|
51
|
+
|
52
|
+
response = make_request(:get, path, options)
|
53
|
+
|
54
|
+
return if response.body.nil?
|
55
|
+
|
56
|
+
Resources::Webhook.new(unenvelope_body(response.body), response)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Requests for a previous webhook to be sent again
|
60
|
+
# Example URL: /webhooks/:identity/actions/retry
|
61
|
+
#
|
62
|
+
# @param identity # Unique identifier, beginning with "WB".
|
63
|
+
# @param options [Hash] parameters as a hash, under a params key.
|
64
|
+
def retry(identity, options = {})
|
65
|
+
path = sub_url('/webhooks/:identity/actions/retry', 'identity' => identity)
|
66
|
+
|
67
|
+
params = options.delete(:params) || {}
|
68
|
+
options[:params] = {}
|
69
|
+
options[:params]['data'] = params
|
70
|
+
|
71
|
+
options[:retry_failures] = false
|
72
|
+
|
73
|
+
begin
|
74
|
+
response = make_request(:post, path, options)
|
75
|
+
|
76
|
+
# Response doesn't raise any errors until #body is called
|
77
|
+
response.tap(&:body)
|
78
|
+
rescue InvalidStateError => e
|
79
|
+
if e.idempotent_creation_conflict?
|
80
|
+
case @api_service.on_idempotency_conflict
|
81
|
+
when :raise
|
82
|
+
raise IdempotencyConflict, e.error
|
83
|
+
when :fetch
|
84
|
+
return get(e.conflicting_resource_id)
|
85
|
+
else
|
86
|
+
raise ArgumentError, 'Unknown mode for :on_idempotency_conflict'
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
raise e
|
91
|
+
end
|
92
|
+
|
93
|
+
return if response.body.nil?
|
94
|
+
|
95
|
+
Resources::Webhook.new(unenvelope_body(response.body), response)
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
# Unenvelope the response of the body using the service's `envelope_key`
|
101
|
+
#
|
102
|
+
# @param body [Hash]
|
103
|
+
def unenvelope_body(body)
|
104
|
+
body[envelope_key] || body['data']
|
105
|
+
end
|
106
|
+
|
107
|
+
# return the key which API responses will envelope data under
|
108
|
+
def envelope_key
|
109
|
+
'webhooks'
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,259 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe GoCardlessPro::Resources::BankAuthorisation 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 '#get' do
|
13
|
+
let(:id) { 'ID123' }
|
14
|
+
|
15
|
+
subject(:get_response) { client.bank_authorisations.get(id) }
|
16
|
+
|
17
|
+
context 'passing in a custom header' do
|
18
|
+
let!(:stub) do
|
19
|
+
stub_url = '/bank_authorisations/:identity'.gsub(':identity', id)
|
20
|
+
stub_request(:get, /.*api.gocardless.com#{stub_url}/).
|
21
|
+
with(headers: { 'Foo' => 'Bar' }).
|
22
|
+
to_return(
|
23
|
+
body: {
|
24
|
+
'bank_authorisations' => {
|
25
|
+
|
26
|
+
'authorisation_type' => 'authorisation_type-input',
|
27
|
+
'created_at' => 'created_at-input',
|
28
|
+
'expires_at' => 'expires_at-input',
|
29
|
+
'id' => 'id-input',
|
30
|
+
'last_visited_at' => 'last_visited_at-input',
|
31
|
+
'links' => 'links-input',
|
32
|
+
'redirect_uri' => 'redirect_uri-input',
|
33
|
+
'short_url' => 'short_url-input',
|
34
|
+
'url' => 'url-input',
|
35
|
+
},
|
36
|
+
}.to_json,
|
37
|
+
headers: response_headers
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
subject(:get_response) do
|
42
|
+
client.bank_authorisations.get(id, headers: {
|
43
|
+
'Foo' => 'Bar',
|
44
|
+
})
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'includes the header' do
|
48
|
+
get_response
|
49
|
+
expect(stub).to have_been_requested
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'when there is a bank_authorisation to return' do
|
54
|
+
before do
|
55
|
+
stub_url = '/bank_authorisations/:identity'.gsub(':identity', id)
|
56
|
+
stub_request(:get, /.*api.gocardless.com#{stub_url}/).to_return(
|
57
|
+
body: {
|
58
|
+
'bank_authorisations' => {
|
59
|
+
|
60
|
+
'authorisation_type' => 'authorisation_type-input',
|
61
|
+
'created_at' => 'created_at-input',
|
62
|
+
'expires_at' => 'expires_at-input',
|
63
|
+
'id' => 'id-input',
|
64
|
+
'last_visited_at' => 'last_visited_at-input',
|
65
|
+
'links' => 'links-input',
|
66
|
+
'redirect_uri' => 'redirect_uri-input',
|
67
|
+
'short_url' => 'short_url-input',
|
68
|
+
'url' => 'url-input',
|
69
|
+
},
|
70
|
+
}.to_json,
|
71
|
+
headers: response_headers
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'wraps the response in a resource' do
|
76
|
+
expect(get_response).to be_a(GoCardlessPro::Resources::BankAuthorisation)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'when nothing is returned' do
|
81
|
+
before do
|
82
|
+
stub_url = '/bank_authorisations/:identity'.gsub(':identity', id)
|
83
|
+
stub_request(:get, /.*api.gocardless.com#{stub_url}/).to_return(
|
84
|
+
body: '',
|
85
|
+
headers: response_headers
|
86
|
+
)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'returns nil' do
|
90
|
+
expect(get_response).to be_nil
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context "when an ID is specified which can't be included in a valid URI" do
|
95
|
+
let(:id) { '`' }
|
96
|
+
|
97
|
+
it "doesn't raise an error" do
|
98
|
+
expect { get_response }.to_not raise_error(/bad URI/)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe '#create' do
|
104
|
+
subject(:post_create_response) { client.bank_authorisations.create(params: new_resource) }
|
105
|
+
context 'with a valid request' do
|
106
|
+
let(:new_resource) do
|
107
|
+
{
|
108
|
+
|
109
|
+
'authorisation_type' => 'authorisation_type-input',
|
110
|
+
'created_at' => 'created_at-input',
|
111
|
+
'expires_at' => 'expires_at-input',
|
112
|
+
'id' => 'id-input',
|
113
|
+
'last_visited_at' => 'last_visited_at-input',
|
114
|
+
'links' => 'links-input',
|
115
|
+
'redirect_uri' => 'redirect_uri-input',
|
116
|
+
'short_url' => 'short_url-input',
|
117
|
+
'url' => 'url-input',
|
118
|
+
}
|
119
|
+
end
|
120
|
+
|
121
|
+
before do
|
122
|
+
stub_request(:post, %r{.*api.gocardless.com/bank_authorisations}).
|
123
|
+
with(
|
124
|
+
body: {
|
125
|
+
'bank_authorisations' => {
|
126
|
+
|
127
|
+
'authorisation_type' => 'authorisation_type-input',
|
128
|
+
'created_at' => 'created_at-input',
|
129
|
+
'expires_at' => 'expires_at-input',
|
130
|
+
'id' => 'id-input',
|
131
|
+
'last_visited_at' => 'last_visited_at-input',
|
132
|
+
'links' => 'links-input',
|
133
|
+
'redirect_uri' => 'redirect_uri-input',
|
134
|
+
'short_url' => 'short_url-input',
|
135
|
+
'url' => 'url-input',
|
136
|
+
},
|
137
|
+
}
|
138
|
+
).
|
139
|
+
to_return(
|
140
|
+
body: {
|
141
|
+
'bank_authorisations' =>
|
142
|
+
|
143
|
+
{
|
144
|
+
|
145
|
+
'authorisation_type' => 'authorisation_type-input',
|
146
|
+
'created_at' => 'created_at-input',
|
147
|
+
'expires_at' => 'expires_at-input',
|
148
|
+
'id' => 'id-input',
|
149
|
+
'last_visited_at' => 'last_visited_at-input',
|
150
|
+
'links' => 'links-input',
|
151
|
+
'redirect_uri' => 'redirect_uri-input',
|
152
|
+
'short_url' => 'short_url-input',
|
153
|
+
'url' => 'url-input',
|
154
|
+
},
|
155
|
+
|
156
|
+
}.to_json,
|
157
|
+
headers: response_headers
|
158
|
+
)
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'creates and returns the resource' do
|
162
|
+
expect(post_create_response).to be_a(GoCardlessPro::Resources::BankAuthorisation)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context 'with a request that returns a validation error' do
|
167
|
+
let(:new_resource) { {} }
|
168
|
+
|
169
|
+
before do
|
170
|
+
stub_request(:post, %r{.*api.gocardless.com/bank_authorisations}).to_return(
|
171
|
+
body: {
|
172
|
+
error: {
|
173
|
+
type: 'validation_failed',
|
174
|
+
code: 422,
|
175
|
+
errors: [
|
176
|
+
{ message: 'test error message', field: 'test_field' },
|
177
|
+
],
|
178
|
+
},
|
179
|
+
}.to_json,
|
180
|
+
headers: response_headers,
|
181
|
+
status: 422
|
182
|
+
)
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'throws the correct error' do
|
186
|
+
expect { post_create_response }.to raise_error(GoCardlessPro::ValidationError)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context 'with a request that returns an idempotent creation conflict error' do
|
191
|
+
let(:id) { 'ID123' }
|
192
|
+
|
193
|
+
let(:new_resource) do
|
194
|
+
{
|
195
|
+
|
196
|
+
'authorisation_type' => 'authorisation_type-input',
|
197
|
+
'created_at' => 'created_at-input',
|
198
|
+
'expires_at' => 'expires_at-input',
|
199
|
+
'id' => 'id-input',
|
200
|
+
'last_visited_at' => 'last_visited_at-input',
|
201
|
+
'links' => 'links-input',
|
202
|
+
'redirect_uri' => 'redirect_uri-input',
|
203
|
+
'short_url' => 'short_url-input',
|
204
|
+
'url' => 'url-input',
|
205
|
+
}
|
206
|
+
end
|
207
|
+
|
208
|
+
let!(:post_stub) do
|
209
|
+
stub_request(:post, %r{.*api.gocardless.com/bank_authorisations}).to_return(
|
210
|
+
body: {
|
211
|
+
error: {
|
212
|
+
type: 'invalid_state',
|
213
|
+
code: 409,
|
214
|
+
errors: [
|
215
|
+
{
|
216
|
+
message: 'A resource has already been created with this idempotency key',
|
217
|
+
reason: 'idempotent_creation_conflict',
|
218
|
+
links: {
|
219
|
+
conflicting_resource_id: id,
|
220
|
+
},
|
221
|
+
},
|
222
|
+
],
|
223
|
+
},
|
224
|
+
}.to_json,
|
225
|
+
headers: response_headers,
|
226
|
+
status: 409
|
227
|
+
)
|
228
|
+
end
|
229
|
+
|
230
|
+
let!(:get_stub) do
|
231
|
+
stub_url = "/bank_authorisations/#{id}"
|
232
|
+
stub_request(:get, /.*api.gocardless.com#{stub_url}/).
|
233
|
+
to_return(
|
234
|
+
body: {
|
235
|
+
'bank_authorisations' => {
|
236
|
+
|
237
|
+
'authorisation_type' => 'authorisation_type-input',
|
238
|
+
'created_at' => 'created_at-input',
|
239
|
+
'expires_at' => 'expires_at-input',
|
240
|
+
'id' => 'id-input',
|
241
|
+
'last_visited_at' => 'last_visited_at-input',
|
242
|
+
'links' => 'links-input',
|
243
|
+
'redirect_uri' => 'redirect_uri-input',
|
244
|
+
'short_url' => 'short_url-input',
|
245
|
+
'url' => 'url-input',
|
246
|
+
},
|
247
|
+
}.to_json,
|
248
|
+
headers: response_headers
|
249
|
+
)
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'fetches the already-created resource' do
|
253
|
+
post_create_response
|
254
|
+
expect(post_stub).to have_been_requested
|
255
|
+
expect(get_stub).to have_been_requested
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|