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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c632e94efb06e81ab00f5272d042b0c5b26cf55f
4
- data.tar.gz: c947e738844beb8671118a0d76df0468f8361528
3
+ metadata.gz: ea20e4d5e37030b98d697da5b71892ff892a3204
4
+ data.tar.gz: 027a431a05b01d94279b40d194d334d8a5235cf4
5
5
  SHA512:
6
- metadata.gz: edc33857fcf8af5535d2446da9d0cd3327cd2a092b47d722cb1107887ff649f127a65c301cb80e45c4fae9997713e568eb88b81cfe72498971bbc348f07e6a4e
7
- data.tar.gz: cd2315fe944d7790336f50586ad68ef9240092550ca75e2b8327863f880d59ba36ccb8a0012cf9d9fefda4901d2d2ab348a033a51812488136d38c463f7d94de
6
+ metadata.gz: 7a1bedc3f94bd5f532ab9073d0abc9651ef1a9159e0b339b13b9061e8c476967683b5a66bb659a12a6848fc7396a854be6153655acab97bef9f205ad50ada11b
7
+ data.tar.gz: ebbf843ae9cc9293850070b0b40cf638a8e1a7e61655f2022def1d01e3987b78dd2a4227e43ccb403a28d3e941f3813238595b542b6978433ecc86e1462fdd20
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rdstation-ruby-client (1.0.0)
4
+ rdstation-ruby-client (1.0.1)
5
5
  httparty (~> 0.12)
6
6
 
7
7
  GEM
@@ -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
- errors.each(&:raise_error)
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
- def errors
35
- ERROR_TYPES.map { |error| error.new(@response) }
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 :api_response, :response_body, :error
4
+ attr_reader :errors
5
5
 
6
6
  ERROR_CODE = 'CONFLICTING_FIELD'.freeze
7
- EXCEPTION_CLASS = RDStation::Error::ConflictingField
8
7
 
9
- def initialize(api_response)
10
- @api_response = api_response
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 unless conflicting_field?
16
- raise EXCEPTION_CLASS.new(error['error_message'], api_response)
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 conflicting_field?
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 :api_response
5
- EXCEPTION_CLASS = RDStation::Error::Default
4
+ attr_reader :errors
6
5
 
7
- def initialize(api_response)
8
- @api_response = api_response
6
+ def initialize(errors)
7
+ @errors = errors
9
8
  end
10
9
 
11
10
  def raise_error
12
- raise RDStation::Error::Default.new(
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 :api_response, :response_headers, :error
4
+ attr_reader :errors
5
5
 
6
- EXCEPTION_CLASS = RDStation::Error::ExpiredAccessToken
6
+ EXPIRED_TOKEN_ERROR = 'error="expired_token"'.freeze
7
7
 
8
- def initialize(api_response)
9
- @api_response = api_response
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 unless expired_token?
16
- raise EXCEPTION_CLASS.new(error['error_message'], api_response)
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 expired_token?
22
- auth_header = response_headers['x-amzn-remapped-www-authenticate'] ||
23
- response_headers['www-authenticate']
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?('error="expired_token"')
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 :api_response, :response_headers, :error
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(api_response)
10
- @api_response = api_response
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 unless expired_code?
17
- raise EXCEPTION_CLASS.new(error['error_message'], api_response)
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 expired_code?
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 :api_response, :error
4
+ attr_reader :errors
5
5
 
6
6
  ERROR_CODE = 'ACCESS_DENIED'.freeze
7
- EXCEPTION_CLASS = RDStation::Error::InvalidCredentials
8
7
 
9
- def initialize(api_response)
10
- @api_response = api_response
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 unless credentials_errors?
16
- raise EXCEPTION_CLASS.new(error['error_message'], api_response)
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 credentials_errors?
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 :api_response, :error
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(api_response)
10
- @api_response = api_response
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 unless resource_not_found?
16
- raise EXCEPTION_CLASS.new(error['error_message'], api_response)
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 resource_not_found?
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 :api_response, :response_body, :error
4
+ attr_reader :errors
5
5
 
6
6
  ERROR_CODE = 'UNAUTHORIZED'.freeze
7
- EXCEPTION_CLASS = RDStation::Error::Unauthorized
8
7
 
9
- def initialize(api_response)
10
- @api_response = api_response
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 unless unauthorized?
16
- raise EXCEPTION_CLASS.new(error['error_message'], api_response)
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 unauthorized?
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
@@ -1,3 +1,3 @@
1
1
  module RDStation
2
- VERSION = '1.0.0'.freeze
2
+ VERSION = '1.0.1'.freeze
3
3
  end
@@ -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.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-07-11 00:00:00.000000000 Z
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.6.13
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