xe_client 0.1.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: fdaeee0666ddaa0e81f9425aad6e689dd5853570
4
- data.tar.gz: 7b10ff686963faebee6dbd019c0726e9599c94c4
2
+ SHA256:
3
+ metadata.gz: d57a5857429d30d7aa2ab687b7a5d4fc467e18ee1ab10ebf415c914d27f149a9
4
+ data.tar.gz: d0cb8810a53660ac5a45d55d14be341aa8a0876ce6dff1381521a8b9f21af367
5
5
  SHA512:
6
- metadata.gz: a7328447e7f2bd6871fbf40f0613a5eb4591b169cc1008ac9fbecdbdbef9d78c84de04d21b3737a07f4686e1359cfc0e770f26aae6ba66293d1247c61c1d2dbe
7
- data.tar.gz: 50d146942dd556d3606ba348404c70f08b46990e4cecac8596023ff5f7f5ab0820227857f6cbc717e4b71d3c7cb7ddb8df4d7c04af5bb142a208d2a3efd1c31b
6
+ metadata.gz: 55a0a14eee2432daca0c88c9e404453f22c738b6ff6a08d5e44218c349b6536d9fbdf04dbf9ac42a00c65b2a5ba91dd2eaf41bc6a782a9931b08d9f5607da75d
7
+ data.tar.gz: 9868ff4f6350dfed96c509be481595ef17867a9eaa8db0d63399d46a7da3a23610acbc3b069f60afbb2d08470deeb6e895f07666ca032be6ba27be306a95fd5d
@@ -0,0 +1,37 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: Ruby
9
+
10
+ on:
11
+ push:
12
+ branches: [ master ]
13
+ pull_request:
14
+ branches: [ master ]
15
+
16
+ jobs:
17
+ test:
18
+
19
+ runs-on: ubuntu-latest
20
+ strategy:
21
+ matrix:
22
+ ruby-version: ['2.6', '2.7']
23
+
24
+ steps:
25
+ - uses: actions/checkout@v2
26
+ - name: Set up Ruby
27
+ # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
28
+ # change this to (see https://github.com/ruby/setup-ruby#versioning):
29
+ # uses: ruby/setup-ruby@v1
30
+ uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
31
+ with:
32
+ ruby-version: ${{ matrix.ruby-version }}
33
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
34
+ - name: Setup spec config
35
+ run: cp spec/config.yml{.sample,}
36
+ - name: Run tests
37
+ run: bundle exec rspec
data/CHANGELOG.md CHANGED
@@ -2,6 +2,34 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
  This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
