finapps_core 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|