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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb41d5906c1d6d6a9fc78abc852058cf63715020e3c957c7a0a8bcc8e907d74e
4
- data.tar.gz: c85a921b9ea881ed5acc7d56c20b4f75f5c51e1c5e305d4de8c7d0079798adbf
3
+ metadata.gz: 250fed25fc74cb084ad988286e20f8dd2c679fcb62e0de5a1fc3bfca71b67c43
4
+ data.tar.gz: af02087f4d85aafa9337d51219c467bc195c6c9eff6d03b2f9c5dbf209956680
5
5
  SHA512:
6
- metadata.gz: 54114ab5751f18ea4c0b010ca600db89523de93353f309cd0e247dbc13a7339f1cf14d7869f44db7d7b0a7571233a54bd9bc0130c9c4eb796bf186bda5e659eb
7
- data.tar.gz: a2c5a5cdc5321d2e8a00f82adaba6b56540f3aa86d55cf950862f92fbc1cd971e5bad955b4701d69c4babb2fa5ac83a01a53f5da3427117ec7c11d652c47730e
6
+ metadata.gz: a3bd1149c2936dfd1ba6d8b60e7183c279d105046c4c02ab497e2d11da3c3f93c363a56ce5a2c1133138ad9acd421bbfb4c479c1da3970afb4c6b650a0197965
7
+ data.tar.gz: '07951005f59ae4328b34342bb24c9b06bfb9f0221a87630751d21b9755354fb3daaf7f0b34bb51d98811f2e1199479be08745afdb66c888953bfad50fc8bc099'
Binary file
@@ -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.17.1',
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 can either be an array of payment properties
17
- # (`amount`
18
- # and `charge_date`) or a schedule object with `interval`, `interval_unit` and
19
- # `amounts`.
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 create(options = {})
85
+ def create_with_schedule(options = {})
31
86
  path = '/instalment_schedules'
32
87
 
33
88
  params = options.delete(:params) || {}
@@ -4,5 +4,5 @@ end
4
4
 
5
5
  module GoCardlessPro
6
6
  # Current version of the GC gem
7
- VERSION = '2.17.1'.freeze
7
+ VERSION = '2.18.0'.freeze
8
8
  end
@@ -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.create(params: new_resource) }
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.create(params: new_resource) }
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.17.1
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-02-24 00:00:00.000000000 Z
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