gocardless_pro 2.17.1 → 2.18.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.
- checksums.yaml +4 -4
- data/gocardless_pro-2.17.1.gem +0 -0
- data/lib/gocardless_pro.rb +3 -0
- data/lib/gocardless_pro/client.rb +6 -1
- data/lib/gocardless_pro/resources/currency_exchange_rate.rb +44 -0
- data/lib/gocardless_pro/resources/subscription.rb +2 -0
- data/lib/gocardless_pro/services/currency_exchange_rates_service.rb +67 -0
- data/lib/gocardless_pro/services/instalment_schedules_service.rb +60 -5
- data/lib/gocardless_pro/version.rb +1 -1
- data/spec/resources/currency_exchange_rate_spec.rb +103 -0
- data/spec/resources/instalment_schedule_spec.rb +158 -1
- data/spec/resources/subscription_spec.rb +15 -0
- data/spec/services/currency_exchange_rates_service_spec.rb +223 -0
- data/spec/services/instalment_schedules_service_spec.rb +210 -1
- data/spec/services/subscriptions_service_spec.rb +19 -0
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 250fed25fc74cb084ad988286e20f8dd2c679fcb62e0de5a1fc3bfca71b67c43
|
4
|
+
data.tar.gz: af02087f4d85aafa9337d51219c467bc195c6c9eff6d03b2f9c5dbf209956680
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a3bd1149c2936dfd1ba6d8b60e7183c279d105046c4c02ab497e2d11da3c3f93c363a56ce5a2c1133138ad9acd421bbfb4c479c1da3970afb4c6b650a0197965
|
7
|
+
data.tar.gz: '07951005f59ae4328b34342bb24c9b06bfb9f0221a87630751d21b9755354fb3daaf7f0b34bb51d98811f2e1199479be08745afdb66c888953bfad50fc8bc099'
|
Binary file
|
data/lib/gocardless_pro.rb
CHANGED
@@ -47,6 +47,9 @@ require_relative 'gocardless_pro/services/creditors_service'
|
|
47
47
|
require_relative 'gocardless_pro/resources/creditor_bank_account'
|
48
48
|
require_relative 'gocardless_pro/services/creditor_bank_accounts_service'
|
49
49
|
|
50
|
+
require_relative 'gocardless_pro/resources/currency_exchange_rate'
|
51
|
+
require_relative 'gocardless_pro/services/currency_exchange_rates_service'
|
52
|
+
|
50
53
|
require_relative 'gocardless_pro/resources/customer'
|
51
54
|
require_relative 'gocardless_pro/services/customers_service'
|
52
55
|
|
@@ -18,6 +18,11 @@ module GoCardlessPro
|
|
18
18
|
@creditor_bank_accounts ||= Services::CreditorBankAccountsService.new(@api_service)
|
19
19
|
end
|
20
20
|
|
21
|
+
# Access to the service for currency_exchange_rate to make API calls
|
22
|
+
def currency_exchange_rates
|
23
|
+
@currency_exchange_rates ||= Services::CurrencyExchangeRatesService.new(@api_service)
|
24
|
+
end
|
25
|
+
|
21
26
|
# Access to the service for customer to make API calls
|
22
27
|
def customers
|
23
28
|
@customers ||= Services::CustomersService.new(@api_service)
|
@@ -143,7 +148,7 @@ module GoCardlessPro
|
|
143
148
|
'User-Agent' => user_agent.to_s,
|
144
149
|
'Content-Type' => 'application/json',
|
145
150
|
'GoCardless-Client-Library' => 'gocardless-pro-ruby',
|
146
|
-
'GoCardless-Client-Version' => '2.
|
151
|
+
'GoCardless-Client-Version' => '2.18.0',
|
147
152
|
},
|
148
153
|
}
|
149
154
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#
|
4
|
+
# This client is automatically generated from a template and JSON schema definition.
|
5
|
+
# See https://github.com/gocardless/gocardless-pro-ruby#contributing before editing.
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'uri'
|
9
|
+
|
10
|
+
module GoCardlessPro
|
11
|
+
# A module containing classes for each of the resources in the GC Api
|
12
|
+
module Resources
|
13
|
+
# Represents an instance of a currency_exchange_rate resource returned from the API
|
14
|
+
|
15
|
+
# Currency exchange rates from our foreign exchange provider.
|
16
|
+
class CurrencyExchangeRate
|
17
|
+
attr_reader :rate
|
18
|
+
attr_reader :source
|
19
|
+
attr_reader :target
|
20
|
+
attr_reader :time
|
21
|
+
|
22
|
+
# Initialize a currency_exchange_rate resource instance
|
23
|
+
# @param object [Hash] an object returned from the API
|
24
|
+
def initialize(object, response = nil)
|
25
|
+
@object = object
|
26
|
+
|
27
|
+
@rate = object['rate']
|
28
|
+
@source = object['source']
|
29
|
+
@target = object['target']
|
30
|
+
@time = object['time']
|
31
|
+
@response = response
|
32
|
+
end
|
33
|
+
|
34
|
+
def api_response
|
35
|
+
ApiResponse.new(@response)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Provides the currency_exchange_rate resource as a hash of all its readable attributes
|
39
|
+
def to_h
|
40
|
+
@object
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -69,6 +69,7 @@ module GoCardlessPro
|
|
69
69
|
class Subscription
|
70
70
|
attr_reader :amount
|
71
71
|
attr_reader :app_fee
|
72
|
+
attr_reader :count
|
72
73
|
attr_reader :created_at
|
73
74
|
attr_reader :currency
|
74
75
|
attr_reader :day_of_month
|
@@ -92,6 +93,7 @@ module GoCardlessPro
|
|
92
93
|
|
93
94
|
@amount = object['amount']
|
94
95
|
@app_fee = object['app_fee']
|
96
|
+
@count = object['count']
|
95
97
|
@created_at = object['created_at']
|
96
98
|
@currency = object['currency']
|
97
99
|
@day_of_month = object['day_of_month']
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require_relative './base_service'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
# encoding: utf-8
|
5
|
+
#
|
6
|
+
# This client is automatically generated from a template and JSON schema definition.
|
7
|
+
# See https://github.com/gocardless/gocardless-pro-ruby#contributing before editing.
|
8
|
+
#
|
9
|
+
|
10
|
+
module GoCardlessPro
|
11
|
+
module Services
|
12
|
+
# Service for making requests to the CurrencyExchangeRate endpoints
|
13
|
+
class CurrencyExchangeRatesService < BaseService
|
14
|
+
# Returns a [cursor-paginated](#api-usage-cursor-pagination) list of all
|
15
|
+
# exchange rates.
|
16
|
+
# Example URL: /currency_exchange_rates
|
17
|
+
# @param options [Hash] parameters as a hash, under a params key.
|
18
|
+
def list(options = {})
|
19
|
+
path = '/currency_exchange_rates'
|
20
|
+
|
21
|
+
options[:retry_failures] = true
|
22
|
+
|
23
|
+
response = make_request(:get, path, options)
|
24
|
+
|
25
|
+
ListResponse.new(
|
26
|
+
response: response,
|
27
|
+
unenveloped_body: unenvelope_body(response.body),
|
28
|
+
resource_class: Resources::CurrencyExchangeRate
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Get a lazily enumerated list of all the items returned. This is simmilar to the `list` method but will paginate for you automatically.
|
33
|
+
#
|
34
|
+
# @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
|
35
|
+
# Otherwise they will be the body of the request.
|
36
|
+
def all(options = {})
|
37
|
+
Paginator.new(
|
38
|
+
service: self,
|
39
|
+
options: options
|
40
|
+
).enumerator
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
# Unenvelope the response of the body using the service's `envelope_key`
|
46
|
+
#
|
47
|
+
# @param body [Hash]
|
48
|
+
def unenvelope_body(body)
|
49
|
+
body[envelope_key] || body['data']
|
50
|
+
end
|
51
|
+
|
52
|
+
# return the key which API responses will envelope data under
|
53
|
+
def envelope_key
|
54
|
+
'currency_exchange_rates'
|
55
|
+
end
|
56
|
+
|
57
|
+
# take a URL with placeholder params and substitute them out for the actual value
|
58
|
+
# @param url [String] the URL with placeholders in
|
59
|
+
# @param param_map [Hash] a hash of placeholders and their actual values (which will be escaped)
|
60
|
+
def sub_url(url, param_map)
|
61
|
+
param_map.reduce(url) do |new_url, (param, value)|
|
62
|
+
new_url.gsub(":#{param}", URI.escape(value))
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -12,11 +12,66 @@ module GoCardlessPro
|
|
12
12
|
# Service for making requests to the InstalmentSchedule endpoints
|
13
13
|
class InstalmentSchedulesService < BaseService
|
14
14
|
# Creates a new instalment schedule object, along with the associated payments.
|
15
|
+
# This
|
16
|
+
# API is recommended if you know the specific dates you wish to charge.
|
17
|
+
# Otherwise,
|
18
|
+
# please check out the [scheduling
|
19
|
+
# version](#instalment-schedules-create-with-schedule).
|
15
20
|
#
|
16
|
-
# The `instalments` property
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
21
|
+
# The `instalments` property is an array of payment properties (`amount` and
|
22
|
+
# `charge_date`).
|
23
|
+
#
|
24
|
+
# It can take quite a while to create the associated payments, so the API will
|
25
|
+
# return
|
26
|
+
# the status as `pending` initially. When processing has completed, a subsequent
|
27
|
+
# GET
|
28
|
+
# request for the instalment schedule will either have the status `success` and
|
29
|
+
# link
|
30
|
+
# to the created payments, or the status `error` and detailed information about
|
31
|
+
# the
|
32
|
+
# failures.
|
33
|
+
# Example URL: /instalment_schedules
|
34
|
+
# @param options [Hash] parameters as a hash, under a params key.
|
35
|
+
def create_with_dates(options = {})
|
36
|
+
path = '/instalment_schedules'
|
37
|
+
|
38
|
+
params = options.delete(:params) || {}
|
39
|
+
options[:params] = {}
|
40
|
+
options[:params][envelope_key] = params
|
41
|
+
|
42
|
+
options[:retry_failures] = true
|
43
|
+
|
44
|
+
begin
|
45
|
+
response = make_request(:post, path, options)
|
46
|
+
|
47
|
+
# Response doesn't raise any errors until #body is called
|
48
|
+
response.tap(&:body)
|
49
|
+
rescue InvalidStateError => e
|
50
|
+
if e.idempotent_creation_conflict?
|
51
|
+
case @api_service.on_idempotency_conflict
|
52
|
+
when :raise
|
53
|
+
raise IdempotencyConflict, e.error
|
54
|
+
when :fetch
|
55
|
+
return get(e.conflicting_resource_id)
|
56
|
+
else
|
57
|
+
raise ArgumentError, 'Unknown mode for :on_idempotency_conflict'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
raise e
|
62
|
+
end
|
63
|
+
|
64
|
+
return if response.body.nil?
|
65
|
+
|
66
|
+
Resources::InstalmentSchedule.new(unenvelope_body(response.body), response)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Creates a new instalment schedule object, along with the associated payments.
|
70
|
+
# This
|
71
|
+
# API is recommended if you wish to use the GoCardless scheduling logic. For
|
72
|
+
# finer
|
73
|
+
# control over the individual dates, please check out the [alternative
|
74
|
+
# version](#instalment-schedules-create-with-dates).
|
20
75
|
#
|
21
76
|
# It can take quite a while to create the associated payments, so the API will
|
22
77
|
# return
|
@@ -27,7 +82,7 @@ module GoCardlessPro
|
|
27
82
|
# failures.
|
28
83
|
# Example URL: /instalment_schedules
|
29
84
|
# @param options [Hash] parameters as a hash, under a params key.
|
30
|
-
def
|
85
|
+
def create_with_schedule(options = {})
|
31
86
|
path = '/instalment_schedules'
|
32
87
|
|
33
88
|
params = options.delete(:params) || {}
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe GoCardlessPro::Resources::CurrencyExchangeRate 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.currency_exchange_rates.list }
|
15
|
+
|
16
|
+
before do
|
17
|
+
stub_request(:get, %r{.*api.gocardless.com/currency_exchange_rates}).to_return(
|
18
|
+
body: {
|
19
|
+
'currency_exchange_rates' => [{
|
20
|
+
|
21
|
+
'rate' => 'rate-input',
|
22
|
+
'source' => 'source-input',
|
23
|
+
'target' => 'target-input',
|
24
|
+
'time' => 'time-input',
|
25
|
+
}],
|
26
|
+
meta: {
|
27
|
+
cursors: {
|
28
|
+
before: nil,
|
29
|
+
after: 'ABC123',
|
30
|
+
},
|
31
|
+
},
|
32
|
+
}.to_json,
|
33
|
+
headers: response_headers
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'wraps each item in the resource class' do
|
38
|
+
expect(get_list_response.records.map(&:class).uniq.first).to eq(GoCardlessPro::Resources::CurrencyExchangeRate)
|
39
|
+
|
40
|
+
expect(get_list_response.records.first.rate).to eq('rate-input')
|
41
|
+
|
42
|
+
expect(get_list_response.records.first.source).to eq('source-input')
|
43
|
+
|
44
|
+
expect(get_list_response.records.first.target).to eq('target-input')
|
45
|
+
|
46
|
+
expect(get_list_response.records.first.time).to eq('time-input')
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'exposes the cursors for before and after' do
|
50
|
+
expect(get_list_response.before).to eq(nil)
|
51
|
+
expect(get_list_response.after).to eq('ABC123')
|
52
|
+
end
|
53
|
+
|
54
|
+
specify { expect(get_list_response.api_response.headers).to eql('content-type' => 'application/json') }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#all' do
|
59
|
+
let!(:first_response_stub) do
|
60
|
+
stub_request(:get, %r{.*api.gocardless.com/currency_exchange_rates$}).to_return(
|
61
|
+
body: {
|
62
|
+
'currency_exchange_rates' => [{
|
63
|
+
|
64
|
+
'rate' => 'rate-input',
|
65
|
+
'source' => 'source-input',
|
66
|
+
'target' => 'target-input',
|
67
|
+
'time' => 'time-input',
|
68
|
+
}],
|
69
|
+
meta: {
|
70
|
+
cursors: { after: 'AB345' },
|
71
|
+
limit: 1,
|
72
|
+
},
|
73
|
+
}.to_json,
|
74
|
+
headers: response_headers
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
let!(:second_response_stub) do
|
79
|
+
stub_request(:get, %r{.*api.gocardless.com/currency_exchange_rates\?after=AB345}).to_return(
|
80
|
+
body: {
|
81
|
+
'currency_exchange_rates' => [{
|
82
|
+
|
83
|
+
'rate' => 'rate-input',
|
84
|
+
'source' => 'source-input',
|
85
|
+
'target' => 'target-input',
|
86
|
+
'time' => 'time-input',
|
87
|
+
}],
|
88
|
+
meta: {
|
89
|
+
limit: 2,
|
90
|
+
cursors: {},
|
91
|
+
},
|
92
|
+
}.to_json,
|
93
|
+
headers: response_headers
|
94
|
+
)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'automatically makes the extra requests' do
|
98
|
+
expect(client.currency_exchange_rates.all.to_a.length).to eq(2)
|
99
|
+
expect(first_response_stub).to have_been_requested
|
100
|
+
expect(second_response_stub).to have_been_requested
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -10,7 +10,164 @@ describe GoCardlessPro::Resources::InstalmentSchedule do
|
|
10
10
|
let(:response_headers) { { 'Content-Type' => 'application/json' } }
|
11
11
|
|
12
12
|
describe '#create' do
|
13
|
-
subject(:post_create_response) { client.instalment_schedules.
|
13
|
+
subject(:post_create_response) { client.instalment_schedules.create_with_dates(params: new_resource) }
|
14
|
+
context 'with a valid request' do
|
15
|
+
let(:new_resource) do
|
16
|
+
{
|
17
|
+
|
18
|
+
'created_at' => 'created_at-input',
|
19
|
+
'currency' => 'currency-input',
|
20
|
+
'id' => 'id-input',
|
21
|
+
'links' => 'links-input',
|
22
|
+
'metadata' => 'metadata-input',
|
23
|
+
'name' => 'name-input',
|
24
|
+
'payment_errors' => 'payment_errors-input',
|
25
|
+
'status' => 'status-input',
|
26
|
+
'total_amount' => 'total_amount-input',
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
before do
|
31
|
+
stub_request(:post, %r{.*api.gocardless.com/instalment_schedules}).
|
32
|
+
with(
|
33
|
+
body: {
|
34
|
+
'instalment_schedules' => {
|
35
|
+
|
36
|
+
'created_at' => 'created_at-input',
|
37
|
+
'currency' => 'currency-input',
|
38
|
+
'id' => 'id-input',
|
39
|
+
'links' => 'links-input',
|
40
|
+
'metadata' => 'metadata-input',
|
41
|
+
'name' => 'name-input',
|
42
|
+
'payment_errors' => 'payment_errors-input',
|
43
|
+
'status' => 'status-input',
|
44
|
+
'total_amount' => 'total_amount-input',
|
45
|
+
},
|
46
|
+
}
|
47
|
+
).
|
48
|
+
to_return(
|
49
|
+
body: {
|
50
|
+
'instalment_schedules' =>
|
51
|
+
|
52
|
+
{
|
53
|
+
|
54
|
+
'created_at' => 'created_at-input',
|
55
|
+
'currency' => 'currency-input',
|
56
|
+
'id' => 'id-input',
|
57
|
+
'links' => 'links-input',
|
58
|
+
'metadata' => 'metadata-input',
|
59
|
+
'name' => 'name-input',
|
60
|
+
'payment_errors' => 'payment_errors-input',
|
61
|
+
'status' => 'status-input',
|
62
|
+
'total_amount' => 'total_amount-input',
|
63
|
+
},
|
64
|
+
|
65
|
+
}.to_json,
|
66
|
+
headers: response_headers
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'creates and returns the resource' do
|
71
|
+
expect(post_create_response).to be_a(GoCardlessPro::Resources::InstalmentSchedule)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'with a request that returns a validation error' do
|
76
|
+
let(:new_resource) { {} }
|
77
|
+
|
78
|
+
before do
|
79
|
+
stub_request(:post, %r{.*api.gocardless.com/instalment_schedules}).to_return(
|
80
|
+
body: {
|
81
|
+
error: {
|
82
|
+
type: 'validation_failed',
|
83
|
+
code: 422,
|
84
|
+
errors: [
|
85
|
+
{ message: 'test error message', field: 'test_field' },
|
86
|
+
],
|
87
|
+
},
|
88
|
+
}.to_json,
|
89
|
+
headers: response_headers,
|
90
|
+
status: 422
|
91
|
+
)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'throws the correct error' do
|
95
|
+
expect { post_create_response }.to raise_error(GoCardlessPro::ValidationError)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'with a request that returns an idempotent creation conflict error' do
|
100
|
+
let(:id) { 'ID123' }
|
101
|
+
|
102
|
+
let(:new_resource) do
|
103
|
+
{
|
104
|
+
|
105
|
+
'created_at' => 'created_at-input',
|
106
|
+
'currency' => 'currency-input',
|
107
|
+
'id' => 'id-input',
|
108
|
+
'links' => 'links-input',
|
109
|
+
'metadata' => 'metadata-input',
|
110
|
+
'name' => 'name-input',
|
111
|
+
'payment_errors' => 'payment_errors-input',
|
112
|
+
'status' => 'status-input',
|
113
|
+
'total_amount' => 'total_amount-input',
|
114
|
+
}
|
115
|
+
end
|
116
|
+
|
117
|
+
let!(:post_stub) do
|
118
|
+
stub_request(:post, %r{.*api.gocardless.com/instalment_schedules}).to_return(
|
119
|
+
body: {
|
120
|
+
error: {
|
121
|
+
type: 'invalid_state',
|
122
|
+
code: 409,
|
123
|
+
errors: [
|
124
|
+
{
|
125
|
+
message: 'A resource has already been created with this idempotency key',
|
126
|
+
reason: 'idempotent_creation_conflict',
|
127
|
+
links: {
|
128
|
+
conflicting_resource_id: id,
|
129
|
+
},
|
130
|
+
},
|
131
|
+
],
|
132
|
+
},
|
133
|
+
}.to_json,
|
134
|
+
headers: response_headers,
|
135
|
+
status: 409
|
136
|
+
)
|
137
|
+
end
|
138
|
+
|
139
|
+
let!(:get_stub) do
|
140
|
+
stub_url = "/instalment_schedules/#{id}"
|
141
|
+
stub_request(:get, /.*api.gocardless.com#{stub_url}/).
|
142
|
+
to_return(
|
143
|
+
body: {
|
144
|
+
'instalment_schedules' => {
|
145
|
+
|
146
|
+
'created_at' => 'created_at-input',
|
147
|
+
'currency' => 'currency-input',
|
148
|
+
'id' => 'id-input',
|
149
|
+
'links' => 'links-input',
|
150
|
+
'metadata' => 'metadata-input',
|
151
|
+
'name' => 'name-input',
|
152
|
+
'payment_errors' => 'payment_errors-input',
|
153
|
+
'status' => 'status-input',
|
154
|
+
'total_amount' => 'total_amount-input',
|
155
|
+
},
|
156
|
+
}.to_json,
|
157
|
+
headers: response_headers
|
158
|
+
)
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'fetches the already-created resource' do
|
162
|
+
post_create_response
|
163
|
+
expect(post_stub).to have_been_requested
|
164
|
+
expect(get_stub).to have_been_requested
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
describe '#create' do
|
170
|
+
subject(:post_create_response) { client.instalment_schedules.create_with_schedule(params: new_resource) }
|
14
171
|
context 'with a valid request' do
|
15
172
|
let(:new_resource) do
|
16
173
|
{
|
@@ -17,6 +17,7 @@ describe GoCardlessPro::Resources::Subscription do
|
|
17
17
|
|
18
18
|
'amount' => 'amount-input',
|
19
19
|
'app_fee' => 'app_fee-input',
|
20
|
+
'count' => 'count-input',
|
20
21
|
'created_at' => 'created_at-input',
|
21
22
|
'currency' => 'currency-input',
|
22
23
|
'day_of_month' => 'day_of_month-input',
|
@@ -44,6 +45,7 @@ describe GoCardlessPro::Resources::Subscription do
|
|
44
45
|
|
45
46
|
'amount' => 'amount-input',
|
46
47
|
'app_fee' => 'app_fee-input',
|
48
|
+
'count' => 'count-input',
|
47
49
|
'created_at' => 'created_at-input',
|
48
50
|
'currency' => 'currency-input',
|
49
51
|
'day_of_month' => 'day_of_month-input',
|
@@ -71,6 +73,7 @@ describe GoCardlessPro::Resources::Subscription do
|
|
71
73
|
|
72
74
|
'amount' => 'amount-input',
|
73
75
|
'app_fee' => 'app_fee-input',
|
76
|
+
'count' => 'count-input',
|
74
77
|
'created_at' => 'created_at-input',
|
75
78
|
'currency' => 'currency-input',
|
76
79
|
'day_of_month' => 'day_of_month-input',
|
@@ -131,6 +134,7 @@ describe GoCardlessPro::Resources::Subscription do
|
|
131
134
|
|
132
135
|
'amount' => 'amount-input',
|
133
136
|
'app_fee' => 'app_fee-input',
|
137
|
+
'count' => 'count-input',
|
134
138
|
'created_at' => 'created_at-input',
|
135
139
|
'currency' => 'currency-input',
|
136
140
|
'day_of_month' => 'day_of_month-input',
|
@@ -181,6 +185,7 @@ describe GoCardlessPro::Resources::Subscription do
|
|
181
185
|
|
182
186
|
'amount' => 'amount-input',
|
183
187
|
'app_fee' => 'app_fee-input',
|
188
|
+
'count' => 'count-input',
|
184
189
|
'created_at' => 'created_at-input',
|
185
190
|
'currency' => 'currency-input',
|
186
191
|
'day_of_month' => 'day_of_month-input',
|
@@ -222,6 +227,7 @@ describe GoCardlessPro::Resources::Subscription do
|
|
222
227
|
|
223
228
|
'amount' => 'amount-input',
|
224
229
|
'app_fee' => 'app_fee-input',
|
230
|
+
'count' => 'count-input',
|
225
231
|
'created_at' => 'created_at-input',
|
226
232
|
'currency' => 'currency-input',
|
227
233
|
'day_of_month' => 'day_of_month-input',
|
@@ -257,6 +263,8 @@ describe GoCardlessPro::Resources::Subscription do
|
|
257
263
|
|
258
264
|
expect(get_list_response.records.first.app_fee).to eq('app_fee-input')
|
259
265
|
|
266
|
+
expect(get_list_response.records.first.count).to eq('count-input')
|
267
|
+
|
260
268
|
expect(get_list_response.records.first.created_at).to eq('created_at-input')
|
261
269
|
|
262
270
|
expect(get_list_response.records.first.currency).to eq('currency-input')
|
@@ -305,6 +313,7 @@ describe GoCardlessPro::Resources::Subscription do
|
|
305
313
|
|
306
314
|
'amount' => 'amount-input',
|
307
315
|
'app_fee' => 'app_fee-input',
|
316
|
+
'count' => 'count-input',
|
308
317
|
'created_at' => 'created_at-input',
|
309
318
|
'currency' => 'currency-input',
|
310
319
|
'day_of_month' => 'day_of_month-input',
|
@@ -338,6 +347,7 @@ describe GoCardlessPro::Resources::Subscription do
|
|
338
347
|
|
339
348
|
'amount' => 'amount-input',
|
340
349
|
'app_fee' => 'app_fee-input',
|
350
|
+
'count' => 'count-input',
|
341
351
|
'created_at' => 'created_at-input',
|
342
352
|
'currency' => 'currency-input',
|
343
353
|
'day_of_month' => 'day_of_month-input',
|
@@ -387,6 +397,7 @@ describe GoCardlessPro::Resources::Subscription do
|
|
387
397
|
|
388
398
|
'amount' => 'amount-input',
|
389
399
|
'app_fee' => 'app_fee-input',
|
400
|
+
'count' => 'count-input',
|
390
401
|
'created_at' => 'created_at-input',
|
391
402
|
'currency' => 'currency-input',
|
392
403
|
'day_of_month' => 'day_of_month-input',
|
@@ -430,6 +441,7 @@ describe GoCardlessPro::Resources::Subscription do
|
|
430
441
|
|
431
442
|
'amount' => 'amount-input',
|
432
443
|
'app_fee' => 'app_fee-input',
|
444
|
+
'count' => 'count-input',
|
433
445
|
'created_at' => 'created_at-input',
|
434
446
|
'currency' => 'currency-input',
|
435
447
|
'day_of_month' => 'day_of_month-input',
|
@@ -495,6 +507,7 @@ describe GoCardlessPro::Resources::Subscription do
|
|
495
507
|
|
496
508
|
'amount' => 'amount-input',
|
497
509
|
'app_fee' => 'app_fee-input',
|
510
|
+
'count' => 'count-input',
|
498
511
|
'created_at' => 'created_at-input',
|
499
512
|
'currency' => 'currency-input',
|
500
513
|
'day_of_month' => 'day_of_month-input',
|
@@ -538,6 +551,7 @@ describe GoCardlessPro::Resources::Subscription do
|
|
538
551
|
|
539
552
|
'amount' => 'amount-input',
|
540
553
|
'app_fee' => 'app_fee-input',
|
554
|
+
'count' => 'count-input',
|
541
555
|
'created_at' => 'created_at-input',
|
542
556
|
'currency' => 'currency-input',
|
543
557
|
'day_of_month' => 'day_of_month-input',
|
@@ -586,6 +600,7 @@ describe GoCardlessPro::Resources::Subscription do
|
|
586
600
|
|
587
601
|
'amount' => 'amount-input',
|
588
602
|
'app_fee' => 'app_fee-input',
|
603
|
+
'count' => 'count-input',
|
589
604
|
'created_at' => 'created_at-input',
|
590
605
|
'currency' => 'currency-input',
|
591
606
|
'day_of_month' => 'day_of_month-input',
|
@@ -0,0 +1,223 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe GoCardlessPro::Services::CurrencyExchangeRatesService 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.currency_exchange_rates.list }
|
15
|
+
|
16
|
+
let(:body) do
|
17
|
+
{
|
18
|
+
'currency_exchange_rates' => [{
|
19
|
+
|
20
|
+
'rate' => 'rate-input',
|
21
|
+
'source' => 'source-input',
|
22
|
+
'target' => 'target-input',
|
23
|
+
'time' => 'time-input',
|
24
|
+
}],
|
25
|
+
meta: {
|
26
|
+
cursors: {
|
27
|
+
before: nil,
|
28
|
+
after: 'ABC123',
|
29
|
+
},
|
30
|
+
},
|
31
|
+
}.to_json
|
32
|
+
end
|
33
|
+
|
34
|
+
before do
|
35
|
+
stub_request(:get, %r{.*api.gocardless.com/currency_exchange_rates}).to_return(
|
36
|
+
body: body,
|
37
|
+
headers: response_headers
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'wraps each item in the resource class' do
|
42
|
+
expect(get_list_response.records.map(&:class).uniq.first).to eq(GoCardlessPro::Resources::CurrencyExchangeRate)
|
43
|
+
|
44
|
+
expect(get_list_response.records.first.rate).to eq('rate-input')
|
45
|
+
|
46
|
+
expect(get_list_response.records.first.source).to eq('source-input')
|
47
|
+
|
48
|
+
expect(get_list_response.records.first.target).to eq('target-input')
|
49
|
+
|
50
|
+
expect(get_list_response.records.first.time).to eq('time-input')
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'exposes the cursors for before and after' do
|
54
|
+
expect(get_list_response.before).to eq(nil)
|
55
|
+
expect(get_list_response.after).to eq('ABC123')
|
56
|
+
end
|
57
|
+
|
58
|
+
specify { expect(get_list_response.api_response.headers).to eql('content-type' => 'application/json') }
|
59
|
+
|
60
|
+
describe 'retry behaviour' do
|
61
|
+
before { allow_any_instance_of(GoCardlessPro::Request).to receive(:sleep) }
|
62
|
+
|
63
|
+
it 'retries timeouts' do
|
64
|
+
stub = stub_request(:get, %r{.*api.gocardless.com/currency_exchange_rates}).
|
65
|
+
to_timeout.then.to_return(status: 200, headers: response_headers, body: body)
|
66
|
+
|
67
|
+
get_list_response
|
68
|
+
expect(stub).to have_been_requested.twice
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'retries 5XX errors' do
|
72
|
+
stub = stub_request(:get, %r{.*api.gocardless.com/currency_exchange_rates}).
|
73
|
+
to_return(status: 502,
|
74
|
+
headers: { 'Content-Type' => 'text/html' },
|
75
|
+
body: '<html><body>Response from Cloudflare</body></html>').
|
76
|
+
then.to_return(status: 200, headers: response_headers, body: body)
|
77
|
+
|
78
|
+
get_list_response
|
79
|
+
expect(stub).to have_been_requested.twice
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '#all' do
|
86
|
+
let!(:first_response_stub) do
|
87
|
+
stub_request(:get, %r{.*api.gocardless.com/currency_exchange_rates$}).to_return(
|
88
|
+
body: {
|
89
|
+
'currency_exchange_rates' => [{
|
90
|
+
|
91
|
+
'rate' => 'rate-input',
|
92
|
+
'source' => 'source-input',
|
93
|
+
'target' => 'target-input',
|
94
|
+
'time' => 'time-input',
|
95
|
+
}],
|
96
|
+
meta: {
|
97
|
+
cursors: { after: 'AB345' },
|
98
|
+
limit: 1,
|
99
|
+
},
|
100
|
+
}.to_json,
|
101
|
+
headers: response_headers
|
102
|
+
)
|
103
|
+
end
|
104
|
+
|
105
|
+
let!(:second_response_stub) do
|
106
|
+
stub_request(:get, %r{.*api.gocardless.com/currency_exchange_rates\?after=AB345}).to_return(
|
107
|
+
body: {
|
108
|
+
'currency_exchange_rates' => [{
|
109
|
+
|
110
|
+
'rate' => 'rate-input',
|
111
|
+
'source' => 'source-input',
|
112
|
+
'target' => 'target-input',
|
113
|
+
'time' => 'time-input',
|
114
|
+
}],
|
115
|
+
meta: {
|
116
|
+
limit: 2,
|
117
|
+
cursors: {},
|
118
|
+
},
|
119
|
+
}.to_json,
|
120
|
+
headers: response_headers
|
121
|
+
)
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'automatically makes the extra requests' do
|
125
|
+
expect(client.currency_exchange_rates.all.to_a.length).to eq(2)
|
126
|
+
expect(first_response_stub).to have_been_requested
|
127
|
+
expect(second_response_stub).to have_been_requested
|
128
|
+
end
|
129
|
+
|
130
|
+
describe 'retry behaviour' do
|
131
|
+
before { allow_any_instance_of(GoCardlessPro::Request).to receive(:sleep) }
|
132
|
+
|
133
|
+
it 'retries timeouts' do
|
134
|
+
first_response_stub = stub_request(:get, %r{.*api.gocardless.com/currency_exchange_rates$}).to_return(
|
135
|
+
body: {
|
136
|
+
'currency_exchange_rates' => [{
|
137
|
+
|
138
|
+
'rate' => 'rate-input',
|
139
|
+
'source' => 'source-input',
|
140
|
+
'target' => 'target-input',
|
141
|
+
'time' => 'time-input',
|
142
|
+
}],
|
143
|
+
meta: {
|
144
|
+
cursors: { after: 'AB345' },
|
145
|
+
limit: 1,
|
146
|
+
},
|
147
|
+
}.to_json,
|
148
|
+
headers: response_headers
|
149
|
+
)
|
150
|
+
|
151
|
+
second_response_stub = stub_request(:get, %r{.*api.gocardless.com/currency_exchange_rates\?after=AB345}).
|
152
|
+
to_timeout.then.
|
153
|
+
to_return(
|
154
|
+
body: {
|
155
|
+
'currency_exchange_rates' => [{
|
156
|
+
|
157
|
+
'rate' => 'rate-input',
|
158
|
+
'source' => 'source-input',
|
159
|
+
'target' => 'target-input',
|
160
|
+
'time' => 'time-input',
|
161
|
+
}],
|
162
|
+
meta: {
|
163
|
+
limit: 2,
|
164
|
+
cursors: {},
|
165
|
+
},
|
166
|
+
}.to_json,
|
167
|
+
headers: response_headers
|
168
|
+
)
|
169
|
+
|
170
|
+
client.currency_exchange_rates.all.to_a
|
171
|
+
|
172
|
+
expect(first_response_stub).to have_been_requested
|
173
|
+
expect(second_response_stub).to have_been_requested.twice
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'retries 5XX errors' do
|
177
|
+
first_response_stub = stub_request(:get, %r{.*api.gocardless.com/currency_exchange_rates$}).to_return(
|
178
|
+
body: {
|
179
|
+
'currency_exchange_rates' => [{
|
180
|
+
|
181
|
+
'rate' => 'rate-input',
|
182
|
+
'source' => 'source-input',
|
183
|
+
'target' => 'target-input',
|
184
|
+
'time' => 'time-input',
|
185
|
+
}],
|
186
|
+
meta: {
|
187
|
+
cursors: { after: 'AB345' },
|
188
|
+
limit: 1,
|
189
|
+
},
|
190
|
+
}.to_json,
|
191
|
+
headers: response_headers
|
192
|
+
)
|
193
|
+
|
194
|
+
second_response_stub = stub_request(:get, %r{.*api.gocardless.com/currency_exchange_rates\?after=AB345}).
|
195
|
+
to_return(
|
196
|
+
status: 502,
|
197
|
+
body: '<html><body>Response from Cloudflare</body></html>',
|
198
|
+
headers: { 'Content-Type' => 'text/html' }
|
199
|
+
).then.to_return(
|
200
|
+
body: {
|
201
|
+
'currency_exchange_rates' => [{
|
202
|
+
|
203
|
+
'rate' => 'rate-input',
|
204
|
+
'source' => 'source-input',
|
205
|
+
'target' => 'target-input',
|
206
|
+
'time' => 'time-input',
|
207
|
+
}],
|
208
|
+
meta: {
|
209
|
+
limit: 2,
|
210
|
+
cursors: {},
|
211
|
+
},
|
212
|
+
}.to_json,
|
213
|
+
headers: response_headers
|
214
|
+
)
|
215
|
+
|
216
|
+
client.currency_exchange_rates.all.to_a
|
217
|
+
|
218
|
+
expect(first_response_stub).to have_been_requested
|
219
|
+
expect(second_response_stub).to have_been_requested.twice
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
@@ -10,7 +10,216 @@ describe GoCardlessPro::Services::InstalmentSchedulesService do
|
|
10
10
|
let(:response_headers) { { 'Content-Type' => 'application/json' } }
|
11
11
|
|
12
12
|
describe '#create' do
|
13
|
-
subject(:post_create_response) { client.instalment_schedules.
|
13
|
+
subject(:post_create_response) { client.instalment_schedules.create_with_dates(params: new_resource) }
|
14
|
+
context 'with a valid request' do
|
15
|
+
let(:new_resource) do
|
16
|
+
{
|
17
|
+
|
18
|
+
'created_at' => 'created_at-input',
|
19
|
+
'currency' => 'currency-input',
|
20
|
+
'id' => 'id-input',
|
21
|
+
'links' => 'links-input',
|
22
|
+
'metadata' => 'metadata-input',
|
23
|
+
'name' => 'name-input',
|
24
|
+
'payment_errors' => 'payment_errors-input',
|
25
|
+
'status' => 'status-input',
|
26
|
+
'total_amount' => 'total_amount-input',
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
before do
|
31
|
+
stub_request(:post, %r{.*api.gocardless.com/instalment_schedules}).
|
32
|
+
with(
|
33
|
+
body: {
|
34
|
+
'instalment_schedules' => {
|
35
|
+
|
36
|
+
'created_at' => 'created_at-input',
|
37
|
+
'currency' => 'currency-input',
|
38
|
+
'id' => 'id-input',
|
39
|
+
'links' => 'links-input',
|
40
|
+
'metadata' => 'metadata-input',
|
41
|
+
'name' => 'name-input',
|
42
|
+
'payment_errors' => 'payment_errors-input',
|
43
|
+
'status' => 'status-input',
|
44
|
+
'total_amount' => 'total_amount-input',
|
45
|
+
},
|
46
|
+
}
|
47
|
+
).
|
48
|
+
to_return(
|
49
|
+
body: {
|
50
|
+
'instalment_schedules' =>
|
51
|
+
|
52
|
+
{
|
53
|
+
|
54
|
+
'created_at' => 'created_at-input',
|
55
|
+
'currency' => 'currency-input',
|
56
|
+
'id' => 'id-input',
|
57
|
+
'links' => 'links-input',
|
58
|
+
'metadata' => 'metadata-input',
|
59
|
+
'name' => 'name-input',
|
60
|
+
'payment_errors' => 'payment_errors-input',
|
61
|
+
'status' => 'status-input',
|
62
|
+
'total_amount' => 'total_amount-input',
|
63
|
+
},
|
64
|
+
|
65
|
+
}.to_json,
|
66
|
+
headers: response_headers
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'creates and returns the resource' do
|
71
|
+
expect(post_create_response).to be_a(GoCardlessPro::Resources::InstalmentSchedule)
|
72
|
+
end
|
73
|
+
|
74
|
+
describe 'retry behaviour' do
|
75
|
+
before { allow_any_instance_of(GoCardlessPro::Request).to receive(:sleep) }
|
76
|
+
|
77
|
+
it 'retries timeouts' do
|
78
|
+
stub = stub_request(:post, %r{.*api.gocardless.com/instalment_schedules}).
|
79
|
+
to_timeout.then.to_return(status: 200, headers: response_headers)
|
80
|
+
|
81
|
+
post_create_response
|
82
|
+
expect(stub).to have_been_requested.twice
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'retries 5XX errors' do
|
86
|
+
stub = stub_request(:post, %r{.*api.gocardless.com/instalment_schedules}).
|
87
|
+
to_return(status: 502,
|
88
|
+
headers: { 'Content-Type' => 'text/html' },
|
89
|
+
body: '<html><body>Response from Cloudflare</body></html>').
|
90
|
+
then.to_return(status: 200, headers: response_headers)
|
91
|
+
|
92
|
+
post_create_response
|
93
|
+
expect(stub).to have_been_requested.twice
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'with a request that returns a validation error' do
|
99
|
+
let(:new_resource) { {} }
|
100
|
+
|
101
|
+
before do
|
102
|
+
stub_request(:post, %r{.*api.gocardless.com/instalment_schedules}).to_return(
|
103
|
+
body: {
|
104
|
+
error: {
|
105
|
+
type: 'validation_failed',
|
106
|
+
code: 422,
|
107
|
+
errors: [
|
108
|
+
{ message: 'test error message', field: 'test_field' },
|
109
|
+
],
|
110
|
+
},
|
111
|
+
}.to_json,
|
112
|
+
headers: response_headers,
|
113
|
+
status: 422
|
114
|
+
)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'throws the correct error' do
|
118
|
+
expect { post_create_response }.to raise_error(GoCardlessPro::ValidationError)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context 'with a request that returns an idempotent creation conflict error' do
|
123
|
+
let(:id) { 'ID123' }
|
124
|
+
|
125
|
+
let(:new_resource) do
|
126
|
+
{
|
127
|
+
|
128
|
+
'created_at' => 'created_at-input',
|
129
|
+
'currency' => 'currency-input',
|
130
|
+
'id' => 'id-input',
|
131
|
+
'links' => 'links-input',
|
132
|
+
'metadata' => 'metadata-input',
|
133
|
+
'name' => 'name-input',
|
134
|
+
'payment_errors' => 'payment_errors-input',
|
135
|
+
'status' => 'status-input',
|
136
|
+
'total_amount' => 'total_amount-input',
|
137
|
+
}
|
138
|
+
end
|
139
|
+
|
140
|
+
let!(:post_stub) do
|
141
|
+
stub_request(:post, %r{.*api.gocardless.com/instalment_schedules}).to_return(
|
142
|
+
body: {
|
143
|
+
error: {
|
144
|
+
type: 'invalid_state',
|
145
|
+
code: 409,
|
146
|
+
errors: [
|
147
|
+
{
|
148
|
+
message: 'A resource has already been created with this idempotency key',
|
149
|
+
reason: 'idempotent_creation_conflict',
|
150
|
+
links: {
|
151
|
+
conflicting_resource_id: id,
|
152
|
+
},
|
153
|
+
},
|
154
|
+
],
|
155
|
+
},
|
156
|
+
}.to_json,
|
157
|
+
headers: response_headers,
|
158
|
+
status: 409
|
159
|
+
)
|
160
|
+
end
|
161
|
+
|
162
|
+
let!(:get_stub) do
|
163
|
+
stub_url = "/instalment_schedules/#{id}"
|
164
|
+
stub_request(:get, /.*api.gocardless.com#{stub_url}/).
|
165
|
+
to_return(
|
166
|
+
body: {
|
167
|
+
'instalment_schedules' => {
|
168
|
+
|
169
|
+
'created_at' => 'created_at-input',
|
170
|
+
'currency' => 'currency-input',
|
171
|
+
'id' => 'id-input',
|
172
|
+
'links' => 'links-input',
|
173
|
+
'metadata' => 'metadata-input',
|
174
|
+
'name' => 'name-input',
|
175
|
+
'payment_errors' => 'payment_errors-input',
|
176
|
+
'status' => 'status-input',
|
177
|
+
'total_amount' => 'total_amount-input',
|
178
|
+
},
|
179
|
+
}.to_json,
|
180
|
+
headers: response_headers
|
181
|
+
)
|
182
|
+
end
|
183
|
+
|
184
|
+
context 'with default behaviour' do
|
185
|
+
it 'fetches the already-created resource' do
|
186
|
+
post_create_response
|
187
|
+
expect(post_stub).to have_been_requested
|
188
|
+
expect(get_stub).to have_been_requested
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
context 'with on_idempotency_conflict: :raise' do
|
193
|
+
let(:client) do
|
194
|
+
GoCardlessPro::Client.new(
|
195
|
+
access_token: 'SECRET_TOKEN',
|
196
|
+
on_idempotency_conflict: :raise
|
197
|
+
)
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'raises an IdempotencyConflict error' do
|
201
|
+
expect { post_create_response }.
|
202
|
+
to raise_error(GoCardlessPro::IdempotencyConflict)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
context 'with on_idempotency_conflict: :unknown' do
|
207
|
+
let(:client) do
|
208
|
+
GoCardlessPro::Client.new(
|
209
|
+
access_token: 'SECRET_TOKEN',
|
210
|
+
on_idempotency_conflict: :unknown
|
211
|
+
)
|
212
|
+
end
|
213
|
+
|
214
|
+
it 'raises an ArgumentError' do
|
215
|
+
expect { post_create_response }.to raise_error(ArgumentError)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
describe '#create' do
|
222
|
+
subject(:post_create_response) { client.instalment_schedules.create_with_schedule(params: new_resource) }
|
14
223
|
context 'with a valid request' do
|
15
224
|
let(:new_resource) do
|
16
225
|
{
|
@@ -17,6 +17,7 @@ describe GoCardlessPro::Services::SubscriptionsService do
|
|
17
17
|
|
18
18
|
'amount' => 'amount-input',
|
19
19
|
'app_fee' => 'app_fee-input',
|
20
|
+
'count' => 'count-input',
|
20
21
|
'created_at' => 'created_at-input',
|
21
22
|
'currency' => 'currency-input',
|
22
23
|
'day_of_month' => 'day_of_month-input',
|
@@ -44,6 +45,7 @@ describe GoCardlessPro::Services::SubscriptionsService do
|
|
44
45
|
|
45
46
|
'amount' => 'amount-input',
|
46
47
|
'app_fee' => 'app_fee-input',
|
48
|
+
'count' => 'count-input',
|
47
49
|
'created_at' => 'created_at-input',
|
48
50
|
'currency' => 'currency-input',
|
49
51
|
'day_of_month' => 'day_of_month-input',
|
@@ -71,6 +73,7 @@ describe GoCardlessPro::Services::SubscriptionsService do
|
|
71
73
|
|
72
74
|
'amount' => 'amount-input',
|
73
75
|
'app_fee' => 'app_fee-input',
|
76
|
+
'count' => 'count-input',
|
74
77
|
'created_at' => 'created_at-input',
|
75
78
|
'currency' => 'currency-input',
|
76
79
|
'day_of_month' => 'day_of_month-input',
|
@@ -154,6 +157,7 @@ describe GoCardlessPro::Services::SubscriptionsService do
|
|
154
157
|
|
155
158
|
'amount' => 'amount-input',
|
156
159
|
'app_fee' => 'app_fee-input',
|
160
|
+
'count' => 'count-input',
|
157
161
|
'created_at' => 'created_at-input',
|
158
162
|
'currency' => 'currency-input',
|
159
163
|
'day_of_month' => 'day_of_month-input',
|
@@ -204,6 +208,7 @@ describe GoCardlessPro::Services::SubscriptionsService do
|
|
204
208
|
|
205
209
|
'amount' => 'amount-input',
|
206
210
|
'app_fee' => 'app_fee-input',
|
211
|
+
'count' => 'count-input',
|
207
212
|
'created_at' => 'created_at-input',
|
208
213
|
'currency' => 'currency-input',
|
209
214
|
'day_of_month' => 'day_of_month-input',
|
@@ -273,6 +278,7 @@ describe GoCardlessPro::Services::SubscriptionsService do
|
|
273
278
|
|
274
279
|
'amount' => 'amount-input',
|
275
280
|
'app_fee' => 'app_fee-input',
|
281
|
+
'count' => 'count-input',
|
276
282
|
'created_at' => 'created_at-input',
|
277
283
|
'currency' => 'currency-input',
|
278
284
|
'day_of_month' => 'day_of_month-input',
|
@@ -313,6 +319,8 @@ describe GoCardlessPro::Services::SubscriptionsService do
|
|
313
319
|
|
314
320
|
expect(get_list_response.records.first.app_fee).to eq('app_fee-input')
|
315
321
|
|
322
|
+
expect(get_list_response.records.first.count).to eq('count-input')
|
323
|
+
|
316
324
|
expect(get_list_response.records.first.created_at).to eq('created_at-input')
|
317
325
|
|
318
326
|
expect(get_list_response.records.first.currency).to eq('currency-input')
|
@@ -384,6 +392,7 @@ describe GoCardlessPro::Services::SubscriptionsService do
|
|
384
392
|
|
385
393
|
'amount' => 'amount-input',
|
386
394
|
'app_fee' => 'app_fee-input',
|
395
|
+
'count' => 'count-input',
|
387
396
|
'created_at' => 'created_at-input',
|
388
397
|
'currency' => 'currency-input',
|
389
398
|
'day_of_month' => 'day_of_month-input',
|
@@ -417,6 +426,7 @@ describe GoCardlessPro::Services::SubscriptionsService do
|
|
417
426
|
|
418
427
|
'amount' => 'amount-input',
|
419
428
|
'app_fee' => 'app_fee-input',
|
429
|
+
'count' => 'count-input',
|
420
430
|
'created_at' => 'created_at-input',
|
421
431
|
'currency' => 'currency-input',
|
422
432
|
'day_of_month' => 'day_of_month-input',
|
@@ -459,6 +469,7 @@ describe GoCardlessPro::Services::SubscriptionsService do
|
|
459
469
|
|
460
470
|
'amount' => 'amount-input',
|
461
471
|
'app_fee' => 'app_fee-input',
|
472
|
+
'count' => 'count-input',
|
462
473
|
'created_at' => 'created_at-input',
|
463
474
|
'currency' => 'currency-input',
|
464
475
|
'day_of_month' => 'day_of_month-input',
|
@@ -492,6 +503,7 @@ describe GoCardlessPro::Services::SubscriptionsService do
|
|
492
503
|
|
493
504
|
'amount' => 'amount-input',
|
494
505
|
'app_fee' => 'app_fee-input',
|
506
|
+
'count' => 'count-input',
|
495
507
|
'created_at' => 'created_at-input',
|
496
508
|
'currency' => 'currency-input',
|
497
509
|
'day_of_month' => 'day_of_month-input',
|
@@ -530,6 +542,7 @@ describe GoCardlessPro::Services::SubscriptionsService do
|
|
530
542
|
|
531
543
|
'amount' => 'amount-input',
|
532
544
|
'app_fee' => 'app_fee-input',
|
545
|
+
'count' => 'count-input',
|
533
546
|
'created_at' => 'created_at-input',
|
534
547
|
'currency' => 'currency-input',
|
535
548
|
'day_of_month' => 'day_of_month-input',
|
@@ -566,6 +579,7 @@ describe GoCardlessPro::Services::SubscriptionsService do
|
|
566
579
|
|
567
580
|
'amount' => 'amount-input',
|
568
581
|
'app_fee' => 'app_fee-input',
|
582
|
+
'count' => 'count-input',
|
569
583
|
'created_at' => 'created_at-input',
|
570
584
|
'currency' => 'currency-input',
|
571
585
|
'day_of_month' => 'day_of_month-input',
|
@@ -615,6 +629,7 @@ describe GoCardlessPro::Services::SubscriptionsService do
|
|
615
629
|
|
616
630
|
'amount' => 'amount-input',
|
617
631
|
'app_fee' => 'app_fee-input',
|
632
|
+
'count' => 'count-input',
|
618
633
|
'created_at' => 'created_at-input',
|
619
634
|
'currency' => 'currency-input',
|
620
635
|
'day_of_month' => 'day_of_month-input',
|
@@ -658,6 +673,7 @@ describe GoCardlessPro::Services::SubscriptionsService do
|
|
658
673
|
|
659
674
|
'amount' => 'amount-input',
|
660
675
|
'app_fee' => 'app_fee-input',
|
676
|
+
'count' => 'count-input',
|
661
677
|
'created_at' => 'created_at-input',
|
662
678
|
'currency' => 'currency-input',
|
663
679
|
'day_of_month' => 'day_of_month-input',
|
@@ -778,6 +794,7 @@ describe GoCardlessPro::Services::SubscriptionsService do
|
|
778
794
|
|
779
795
|
'amount' => 'amount-input',
|
780
796
|
'app_fee' => 'app_fee-input',
|
797
|
+
'count' => 'count-input',
|
781
798
|
'created_at' => 'created_at-input',
|
782
799
|
'currency' => 'currency-input',
|
783
800
|
'day_of_month' => 'day_of_month-input',
|
@@ -846,6 +863,7 @@ describe GoCardlessPro::Services::SubscriptionsService do
|
|
846
863
|
|
847
864
|
'amount' => 'amount-input',
|
848
865
|
'app_fee' => 'app_fee-input',
|
866
|
+
'count' => 'count-input',
|
849
867
|
'created_at' => 'created_at-input',
|
850
868
|
'currency' => 'currency-input',
|
851
869
|
'day_of_month' => 'day_of_month-input',
|
@@ -905,6 +923,7 @@ describe GoCardlessPro::Services::SubscriptionsService do
|
|
905
923
|
|
906
924
|
'amount' => 'amount-input',
|
907
925
|
'app_fee' => 'app_fee-input',
|
926
|
+
'count' => 'count-input',
|
908
927
|
'created_at' => 'created_at-input',
|
909
928
|
'currency' => 'currency-input',
|
910
929
|
'day_of_month' => 'day_of_month-input',
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gocardless_pro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.18.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GoCardless
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -144,6 +144,7 @@ files:
|
|
144
144
|
- LICENSE.txt
|
145
145
|
- README.md
|
146
146
|
- demo.rb
|
147
|
+
- gocardless_pro-2.17.1.gem
|
147
148
|
- gocardless_pro.gemspec
|
148
149
|
- lib/gocardless_pro.rb
|
149
150
|
- lib/gocardless_pro/api_response.rb
|
@@ -162,6 +163,7 @@ files:
|
|
162
163
|
- lib/gocardless_pro/resources/bank_details_lookup.rb
|
163
164
|
- lib/gocardless_pro/resources/creditor.rb
|
164
165
|
- lib/gocardless_pro/resources/creditor_bank_account.rb
|
166
|
+
- lib/gocardless_pro/resources/currency_exchange_rate.rb
|
165
167
|
- lib/gocardless_pro/resources/customer.rb
|
166
168
|
- lib/gocardless_pro/resources/customer_bank_account.rb
|
167
169
|
- lib/gocardless_pro/resources/customer_notification.rb
|
@@ -182,6 +184,7 @@ files:
|
|
182
184
|
- lib/gocardless_pro/services/base_service.rb
|
183
185
|
- lib/gocardless_pro/services/creditor_bank_accounts_service.rb
|
184
186
|
- lib/gocardless_pro/services/creditors_service.rb
|
187
|
+
- lib/gocardless_pro/services/currency_exchange_rates_service.rb
|
185
188
|
- lib/gocardless_pro/services/customer_bank_accounts_service.rb
|
186
189
|
- lib/gocardless_pro/services/customer_notifications_service.rb
|
187
190
|
- lib/gocardless_pro/services/customers_service.rb
|
@@ -207,6 +210,7 @@ files:
|
|
207
210
|
- spec/resources/bank_details_lookup_spec.rb
|
208
211
|
- spec/resources/creditor_bank_account_spec.rb
|
209
212
|
- spec/resources/creditor_spec.rb
|
213
|
+
- spec/resources/currency_exchange_rate_spec.rb
|
210
214
|
- spec/resources/customer_bank_account_spec.rb
|
211
215
|
- spec/resources/customer_notification_spec.rb
|
212
216
|
- spec/resources/customer_spec.rb
|
@@ -226,6 +230,7 @@ files:
|
|
226
230
|
- spec/services/bank_details_lookups_service_spec.rb
|
227
231
|
- spec/services/creditor_bank_accounts_service_spec.rb
|
228
232
|
- spec/services/creditors_service_spec.rb
|
233
|
+
- spec/services/currency_exchange_rates_service_spec.rb
|
229
234
|
- spec/services/customer_bank_accounts_service_spec.rb
|
230
235
|
- spec/services/customer_notifications_service_spec.rb
|
231
236
|
- spec/services/customers_service_spec.rb
|
@@ -275,6 +280,7 @@ test_files:
|
|
275
280
|
- spec/resources/bank_details_lookup_spec.rb
|
276
281
|
- spec/resources/creditor_bank_account_spec.rb
|
277
282
|
- spec/resources/creditor_spec.rb
|
283
|
+
- spec/resources/currency_exchange_rate_spec.rb
|
278
284
|
- spec/resources/customer_bank_account_spec.rb
|
279
285
|
- spec/resources/customer_notification_spec.rb
|
280
286
|
- spec/resources/customer_spec.rb
|
@@ -294,6 +300,7 @@ test_files:
|
|
294
300
|
- spec/services/bank_details_lookups_service_spec.rb
|
295
301
|
- spec/services/creditor_bank_accounts_service_spec.rb
|
296
302
|
- spec/services/creditors_service_spec.rb
|
303
|
+
- spec/services/currency_exchange_rates_service_spec.rb
|
297
304
|
- spec/services/customer_bank_accounts_service_spec.rb
|
298
305
|
- spec/services/customer_notifications_service_spec.rb
|
299
306
|
- spec/services/customers_service_spec.rb
|