finapps 2.0.6 → 2.0.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|