currency_cloud 0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +12 -0
  6. data/Gemfile +7 -0
  7. data/Gemfile.lock +99 -0
  8. data/Guardfile +14 -0
  9. data/LICENSE.md +22 -0
  10. data/README.md +10 -0
  11. data/Rakefile +30 -0
  12. data/currency_cloud.gemspec +27 -0
  13. data/examples/server.rb +15 -0
  14. data/lib/currency_cloud.rb +26 -0
  15. data/lib/currency_cloud/actions/create.rb +9 -0
  16. data/lib/currency_cloud/actions/current.rb +9 -0
  17. data/lib/currency_cloud/actions/delete.rb +15 -0
  18. data/lib/currency_cloud/actions/find.rb +27 -0
  19. data/lib/currency_cloud/actions/retrieve.rb +9 -0
  20. data/lib/currency_cloud/actions/update.rb +12 -0
  21. data/lib/currency_cloud/errors/api_error.rb +38 -0
  22. data/lib/currency_cloud/errors/config_error.rb +5 -0
  23. data/lib/currency_cloud/errors/unexpected_error.rb +10 -0
  24. data/lib/currency_cloud/pagination.rb +7 -0
  25. data/lib/currency_cloud/request_handler.rb +68 -0
  26. data/lib/currency_cloud/resource.rb +73 -0
  27. data/lib/currency_cloud/resourceful_collection.rb +15 -0
  28. data/lib/currency_cloud/resources/account.rb +6 -0
  29. data/lib/currency_cloud/resources/balance.rb +8 -0
  30. data/lib/currency_cloud/resources/beneficiary.rb +14 -0
  31. data/lib/currency_cloud/resources/contact.rb +6 -0
  32. data/lib/currency_cloud/resources/conversion.rb +10 -0
  33. data/lib/currency_cloud/resources/payer.rb +6 -0
  34. data/lib/currency_cloud/resources/payment.rb +11 -0
  35. data/lib/currency_cloud/resources/rate.rb +21 -0
  36. data/lib/currency_cloud/resources/reference.rb +29 -0
  37. data/lib/currency_cloud/resources/settlement.rb +30 -0
  38. data/lib/currency_cloud/resources/transaction.rb +7 -0
  39. data/lib/currency_cloud/response_handler.rb +46 -0
  40. data/lib/currency_cloud/session.rb +62 -0
  41. data/lib/currency_cloud/version.rb +8 -0
  42. data/spec/currency_cloud_spec.rb +78 -0
  43. data/spec/integration/actions_spec.rb +101 -0
  44. data/spec/integration/authentication_spec.rb +37 -0
  45. data/spec/integration/errors_spec.rb +157 -0
  46. data/spec/integration/rates_spec.rb +39 -0
  47. data/spec/integration/reference_spec.rb +57 -0
  48. data/spec/spec_helper.rb +11 -0
  49. data/spec/support/vcr_cassettes/Actions/can_create.yml +38 -0
  50. data/spec/support/vcr_cassettes/Actions/can_current.yml +37 -0
  51. data/spec/support/vcr_cassettes/Actions/can_delete.yml +39 -0
  52. data/spec/support/vcr_cassettes/Actions/can_find.yml +38 -0
  53. data/spec/support/vcr_cassettes/Actions/can_first.yml +75 -0
  54. data/spec/support/vcr_cassettes/Actions/can_retrieve.yml +38 -0
  55. data/spec/support/vcr_cassettes/Actions/can_update.yml +39 -0
  56. data/spec/support/vcr_cassettes/Authentication/can_be_closed.yml +67 -0
  57. data/spec/support/vcr_cassettes/Authentication/can_use_just_a_token.yml +36 -0
  58. data/spec/support/vcr_cassettes/Authentication/handles_session_timeout_error.yml +101 -0
  59. data/spec/support/vcr_cassettes/Authentication/happens_lazily.yml +34 -0
  60. data/spec/support/vcr_cassettes/Error/is_raised_on_a_bad_request.yml +39 -0
  61. data/spec/support/vcr_cassettes/Error/is_raised_on_a_forbidden_request.yml +35 -0
  62. data/spec/support/vcr_cassettes/Error/is_raised_on_an_internal_server_error.yml +69 -0
  63. data/spec/support/vcr_cassettes/Error/is_raised_on_incorrect_authentication_details.yml +39 -0
  64. data/spec/support/vcr_cassettes/Error/is_raised_when_a_resource_is_not_found.yml +37 -0
  65. data/spec/support/vcr_cassettes/Error/is_raised_when_too_many_requests_have_been_issued.yml +34 -0
  66. data/spec/support/vcr_cassettes/Rates/can_find.yml +36 -0
  67. data/spec/support/vcr_cassettes/Rates/can_provided_detailed_rate.yml +36 -0
  68. data/spec/support/vcr_cassettes/Reference/can_retrieve_beneficiary_required_details.yml +36 -0
  69. data/spec/support/vcr_cassettes/Reference/can_retrieve_conversion_dates.yml +46 -0
  70. data/spec/support/vcr_cassettes/Reference/can_retrieve_currencies.yml +47 -0
  71. data/spec/support/vcr_cassettes/Reference/can_retrieve_settlement_accounts.yml +39 -0
  72. metadata +230 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c3d01c436b1a1da0688c30dce2f273fef5b15ee9