+ ## [1.1.0] - 2021-06-15
6
+ ### Added
7
+ - Update `dry-validation` to 1.x
8
+
9
+ ## [1.0.1] - 2020-06-30
10
+ ### Fixed
11
+ - `#historic_rate_period`: Do not blow up if no rates
12
+
13
+ ## [1.0.0] - 2020-06-30
14
+ ### Changed
15
+ - Changed `url` to `host` fot the XE API host (defaults to https://xecdapi.xe.com)
16
+ - Changed `#convert_from` to accept keyword args named more like the API's param names:
17
+ - `from` instead of the first argument aka `base_currency`
18
+ - `to` instead of the second argument aka `counter_currencies`
19
+ - `amount` instead of the third argument
20
+ - No longer raise exception when XE's response contains an error. Developer should use `#success?` on the response instead and inspect `#error` to see details.
21
+ ### Added
22
+ - `historic_rate_period` call to get historic rates over a period
23
+
24
+ ## [0.2.1] - 2016-08-11
25
+ ### Fixed
26
+ - Fix issue when accessing ConvertFromResponse#to and error was raised
27
+
28
+ ## [0.2.0] - 2016-06-30
29
+ ### Added
30
+ - Raise XEClient::AuthenticationError when there's an auth issue
31
+ - Raise XEClient::Error for all other errors
32
+
5
33
  ## [0.1.0] - 2016-06-22
6
34
  ### Added
7
35
  - Add initial working version (`#convert_from`)
data/README.md CHANGED
@@ -30,7 +30,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
30
30
 
31
31
  ## Contributing
32
32
 
33
- Bug reports and pull requests are welcome on [GitHub](https://github.com/imacchiato/xe_client-ruby). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
33
+ Bug reports and pull requests are welcome on [GitHub](https://github.com/bloom-solutions/xe_client-ruby). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
34
34
 
35
35
 
36
36
  ## License
data/lib/xe_client.rb CHANGED
@@ -1,22 +1,35 @@
1
1
  require "xe_client/version"
2
+ require "api_client_base"
2
3
  require "active_model"
4
+ require "dry-validation"
3
5
  require "virtus"
4
6
  require "httparty"
5
7
  require "active_support/core_ext/hash/indifferent_access"
8
+ require "active_support/core_ext/date_time"
9
+ require "active_support/core_ext/string/conversions"
6
10
  require "xe_client/indifferent_hash"
7
11
  require "xe_client/models/quote"
8
12
  require "xe_client/client"
9
13
  require "xe_client/requests/base_request"
10
14
  require "xe_client/requests/convert_from_request"
15
+ require "xe_client/requests/historic_rate_period_request"
11
16
  require "xe_client/responses/base_response"
12
17
  require "xe_client/responses/convert_from_response"
18
+ require "xe_client/responses/historic_rate_period_response"
19
+ require "xe_client/schemas/convert_from_request_schema"
20
+ require "xe_client/errors/error"
21
+ require "xe_client/errors/authentication_error"
13
22
 
14
23
  module XEClient
15
24
 
16
- def self.new(opts)
17
- client = Client.new(opts)
18
- raise ArgumentError, client.errors.full_messages if client.invalid?
19
- client
25
+ include APIClientBase::Base.module
26
+
27
+ DEFAULT_HOST = "https://xecdapi.xe.com"
28
+
29
+ with_configuration do
30
+ has :host, classes: String, default: DEFAULT_HOST
31
+ has :account_id, classes: String
32
+ has :api_key, classes: String
20
33
  end
21
34
 
22
35
  end
@@ -1,30 +1,18 @@
1
1
  module XEClient
2
2
  class Client
3
3
 
4
- DEFAULT_URL = "https://xecdapi.xe.com"
5
-
6
- include Virtus.model
4
+ include APIClientBase::Client.module(default_opts: :default_opts)
5
+ attribute :host, String
7
6
  attribute :account_id, String
8
7
  attribute :api_key, String
9
- attribute :url, String, default: DEFAULT_URL
10
-
11
- include ActiveModel::Validations
12
- validates :account_id, :api_key, presence: true
13
8
 
14
- def convert_from(base_currency, counter_currencies, amount)
15
- args = default_args.merge(
16
- base_currency: base_currency,
17
- counter_currencies: counter_currencies,
18
- amount: amount,
19
- )
20
- raw_response = ConvertFromRequest.(args)
21
- ConvertFromResponse.new(raw_response: raw_response)
22
- end
9
+ api_action :convert_from
10
+ api_action :historic_rate_period
23
11
 
24
12
  private
25
13
 
26
- def default_args
27
- attributes.slice(:account_id, :api_key, :url)
14
+ def default_opts
15
+ { host: host, account_id: account_id, api_key: api_key }
28
16
  end
29
17
 
30
18
  end
@@ -0,0 +1,4 @@
1
+ module XEClient
2
+ class AuthenticationError < Error
3
+ end
4
+ end
@@ -0,0 +1,22 @@
1
+ module XEClient
2
+ class Error < StandardError
3
+
4
+ CODE_ERROR_MAP = {
5
+ 1 => "AuthenticationError",
6
+ }
7
+ attr_accessor :code
8
+
9
+ def self.new_from_response(response)
10
+ return nil if response.code.nil?
11
+ klass = if class_name = CODE_ERROR_MAP[response.code]
12
+ XEClient.const_get(class_name)
13
+ else
14
+ self
15
+ end
16
+ error = klass.new(response.message)
17
+ error.code = response.code
18
+ error
19
+ end
20
+
21
+ end
22
+ end
@@ -4,6 +4,7 @@ module XEClient
4
4
  include Virtus.model
5
5
  attribute :quotecurrency, String
6
6
  attribute :mid, Float
7
+ attribute :timestamp, DateTime
7
8
 
8
9
  end
9
10
  end
@@ -1,16 +1,13 @@
1
1
  module XEClient
2
2
  class BaseRequest
3
3
 
4
- include Virtus.model
4
+ include APIClientBase::Request.module
5
+ attribute :host, String
5
6
  attribute :account_id, String
6
7
  attribute :api_key, String
7
- attribute :url, String
8
8
 
9
- include ActiveModel::Validations
10
- validates :account_id, :api_key, :url, presence: true
11
-
12
- def self.call(opts)
13
- self.new(opts).call
9
+ def typhoeus_options
10
+ { userpwd: [account_id, api_key].join(":") }
14
11
  end
15
12
 
16
13
  end
@@ -1,37 +1,20 @@
1
1
  module XEClient
2
2
  class ConvertFromRequest < BaseRequest
3
3
 
4
- DEFAULT_PATH = "/v1/convert_from.json"
5
- attribute :base_currency, String
6
- attribute :counter_currencies, Array[String]
4
+ attribute :from, String
5
+ attribute :to, Array[String]
7
6
  attribute :amount, Float
8
- attribute :endpoint, String, lazy: true, default: :default_endpoint
9
7
 
10
- validates(
11
- :base_currency,
12
- :counter_currencies,
13
- :amount,
14
- presence: true,
15
- )
16
-
17
- def call
18
- HTTParty.get(
19
- endpoint,
20
- query: {
21
- from: base_currency,
22
- to: counter_currencies.join(","),
23
- amount: amount,
24
- },
25
- basic_auth: { username: account_id, password: api_key },
26
- )
8
+ def path
9
+ "/v1/convert_from.json"
27
10
  end
28
11
 
29
- private
30
-
31
- def default_endpoint
32
- uri = URI.parse(url)
33
- uri.path = DEFAULT_PATH
34
- uri.to_s
12
+ def params
13
+ {
14
+ from: from,
15
+ to: to.join(","),
16
+ amount: amount,
17
+ }
35
18
  end
36
19
 
37
20
  end
@@ -0,0 +1,29 @@
1
+ module XEClient
2
+ class HistoricRatePeriodRequest < BaseRequest
3
+
4
+ attribute :from, String
5
+ attribute :to, Array[String]
6
+ attribute :start_timestamp, DateTime
7
+ attribute :end_timestamp, DateTime
8
+ attribute :interval, String
9
+ attribute :per_page, Integer
10
+ attribute :page, Integer
11
+
12
+ def path
13
+ "/v1/historic_rate/period.json"
14
+ end
15
+
16
+ def params
17
+ {
18
+ from: from,
19
+ to: to.join(","),
20
+ start_timestamp: start_timestamp,
21
+ end_timestamp: end_timestamp,
22
+ interval: interval,
23
+ per_page: per_page,
24
+ page: page,
25
+ }
26
+ end
27
+
28
+ end
29
+ end
@@ -1,7 +1,37 @@
1
1
  module XEClient
2
2
  class BaseResponse
3
3
 
4
- include Virtus.model
4
+ include APIClientBase::Response.module
5
+ attribute :raw_response
6
+ attribute(:response_body, IndifferentHash, {
7
+ lazy: true,
8
+ default: :default_response_body,
9
+ })
10
+ attribute :code, Integer, lazy: true, default: :default_code
11
+ attribute :message, String, lazy: true, default: :default_message
12
+ attribute :error, Object, lazy: true, default: :default_error
13
+
14
+ private
15
+
16
+ def default_code
17
+ response_body[:code]
18
+ end
19
+
20
+ def default_message
21
+ response_body[:message]
22
+ end
23
+
24
+ def default_error
25
+ Error.new_from_response(self)
26
+ end
27
+
28
+ def default_response_body
29
+ JSON.parse(raw_response.body)
30
+ end
31
+
32
+ def default_success
33
+ error.blank?
34
+ end
5
35
 
6
36
  end
7
37
  end
@@ -3,16 +3,15 @@ module XEClient
3
3
 
4
4
  attribute :from, String, lazy: true, default: :default_from
5
5
  attribute :to, Array, lazy: true, default: :default_to
6
- attribute :raw_response, IndifferentHash
7
6
 
8
7
  private
9
8
 
10
9
  def default_from
11
- raw_response[:from]
10
+ response_body[:from]
12
11
  end
13
12
 
14
13
  def default_to
15
- raw_response[:to].map do |quote_hash|
14
+ response_body[:to].map do |quote_hash|
16
15
  Quote.new(quote_hash)
17
16
  end
18
17
  end
@@ -0,0 +1,26 @@
1
+ module XEClient
2
+ class HistoricRatePeriodResponse < BaseResponse
3
+
4
+ attribute :from, String, lazy: true, default: :default_from
5
+ attribute :to, Array, lazy: true, default: :default_to
6
+
7
+ private
8
+
9
+ def default_from
10
+ response_body[:from]
11
+ end
12
+
13
+ def default_to
14
+ to = response_body[:to]
15
+
16
+ return [] if to.blank?
17
+
18
+ to.each_with_object([]) do |(currency, quote_args), arr|
19
+ quote_args.each do |quote_arg|
20
+ arr << Quote.new(quote_arg.merge(quotecurrency: currency))
21
+ end
22
+ end
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,11 @@
1
+ module MyGem
2
+ class ConvertFromRequestSchema < Dry::Validation::Contract
3
+
4
+ params do
5
+ required(:account_id).filled(:str?)
6
+ required(:api_key).filled(:str?)
7
+ required(:host).filled(:str?)
8
+ end
9
+
10
+ end
11
+ end
@@ -1,3 +1,3 @@
1
1
  module XEClient
2
- VERSION = "0.1.0"
2
+ VERSION = "1.1.0"
3
3
  end
data/xe_client.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["ramon.tayag@gmail.com"]
11
11
 
12
12
  spec.summary = %q{Ruby wrapper for XE's REST API}
13
- spec.homepage = "https://github.com/imacchiato/xe_client-ruby"
13
+ spec.homepage = "https://github.com/bloom-solutions/xe_client-ruby"
14
14
  spec.license = "MIT"
15
15
 
16
16
  # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
@@ -30,8 +30,11 @@ Gem::Specification.new do |spec|
30
30
  spec.add_dependency "activemodel", ">= 3.0"
31
31
  spec.add_dependency "virtus", "~> 1.0"
32
32
  spec.add_dependency "httparty"
33
+ spec.add_dependency "api_client_base", "~> 1.9"
34
+ spec.add_dependency "dry-validation", "~> 1.0", "< 2"
35
+ spec.add_dependency "typhoeus", "~> 1.0"
33
36
 
34
- spec.add_development_dependency "bundler", "~> 1.12"
37
+ spec.add_development_dependency "bundler", "~> 2.0"
35
38
  spec.add_development_dependency "rake", "~> 10.0"
36
39
  spec.add_development_dependency "rspec", "~> 3.0"
37
40
  spec.add_development_dependency "shoulda-matchers", "~> 3.0"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xe_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ramon Tayag
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-06-22 00:00:00.000000000 Z
11
+ date: 2021-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -66,20 +66,68 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: api_client_base
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.9'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.9'
83
+ - !ruby/object:Gem::Dependency
84
+ name: dry-validation
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.0'
90
+ - - "<"
91
+ - !ruby/object:Gem::Version
92
+ version: '2'
93
+ type: :runtime
94
+ prerelease: false
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: '1.0'
100
+ - - "<"
101
+ - !ruby/object:Gem::Version
102
+ version: '2'
103
+ - !ruby/object:Gem::Dependency
104
+ name: typhoeus
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '1.0'
110
+ type: :runtime
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '1.0'
69
117
  - !ruby/object:Gem::Dependency
70
118
  name: bundler
71
119
  requirement: !ruby/object:Gem::Requirement
72
120
  requirements:
73
121
  - - "~>"
74
122
  - !ruby/object:Gem::Version
75
- version: '1.12'
123
+ version: '2.0'
76
124
  type: :development
77
125
  prerelease: false
78
126
  version_requirements: !ruby/object:Gem::Requirement
79
127
  requirements:
80
128
  - - "~>"
81
129
  - !ruby/object:Gem::Version
82
- version: '1.12'
130
+ version: '2.0'
83
131
  - !ruby/object:Gem::Dependency
84
132
  name: rake
85
133
  requirement: !ruby/object:Gem::Requirement
@@ -150,7 +198,7 @@ dependencies:
150
198
  - - "~>"
151
199
  - !ruby/object:Gem::Version
152
200
  version: '2.0'
153
- description:
201
+ description:
154
202
  email:
155
203
  - ramon.tayag@gmail.com
156
204
  executables: []
@@ -158,9 +206,9 @@ extensions: []
158
206
  extra_rdoc_files: []
159
207
  files:
160
208
  - ".envrc"
209
+ - ".github/workflows/ruby.yml"
161
210
  - ".gitignore"
162
211
  - ".rspec"
163
- - ".travis.yml"
164
212
  - CHANGELOG.md
165
213
  - CODE_OF_CONDUCT.md
166
214
  - Gemfile
@@ -171,20 +219,25 @@ files:
171
219
  - bin/setup
172
220
  - lib/xe_client.rb
173
221
  - lib/xe_client/client.rb
222
+ - lib/xe_client/errors/authentication_error.rb
223
+ - lib/xe_client/errors/error.rb
174
224
  - lib/xe_client/indifferent_hash.rb
175
225
  - lib/xe_client/models/quote.rb
176
226
  - lib/xe_client/requests/base_request.rb
177
227
  - lib/xe_client/requests/convert_from_request.rb
228
+ - lib/xe_client/requests/historic_rate_period_request.rb
178
229
  - lib/xe_client/responses/base_response.rb
179
230
  - lib/xe_client/responses/convert_from_response.rb
231
+ - lib/xe_client/responses/historic_rate_period_response.rb
232
+ - lib/xe_client/schemas/convert_from_request_schema.rb
180
233
  - lib/xe_client/version.rb
181
234
  - xe_client.gemspec
182
- homepage: https://github.com/imacchiato/xe_client-ruby
235
+ homepage: https://github.com/bloom-solutions/xe_client-ruby
183
236
  licenses:
184
237
  - MIT
185
238
  metadata:
186
239
  allowed_push_host: https://rubygems.org
187
- post_install_message:
240
+ post_install_message:
188
241
  rdoc_options: []
189
242
  require_paths:
190
243
  - lib
@@ -199,9 +252,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
199
252
  - !ruby/object:Gem::Version
200
253
  version: '0'
201
254
  requirements: []
202
- rubyforge_project:
203
- rubygems_version: 2.5.1
204
- signing_key:
255
+ rubygems_version: 3.1.6
256
+ signing_key:
205
257
  specification_version: 4
206
258
  summary: Ruby wrapper for XE's REST API
207
259
  test_files: []
data/.travis.yml DELETED
@@ -1,5 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.3.0
5
- before_install: gem install bundler -v 1.12.5