rdstation-ruby-client 1.0.0 → 1.0.1
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/Gemfile.lock +1 -1
- data/lib/rdstation/error.rb +13 -5
- data/lib/rdstation/error/format.rb +30 -0
- data/lib/rdstation/error/formatter.rb +40 -0
- data/lib/rdstation/error_handler.rb +28 -6
- data/lib/rdstation/error_handler/conflicting_field.rb +7 -9
- data/lib/rdstation/error_handler/default.rb +4 -8
- data/lib/rdstation/error_handler/expired_access_token.rb +16 -12
- data/lib/rdstation/error_handler/expired_code_grant.rb +7 -10
- data/lib/rdstation/error_handler/invalid_credentials.rb +7 -9
- data/lib/rdstation/error_handler/resource_not_found.rb +7 -9
- data/lib/rdstation/error_handler/unauthorized.rb +7 -9
- data/lib/rdstation/version.rb +1 -1
- data/spec/lib/rdstation/error/format_spec.rb +56 -0
- data/spec/lib/rdstation/error/formatter_spec.rb +99 -0
- data/spec/lib/rdstation/error_handler/conflicting_field_spec.rb +49 -0
- data/spec/lib/rdstation/error_handler/default_spec.rb +14 -0
- data/spec/lib/rdstation/error_handler/expired_access_token_spec.rb +103 -0
- data/spec/lib/rdstation/error_handler/expired_code_grant_spec.rb +54 -0
- data/spec/lib/rdstation/error_handler/invalid_credentials_spec.rb +54 -0
- data/spec/lib/rdstation/error_handler/resource_not_found_spec.rb +54 -0
- data/spec/lib/rdstation/error_handler/unauthorized_spec.rb +54 -0
- data/spec/lib/rdstation/error_handler_spec.rb +49 -0
- data/spec/lib/rdstation/error_spec.rb +24 -0
- metadata +27 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ea20e4d5e37030b98d697da5b71892ff892a3204
|
4
|
+
data.tar.gz: 027a431a05b01d94279b40d194d334d8a5235cf4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a1bedc3f94bd5f532ab9073d0abc9651ef1a9159e0b339b13b9061e8c476967683b5a66bb659a12a6848fc7396a854be6153655acab97bef9f205ad50ada11b
|
7
|
+
data.tar.gz: ebbf843ae9cc9293850070b0b40cf638a8e1a7e61655f2022def1d01e3987b78dd2a4227e43ccb403a28d3e941f3813238595b542b6978433ecc86e1462fdd20
|
data/Gemfile.lock
CHANGED
data/lib/rdstation/error.rb
CHANGED
@@ -1,12 +1,20 @@
|
|
1
1
|
module RDStation
|
2
2
|
|
3
3
|
class Error < StandardError
|
4
|
-
attr_reader :http_status, :headers, :body
|
4
|
+
attr_reader :details, :http_status, :headers, :body
|
5
|
+
|
6
|
+
def initialize(details)
|
7
|
+
@details = details
|
8
|
+
message = details['error_message']
|
9
|
+
raise ArgumentError, 'The details hash must contain an error message' unless message
|
10
|
+
|
11
|
+
# Those three arguments are kept only for compatibility reasons.
|
12
|
+
# They aren't needed since we can get them directly in the details hash.
|
13
|
+
# Consider removing them when update the major version.
|
14
|
+
@http_status = details['http_status']
|
15
|
+
@headers = details['headers']
|
16
|
+
@body = details['body']
|
5
17
|
|
6
|
-
def initialize(message, api_response_error)
|
7
|
-
@http_status = api_response_error.code
|
8
|
-
@headers = api_response_error.headers
|
9
|
-
@body = JSON.parse(api_response_error.body)
|
10
18
|
super(message)
|
11
19
|
end
|
12
20
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module RDStation
|
2
|
+
class Error
|
3
|
+
class Format
|
4
|
+
FLAT_HASH = 'FLAT_HASH'.freeze
|
5
|
+
HASH_OF_ARRAYS = 'HASH_OF_ARRAYS'.freeze
|
6
|
+
ARRAY_OF_HASHES = 'ARRAY_OF_HASHES'.freeze
|
7
|
+
|
8
|
+
def initialize(errors)
|
9
|
+
@errors = errors
|
10
|
+
end
|
11
|
+
|
12
|
+
def format
|
13
|
+
return FLAT_HASH if flat_hash?
|
14
|
+
return HASH_OF_ARRAYS if hash_of_arrays?
|
15
|
+
ARRAY_OF_HASHES
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def flat_hash?
|
21
|
+
return unless @errors.is_a?(Hash)
|
22
|
+
@errors.key?('error_type')
|
23
|
+
end
|
24
|
+
|
25
|
+
def hash_of_arrays?
|
26
|
+
@errors.is_a?(Hash) && @errors.values.all? { |error| error.is_a? Array }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require_relative './format'
|
2
|
+
|
3
|
+
module RDStation
|
4
|
+
class Error
|
5
|
+
class Formatter
|
6
|
+
def initialize(errors)
|
7
|
+
@errors = errors
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_array
|
11
|
+
case error_format.format
|
12
|
+
when RDStation::Error::Format::FLAT_HASH
|
13
|
+
from_flat_hash
|
14
|
+
when RDStation::Error::Format::HASH_OF_ARRAYS
|
15
|
+
from_hash_of_arrays
|
16
|
+
else
|
17
|
+
@errors
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def from_flat_hash
|
22
|
+
[@errors]
|
23
|
+
end
|
24
|
+
|
25
|
+
def from_hash_of_arrays
|
26
|
+
@errors.each_with_object([]) do |errors, array_of_errors|
|
27
|
+
attribute_name = errors.first
|
28
|
+
attribute_errors = errors.last
|
29
|
+
path = { 'path' => "body.#{attribute_name}" }
|
30
|
+
errors = attribute_errors.map { |error| error.merge(path) }
|
31
|
+
array_of_errors.push(*errors)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def error_format
|
36
|
+
@error_format ||= RDStation::Error::Format.new(@errors)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require_relative 'error/formatter'
|
1
2
|
require_relative 'error_handler/conflicting_field'
|
2
3
|
require_relative 'error_handler/default'
|
3
4
|
require_relative 'error_handler/expired_access_token'
|
@@ -23,16 +24,37 @@ module RDStation
|
|
23
24
|
end
|
24
25
|
|
25
26
|
def raise_errors
|
26
|
-
|
27
|
-
# Raise only the exception message when the error is not recognized
|
28
|
-
unrecognized_error = @response['errors']
|
29
|
-
raise unrecognized_error['error_message']
|
27
|
+
error_types.each(&:raise_error)
|
30
28
|
end
|
31
29
|
|
32
30
|
private
|
33
31
|
|
34
|
-
|
35
|
-
|
32
|
+
attr_reader :response
|
33
|
+
|
34
|
+
def array_of_errors
|
35
|
+
error_formatter.to_array.map do |error|
|
36
|
+
error.merge(additional_error_attributes)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def error_types
|
41
|
+
ERROR_TYPES.map { |error_type| error_type.new(array_of_errors) }
|
42
|
+
end
|
43
|
+
|
44
|
+
def response_errors
|
45
|
+
JSON.parse(response.body)['errors']
|
46
|
+
end
|
47
|
+
|
48
|
+
def error_formatter
|
49
|
+
@error_formatter = RDStation::Error::Formatter.new(response_errors)
|
50
|
+
end
|
51
|
+
|
52
|
+
def additional_error_attributes
|
53
|
+
{
|
54
|
+
'headers' => response.headers,
|
55
|
+
'body' => JSON.parse(response.body),
|
56
|
+
'http_status' => response.code
|
57
|
+
}
|
36
58
|
end
|
37
59
|
end
|
38
60
|
end
|
@@ -1,25 +1,23 @@
|
|
1
1
|
module RDStation
|
2
2
|
class ErrorHandler
|
3
3
|
class ConflictingField
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :errors
|
5
5
|
|
6
6
|
ERROR_CODE = 'CONFLICTING_FIELD'.freeze
|
7
|
-
EXCEPTION_CLASS = RDStation::Error::ConflictingField
|
8
7
|
|
9
|
-
def initialize(
|
10
|
-
@
|
11
|
-
@error = JSON.parse(api_response.body)['errors']
|
8
|
+
def initialize(errors)
|
9
|
+
@errors = errors
|
12
10
|
end
|
13
11
|
|
14
12
|
def raise_error
|
15
|
-
return
|
16
|
-
raise
|
13
|
+
return if conflicting_field_errors.empty?
|
14
|
+
raise RDStation::Error::ConflictingField, conflicting_field_errors.first
|
17
15
|
end
|
18
16
|
|
19
17
|
private
|
20
18
|
|
21
|
-
def
|
22
|
-
error['error_type'] == ERROR_CODE
|
19
|
+
def conflicting_field_errors
|
20
|
+
errors.select { |error| error['error_type'] == ERROR_CODE }
|
23
21
|
end
|
24
22
|
end
|
25
23
|
end
|
@@ -1,18 +1,14 @@
|
|
1
1
|
module RDStation
|
2
2
|
class ErrorHandler
|
3
3
|
class Default
|
4
|
-
attr_reader :
|
5
|
-
EXCEPTION_CLASS = RDStation::Error::Default
|
4
|
+
attr_reader :errors
|
6
5
|
|
7
|
-
def initialize(
|
8
|
-
@
|
6
|
+
def initialize(errors)
|
7
|
+
@errors = errors
|
9
8
|
end
|
10
9
|
|
11
10
|
def raise_error
|
12
|
-
raise RDStation::Error::Default.
|
13
|
-
'An unrecognized error has occurred.',
|
14
|
-
api_response
|
15
|
-
)
|
11
|
+
raise RDStation::Error::Default, errors.first
|
16
12
|
end
|
17
13
|
end
|
18
14
|
end
|
@@ -1,29 +1,33 @@
|
|
1
1
|
module RDStation
|
2
2
|
class ErrorHandler
|
3
3
|
class ExpiredAccessToken
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :errors
|
5
5
|
|
6
|
-
|
6
|
+
EXPIRED_TOKEN_ERROR = 'error="expired_token"'.freeze
|
7
7
|
|
8
|
-
def initialize(
|
9
|
-
@
|
10
|
-
@error = JSON.parse(api_response.body)['errors']
|
11
|
-
@response_headers = api_response.headers
|
8
|
+
def initialize(errors)
|
9
|
+
@errors = errors
|
12
10
|
end
|
13
11
|
|
14
12
|
def raise_error
|
15
|
-
return
|
16
|
-
raise
|
13
|
+
return if expired_token_errors.empty?
|
14
|
+
raise RDStation::Error::ExpiredAccessToken, expired_token_errors.first
|
17
15
|
end
|
18
16
|
|
19
17
|
private
|
20
18
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
19
|
+
def expired_token_errors
|
20
|
+
errors.select do |error|
|
21
|
+
error_header = error['headers']
|
22
|
+
next unless error_header
|
23
|
+
expired_token_error?(error_header)
|
24
|
+
end
|
25
|
+
end
|
24
26
|
|
27
|
+
def expired_token_error?(error_header)
|
28
|
+
auth_header = error_header['x-amzn-remapped-www-authenticate'] || error_header['www-authenticate']
|
25
29
|
return unless auth_header
|
26
|
-
auth_header.include?(
|
30
|
+
auth_header.include?(EXPIRED_TOKEN_ERROR)
|
27
31
|
end
|
28
32
|
end
|
29
33
|
end
|
@@ -1,26 +1,23 @@
|
|
1
1
|
module RDStation
|
2
2
|
class ErrorHandler
|
3
3
|
class ExpiredCodeGrant
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :errors
|
5
5
|
|
6
6
|
ERROR_CODE = 'EXPIRED_CODE_GRANT'.freeze
|
7
|
-
EXCEPTION_CLASS = RDStation::Error::ExpiredCodeGrant
|
8
7
|
|
9
|
-
def initialize(
|
10
|
-
@
|
11
|
-
@error = JSON.parse(api_response.body)['errors']
|
12
|
-
@response_headers = api_response.headers
|
8
|
+
def initialize(errors)
|
9
|
+
@errors = errors
|
13
10
|
end
|
14
11
|
|
15
12
|
def raise_error
|
16
|
-
return
|
17
|
-
raise
|
13
|
+
return if expired_code_errors.empty?
|
14
|
+
raise RDStation::Error::ExpiredCodeGrant, expired_code_errors.first
|
18
15
|
end
|
19
16
|
|
20
17
|
private
|
21
18
|
|
22
|
-
def
|
23
|
-
error['error_type'] == ERROR_CODE
|
19
|
+
def expired_code_errors
|
20
|
+
errors.select { |error| error['error_type'] == ERROR_CODE }
|
24
21
|
end
|
25
22
|
end
|
26
23
|
end
|
@@ -1,25 +1,23 @@
|
|
1
1
|
module RDStation
|
2
2
|
class ErrorHandler
|
3
3
|
class InvalidCredentials
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :errors
|
5
5
|
|
6
6
|
ERROR_CODE = 'ACCESS_DENIED'.freeze
|
7
|
-
EXCEPTION_CLASS = RDStation::Error::InvalidCredentials
|
8
7
|
|
9
|
-
def initialize(
|
10
|
-
@
|
11
|
-
@error = JSON.parse(api_response.body)['errors']
|
8
|
+
def initialize(errors)
|
9
|
+
@errors = errors
|
12
10
|
end
|
13
11
|
|
14
12
|
def raise_error
|
15
|
-
return
|
16
|
-
raise
|
13
|
+
return if invalid_credentials_error.empty?
|
14
|
+
raise RDStation::Error::InvalidCredentials, invalid_credentials_error.first
|
17
15
|
end
|
18
16
|
|
19
17
|
private
|
20
18
|
|
21
|
-
def
|
22
|
-
error['error_type'] == ERROR_CODE
|
19
|
+
def invalid_credentials_error
|
20
|
+
errors.select { |error| error['error_type'] == ERROR_CODE }
|
23
21
|
end
|
24
22
|
end
|
25
23
|
end
|
@@ -1,25 +1,23 @@
|
|
1
1
|
module RDStation
|
2
2
|
class ErrorHandler
|
3
3
|
class ResourceNotFound
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :errors
|
5
5
|
|
6
6
|
ERROR_CODE = 'RESOURCE_NOT_FOUND'.freeze
|
7
|
-
EXCEPTION_CLASS = RDStation::Error::ResourceNotFound
|
8
7
|
|
9
|
-
def initialize(
|
10
|
-
@
|
11
|
-
@error = JSON.parse(api_response.body)['errors']
|
8
|
+
def initialize(errors)
|
9
|
+
@errors = errors
|
12
10
|
end
|
13
11
|
|
14
12
|
def raise_error
|
15
|
-
return
|
16
|
-
raise
|
13
|
+
return if resource_not_found_errors.empty?
|
14
|
+
raise RDStation::Error::ResourceNotFound, resource_not_found_errors.first
|
17
15
|
end
|
18
16
|
|
19
17
|
private
|
20
18
|
|
21
|
-
def
|
22
|
-
error['error_type'] == ERROR_CODE
|
19
|
+
def resource_not_found_errors
|
20
|
+
errors.select { |error| error['error_type'] == ERROR_CODE }
|
23
21
|
end
|
24
22
|
end
|
25
23
|
end
|
@@ -1,25 +1,23 @@
|
|
1
1
|
module RDStation
|
2
2
|
class ErrorHandler
|
3
3
|
class Unauthorized
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :errors
|
5
5
|
|
6
6
|
ERROR_CODE = 'UNAUTHORIZED'.freeze
|
7
|
-
EXCEPTION_CLASS = RDStation::Error::Unauthorized
|
8
7
|
|
9
|
-
def initialize(
|
10
|
-
@
|
11
|
-
@error = JSON.parse(api_response.body)['errors']
|
8
|
+
def initialize(errors)
|
9
|
+
@errors = errors
|
12
10
|
end
|
13
11
|
|
14
12
|
def raise_error
|
15
|
-
return
|
16
|
-
raise
|
13
|
+
return if unauthorized_errors.empty?
|
14
|
+
raise RDStation::Error::Unauthorized, unauthorized_errors.first
|
17
15
|
end
|
18
16
|
|
19
17
|
private
|
20
18
|
|
21
|
-
def
|
22
|
-
error['error_type'] == ERROR_CODE
|
19
|
+
def unauthorized_errors
|
20
|
+
errors.select { |error| error['error_type'] == ERROR_CODE }
|
23
21
|
end
|
24
22
|
end
|
25
23
|
end
|
data/lib/rdstation/version.rb
CHANGED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RDStation::Error::Format do
|
4
|
+
describe '#format' do
|
5
|
+
subject(:error_format) { described_class.new(errors) }
|
6
|
+
|
7
|
+
context 'when receives a flat hash of errors' do
|
8
|
+
let(:errors) do
|
9
|
+
{
|
10
|
+
'error_type' => 'CONFLICTING_FIELD',
|
11
|
+
'error_message' => 'The payload contains an attribute that was used to identify the lead'
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'returns the FLAT_HASH format' do
|
16
|
+
result = error_format.format
|
17
|
+
expect(result).to eq(RDStation::Error::Format::FLAT_HASH)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'when receives a hash of arrays of errors' do
|
22
|
+
let(:errors) do
|
23
|
+
{
|
24
|
+
'name' => [
|
25
|
+
{
|
26
|
+
'error_type' => 'MUST_BE_STRING',
|
27
|
+
'error_message' => 'Name must be string.'
|
28
|
+
}
|
29
|
+
]
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'returns the HASH_OF_ARRAYS format' do
|
34
|
+
result = error_format.format
|
35
|
+
expect(result).to eq(RDStation::Error::Format::HASH_OF_ARRAYS)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'when receives an array of errors' do
|
40
|
+
let(:errors) do
|
41
|
+
[
|
42
|
+
{
|
43
|
+
'error_type' => 'CANNOT_BE_NULL',
|
44
|
+
'error_message' => 'Cannot be null.',
|
45
|
+
'path' => 'body.client_secret'
|
46
|
+
}
|
47
|
+
]
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'returns the ARRAY_OF_HASHES format' do
|
51
|
+
result = error_format.format
|
52
|
+
expect(result).to eq(RDStation::Error::Format::ARRAY_OF_HASHES)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RDStation::Error::Formatter do
|
4
|
+
describe '#to_array' do
|
5
|
+
before do
|
6
|
+
allow(RDStation::Error::Format).to receive(:new).and_return(error_format)
|
7
|
+
end
|
8
|
+
|
9
|
+
context 'when receives a flat hash of errors' do
|
10
|
+
let(:error_format) { instance_double(RDStation::Error::Format, format: RDStation::Error::Format::FLAT_HASH) }
|
11
|
+
|
12
|
+
let(:errors) do
|
13
|
+
{
|
14
|
+
'error_type' => 'CONFLICTING_FIELD',
|
15
|
+
'error_message' => 'The payload contains an attribute that was used to identify the lead'
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:error_formatter) { described_class.new(errors) }
|
20
|
+
|
21
|
+
let(:expected_result) do
|
22
|
+
[
|
23
|
+
{
|
24
|
+
'error_type' => 'CONFLICTING_FIELD',
|
25
|
+
'error_message' => 'The payload contains an attribute that was used to identify the lead'
|
26
|
+
}
|
27
|
+
]
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'returns an array of errors including the status code and headers' do
|
31
|
+
result = error_formatter.to_array
|
32
|
+
expect(result).to eq(expected_result)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when receives a hash of arrays of errors' do
|
37
|
+
let(:error_format) { instance_double(RDStation::Error::Format, format: RDStation::Error::Format::HASH_OF_ARRAYS) }
|
38
|
+
|
39
|
+
let(:errors) do
|
40
|
+
{
|
41
|
+
'name' => [
|
42
|
+
{
|
43
|
+
'error_type' => 'MUST_BE_STRING',
|
44
|
+
'error_message' => 'Name must be string.'
|
45
|
+
}
|
46
|
+
]
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
let(:error_formatter) { described_class.new(errors) }
|
51
|
+
|
52
|
+
let(:expected_result) do
|
53
|
+
[
|
54
|
+
{
|
55
|
+
'error_type' => 'MUST_BE_STRING',
|
56
|
+
'error_message' => 'Name must be string.',
|
57
|
+
'path' => 'body.name'
|
58
|
+
}
|
59
|
+
]
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'returns an array of errors including the status code and headers' do
|
63
|
+
result = error_formatter.to_array
|
64
|
+
expect(result).to eq(expected_result)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'when receives an array of errors' do
|
69
|
+
let(:error_format) { instance_double(RDStation::Error::Format, format: RDStation::Error::Format::ARRAY_OF_HASHES) }
|
70
|
+
|
71
|
+
let(:errors) do
|
72
|
+
[
|
73
|
+
{
|
74
|
+
'error_type' => 'CANNOT_BE_NULL',
|
75
|
+
'error_message' => 'Cannot be null.',
|
76
|
+
'path' => 'body.client_secret'
|
77
|
+
}
|
78
|
+
]
|
79
|
+
end
|
80
|
+
|
81
|
+
let(:error_formatter) { described_class.new(errors) }
|
82
|
+
|
83
|
+
let(:expected_result) do
|
84
|
+
[
|
85
|
+
{
|
86
|
+
'error_type' => 'CANNOT_BE_NULL',
|
87
|
+
'error_message' => 'Cannot be null.',
|
88
|
+
'path' => 'body.client_secret'
|
89
|
+
}
|
90
|
+
]
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'returns an array of errors including the status code and headers' do
|
94
|
+
result = error_formatter.to_array
|
95
|
+
expect(result).to eq(expected_result)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RDStation::ErrorHandler::ConflictingField do
|
4
|
+
describe '#raise_error' do
|
5
|
+
subject(:conflicting_field_errors) { described_class.new(errors) }
|
6
|
+
|
7
|
+
context 'when none of the errors are conflicting field errors' do
|
8
|
+
let(:errors) do
|
9
|
+
[
|
10
|
+
{
|
11
|
+
'error_type' => 'RANDOM_ERROR_TYPE',
|
12
|
+
'error_message' => 'Random error message'
|
13
|
+
}
|
14
|
+
]
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'does not raise the error' do
|
18
|
+
result = conflicting_field_errors.raise_error
|
19
|
+
expect(result).to be_nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when there is a conflict field errors' do
|
24
|
+
let(:errors) do
|
25
|
+
[
|
26
|
+
{
|
27
|
+
'error_type' => 'CONFLICTING_FIELD',
|
28
|
+
'error_message' => 'The payload contains an attribute that was used to identify the lead'
|
29
|
+
}
|
30
|
+
]
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'raises the error' do
|
34
|
+
expect do
|
35
|
+
conflicting_field_errors.raise_error
|
36
|
+
end.to raise_error(RDStation::Error::ConflictingField)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'when there are no errors' do
|
41
|
+
let(:errors) { [] }
|
42
|
+
|
43
|
+
it 'does not raise the error' do
|
44
|
+
result = conflicting_field_errors.raise_error
|
45
|
+
expect(result).to be_nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RDStation::ErrorHandler::Default do
|
4
|
+
describe '#raise_error' do
|
5
|
+
let(:errors) { [{ 'error_message' => 'Error Message' }] }
|
6
|
+
let(:default_error) { described_class.new(errors) }
|
7
|
+
|
8
|
+
it 'raises the received error' do
|
9
|
+
expect do
|
10
|
+
default_error.raise_error
|
11
|
+
end.to raise_error(RDStation::Error::Default, errors.first['error_message'])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RDStation::ErrorHandler::ExpiredAccessToken do
|
4
|
+
describe '#raise_error' do
|
5
|
+
|
6
|
+
subject(:expired_access_token_error) { described_class.new(errors) }
|
7
|
+
|
8
|
+
context 'when there is an expired token error' do
|
9
|
+
let(:errors) do
|
10
|
+
[
|
11
|
+
{
|
12
|
+
'headers' => {
|
13
|
+
'www-authenticate' => 'Bearer realm="https://api.rd.services/", error="expired_token", error_description="The access token expired"'
|
14
|
+
},
|
15
|
+
'error_message' => 'Error Message',
|
16
|
+
'error_type' => 'EXPIRED_TOKEN_ERROR'
|
17
|
+
}
|
18
|
+
]
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'raises an ExpiredAccessToken error' do
|
22
|
+
expect do
|
23
|
+
expired_access_token_error.raise_error
|
24
|
+
end.to raise_error(RDStation::Error::ExpiredAccessToken, 'Error Message')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'when the errors does not contain a header' do
|
29
|
+
let(:errors) do
|
30
|
+
[
|
31
|
+
{
|
32
|
+
'error_message' => 'Error Message',
|
33
|
+
'error_type' => 'RANDOM_ERROR_TYPE'
|
34
|
+
},
|
35
|
+
{
|
36
|
+
'error_message' => 'Another Error Message',
|
37
|
+
'error_type' => 'ANOTHER_RANDOM_ERROR_TYPE'
|
38
|
+
}
|
39
|
+
]
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'does not raise an ExpiredAccessToken error' do
|
43
|
+
result = expired_access_token_error.raise_error
|
44
|
+
expect(result).to be_nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'when none of the errors are expired token errors' do
|
49
|
+
let(:errors) do
|
50
|
+
[
|
51
|
+
{
|
52
|
+
'headers' => {
|
53
|
+
'Content-Type' => 'application/json'
|
54
|
+
},
|
55
|
+
'error_message' => 'Error Message',
|
56
|
+
'error_type' => 'RANDOM_ERROR_TYPE'
|
57
|
+
},
|
58
|
+
{
|
59
|
+
'headers' => {
|
60
|
+
'Content-Type' => 'application/json'
|
61
|
+
},
|
62
|
+
'error_message' => 'Another Error Message',
|
63
|
+
'error_type' => 'ANOTHER_RANDOM_ERROR_TYPE'
|
64
|
+
}
|
65
|
+
]
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'does not raise an ExpiredAccessToken error' do
|
69
|
+
result = expired_access_token_error.raise_error
|
70
|
+
expect(result).to be_nil
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'when there are no errors' do
|
75
|
+
let(:errors) { [] }
|
76
|
+
|
77
|
+
it 'does not raise an ExpiredAccessToken error' do
|
78
|
+
result = expired_access_token_error.raise_error
|
79
|
+
expect(result).to be_nil
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'when the expired token header is x-amzn-remapped-www-authenticate' do
|
84
|
+
let(:errors) do
|
85
|
+
[
|
86
|
+
{
|
87
|
+
'headers' => {
|
88
|
+
'x-amzn-remapped-www-authenticate' => 'Bearer realm="https://api.rd.services/", error="expired_token", error_description="The access token expired"'
|
89
|
+
},
|
90
|
+
'error_message' => 'Error Message',
|
91
|
+
'error_type' => 'EXPIRED_TOKEN_ERROR'
|
92
|
+
}
|
93
|
+
]
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'raises an ExpiredAccessToken error' do
|
97
|
+
expect do
|
98
|
+
expired_access_token_error.raise_error
|
99
|
+
end.to raise_error(RDStation::Error::ExpiredAccessToken, 'Error Message')
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RDStation::ErrorHandler::ExpiredCodeGrant do
|
4
|
+
describe '#raise_error' do
|
5
|
+
|
6
|
+
subject(:expired_code_grant_error) { described_class.new(errors) }
|
7
|
+
|
8
|
+
context 'when there is an expired code grant error' do
|
9
|
+
let(:errors) do
|
10
|
+
[
|
11
|
+
{
|
12
|
+
'error_message' => 'Error Message',
|
13
|
+
'error_type' => 'EXPIRED_CODE_GRANT'
|
14
|
+
}
|
15
|
+
]
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'raises an ExpiredCodeGrant error' do
|
19
|
+
expect do
|
20
|
+
expired_code_grant_error.raise_error
|
21
|
+
end.to raise_error(RDStation::Error::ExpiredCodeGrant, 'Error Message')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when none of the errors are expired code grant errors' do
|
26
|
+
let(:errors) do
|
27
|
+
[
|
28
|
+
{
|
29
|
+
'error_message' => 'Error Message',
|
30
|
+
'error_type' => 'RANDOM_ERROR_TYPE'
|
31
|
+
},
|
32
|
+
{
|
33
|
+
'error_message' => 'Another Error Message',
|
34
|
+
'error_type' => 'ANOTHER_RANDOM_ERROR_TYPE'
|
35
|
+
}
|
36
|
+
]
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'does not raise an ExpiredCodeGrant error' do
|
40
|
+
result = expired_code_grant_error.raise_error
|
41
|
+
expect(result).to be_nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when there are no errors' do
|
46
|
+
let(:errors) { [] }
|
47
|
+
|
48
|
+
it 'does not raise an ExpiredCodeGrant error' do
|
49
|
+
result = expired_code_grant_error.raise_error
|
50
|
+
expect(result).to be_nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RDStation::ErrorHandler::InvalidCredentials do
|
4
|
+
describe '#raise_error' do
|
5
|
+
|
6
|
+
subject(:invalid_credentials_error) { described_class.new(errors) }
|
7
|
+
|
8
|
+
context 'when there are invalid credentials errors' do
|
9
|
+
let(:errors) do
|
10
|
+
[
|
11
|
+
{
|
12
|
+
'error_message' => 'Error Message',
|
13
|
+
'error_type' => 'ACCESS_DENIED'
|
14
|
+
}
|
15
|
+
]
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'raises an InvalidCredentials error' do
|
19
|
+
expect do
|
20
|
+
invalid_credentials_error.raise_error
|
21
|
+
end.to raise_error(RDStation::Error::InvalidCredentials, 'Error Message')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when none of the errors are invalid credentials errors' do
|
26
|
+
let(:errors) do
|
27
|
+
[
|
28
|
+
{
|
29
|
+
'error_message' => 'Error Message',
|
30
|
+
'error_type' => 'RANDOM_ERROR_TYPE'
|
31
|
+
},
|
32
|
+
{
|
33
|
+
'error_message' => 'Another Error Message',
|
34
|
+
'error_type' => 'ANOTHER_RANDOM_ERROR_TYPE'
|
35
|
+
}
|
36
|
+
]
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'does not raise an InvalidCredentials error' do
|
40
|
+
result = invalid_credentials_error.raise_error
|
41
|
+
expect(result).to be_nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when there are no errors' do
|
46
|
+
let(:errors) { [] }
|
47
|
+
|
48
|
+
it 'does not raise an InvalidCredentials error' do
|
49
|
+
result = invalid_credentials_error.raise_error
|
50
|
+
expect(result).to be_nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RDStation::ErrorHandler::ResourceNotFound do
|
4
|
+
describe '#raise_error' do
|
5
|
+
|
6
|
+
subject(:resource_not_found_error) { described_class.new(errors) }
|
7
|
+
|
8
|
+
context 'when there is a resource not found error' do
|
9
|
+
let(:errors) do
|
10
|
+
[
|
11
|
+
{
|
12
|
+
'error_message' => 'Error Message',
|
13
|
+
'error_type' => 'RESOURCE_NOT_FOUND'
|
14
|
+
}
|
15
|
+
]
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'raises an ResourceNotFound error' do
|
19
|
+
expect do
|
20
|
+
resource_not_found_error.raise_error
|
21
|
+
end.to raise_error(RDStation::Error::ResourceNotFound, 'Error Message')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when none of the errors are resource not found errors' do
|
26
|
+
let(:errors) do
|
27
|
+
[
|
28
|
+
{
|
29
|
+
'error_message' => 'Error Message',
|
30
|
+
'error_type' => 'RANDOM_ERROR_TYPE'
|
31
|
+
},
|
32
|
+
{
|
33
|
+
'error_message' => 'Another Error Message',
|
34
|
+
'error_type' => 'ANOTHER_RANDOM_ERROR_TYPE'
|
35
|
+
}
|
36
|
+
]
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'does not raise an ResourceNotFound error' do
|
40
|
+
result = resource_not_found_error.raise_error
|
41
|
+
expect(result).to be_nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when there are no errors' do
|
46
|
+
let(:errors) { [] }
|
47
|
+
|
48
|
+
it 'does not raise an ResourceNotFound error' do
|
49
|
+
result = resource_not_found_error.raise_error
|
50
|
+
expect(result).to be_nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RDStation::ErrorHandler::Unauthorized do
|
4
|
+
describe '#raise_error' do
|
5
|
+
|
6
|
+
subject(:unauthorized_error) { described_class.new(errors) }
|
7
|
+
|
8
|
+
context 'when there is an unauthorized error' do
|
9
|
+
let(:errors) do
|
10
|
+
[
|
11
|
+
{
|
12
|
+
'error_message' => 'Error Message',
|
13
|
+
'error_type' => 'UNAUTHORIZED'
|
14
|
+
}
|
15
|
+
]
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'raises an Unauthorized error' do
|
19
|
+
expect do
|
20
|
+
unauthorized_error.raise_error
|
21
|
+
end.to raise_error(RDStation::Error::Unauthorized, 'Error Message')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when none of the errors are unauthorized errors' do
|
26
|
+
let(:errors) do
|
27
|
+
[
|
28
|
+
{
|
29
|
+
'error_message' => 'Error Message',
|
30
|
+
'error_type' => 'RANDOM_ERROR_TYPE'
|
31
|
+
},
|
32
|
+
{
|
33
|
+
'error_message' => 'Another Error Message',
|
34
|
+
'error_type' => 'ANOTHER_RANDOM_ERROR_TYPE'
|
35
|
+
}
|
36
|
+
]
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'does not raise an Unauthorized error' do
|
40
|
+
result = unauthorized_error.raise_error
|
41
|
+
expect(result).to be_nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when there are no errors' do
|
46
|
+
let(:errors) { [] }
|
47
|
+
|
48
|
+
it 'does not raise an Unauthorized error' do
|
49
|
+
result = unauthorized_error.raise_error
|
50
|
+
expect(result).to be_nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RDStation::ErrorHandler do
|
4
|
+
describe '#raise_errors' do
|
5
|
+
subject(:error_handler) { described_class.new(error_response) }
|
6
|
+
|
7
|
+
context 'when the error type is recognized' do
|
8
|
+
let(:error_response) do
|
9
|
+
OpenStruct.new(
|
10
|
+
code: 400,
|
11
|
+
body: {
|
12
|
+
'errors' => {
|
13
|
+
'error_type' => 'CONFLICTING_FIELD',
|
14
|
+
'error_message' => 'Error Message'
|
15
|
+
}
|
16
|
+
}.to_json
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'raises the corresponding error class' do
|
21
|
+
expect { error_handler.raise_errors }.to raise_error(RDStation::Error::ConflictingField, 'Error Message')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when the error type is not recognized' do
|
26
|
+
let(:error_response) do
|
27
|
+
OpenStruct.new(
|
28
|
+
code: 400,
|
29
|
+
headers: { 'Content-Type' => 'application/json' },
|
30
|
+
body: {
|
31
|
+
'errors' => {
|
32
|
+
'error_type' => 'UNRECOGNIZED_ERROR_TYPE',
|
33
|
+
'error_message' => 'Error Message'
|
34
|
+
}
|
35
|
+
}.to_json
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'raises the Default error' do
|
40
|
+
expect { error_handler.raise_errors }.to raise_error(RDStation::Error::Default, 'Error Message') do |error|
|
41
|
+
expect(error.details).to be
|
42
|
+
expect(error.headers).to be
|
43
|
+
expect(error.body).to be
|
44
|
+
expect(error.http_status).to be
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RDStation::Error do
|
4
|
+
describe '.new' do
|
5
|
+
context 'with a valid details hash' do
|
6
|
+
let(:error_details) { { 'error_message' => 'message', 'error_type' => 'ERROR_TYPE' } }
|
7
|
+
let(:result) { described_class.new(error_details) }
|
8
|
+
|
9
|
+
it 'creates a new instance of errors with details' do
|
10
|
+
expect(result.details).to eq(error_details)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'with an invalid details hash' do
|
15
|
+
let(:error_details) { { 'error_type' => 'ERROR_TYPE' } }
|
16
|
+
|
17
|
+
it 'raises an invalid argument error' do
|
18
|
+
expect do
|
19
|
+
described_class.new(error_details)
|
20
|
+
end.to raise_error(ArgumentError, 'The details hash must contain an error message')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rdstation-ruby-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paulo L F Casaretto
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-11-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -112,6 +112,8 @@ files:
|
|
112
112
|
- lib/rdstation/client.rb
|
113
113
|
- lib/rdstation/contacts.rb
|
114
114
|
- lib/rdstation/error.rb
|
115
|
+
- lib/rdstation/error/format.rb
|
116
|
+
- lib/rdstation/error/formatter.rb
|
115
117
|
- lib/rdstation/error_handler.rb
|
116
118
|
- lib/rdstation/error_handler/conflicting_field.rb
|
117
119
|
- lib/rdstation/error_handler/default.rb
|
@@ -126,6 +128,17 @@ files:
|
|
126
128
|
- spec/lib/rdstation-ruby-client_spec.rb
|
127
129
|
- spec/lib/rdstation/authentication_spec.rb
|
128
130
|
- spec/lib/rdstation/contacts_spec.rb
|
131
|
+
- spec/lib/rdstation/error/format_spec.rb
|
132
|
+
- spec/lib/rdstation/error/formatter_spec.rb
|
133
|
+
- spec/lib/rdstation/error_handler/conflicting_field_spec.rb
|
134
|
+
- spec/lib/rdstation/error_handler/default_spec.rb
|
135
|
+
- spec/lib/rdstation/error_handler/expired_access_token_spec.rb
|
136
|
+
- spec/lib/rdstation/error_handler/expired_code_grant_spec.rb
|
137
|
+
- spec/lib/rdstation/error_handler/invalid_credentials_spec.rb
|
138
|
+
- spec/lib/rdstation/error_handler/resource_not_found_spec.rb
|
139
|
+
- spec/lib/rdstation/error_handler/unauthorized_spec.rb
|
140
|
+
- spec/lib/rdstation/error_handler_spec.rb
|
141
|
+
- spec/lib/rdstation/error_spec.rb
|
129
142
|
- spec/lib/rdstation/fields_spec.rb
|
130
143
|
- spec/spec_helper.rb
|
131
144
|
homepage: http://resultadosdigitais.com.br
|
@@ -148,7 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
161
|
version: '0'
|
149
162
|
requirements: []
|
150
163
|
rubyforge_project:
|
151
|
-
rubygems_version: 2.
|
164
|
+
rubygems_version: 2.5.2
|
152
165
|
signing_key:
|
153
166
|
specification_version: 4
|
154
167
|
summary: Ruby API wrapper for RD Station
|
@@ -156,5 +169,16 @@ test_files:
|
|
156
169
|
- spec/lib/rdstation-ruby-client_spec.rb
|
157
170
|
- spec/lib/rdstation/authentication_spec.rb
|
158
171
|
- spec/lib/rdstation/contacts_spec.rb
|
172
|
+
- spec/lib/rdstation/error/format_spec.rb
|
173
|
+
- spec/lib/rdstation/error/formatter_spec.rb
|
174
|
+
- spec/lib/rdstation/error_handler/conflicting_field_spec.rb
|
175
|
+
- spec/lib/rdstation/error_handler/default_spec.rb
|
176
|
+
- spec/lib/rdstation/error_handler/expired_access_token_spec.rb
|
177
|
+
- spec/lib/rdstation/error_handler/expired_code_grant_spec.rb
|
178
|
+
- spec/lib/rdstation/error_handler/invalid_credentials_spec.rb
|
179
|
+
- spec/lib/rdstation/error_handler/resource_not_found_spec.rb
|
180
|
+
- spec/lib/rdstation/error_handler/unauthorized_spec.rb
|
181
|
+
- spec/lib/rdstation/error_handler_spec.rb
|
182
|
+
- spec/lib/rdstation/error_spec.rb
|
159
183
|
- spec/lib/rdstation/fields_spec.rb
|
160
184
|
- spec/spec_helper.rb
|