4
+ data.tar.gz: a4cc4a7719b2c9de95d0628c9b9c2a7f6a332fc5
5
+ SHA512:
6
+ metadata.gz: c312578d3bb0aa6f831ab88567c987943a342d995419deb63d5ed36a32b0f251c867114fa5dc8870d71c4d996657382939f26b9e382040d77bc28ce3a925ed4a
7
+ data.tar.gz: 42cd53dcffc54a796656728a3cdab39083fc4149bcc225d6e2d42d99b9d2e6e655c5c25516f1a1aa9642dcb62b265fb168f4ee3a50697a7156e800a123cec720
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ .DS_Store
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ currencycloud-ruby
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.2.0
data/.travis.yml ADDED
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ script: bundle exec rspec
3
+ cache: bundler
4
+
5
+ rvm:
6
+ - 1.9.3
7
+ - 2.0.0
8
+ - 2.1
9
+ - 2.2
10
+ - jruby-19mode
11
+ - jruby-head
12
+ - rbx-2
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+
4
+ gem 'sinatra'
5
+ gem 'guard-rspec', require: false
6
+
7
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,99 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ currency_cloud (0.5)
5
+ httparty (~> 0.13)
6
+ json (~> 1.8)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ addressable (2.3.8)
12
+ celluloid (0.16.0)
13
+ timers (~> 4.0.0)
14
+ coderay (1.1.0)
15
+ crack (0.4.2)
16
+ safe_yaml (~> 1.0.0)
17
+ diff-lcs (1.2.5)
18
+ ffi (1.9.8)
19
+ formatador (0.2.5)
20
+ guard (2.12.5)
21
+ formatador (>= 0.2.4)
22
+ listen (~> 2.7)
23
+ lumberjack (~> 1.0)
24
+ nenv (~> 0.1)
25
+ notiffany (~> 0.0)
26
+ pry (>= 0.9.12)
27
+ shellany (~> 0.0)
28
+ thor (>= 0.18.1)
29
+ guard-compat (1.2.1)
30
+ guard-rspec (4.5.0)
31
+ guard (~> 2.1)
32
+ guard-compat (~> 1.1)
33
+ rspec (>= 2.99.0, < 4.0)
34
+ hitimes (1.2.2)
35
+ httparty (0.13.3)
36
+ json (~> 1.8)
37
+ multi_xml (>= 0.5.2)
38
+ json (1.8.2)
39
+ listen (2.10.0)
40
+ celluloid (~> 0.16.0)
41
+ rb-fsevent (>= 0.9.3)
42
+ rb-inotify (>= 0.9)
43
+ lumberjack (1.0.9)
44
+ method_source (0.8.2)
45
+ multi_xml (0.5.5)
46
+ nenv (0.2.0)
47
+ notiffany (0.0.6)
48
+ nenv (~> 0.1)
49
+ shellany (~> 0.0)
50
+ pry (0.10.1)
51
+ coderay (~> 1.1.0)
52
+ method_source (~> 0.8.1)
53
+ slop (~> 3.4)
54
+ rack (1.6.0)
55
+ rack-protection (1.5.3)
56
+ rack
57
+ rake (10.4.2)
58
+ rb-fsevent (0.9.4)
59
+ rb-inotify (0.9.5)
60
+ ffi (>= 0.5.0)
61
+ rspec (3.1.0)
62
+ rspec-core (~> 3.1.0)
63
+ rspec-expectations (~> 3.1.0)
64
+ rspec-mocks (~> 3.1.0)
65
+ rspec-core (3.1.7)
66
+ rspec-support (~> 3.1.0)
67
+ rspec-expectations (3.1.2)
68
+ diff-lcs (>= 1.2.0, < 2.0)
69
+ rspec-support (~> 3.1.0)
70
+ rspec-mocks (3.1.3)
71
+ rspec-support (~> 3.1.0)
72
+ rspec-support (3.1.2)
73
+ safe_yaml (1.0.4)
74
+ shellany (0.0.1)
75
+ sinatra (1.4.5)
76
+ rack (~> 1.4)
77
+ rack-protection (~> 1.4)
78
+ tilt (~> 1.3, >= 1.3.4)
79
+ slop (3.6.0)
80
+ thor (0.19.1)
81
+ tilt (1.4.1)
82
+ timers (4.0.1)
83
+ hitimes
84
+ vcr (2.9.3)
85
+ webmock (1.21.0)
86
+ addressable (>= 2.3.6)
87
+ crack (>= 0.3.2)
88
+
89
+ PLATFORMS
90
+ ruby
91
+
92
+ DEPENDENCIES
93
+ currency_cloud!
94
+ guard-rspec
95
+ rake (~> 10.3)
96
+ rspec (~> 3.1)
97
+ sinatra
98
+ vcr (~> 2.9)
99
+ webmock (~> 1.21)
data/Guardfile ADDED
@@ -0,0 +1,14 @@
1
+ guard :rspec, cmd: "bundle exec rspec" do
2
+ require "guard/rspec/dsl"
3
+ dsl = Guard::RSpec::Dsl.new(self)
4
+
5
+ # RSpec files
6
+ rspec = dsl.rspec
7
+ watch(rspec.spec_helper) { rspec.spec_dir }
8
+ watch(rspec.spec_support) { rspec.spec_dir }
9
+ watch(rspec.spec_files)
10
+
11
+ # Ruby files
12
+ ruby = dsl.ruby
13
+ dsl.watch_spec_files_for(ruby.lib_files)
14
+ end
data/LICENSE.md ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Currency Cloud
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,10 @@
1
+ [![Build Status](https://travis-ci.org/CurrencyCloud/currencycloud-ruby.png?branch=master)](https://travis-ci.org/CurrencyCloud/currencycloud-ruby)
2
+
3
+ ### TODO
4
+
5
+ - Additional debug logging
6
+ - Update from object (.save method)
7
+ - Delete from object (.delete method)
8
+ - Relationships: has_many, has_one, belongs_to
9
+ - pagination - .next_page, .previous_page
10
+ - On behalf of
data/Rakefile ADDED
@@ -0,0 +1,30 @@
1
+ desc "Run an IRB session"
2
+ task :console do
3
+ exec "irb -I lib -r irb/completion -r currency_cloud"
4
+ end
5
+
6
+ def play
7
+ sleep 1
8
+ puts "..."
9
+ IRB.conf[:MAIN_CONTEXT].irb
10
+ IRB.conf[:MAIN_CONTEXT].io.prompt = "HELLO"
11
+ end
12
+
13
+ desc "Run an IRB session in kiosk mode"
14
+ task :kiosk do
15
+ Thread.abort_on_exception=true
16
+ #exec "irb -I lib -r irb/completion -r currency_cloud -r currency_cloud/kiosk"
17
+ require 'irb'
18
+ IRB.setup nil
19
+ IRB.conf[:MAIN_CONTEXT] = IRB::Irb.new.context
20
+ require 'irb/ext/multi-irb'
21
+ Thread.new { play }
22
+ @irb = IRB.irb nil, self
23
+ end
24
+
25
+ desc "Test and build gem"
26
+ task :build do
27
+ sh("rm -f currency_cloud*.gem")
28
+ sh("rspec")
29
+ sh("gem build currency_cloud.gemspec")
30
+ end
@@ -0,0 +1,27 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), 'lib'))
2
+
3
+ require 'currency_cloud/version'
4
+
5
+ spec = Gem::Specification.new do |s|
6
+ s.name = 'currency_cloud'
7
+ s.version = CurrencyCloud::Version
8
+ s.summary = 'Ruby SDK for the Currency Cloud API'
9
+ s.description = 'Ruby SDK for the Currency Cloud API - https://connect.currencycloud.com/'
10
+ s.authors = ['Liam McAndrew', 'Richard Nienaber']
11
+ s.email = ['liam.mcandrew@currencycloud.com', 'richard.nienaber@currencycloud.com']
12
+ s.homepage = 'https://connect.currencycloud.com/documentation/getting-started/introduction'
13
+ s.licenses = ['MIT']
14
+
15
+ s.add_dependency('httparty', '~> 0.13')
16
+ s.add_dependency('json', '~> 1.8')
17
+
18
+ s.add_development_dependency('rspec', '~> 3.1')
19
+ s.add_development_dependency('rake', '~> 10.3')
20
+ s.add_development_dependency('webmock', '~> 1.21')
21
+ s.add_development_dependency('vcr', '~> 2.9')
22
+
23
+ s.files = `git ls-files`.split("\n")
24
+ s.test_files = `git ls-files -- spec/*`.split("\n")
25
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
26
+ s.require_paths = ['lib']
27
+ end
@@ -0,0 +1,15 @@
1
+ require_relative 'currency_cloud'
2
+
3
+ require 'sinatra'
4
+
5
+ get '/conversion' do
6
+ conversion = CurrencyCloud::Conversion.create({
7
+ buy_currency: params[:buy_currency],
8
+ sell_currency: params[:sell_currency],
9
+ amount: params[:amount],
10
+ fixed_side: 'buy',
11
+ reason: 'test',
12
+ term_agreement: true
13
+ })
14
+ "Conversion created: #{conversion.short_reference}"
15
+ end
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+ require 'httparty'
3
+ require 'json'
4
+
5
+ require 'currency_cloud/resource'
6
+ lib_path = File.join(File.dirname(__FILE__), '**/*.*')
7
+ Dir[lib_path].sort.each { |f| require f}
8
+
9
+ module CurrencyCloud
10
+ class << self
11
+ attr_accessor :environment, :login_id, :api_key, :token
12
+ end
13
+
14
+ def self.session
15
+ @session ||= CurrencyCloud::Session.new(environment, login_id, api_key, token)
16
+ end
17
+
18
+ def self.close_session
19
+ @session.close if @session
20
+ true
21
+ end
22
+
23
+ def self.reset_session
24
+ @session = nil
25
+ end
26
+ end
@@ -0,0 +1,9 @@
1
+ module CurrencyCloud
2
+ module Actions
3
+ module Create
4
+ def create(params={})
5
+ post("create", params)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module CurrencyCloud
2
+ module Actions
3
+ module Current
4
+ def current
5
+ get('current')
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ module CurrencyCloud
2
+ module Actions
3
+
4
+ module Delete
5
+
6
+ # TODO: Set state to be deleted
7
+ # TODO: Add .delete instance method
8
+ # TODO: Disable all actionable methods / freeze?
9
+
10
+ def delete(id)
11
+ post("#{id}/delete")
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,27 @@
1
+ module CurrencyCloud
2
+ module Actions
3
+
4
+ module Find
5
+
6
+ def find(params={})
7
+ response = request.get("#{self.resource}/find", params)
8
+ mixin_class.new(self.resource, self, response)
9
+ end
10
+
11
+ def first(params={})
12
+ entities = find((params || {}).merge(per_page: 1))
13
+ return nil if entities.empty?
14
+
15
+ entities.first
16
+ end
17
+
18
+ private
19
+ def mixin_class
20
+ unless CurrencyCloud.const_defined?(self.resource.capitalize)
21
+ CurrencyCloud.const_set(self.resource.capitalize, Class.new(CurrencyCloud::ResourcefulCollection))
22
+ end
23
+ CurrencyCloud.const_get(self.resource.capitalize)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,9 @@
1
+ module CurrencyCloud
2
+ module Actions
3
+ module Retrieve
4
+ def retrieve(id)
5
+ get(id)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ module CurrencyCloud
2
+ module Actions
3
+ module Update
4
+
5
+ # TODO: Add .save instance method, which calls update on changed attributes
6
+
7
+ def update(id, params)
8
+ post("#{id}", params)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,38 @@
1
+ module CurrencyCloud
2
+ class ApiErrorMessage
3
+ attr_reader :field, :code, :message, :params
4
+
5
+ def initialize(field, error)
6
+ @field = field
7
+ @code = error['code']
8
+ @message = error['message']
9
+ @params = error['params']
10
+ end
11
+ end
12
+
13
+
14
+ class ApiError < StandardError
15
+ attr_reader :code, :messages, :raw_response, :status_code
16
+
17
+ def initialize(raw_response)
18
+ @raw_response = raw_response
19
+ @status_code = raw_response.code
20
+ errors = raw_response.parsed_response
21
+ @code = errors['error_code']
22
+ @messages = []
23
+
24
+ errors['error_messages'].each do |field, messages|
25
+ messages.each do |message|
26
+ @messages << ApiErrorMessage.new(field, message)
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ class BadRequestError < ApiError; end
33
+ class AuthenticationError < ApiError; end
34
+ class ForbiddenError < ApiError; end
35
+ class TooManyRequestsError < ApiError; end
36
+ class InternalApplicationError < ApiError; end
37
+ class NotFoundError < ApiError; end
38
+ end
@@ -0,0 +1,5 @@
1
+ module CurrencyCloud
2
+
3
+ class ConfigError < StandardError; end
4
+
5
+ end
@@ -0,0 +1,10 @@
1
+ module CurrencyCloud
2
+
3
+ class UnexpectedError < StandardError
4
+ attr_reader :inner_error
5
+
6
+ def initialize(e)
7
+ @inner_error = e
8
+ end
9
+ end
10
+ end