finapps 2.0.6 → 2.0.10
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/.codeclimate.yml +3 -6
- data/Gemfile +1 -0
- data/Rakefile +1 -0
- data/finapps.gemspec +1 -1
- data/lib/core_extensions/hash/compact.rb +23 -0
- data/lib/core_extensions/object/blank.rb +69 -0
- data/lib/core_extensions/object/is_integer.rb +12 -0
- data/lib/finapps.rb +10 -6
- data/lib/finapps/error.rb +5 -0
- data/lib/finapps/middleware/middleware.rb +17 -0
- data/lib/finapps/middleware/request/accept_json.rb +14 -0
- data/lib/finapps/middleware/{tenant_authentication.rb → request/tenant_authentication.rb} +4 -3
- data/lib/finapps/middleware/request/user_agent.rb +15 -0
- data/lib/finapps/middleware/{raise_error.rb → response/raise_error.rb} +5 -2
- data/lib/finapps/rest/base_client.rb +29 -13
- data/lib/finapps/rest/client.rb +6 -4
- data/lib/finapps/rest/configuration.rb +11 -39
- data/lib/finapps/rest/connection.rb +17 -11
- data/lib/finapps/rest/credentials.rb +21 -0
- data/lib/finapps/rest/defaults.rb +9 -9
- data/lib/finapps/rest/orders.rb +4 -0
- data/lib/finapps/rest/resources.rb +2 -1
- data/lib/finapps/rest/users.rb +4 -0
- data/lib/finapps/utils/loggeable.rb +1 -0
- data/lib/finapps/version.rb +2 -1
- data/lib/tasks/releaser.rake +1 -0
- data/spec/middleware/accept_json_spec.rb +12 -0
- data/spec/middleware/tenant_authentication_spec.rb +6 -1
- data/spec/middleware/user_agent_spec.rb +12 -0
- data/spec/rest/base_client_spec.rb +9 -5
- data/spec/rest/client_spec.rb +1 -0
- data/spec/rest/configuration_spec.rb +16 -63
- data/spec/rest/credentials_spec.rb +20 -0
- data/spec/rest/orders_spec.rb +1 -0
- data/spec/rest/resources_spec.rb +1 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/support/fake_api.rb +2 -0
- metadata +23 -32
- data/lib/finapps/core_extensions/integerable.rb +0 -14
- data/lib/finapps/hash_constructable.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bcf4ea9c9605ea437a7c813888251d0ade6c48ff
|
4
|
+
data.tar.gz: 4566ea877d76bfd844191fa425dc520bb72a63d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1370d0de8ce5510d1defe65b08caf38c7a10d0ed507d38040ff3e6a5e6e75b2b4f7582ff02728c660c1082a271f0a9d3e09fa59e3dc9458779ff741cbf669cbb
|
7
|
+
data.tar.gz: 240d6213a3f48f1eb9395c9050754f74dc4eeabb4a8e2697fa92901ebf61c50a6d8a100c1f2d32d3abf8ba7913c9358f4c380f404f4d09e496c38bc6975b7c23
|
data/.codeclimate.yml
CHANGED
@@ -1,15 +1,12 @@
|
|
1
1
|
engines:
|
2
2
|
rubocop:
|
3
3
|
enabled: true
|
4
|
-
#checks:
|
5
|
-
# Rubocop/Metrics/ClassLength:
|
6
|
-
# enabled: false
|
7
4
|
brakeman:
|
8
|
-
enabled:
|
5
|
+
enabled: false
|
9
6
|
eslint:
|
10
|
-
enabled:
|
7
|
+
enabled: false
|
11
8
|
csslint:
|
12
|
-
enabled:
|
9
|
+
enabled: false
|
13
10
|
duplication:
|
14
11
|
enabled: true
|
15
12
|
config:
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
data/finapps.gemspec
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
lib = File.expand_path('../lib', __FILE__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'finapps/version'
|
@@ -20,7 +21,6 @@ Gem::Specification.new do |spec|
|
|
20
21
|
spec.test_files = Dir['spec/**/*.rb']
|
21
22
|
spec.require_paths = ['lib']
|
22
23
|
|
23
|
-
spec.add_runtime_dependency 'activesupport', '~> 4.2', '>= 4.2.6'
|
24
24
|
spec.add_runtime_dependency 'faraday', '~> 0.9', '>= 0.9.2'
|
25
25
|
spec.add_runtime_dependency 'faraday_middleware', '~> 0.10', '>= 0.10.0'
|
26
26
|
spec.add_runtime_dependency 'typhoeus', '~> 1.0', '>= 1.0.2'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module HashExtensions
|
3
|
+
refine Hash do
|
4
|
+
# Returns a hash with non +nil+ values.
|
5
|
+
#
|
6
|
+
# hash = { a: true, b: false, c: nil}
|
7
|
+
# hash.compact # => { a: true, b: false}
|
8
|
+
# hash # => { a: true, b: false, c: nil}
|
9
|
+
# { c: nil }.compact # => {}
|
10
|
+
def compact
|
11
|
+
select {|_, value| !value.nil? }
|
12
|
+
end
|
13
|
+
|
14
|
+
# Replaces current hash with non +nil+ values.
|
15
|
+
#
|
16
|
+
# hash = { a: true, b: false, c: nil}
|
17
|
+
# hash.compact! # => { a: true, b: false}
|
18
|
+
# hash # => { a: true, b: false}
|
19
|
+
def compact!
|
20
|
+
reject! {|_, value| value.nil? }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module ObjectExtensions
|
3
|
+
refine Object do
|
4
|
+
# An object is blank if it's false, empty, or a whitespace string.
|
5
|
+
# For example, +false+, '', ' ', +nil+, [], and {} are all blank.
|
6
|
+
#
|
7
|
+
# This simplifies
|
8
|
+
#
|
9
|
+
# !address || address.empty?
|
10
|
+
#
|
11
|
+
# to
|
12
|
+
#
|
13
|
+
# address.blank?
|
14
|
+
#
|
15
|
+
# @return [true, false]
|
16
|
+
def blank?
|
17
|
+
respond_to?(:empty?) ? !!empty? : !self
|
18
|
+
end
|
19
|
+
|
20
|
+
# An object is present if it's not blank.
|
21
|
+
#
|
22
|
+
# @return [true, false]
|
23
|
+
def present?
|
24
|
+
!blank?
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns the receiver if it's present otherwise returns +nil+.
|
28
|
+
# <tt>object.presence</tt> is equivalent to
|
29
|
+
#
|
30
|
+
# object.present? ? object : nil
|
31
|
+
#
|
32
|
+
# For example, something like
|
33
|
+
#
|
34
|
+
# state = params[:state] if params[:state].present?
|
35
|
+
# country = params[:country] if params[:country].present?
|
36
|
+
# region = state || country || 'US'
|
37
|
+
#
|
38
|
+
# becomes
|
39
|
+
#
|
40
|
+
# region = params[:state].presence || params[:country].presence || 'US'
|
41
|
+
#
|
42
|
+
# @return [Object]
|
43
|
+
def presence
|
44
|
+
self if present?
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
module StringExtensions
|
50
|
+
refine String do
|
51
|
+
BLANK_RE = /\A[[:space:]]*\z/
|
52
|
+
|
53
|
+
# A string is blank if it's empty or contains whitespaces only:
|
54
|
+
#
|
55
|
+
# ''.blank? # => true
|
56
|
+
# ' '.blank? # => true
|
57
|
+
# "\t\n\r".blank? # => true
|
58
|
+
# ' blah '.blank? # => false
|
59
|
+
#
|
60
|
+
# Unicode whitespace is supported:
|
61
|
+
#
|
62
|
+
# "\u00a0".blank? # => true
|
63
|
+
#
|
64
|
+
# @return [true, false]
|
65
|
+
def blank?
|
66
|
+
match BLANK_RE
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/finapps.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'finapps/version' unless defined?(FinApps::VERSION)
|
2
3
|
|
3
4
|
require 'faraday'
|
@@ -5,15 +6,17 @@ require 'faraday_middleware'
|
|
5
6
|
require 'typhoeus'
|
6
7
|
require 'typhoeus/adapters/faraday'
|
7
8
|
|
8
|
-
require '
|
9
|
-
require '
|
10
|
-
require '
|
11
|
-
require 'finapps/hash_constructable'
|
9
|
+
require 'core_extensions/hash/compact'
|
10
|
+
require 'core_extensions/object/blank'
|
11
|
+
require 'core_extensions/object/is_integer'
|
12
12
|
require 'finapps/utils/loggeable'
|
13
13
|
require 'finapps/error'
|
14
14
|
|
15
|
-
require 'finapps/middleware/tenant_authentication'
|
16
|
-
require 'finapps/middleware/
|
15
|
+
require 'finapps/middleware/request/tenant_authentication'
|
16
|
+
require 'finapps/middleware/request/accept_json'
|
17
|
+
require 'finapps/middleware/request/user_agent'
|
18
|
+
require 'finapps/middleware/response/raise_error'
|
19
|
+
require 'finapps/middleware/middleware'
|
17
20
|
|
18
21
|
require 'finapps/rest/defaults'
|
19
22
|
require 'finapps/rest/resources'
|
@@ -22,6 +25,7 @@ require 'finapps/rest/users'
|
|
22
25
|
require 'finapps/rest/orders'
|
23
26
|
|
24
27
|
require 'finapps/rest/configuration'
|
28
|
+
require 'finapps/rest/credentials'
|
25
29
|
require 'finapps/rest/connection'
|
26
30
|
require 'finapps/rest/base_client'
|
27
31
|
require 'finapps/rest/client'
|
data/lib/finapps/error.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Defines some errors to identify Exceptions within this gem
|
1
3
|
module FinApps # :nodoc:
|
4
|
+
# Base error class.
|
2
5
|
class Error < StandardError; end
|
6
|
+
# Raised for existing but invalid arguments.
|
3
7
|
class InvalidArgumentsError < Error; end
|
8
|
+
# Raised whenever a required argument is missing.
|
4
9
|
class MissingArgumentsError < Error; end
|
5
10
|
|
6
11
|
%i(InvalidArgumentsError MissingArgumentsError).each {|const| Error.const_set(const, FinApps.const_get(const)) }
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'faraday' unless defined? Faraday
|
3
|
+
|
4
|
+
module FinApps
|
5
|
+
module Middleware
|
6
|
+
autoload :AcceptJson, 'finapps/middleware/request/accept_json'
|
7
|
+
autoload :UserAgent, 'finapps/middleware/request/user_agent'
|
8
|
+
autoload :TenantAuthentication, 'finapps/middleware/request/tenant_authentication'
|
9
|
+
|
10
|
+
if Faraday::Middleware.respond_to? :register_middleware
|
11
|
+
Faraday::Request.register_middleware \
|
12
|
+
accept_json: -> { AcceptJson },
|
13
|
+
user_agent: -> { UserAgent },
|
14
|
+
tenant_authentication: -> { TenantAuthentication }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module FinApps
|
3
|
+
module Middleware
|
4
|
+
# This middleware sets the Accept request-header field to specify JSON as acceptable media type for the response.
|
5
|
+
class AcceptJson < Faraday::Middleware
|
6
|
+
KEY = 'Accept' unless defined? KEY
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
env[:request_headers][KEY] = 'application/json'
|
10
|
+
@app.call(env)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -1,13 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module FinApps
|
2
3
|
module Middleware
|
3
4
|
# Adds a custom header for tenant level authorization.
|
4
5
|
# If the value for this header already exists, it is not overriden.
|
5
6
|
class TenantAuthentication < Faraday::Middleware
|
6
|
-
KEY = 'X-FinApps-Token'
|
7
|
+
KEY = 'X-FinApps-Token' unless defined? KEY
|
7
8
|
|
8
|
-
def initialize(app,
|
9
|
+
def initialize(app, identifier, token)
|
9
10
|
super(app)
|
10
|
-
@header_value = "#{
|
11
|
+
@header_value = "#{identifier.to_s.strip}=#{token.to_s.strip}"
|
11
12
|
end
|
12
13
|
|
13
14
|
def call(env)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module FinApps
|
3
|
+
module Middleware
|
4
|
+
# This middleware sets the User-Agent request-header field to identify thei client.
|
5
|
+
class UserAgent < Faraday::Middleware
|
6
|
+
KEY = 'User-Agent' unless defined? KEY
|
7
|
+
RUBY = "#{RUBY_ENGINE}/#{RUBY_PLATFORM} #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}"
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
env[:request_headers][KEY] = "finapps-ruby/#{FinApps::VERSION} (#{RUBY})"
|
11
|
+
@app.call(env)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,6 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module FinApps
|
2
3
|
module Middleware
|
3
4
|
class RaiseError < Faraday::Response::Middleware # :nodoc:
|
5
|
+
using ObjectExtensions
|
6
|
+
using StringExtensions
|
4
7
|
include FinApps::Utils::Loggeable
|
5
8
|
|
6
9
|
CLIENT_ERROR_STATUSES = 400...600
|
@@ -31,9 +34,9 @@ module FinApps
|
|
31
34
|
private
|
32
35
|
|
33
36
|
def error_messages(body)
|
34
|
-
return nil
|
37
|
+
return nil if body.blank?
|
35
38
|
body = parse_string(body) if body.is_a?(String)
|
36
|
-
body.is_a?(Hash) ? body['messages']
|
39
|
+
body.is_a?(Hash) && body.key?('messages') ? body['messages'] : nil
|
37
40
|
end
|
38
41
|
|
39
42
|
def parse_string(body)
|
@@ -1,11 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module FinApps
|
2
3
|
module REST
|
3
|
-
|
4
|
+
# base client functionality
|
5
|
+
class BaseClient
|
4
6
|
include ::FinApps::Utils::Loggeable
|
7
|
+
include ::FinApps::REST::Connection
|
8
|
+
using ObjectExtensions
|
9
|
+
using StringExtensions
|
5
10
|
|
6
11
|
attr_reader :config
|
7
12
|
|
8
|
-
def initialize(options
|
13
|
+
def initialize(options, logger=nil)
|
9
14
|
@config = FinApps::REST::Configuration.new options
|
10
15
|
@logger = logger
|
11
16
|
end
|
@@ -14,7 +19,7 @@ module FinApps
|
|
14
19
|
#
|
15
20
|
# @return Faraday::Connection.
|
16
21
|
def connection
|
17
|
-
@connection ||=
|
22
|
+
@connection ||= faraday(config, logger)
|
18
23
|
end
|
19
24
|
|
20
25
|
# Performs HTTP GET, POST, UPDATE and DELETE requests.
|
@@ -30,11 +35,11 @@ module FinApps
|
|
30
35
|
raise FinApps::MissingArgumentsError.new 'Missing argument: method.' if method.blank?
|
31
36
|
|
32
37
|
response, error_messages = execute_request(method, params, path)
|
33
|
-
result = if response.
|
34
|
-
block_given? ? yield(response) : response.body
|
35
|
-
else
|
38
|
+
result = if response.blank?
|
36
39
|
logger.error "##{__method__} => Null response found. Unable to process it."
|
37
40
|
nil
|
41
|
+
else
|
42
|
+
block_given? ? yield(response) : response.body
|
38
43
|
end
|
39
44
|
|
40
45
|
[result, error_messages]
|
@@ -44,25 +49,36 @@ module FinApps
|
|
44
49
|
|
45
50
|
def execute_request(method, params, path)
|
46
51
|
error_messages = []
|
47
|
-
|
48
52
|
begin
|
49
53
|
response = execute_method method, params, path
|
50
54
|
rescue FinApps::InvalidArgumentsError,
|
51
55
|
FinApps::MissingArgumentsError,
|
52
56
|
Faraday::Error::ConnectionFailed => error
|
53
|
-
|
54
|
-
raise error
|
57
|
+
handle_error error
|
55
58
|
rescue Faraday::Error::ClientError => error
|
56
|
-
error_messages =
|
57
|
-
logger.error "##{__method__} => Faraday::Error::ClientError, #{error}"
|
59
|
+
error_messages = handle_client_error error
|
58
60
|
rescue StandardError => error
|
59
|
-
error_messages
|
60
|
-
logger.fatal "##{__method__} => StandardError, #{error}"
|
61
|
+
error_messages = handle_standard_error error
|
61
62
|
end
|
62
63
|
|
63
64
|
[response, error_messages]
|
64
65
|
end
|
65
66
|
|
67
|
+
def handle_error(error)
|
68
|
+
logger.fatal "#{self.class}##{__method__} => #{error}"
|
69
|
+
raise error
|
70
|
+
end
|
71
|
+
|
72
|
+
def handle_client_error(error)
|
73
|
+
logger.error "#{self.class}##{__method__} => Faraday::Error::ClientError, #{error}"
|
74
|
+
error.response[:error_messages] || [error.message]
|
75
|
+
end
|
76
|
+
|
77
|
+
def handle_standard_error(error)
|
78
|
+
logger.error "#{self.class}##{__method__} => StandardError, #{error}"
|
79
|
+
['Unexpected error.']
|
80
|
+
end
|
81
|
+
|
66
82
|
def execute_method(method, params, path)
|
67
83
|
case method
|
68
84
|
when :get
|
data/lib/finapps/rest/client.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module FinApps
|
2
3
|
module REST
|
3
4
|
class Client < BaseClient # :nodoc:
|
5
|
+
using ObjectExtensions
|
6
|
+
using StringExtensions
|
7
|
+
|
4
8
|
include FinApps::REST::Defaults
|
5
9
|
|
6
10
|
# @param [String] tenant_identifier
|
@@ -11,10 +15,8 @@ module FinApps
|
|
11
15
|
raise FinApps::MissingArgumentsError.new 'Invalid company_identifier.' if tenant_identifier.blank?
|
12
16
|
raise FinApps::MissingArgumentsError.new 'Invalid company_token.' if tenant_token.blank?
|
13
17
|
|
14
|
-
merged_options = FinApps::REST::Defaults::DEFAULTS.merge
|
15
|
-
|
16
|
-
token: tenant_token}
|
17
|
-
|
18
|
+
merged_options = FinApps::REST::Defaults::DEFAULTS.merge(options.merge(tenant_identifier: tenant_identifier,
|
19
|
+
tenant_token: tenant_token))
|
18
20
|
super(merged_options, logger)
|
19
21
|
end
|
20
22
|
|
@@ -1,51 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module FinApps
|
2
3
|
module REST
|
4
|
+
# Represents the client configuration options
|
3
5
|
class Configuration # :nodoc:
|
4
|
-
|
6
|
+
using ObjectExtensions
|
7
|
+
using HashExtensions
|
5
8
|
|
6
|
-
|
9
|
+
attr_accessor :host,
|
10
|
+
:tenant_identifier, :tenant_token,
|
11
|
+
:user_identifier, :user_token,
|
12
|
+
:proxy, :timeout, :retry_limit, :log_level
|
7
13
|
|
8
|
-
|
9
|
-
|
10
|
-
accept: 'application/json',
|
11
|
-
user_agent: "finapps-ruby/#{FinApps::VERSION} (#{RUBY})"
|
12
|
-
}.freeze
|
13
|
-
|
14
|
-
attr_accessor :host, :timeout, :tenant_credentials, :user_credentials, :url,
|
15
|
-
:proxy_addr, :proxy_port, :proxy_user, :proxy_pass,
|
16
|
-
:retry_limit, :log_level
|
17
|
-
|
18
|
-
def initialize(options)
|
19
|
-
super(options, FinApps::REST::Defaults::DEFAULTS)
|
20
|
-
validate
|
21
|
-
@url = "#{host}/v#{FinApps::REST::Defaults::API_VERSION}/"
|
22
|
-
end
|
23
|
-
|
24
|
-
def connection_options
|
25
|
-
{url: url,
|
26
|
-
request: {open_timeout: timeout, timeout: timeout},
|
27
|
-
headers: {accept: HEADERS[:accept], user_agent: HEADERS[:user_agent]}}
|
28
|
-
end
|
29
|
-
|
30
|
-
def valid_user_credentials?
|
31
|
-
valid_credentials? user_credentials
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
def validate
|
37
|
-
raise FinApps::MissingArgumentsError.new 'Missing tenant_credentials.' unless valid_tenant_credentials?
|
14
|
+
def initialize(options={})
|
15
|
+
FinApps::REST::Defaults::DEFAULTS.merge(options.compact).each {|key, value| public_send("#{key}=", value) }
|
38
16
|
raise FinApps::InvalidArgumentsError.new "Invalid argument. {host: #{host}}" unless valid_host?
|
39
17
|
raise FinApps::InvalidArgumentsError.new "Invalid argument. {timeout: #{timeout}}" unless timeout.integer?
|
40
18
|
end
|
41
19
|
|
42
|
-
|
43
|
-
valid_credentials? tenant_credentials
|
44
|
-
end
|
45
|
-
|
46
|
-
def valid_credentials?(h)
|
47
|
-
h.is_a?(Hash) && %i(identifier token).all? {|x| h.key? x } && h.values.all?(&:present?)
|
48
|
-
end
|
20
|
+
private
|
49
21
|
|
50
22
|
def valid_host?
|
51
23
|
host.start_with?('http://', 'https://')
|
@@ -1,31 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module FinApps
|
2
3
|
module REST
|
3
4
|
module Connection # :nodoc:
|
4
|
-
|
5
|
-
|
5
|
+
# @return [Faraday::Connection]
|
6
6
|
def faraday(config, logger)
|
7
|
-
|
8
|
-
#
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
if config.valid_user_credentials?
|
13
|
-
conn.request :basic_auth, config.user_credentials[:identifier], config.user_credentials[:token]
|
14
|
-
end
|
7
|
+
options = {
|
8
|
+
url: "#{config.host}/v#{Defaults::API_VERSION}/",
|
9
|
+
request: {open_timeout: config.timeout,
|
10
|
+
timeout: config.timeout}
|
11
|
+
}
|
15
12
|
|
13
|
+
Faraday.new(options) do |conn|
|
14
|
+
conn.request :accept_json
|
15
|
+
conn.request :user_agent
|
16
|
+
conn.request :tenant_authentication, config.tenant_identifier, config.tenant_token
|
16
17
|
conn.request :json
|
17
18
|
conn.request :retry
|
18
19
|
conn.request :multipart
|
19
20
|
conn.request :url_encoded
|
21
|
+
if FinApps::REST::Credentials.new(config.user_identifier, config.user_token).valid?
|
22
|
+
conn.request :basic_auth, config.user_identifier, config.user_token
|
23
|
+
end
|
24
|
+
|
20
25
|
conn.use FinApps::Middleware::RaiseError
|
21
26
|
conn.response :rashify
|
22
27
|
conn.response :json, content_type: /\bjson$/
|
23
|
-
conn.response :logger, logger
|
28
|
+
conn.response :logger, logger, bodies: true
|
24
29
|
|
25
30
|
# Adapter (ensure that the adapter is always last.)
|
26
31
|
conn.adapter :typhoeus
|
27
32
|
end
|
28
33
|
end
|
34
|
+
module_function :faraday # becomes available as a *private instance method* to classes that mix in the module
|
29
35
|
end
|
30
36
|
end
|
31
37
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module FinApps
|
3
|
+
module REST
|
4
|
+
# represents both tenant and user credentials
|
5
|
+
class Credentials
|
6
|
+
using ObjectExtensions
|
7
|
+
using StringExtensions
|
8
|
+
|
9
|
+
attr_reader :identifier, :token
|
10
|
+
|
11
|
+
def initialize(identifier, token)
|
12
|
+
@identifier = identifier
|
13
|
+
@token = token
|
14
|
+
end
|
15
|
+
|
16
|
+
def valid?
|
17
|
+
identifier.present? && token.present?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,18 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module FinApps
|
2
3
|
module REST
|
3
4
|
module Defaults
|
4
|
-
API_VERSION = '2'
|
5
|
+
API_VERSION = '2'
|
5
6
|
|
6
7
|
# noinspection SpellCheckingInspection
|
7
8
|
DEFAULTS = {
|
8
|
-
host:
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
log_level: Logger::INFO
|
9
|
+
host: 'https://api.financialapps.com',
|
10
|
+
user_identifier: nil,
|
11
|
+
user_token: nil,
|
12
|
+
timeout: 30,
|
13
|
+
proxy: nil,
|
14
|
+
retry_limit: 1,
|
15
|
+
log_level: Logger::INFO
|
16
16
|
}.freeze
|
17
17
|
|
18
18
|
END_POINTS = {
|
data/lib/finapps/rest/orders.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module FinApps
|
2
3
|
module REST
|
3
4
|
class Orders < FinApps::REST::Resources # :nodoc:
|
5
|
+
using ObjectExtensions
|
6
|
+
using StringExtensions
|
7
|
+
|
4
8
|
def show(id)
|
5
9
|
raise MissingArgumentsError.new 'Missing argument: params.' if id.blank?
|
6
10
|
super
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module FinApps
|
2
3
|
module REST
|
3
4
|
class Resources # :nodoc:
|
@@ -8,7 +9,7 @@ module FinApps
|
|
8
9
|
# @param [FinApps::REST::Client] client
|
9
10
|
# @return [FinApps::REST::Resources]
|
10
11
|
def initialize(client)
|
11
|
-
raise MissingArgumentsError.new 'Missing argument: client.' if client.
|
12
|
+
raise MissingArgumentsError.new 'Missing argument: client.' if client.nil?
|
12
13
|
@client = client
|
13
14
|
end
|
14
15
|
|
data/lib/finapps/rest/users.rb
CHANGED
data/lib/finapps/version.rb
CHANGED
data/lib/tasks/releaser.rake
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
RSpec.describe FinApps::Middleware::AcceptJson do
|
3
|
+
let(:fake_app) { proc {|env| env } }
|
4
|
+
describe '#call' do
|
5
|
+
subject { FinApps::Middleware::AcceptJson.new(fake_app) }
|
6
|
+
env = {request_headers: {}}
|
7
|
+
|
8
|
+
it('generates a UserAgent header') do
|
9
|
+
expect(subject.call(env)[:request_headers][FinApps::Middleware::AcceptJson::KEY]).to eq('application/json')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
RSpec.describe FinApps::Middleware::TenantAuthentication do
|
2
3
|
let(:valid_tenant_options) { VALID_CREDENTIALS }
|
3
4
|
let(:key) { FinApps::Middleware::TenantAuthentication::KEY }
|
@@ -6,7 +7,11 @@ RSpec.describe FinApps::Middleware::TenantAuthentication do
|
|
6
7
|
fake_app = proc {|env| env }
|
7
8
|
|
8
9
|
context 'when company credentials were provided' do
|
9
|
-
let(:middleware)
|
10
|
+
let(:middleware) do
|
11
|
+
FinApps::Middleware::TenantAuthentication.new(fake_app,
|
12
|
+
VALID_CREDENTIALS[:identifier],
|
13
|
+
VALID_CREDENTIALS[:token])
|
14
|
+
end
|
10
15
|
let(:expected_header) { "#{valid_tenant_options[:identifier]}=#{valid_tenant_options[:token]}" }
|
11
16
|
|
12
17
|
context 'when header was not previously set' do
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
RSpec.describe FinApps::Middleware::UserAgent do
|
3
|
+
let(:fake_app) { proc {|env| env } }
|
4
|
+
describe '#call' do
|
5
|
+
subject { FinApps::Middleware::UserAgent.new(fake_app) }
|
6
|
+
env = {request_headers: {}}
|
7
|
+
|
8
|
+
it('generates a UserAgent header') do
|
9
|
+
expect(subject.call(env)[:request_headers][FinApps::Middleware::UserAgent::KEY]).to start_with('finapps-ruby')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -1,5 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
RSpec.describe FinApps::REST::BaseClient do
|
2
|
-
let(:valid_tenant_options)
|
3
|
+
let(:valid_tenant_options) do
|
4
|
+
{tenant_identifier: VALID_CREDENTIALS[:identifier],
|
5
|
+
tenant_token: VALID_CREDENTIALS[:token]}
|
6
|
+
end
|
3
7
|
subject { FinApps::REST::BaseClient.new(valid_tenant_options) }
|
4
8
|
|
5
9
|
RESPONSE = 0
|
@@ -54,10 +58,10 @@ RSpec.describe FinApps::REST::BaseClient do
|
|
54
58
|
context 'for client errors' do
|
55
59
|
subject { FinApps::REST::BaseClient.new(valid_tenant_options).send_request('client_error', :get) }
|
56
60
|
|
57
|
-
it('
|
58
|
-
it { expect(subject[ERROR_MESSAGES]).not_to be_nil }
|
59
|
-
it { expect(subject[ERROR_MESSAGES]).to be_a(Array) }
|
60
|
-
it { expect(subject[ERROR_MESSAGES].length).to be > 0 }
|
61
|
+
it('result is null') { expect(subject[RESPONSE]).to be_nil }
|
62
|
+
it('error_messages is not null') { expect(subject[ERROR_MESSAGES]).not_to be_nil }
|
63
|
+
it('error_messages is an array') { expect(subject[ERROR_MESSAGES]).to be_a(Array) }
|
64
|
+
it('error messages array contains elements') { expect(subject[ERROR_MESSAGES].length).to be > 0 }
|
61
65
|
end
|
62
66
|
|
63
67
|
context 'for server errors' do
|
data/spec/rest/client_spec.rb
CHANGED
@@ -1,74 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
RSpec.describe FinApps::REST::Configuration do
|
2
3
|
describe '#new' do
|
3
|
-
|
4
|
-
|
5
|
-
|
4
|
+
context 'for invalid timeout configuration' do
|
5
|
+
subject { FinApps::REST::Configuration.new(timeout: 'whatever') }
|
6
|
+
it { expect { subject }.to raise_error(FinApps::InvalidArgumentsError, 'Invalid argument. {timeout: whatever}') }
|
6
7
|
end
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
context 'for missing timeout configuration' do
|
10
|
+
subject { FinApps::REST::Configuration.new(timeout: nil) }
|
11
|
+
it 'should have a default timeout value' do
|
12
|
+
expect(subject.timeout).to eq(FinApps::REST::Defaults::DEFAULTS[:timeout])
|
13
|
+
end
|
11
14
|
end
|
12
15
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
+
context 'for invalid host configuration' do
|
17
|
+
subject { FinApps::REST::Configuration.new(host: 'whatever') }
|
18
|
+
it { expect { subject }.to raise_error(FinApps::InvalidArgumentsError, 'Invalid argument. {host: whatever}') }
|
16
19
|
end
|
17
20
|
|
18
|
-
context 'for
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
let(:valid_creds) { valid_tenant_options.merge(user_credentials: VALID_CREDENTIALS) }
|
23
|
-
subject { FinApps::REST::Configuration.new(valid_creds) }
|
24
|
-
it('should have user_credentials') { expect(subject.user_credentials).to eq(VALID_CREDENTIALS) }
|
25
|
-
it('user_credentials are valid') { expect(subject.valid_user_credentials?).to eq true }
|
26
|
-
end
|
27
|
-
|
28
|
-
context 'for missing user credentials' do
|
29
|
-
subject { FinApps::REST::Configuration.new(valid_tenant_options) }
|
30
|
-
it('user_credentials are not valid') { expect(subject.valid_user_credentials?).to eq false }
|
31
|
-
end
|
32
|
-
|
33
|
-
context 'for invalid user credentials (token)' do
|
34
|
-
let(:invalid_user_creds) { {identifier: :identifier, token: ''} }
|
35
|
-
subject { FinApps::REST::Configuration.new(valid_tenant_options.merge(user_credentials: invalid_user_creds)) }
|
36
|
-
|
37
|
-
it('user_credentials are not valid') { expect(subject.valid_user_credentials?).to eq false }
|
38
|
-
end
|
39
|
-
|
40
|
-
context 'for invalid user credentials (identifier)' do
|
41
|
-
let(:invalid_user_creds) { {identifier: '', token: :token} }
|
42
|
-
subject { FinApps::REST::Configuration.new(valid_tenant_options.merge(user_credentials: invalid_user_creds)) }
|
43
|
-
|
44
|
-
it('user_credentials are not valid') { expect(subject.valid_user_credentials?).to eq false }
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'raises for invalid timeout values' do
|
48
|
-
expect { FinApps::REST::Configuration.new(valid_tenant_options.merge(timeout: 'whatever')) }
|
49
|
-
.to raise_error(FinApps::InvalidArgumentsError, 'Invalid argument. {timeout: whatever}')
|
50
|
-
end
|
51
|
-
|
52
|
-
context 'for valid timeout' do
|
53
|
-
subject { FinApps::REST::Configuration.new(valid_tenant_options.merge(timeout: nil)) }
|
54
|
-
it 'should have a default timeout value' do
|
55
|
-
config = FinApps::REST::Configuration.new(valid_tenant_options.merge(timeout: nil))
|
56
|
-
expect(config.timeout).to eq(FinApps::REST::Defaults::DEFAULTS[:timeout])
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'raises for invalid host values' do
|
61
|
-
expect { FinApps::REST::Configuration.new(valid_tenant_options.merge(host: 'whatever')) }
|
62
|
-
.to raise_error(FinApps::InvalidArgumentsError, 'Invalid argument. {host: whatever}')
|
63
|
-
end
|
64
|
-
|
65
|
-
context 'for valid host' do
|
66
|
-
subject { FinApps::REST::Configuration.new(valid_tenant_options.merge(host: nil)) }
|
67
|
-
|
68
|
-
it('should have a default host') { expect(subject.host).to eq(FinApps::REST::Defaults::DEFAULTS[:host]) }
|
69
|
-
it('url should include version') do
|
70
|
-
expect(subject.url).to eq("#{subject.host}/v#{FinApps::REST::Defaults::API_VERSION}/")
|
71
|
-
end
|
21
|
+
context 'for missing host configuration' do
|
22
|
+
subject { FinApps::REST::Configuration.new(host: nil) }
|
23
|
+
it 'should have a default host value' do
|
24
|
+
expect(subject.host).to eq(FinApps::REST::Defaults::DEFAULTS[:host])
|
72
25
|
end
|
73
26
|
end
|
74
27
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
RSpec.describe FinApps::REST::Credentials do
|
3
|
+
describe '#valid?' do
|
4
|
+
context 'when missing identifier' do
|
5
|
+
it { expect(FinApps::REST::Credentials.new(nil, :token).valid?).to eql(false) }
|
6
|
+
end
|
7
|
+
|
8
|
+
context 'when missing token' do
|
9
|
+
it { expect(FinApps::REST::Credentials.new(:identifier, nil).valid?).to eql(false) }
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'when missing both identifier and token' do
|
13
|
+
it { expect(FinApps::REST::Credentials.new(nil, nil).valid?).to eql(false) }
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'when having identifier and token' do
|
17
|
+
it { expect(FinApps::REST::Credentials.new(:identifier, :token).valid?).to eql(true) }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/spec/rest/orders_spec.rb
CHANGED
data/spec/rest/resources_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
if ENV['CODECLIMATE_REPO_TOKEN']
|
2
3
|
require 'codeclimate-test-reporter'
|
3
4
|
CodeClimate::TestReporter.start
|
@@ -29,6 +30,7 @@ RSpec.configure do |config|
|
|
29
30
|
base_url = "#{FinApps::REST::Defaults::DEFAULTS[:host]}/v#{FinApps::REST::Defaults::API_VERSION}/"
|
30
31
|
stub_request(:any, /#{base_url}/).to_rack(::FakeApi)
|
31
32
|
end
|
33
|
+
WebMock.disable_net_connect!(allow: 'codeclimate.com')
|
32
34
|
end
|
33
35
|
|
34
36
|
VALID_CREDENTIALS = {identifier: '49fb918d-7e71-44dd-7378-58f19606df2a',
|
data/spec/support/fake_api.rb
CHANGED
metadata
CHANGED
@@ -1,35 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: finapps
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Erich Quintero
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-07-
|
11
|
+
date: 2016-07-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: activesupport
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '4.2'
|
20
|
-
- - ">="
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: 4.2.6
|
23
|
-
type: :runtime
|
24
|
-
prerelease: false
|
25
|
-
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
requirements:
|
27
|
-
- - "~>"
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '4.2'
|
30
|
-
- - ">="
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: 4.2.6
|
33
13
|
- !ruby/object:Gem::Dependency
|
34
14
|
name: faraday
|
35
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -265,16 +245,21 @@ files:
|
|
265
245
|
- README.md
|
266
246
|
- Rakefile
|
267
247
|
- finapps.gemspec
|
248
|
+
- lib/core_extensions/hash/compact.rb
|
249
|
+
- lib/core_extensions/object/blank.rb
|
250
|
+
- lib/core_extensions/object/is_integer.rb
|
268
251
|
- lib/finapps.rb
|
269
|
-
- lib/finapps/core_extensions/integerable.rb
|
270
252
|
- lib/finapps/error.rb
|
271
|
-
- lib/finapps/
|
272
|
-
- lib/finapps/middleware/
|
273
|
-
- lib/finapps/middleware/tenant_authentication.rb
|
253
|
+
- lib/finapps/middleware/middleware.rb
|
254
|
+
- lib/finapps/middleware/request/accept_json.rb
|
255
|
+
- lib/finapps/middleware/request/tenant_authentication.rb
|
256
|
+
- lib/finapps/middleware/request/user_agent.rb
|
257
|
+
- lib/finapps/middleware/response/raise_error.rb
|
274
258
|
- lib/finapps/rest/base_client.rb
|
275
259
|
- lib/finapps/rest/client.rb
|
276
260
|
- lib/finapps/rest/configuration.rb
|
277
261
|
- lib/finapps/rest/connection.rb
|
262
|
+
- lib/finapps/rest/credentials.rb
|
278
263
|
- lib/finapps/rest/defaults.rb
|
279
264
|
- lib/finapps/rest/orders.rb
|
280
265
|
- lib/finapps/rest/resources.rb
|
@@ -282,10 +267,13 @@ files:
|
|
282
267
|
- lib/finapps/utils/loggeable.rb
|
283
268
|
- lib/finapps/version.rb
|
284
269
|
- lib/tasks/releaser.rake
|
270
|
+
- spec/middleware/accept_json_spec.rb
|
285
271
|
- spec/middleware/tenant_authentication_spec.rb
|
272
|
+
- spec/middleware/user_agent_spec.rb
|
286
273
|
- spec/rest/base_client_spec.rb
|
287
274
|
- spec/rest/client_spec.rb
|
288
275
|
- spec/rest/configuration_spec.rb
|
276
|
+
- spec/rest/credentials_spec.rb
|
289
277
|
- spec/rest/orders_spec.rb
|
290
278
|
- spec/rest/resources_spec.rb
|
291
279
|
- spec/spec_helper.rb
|
@@ -320,16 +308,19 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
320
308
|
version: '0'
|
321
309
|
requirements: []
|
322
310
|
rubyforge_project:
|
323
|
-
rubygems_version: 2.
|
311
|
+
rubygems_version: 2.5.1
|
324
312
|
signing_key:
|
325
313
|
specification_version: 4
|
326
314
|
summary: FinApps REST API ruby client.
|
327
315
|
test_files:
|
328
|
-
- spec/
|
329
|
-
- spec/support/fake_api.rb
|
316
|
+
- spec/middleware/accept_json_spec.rb
|
330
317
|
- spec/middleware/tenant_authentication_spec.rb
|
331
|
-
- spec/
|
332
|
-
- spec/rest/client_spec.rb
|
333
|
-
- spec/rest/orders_spec.rb
|
318
|
+
- spec/middleware/user_agent_spec.rb
|
334
319
|
- spec/rest/base_client_spec.rb
|
320
|
+
- spec/rest/client_spec.rb
|
335
321
|
- spec/rest/configuration_spec.rb
|
322
|
+
- spec/rest/credentials_spec.rb
|
323
|
+
- spec/rest/orders_spec.rb
|
324
|
+
- spec/rest/resources_spec.rb
|
325
|
+
- spec/spec_helper.rb
|
326
|
+
- spec/support/fake_api.rb
|
@@ -1,9 +0,0 @@
|
|
1
|
-
module FinApps
|
2
|
-
# when included into any object, allows to initialize public attributes from a hash
|
3
|
-
module HashConstructable
|
4
|
-
def initialize(options_hash={}, defaults=nil)
|
5
|
-
merged_hash = defaults.nil? ? options_hash : defaults.merge(options_hash.compact)
|
6
|
-
merged_hash.each {|k, v| public_send("#{k}=", v) }
|
7
|
-
end
|
8
|
-
end
|
9
|
-
end
|