finapps_core 2.0.2
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 +7 -0
- data/.codeclimate.yml +21 -0
- data/.gitignore +53 -0
- data/.hound.yml +2 -0
- data/.rspec +4 -0
- data/.rubocop.yml +271 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +14 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +98 -0
- data/LICENSE +21 -0
- data/README.md +21 -0
- data/Rakefile +2 -0
- data/finapps_core.gemspec +39 -0
- data/lib/core_extensions/object/blank.rb +69 -0
- data/lib/core_extensions/object/is_integer.rb +10 -0
- data/lib/core_extensions/string/json_to_hash.rb +10 -0
- data/lib/finapps_core.rb +30 -0
- data/lib/finapps_core/error.rb +17 -0
- data/lib/finapps_core/middleware/middleware.rb +22 -0
- data/lib/finapps_core/middleware/request/accept_json.rb +14 -0
- data/lib/finapps_core/middleware/request/no_encoding_basic_authentication.rb +21 -0
- data/lib/finapps_core/middleware/request/tenant_authentication.rb +20 -0
- data/lib/finapps_core/middleware/request/user_agent.rb +15 -0
- data/lib/finapps_core/middleware/response/custom_logger.rb +39 -0
- data/lib/finapps_core/middleware/response/raise_error.rb +46 -0
- data/lib/finapps_core/rest/base_client.rb +118 -0
- data/lib/finapps_core/rest/configuration.rb +32 -0
- data/lib/finapps_core/rest/connection.rb +35 -0
- data/lib/finapps_core/rest/credentials.rb +21 -0
- data/lib/finapps_core/rest/defaults.rb +19 -0
- data/lib/finapps_core/rest/resources.rb +62 -0
- data/lib/finapps_core/utils/loggeable.rb +14 -0
- data/lib/finapps_core/utils/parameter_filter.rb +32 -0
- data/lib/finapps_core/version.rb +4 -0
- data/lib/tasks/releaser.rake +9 -0
- data/spec/core_extensions/object/blank_spec.rb +44 -0
- data/spec/core_extensions/object/is_integer_spec.rb +17 -0
- data/spec/middleware/request/accept_json_spec.rb +12 -0
- data/spec/middleware/request/no_encoding_basic_authentication_spec.rb +32 -0
- data/spec/middleware/request/tenant_authentication_spec.rb +34 -0
- data/spec/middleware/request/user_agent_spec.rb +12 -0
- data/spec/middleware/response/raise_error_spec.rb +24 -0
- data/spec/rest/base_client_spec.rb +110 -0
- data/spec/rest/configuration_spec.rb +43 -0
- data/spec/rest/credentials_spec.rb +20 -0
- data/spec/rest/relevance_ruleset_names.json +47 -0
- data/spec/rest/timeout_spec.rb +7 -0
- data/spec/spec_helper.rb +37 -0
- data/spec/spec_helpers/client.rb +8 -0
- data/spec/support/fake_api.rb +34 -0
- data/spec/support/fixtures/error.json +5 -0
- data/spec/support/fixtures/relevance_ruleset_names.json +47 -0
- data/spec/support/fixtures/resource.json +3 -0
- data/spec/support/fixtures/resource_not_found.json +5 -0
- data/spec/support/fixtures/resources.json +11 -0
- data/spec/support/fixtures/unauthorized.json +5 -0
- data/spec/utils/parameter_filter_spec.rb +23 -0
- metadata +353 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module FinAppsCore
|
3
|
+
module REST
|
4
|
+
# Represents the client configuration options
|
5
|
+
class Configuration # :nodoc:
|
6
|
+
using ObjectExtensions
|
7
|
+
|
8
|
+
attr_accessor :host,
|
9
|
+
:tenant_identifier, :tenant_token,
|
10
|
+
:user_identifier, :user_token,
|
11
|
+
:proxy, :timeout, :retry_limit, :log_level
|
12
|
+
|
13
|
+
def initialize(options={})
|
14
|
+
non_nil_options = options.select {|_, value| !value.nil? }
|
15
|
+
FinAppsCore::REST::Defaults::DEFAULTS.merge(non_nil_options)
|
16
|
+
.each {|key, value| public_send("#{key}=", value) }
|
17
|
+
raise FinAppsCore::InvalidArgumentsError.new "Invalid argument. {host: #{host}}" unless valid_host?
|
18
|
+
raise FinAppsCore::InvalidArgumentsError.new "Invalid argument. {timeout: #{timeout}}" unless timeout.integer?
|
19
|
+
end
|
20
|
+
|
21
|
+
def valid_user_credentials?
|
22
|
+
FinAppsCore::REST::Credentials.new(user_identifier, user_token).valid?
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def valid_host?
|
28
|
+
host.start_with?('http://', 'https://')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module FinAppsCore
|
3
|
+
module REST
|
4
|
+
module Connection # :nodoc:
|
5
|
+
# @return [Faraday::Connection]
|
6
|
+
def faraday(config, logger)
|
7
|
+
options = {
|
8
|
+
url: "#{config.host}/v#{Defaults::API_VERSION}/",
|
9
|
+
request: {open_timeout: config.timeout,
|
10
|
+
timeout: config.timeout}
|
11
|
+
}
|
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
|
17
|
+
conn.request :json
|
18
|
+
conn.request :retry
|
19
|
+
conn.request :multipart
|
20
|
+
conn.request :url_encoded
|
21
|
+
conn.request :no_encoding_basic_authentication, config.user_token if config.valid_user_credentials?
|
22
|
+
|
23
|
+
conn.use FinAppsCore::Middleware::RaiseError
|
24
|
+
conn.response :rashify
|
25
|
+
conn.response :json, content_type: /\bjson$/
|
26
|
+
conn.response :custom_logger, logger, bodies: (ENV['SILENT_LOG_BODIES'] != 'true')
|
27
|
+
|
28
|
+
# Adapter (ensure that the adapter is always last.)
|
29
|
+
conn.adapter :typhoeus
|
30
|
+
end
|
31
|
+
end
|
32
|
+
module_function :faraday # becomes available as a *private instance method* to classes that mix in the module
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module FinAppsCore
|
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
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module FinAppsCore
|
3
|
+
module REST
|
4
|
+
module Defaults
|
5
|
+
API_VERSION = '2'
|
6
|
+
|
7
|
+
# noinspection SpellCheckingInspection
|
8
|
+
DEFAULTS = {
|
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
|
+
}.freeze
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module FinAppsCore
|
3
|
+
module REST
|
4
|
+
class Resources # :nodoc:
|
5
|
+
include FinAppsCore::Utils::ParameterFilter
|
6
|
+
require 'erb'
|
7
|
+
|
8
|
+
attr_reader :client
|
9
|
+
|
10
|
+
# @param [FinAppsCore::REST::Client] client
|
11
|
+
# @return [FinAppsCore::REST::Resources]
|
12
|
+
def initialize(client)
|
13
|
+
raise MissingArgumentsError.new 'Missing argument: client.' if client.nil?
|
14
|
+
@client = client
|
15
|
+
end
|
16
|
+
|
17
|
+
def list(path=nil)
|
18
|
+
path = end_point.to_s if path.nil?
|
19
|
+
request_with_body(path, :get, {})
|
20
|
+
end
|
21
|
+
|
22
|
+
def create(params={}, path=nil)
|
23
|
+
request_with_body(path, :post, params)
|
24
|
+
end
|
25
|
+
|
26
|
+
def update(params={}, path=nil)
|
27
|
+
request_with_body(path, :put, params)
|
28
|
+
end
|
29
|
+
|
30
|
+
def show(id=nil, path=nil)
|
31
|
+
request_without_body(path, :get, id)
|
32
|
+
end
|
33
|
+
|
34
|
+
def destroy(id=nil, path=nil)
|
35
|
+
request_without_body(path, :delete, id)
|
36
|
+
end
|
37
|
+
|
38
|
+
def request_without_body(path, method, id)
|
39
|
+
raise MissingArgumentsError.new 'Missing argument: id.' if id.nil? && path.nil?
|
40
|
+
path = "#{end_point}/:id".sub ':id', ERB::Util.url_encode(id) if path.nil?
|
41
|
+
request_with_body path, method, {}
|
42
|
+
end
|
43
|
+
|
44
|
+
def request_with_body(path, method, params)
|
45
|
+
path = end_point if path.nil?
|
46
|
+
logger.debug "#{self.class.name}##{__method__} => path: #{path} params: #{skip_sensitive_data(params)}"
|
47
|
+
|
48
|
+
client.send_request path, method, params
|
49
|
+
end
|
50
|
+
|
51
|
+
protected
|
52
|
+
|
53
|
+
def logger
|
54
|
+
client.logger
|
55
|
+
end
|
56
|
+
|
57
|
+
def end_point
|
58
|
+
self.class.name.split('::').last.downcase
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module FinAppsCore
|
3
|
+
module Utils
|
4
|
+
# Adds logging capabilities when included into other classes
|
5
|
+
module Loggeable
|
6
|
+
def logger
|
7
|
+
@logger ||= begin
|
8
|
+
require 'logger'
|
9
|
+
::Logger.new(STDOUT)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module FinAppsCore
|
3
|
+
module Utils
|
4
|
+
module ParameterFilter
|
5
|
+
using StringExtensions
|
6
|
+
PROTECTED_KEYS = %w(login login1 username password password1 password_confirm token
|
7
|
+
x-finapps-token authorization).freeze
|
8
|
+
|
9
|
+
def skip_sensitive_data(hash)
|
10
|
+
if hash.is_a? String
|
11
|
+
hash = hash.json_to_hash
|
12
|
+
end
|
13
|
+
if hash.is_a? Hash
|
14
|
+
filtered_hash = hash.clone
|
15
|
+
filtered_hash.each do |key, value|
|
16
|
+
if PROTECTED_KEYS.include? key.to_s.downcase
|
17
|
+
filtered_hash[key] = '[REDACTED]'
|
18
|
+
elsif value.is_a?(Hash)
|
19
|
+
filtered_hash[key] = skip_sensitive_data(value)
|
20
|
+
elsif value.is_a?(Array)
|
21
|
+
filtered_hash[key] = value.map {|v| v.is_a?(Hash) ? skip_sensitive_data(v) : v }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
filtered_hash
|
26
|
+
else
|
27
|
+
hash
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
desc 'Bumps the version to the next patch level, tags and pushes the code to
|
3
|
+
origin repository and releases the gem. BOOM!'
|
4
|
+
|
5
|
+
# https://github.com/svenfuchs/gem-release
|
6
|
+
|
7
|
+
task :release do
|
8
|
+
system 'gem bump --tag --release'
|
9
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
RSpec.describe ObjectExtensions do
|
3
|
+
context 'when refining Object' do
|
4
|
+
using ObjectExtensions
|
5
|
+
|
6
|
+
describe '#blank?' do
|
7
|
+
# An object is blank if it's false, empty, or a whitespace string.
|
8
|
+
context 'for false' do
|
9
|
+
it { expect(false.blank?).to eq(true) }
|
10
|
+
end
|
11
|
+
context 'for empty arrays' do
|
12
|
+
it { expect([].blank?).to eq(true) }
|
13
|
+
end
|
14
|
+
context 'for empty hashes' do
|
15
|
+
it { expect({}.blank?).to eq(true) }
|
16
|
+
end
|
17
|
+
context 'for whitespace string' do
|
18
|
+
it { expect(''.blank?).to eq(true) }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#present?' do
|
23
|
+
# An object is present if it's not blank.
|
24
|
+
context 'for not blank objects' do
|
25
|
+
it { expect(1.present?).to eq(true) }
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'for blank objects' do
|
29
|
+
it { expect(false.present?).to eq(false) }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#presence' do
|
34
|
+
# Returns the receiver if it's present otherwise returns +nil+.
|
35
|
+
context 'returns the receiver when the receiver is present' do
|
36
|
+
it { expect(true.presence).to eq(true) }
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'returns nil when the receiver is not present' do
|
40
|
+
it { expect(false.presence).to be_nil }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
RSpec.describe ObjectExtensions do
|
3
|
+
context 'when refining Object' do
|
4
|
+
using ObjectExtensions
|
5
|
+
|
6
|
+
describe '#integer?' do
|
7
|
+
context 'for integers' do
|
8
|
+
subject { 1 + rand(10) }
|
9
|
+
it { expect(subject.integer?).to eq(true) }
|
10
|
+
end
|
11
|
+
context 'for non integers' do
|
12
|
+
subject { rand }
|
13
|
+
it { expect(subject.integer?).to eq(false) }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
RSpec.describe FinAppsCore::Middleware::AcceptJson do
|
3
|
+
let(:fake_app) { proc {|env| env } }
|
4
|
+
describe '#call' do
|
5
|
+
subject { FinAppsCore::Middleware::AcceptJson.new(fake_app) }
|
6
|
+
env = {request_headers: {}}
|
7
|
+
|
8
|
+
it('generates a UserAgent header') do
|
9
|
+
expect(subject.call(env)[:request_headers][FinAppsCore::Middleware::AcceptJson::KEY]).to eq('application/json')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
RSpec.describe FinAppsCore::Middleware::NoEncodingBasicAuthentication do
|
3
|
+
let(:valid_credentials) { VALID_CREDENTIALS }
|
4
|
+
let(:key) { FinAppsCore::Middleware::NoEncodingBasicAuthentication::KEY }
|
5
|
+
|
6
|
+
describe '#call' do
|
7
|
+
fake_app = proc {|env| env }
|
8
|
+
|
9
|
+
context 'when credentials were provided' do
|
10
|
+
let(:middleware) do
|
11
|
+
FinAppsCore::Middleware::NoEncodingBasicAuthentication.new(fake_app, VALID_CREDENTIALS[:token])
|
12
|
+
end
|
13
|
+
let(:expected_header) { "Basic #{valid_credentials[:token]}" }
|
14
|
+
|
15
|
+
context 'when header was not previously set' do
|
16
|
+
let(:request_env) { {request_headers: {}} }
|
17
|
+
subject(:actual_header) { middleware.call(request_env)[:request_headers][key] }
|
18
|
+
|
19
|
+
it('generates a header') { expect(actual_header).to eq(expected_header) }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when header was previously set' do
|
23
|
+
let(:existing_header) { {FinAppsCore::Middleware::NoEncodingBasicAuthentication::KEY => 'foo'} }
|
24
|
+
let(:request_env) { {request_headers: existing_header} }
|
25
|
+
subject(:actual_header) { middleware.call(request_env)[:request_headers][key] }
|
26
|
+
|
27
|
+
it('does not override existing header') { expect(actual_header).to eq('foo') }
|
28
|
+
it('does not generate a header') { expect(actual_header).to_not eq(expected_header) }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
RSpec.describe FinAppsCore::Middleware::TenantAuthentication do
|
3
|
+
let(:valid_tenant_options) { VALID_CREDENTIALS }
|
4
|
+
let(:key) { FinAppsCore::Middleware::TenantAuthentication::KEY }
|
5
|
+
|
6
|
+
describe '#call' do
|
7
|
+
fake_app = proc {|env| env }
|
8
|
+
|
9
|
+
context 'when company credentials were provided' do
|
10
|
+
let(:middleware) do
|
11
|
+
FinAppsCore::Middleware::TenantAuthentication.new(fake_app,
|
12
|
+
VALID_CREDENTIALS[:identifier],
|
13
|
+
VALID_CREDENTIALS[:token])
|
14
|
+
end
|
15
|
+
let(:expected_header) { "#{valid_tenant_options[:identifier]}=#{valid_tenant_options[:token]}" }
|
16
|
+
|
17
|
+
context 'when header was not previously set' do
|
18
|
+
let(:request_env) { {request_headers: {}} }
|
19
|
+
subject(:actual_header) { middleware.call(request_env)[:request_headers][key] }
|
20
|
+
|
21
|
+
it('generates a Tenant Authentication header') { expect(actual_header).to eq(expected_header) }
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when header was previously set' do
|
25
|
+
let(:existing_header) { {FinAppsCore::Middleware::TenantAuthentication::KEY => 'foo'} }
|
26
|
+
let(:request_env) { {request_headers: existing_header} }
|
27
|
+
subject(:actual_header) { middleware.call(request_env)[:request_headers][key] }
|
28
|
+
|
29
|
+
it('does not override existing Tenant Authentication header') { expect(actual_header).to eq('foo') }
|
30
|
+
it('does not generate a Tenant Authentication header') { expect(actual_header).to_not eq(expected_header) }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
RSpec.describe FinAppsCore::Middleware::UserAgent do
|
3
|
+
let(:fake_app) { proc {|env| env } }
|
4
|
+
describe '#call' do
|
5
|
+
subject { FinAppsCore::Middleware::UserAgent.new(fake_app) }
|
6
|
+
env = {request_headers: {}}
|
7
|
+
|
8
|
+
it('generates a UserAgent header') do
|
9
|
+
expect(subject.call(env)[:request_headers][FinAppsCore::Middleware::UserAgent::KEY]).to start_with('finapps-ruby')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
RSpec.describe FinAppsCore::Middleware::RaiseError do
|
3
|
+
let(:fake_app) { proc {|env| env } }
|
4
|
+
Env = Struct.new(:status, :response_headers, :body)
|
5
|
+
|
6
|
+
describe '#on_complete' do
|
7
|
+
subject { FinAppsCore::Middleware::RaiseError.new(fake_app) }
|
8
|
+
|
9
|
+
context 'for successful requests' do
|
10
|
+
let(:env) { Env.new(200) }
|
11
|
+
it { expect { subject.on_complete(env) }.not_to raise_error }
|
12
|
+
end
|
13
|
+
context 'for client errors' do
|
14
|
+
let(:env) { Env.new(401, {}, '{"messages":["Invalid User Identifier or Credentials"]}') }
|
15
|
+
error_message = 'the server responded with status 401'
|
16
|
+
it { expect { subject.on_complete(env) }.to raise_error(Faraday::Error::ClientError, error_message) }
|
17
|
+
end
|
18
|
+
context 'for connection failed error' do
|
19
|
+
let(:env) { Env.new(407) }
|
20
|
+
error_message = '407 "Proxy Authentication Required"'
|
21
|
+
it { expect { subject.on_complete(env) }.to raise_error(Faraday::Error::ConnectionFailed, error_message) }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
RSpec.describe FinAppsCore::REST::BaseClient do
|
3
|
+
let(:valid_tenant_options) do
|
4
|
+
{tenant_identifier: VALID_CREDENTIALS[:identifier],
|
5
|
+
tenant_token: VALID_CREDENTIALS[:token]}
|
6
|
+
end
|
7
|
+
subject { FinAppsCore::REST::BaseClient.new(valid_tenant_options) }
|
8
|
+
|
9
|
+
RESPONSE = 0
|
10
|
+
ERROR_MESSAGES = 1
|
11
|
+
let(:return_array) { %i(RESPONSE ERROR_MESSAGES) }
|
12
|
+
|
13
|
+
describe '#new' do
|
14
|
+
it 'assigns @config' do
|
15
|
+
expect(subject.config).to be_a(FinAppsCore::REST::Configuration)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#connection' do
|
20
|
+
it 'created a Faraday connection object' do
|
21
|
+
expect(subject.connection).to be_a(Faraday::Connection)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'memoizes the results' do
|
25
|
+
first = subject.connection
|
26
|
+
second = subject.connection
|
27
|
+
expect(first.object_id).to eq(second.object_id)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#send_request' do
|
32
|
+
it 'should raise FinAppsCore::InvalidArgumentsError if method is NOT supported' do
|
33
|
+
expect { subject.send_request('fake_path', :option) }.to raise_error(FinAppsCore::InvalidArgumentsError,
|
34
|
+
'Method not supported: option.')
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should raise FinAppsCore::MissingArgumentsError if method is NOT provided' do
|
38
|
+
expect { subject.send_request(nil, :get) }.to raise_error(FinAppsCore::MissingArgumentsError,
|
39
|
+
'Missing argument: path.')
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should raise FinAppsCore::MissingArgumentsError if path is NOT provided' do
|
43
|
+
expect { subject.send_request('fake_path', nil) }.to raise_error(FinAppsCore::MissingArgumentsError,
|
44
|
+
'Missing argument: method.')
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when method and path are provided' do
|
48
|
+
subject { FinAppsCore::REST::BaseClient.new(valid_tenant_options).send_request('relevance/ruleset/names', :get) }
|
49
|
+
let(:return_array) { %i(RESPONSE ERROR_MESSAGES) }
|
50
|
+
|
51
|
+
it('returns an array of 2 items') do
|
52
|
+
expect(subject).to be_a(Array)
|
53
|
+
expect(subject.size).to eq(return_array.length)
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'for unsupported methods' do
|
57
|
+
subject { FinAppsCore::REST::BaseClient.new(valid_tenant_options).send_request('users', :options) }
|
58
|
+
|
59
|
+
it do
|
60
|
+
expect { subject.send_request(nil, :get) }
|
61
|
+
.to raise_error(FinAppsCore::InvalidArgumentsError, 'Method not supported: options.')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'for client errors' do
|
66
|
+
subject { FinAppsCore::REST::BaseClient.new(valid_tenant_options).send_request('client_error', :get) }
|
67
|
+
|
68
|
+
it('result is null') { expect(subject[RESPONSE]).to be_nil }
|
69
|
+
it('error_messages is an array') { expect(subject[ERROR_MESSAGES]).to be_a(Array) }
|
70
|
+
it('error_messages gets populated') { expect(subject[ERROR_MESSAGES].first).to eq 'Password Minimum size is 8' }
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'for server errors' do
|
74
|
+
subject { FinAppsCore::REST::BaseClient.new(valid_tenant_options).send_request('server_error', :get) }
|
75
|
+
|
76
|
+
it('the result should be nil') { expect(subject[RESPONSE]).to be_nil }
|
77
|
+
it { expect(subject[ERROR_MESSAGES]).not_to be_nil }
|
78
|
+
it { expect(subject[ERROR_MESSAGES]).to be_a(Array) }
|
79
|
+
it { expect(subject[ERROR_MESSAGES].first).to eq 'the server responded with status 500' }
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'for proxy errors' do
|
83
|
+
subject { FinAppsCore::REST::BaseClient.new(valid_tenant_options).send_request('proxy_error', :get) }
|
84
|
+
|
85
|
+
it { expect { subject }.to raise_error(Faraday::ConnectionFailed, '407 "Proxy Authentication Required"') }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'if a block is provided' do
|
90
|
+
it('gets executed on the response') do
|
91
|
+
expect(subject.send_request('relevance/ruleset/names', :get, &:status)[RESPONSE]).to eq(200)
|
92
|
+
expect(subject.send_request('relevance/ruleset/names', :get) {|r| r.body.length }[RESPONSE]).to eq(45)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe '#method_missing' do
|
98
|
+
context 'for unsupported methods' do
|
99
|
+
it { expect { subject.unsupported }.to raise_error(NoMethodError) }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe '#respond_to_missing?' do
|
104
|
+
context 'for supported methods' do
|
105
|
+
[:get, :post, :put, :delete].each do |method|
|
106
|
+
it("responds to #{method}") { expect(subject).to respond_to(method) }
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|