rdstation-ruby-client 1.2.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,9 +3,9 @@ module RDStation
3
3
  # More info: https://developers.rdstation.com/pt-BR/reference/contacts
4
4
  class Contacts
5
5
  include HTTParty
6
-
7
- def initialize(auth_token)
8
- @auth_token = auth_token
6
+
7
+ def initialize(authorization_header:)
8
+ @authorization_header = authorization_header
9
9
  end
10
10
 
11
11
  #
@@ -13,12 +13,12 @@ module RDStation
13
13
  # The unique uuid associated to each RD Station Contact.
14
14
  #
15
15
  def by_uuid(uuid)
16
- response = self.class.get(base_url(uuid), headers: required_headers)
16
+ response = self.class.get(base_url(uuid), headers: @authorization_header.to_h)
17
17
  ApiResponse.build(response)
18
18
  end
19
19
 
20
20
  def by_email(email)
21
- response = self.class.get(base_url("email:#{email}"), headers: required_headers)
21
+ response = self.class.get(base_url("email:#{email}"), headers: @authorization_header.to_h)
22
22
  ApiResponse.build(response)
23
23
  end
24
24
 
@@ -34,7 +34,7 @@ module RDStation
34
34
  # :website
35
35
  # :tags
36
36
  def update(uuid, contact_hash)
37
- response = self.class.patch(base_url(uuid), :body => contact_hash.to_json, :headers => required_headers)
37
+ response = self.class.patch(base_url(uuid), :body => contact_hash.to_json, :headers => @authorization_header.to_h)
38
38
  ApiResponse.build(response)
39
39
  end
40
40
 
@@ -48,7 +48,7 @@ module RDStation
48
48
  #
49
49
  def upsert(identifier, identifier_value, contact_hash)
50
50
  path = "#{identifier}:#{identifier_value}"
51
- response = self.class.patch(base_url(path), body: contact_hash.to_json, headers: required_headers)
51
+ response = self.class.patch(base_url(path), body: contact_hash.to_json, headers: @authorization_header.to_h)
52
52
  ApiResponse.build(response)
53
53
  end
54
54
 
@@ -57,9 +57,5 @@ module RDStation
57
57
  def base_url(path = "")
58
58
  "https://api.rd.services/platform/contacts/#{path}"
59
59
  end
60
-
61
- def required_headers
62
- { "Authorization" => "Bearer #{@auth_token}", "Content-Type" => "application/json" }
63
- end
64
60
  end
65
61
  end
@@ -1,5 +1,4 @@
1
1
  module RDStation
2
-
3
2
  class Error < StandardError
4
3
  attr_reader :details, :http_status, :headers, :body
5
4
 
@@ -8,23 +7,31 @@ module RDStation
8
7
  message = details['error_message']
9
8
  raise ArgumentError, 'The details hash must contain an error message' unless message
10
9
 
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']
17
-
18
10
  super(message)
19
11
  end
20
12
 
21
- class ConflictingField < Error; end
22
- class Default < Error; end
23
- class ExpiredAccessToken < Error; end
24
- class ExpiredCodeGrant < Error; end
25
- class InvalidCredentials < Error; end
26
- class InvalidEventType < Error; end
27
- class ResourceNotFound < Error; end
13
+ class BadRequest < Error; end
28
14
  class Unauthorized < Error; end
15
+ class Forbidden < Error; end
16
+ class NotFound < Error; end
17
+ class MethodNotAllowed < Error; end
18
+ class NotAcceptable < Error; end
19
+ class Conflict < Error; end
20
+ class UnsupportedMediaType < Error; end
21
+ class UnprocessableEntity < Error; end
22
+ class InternalServerError < Error; end
23
+ class NotImplemented < Error; end
24
+ class BadGateway < Error; end
25
+ class ServiceUnavailable < Error; end
26
+ class ServerError < Error; end
27
+
28
+ # 400 - Bad Request
29
+ class ConflictingField < BadRequest; end
30
+ class InvalidEventType < BadRequest; end
31
+
32
+ # 401 - Unauthorized
33
+ class ExpiredAccessToken < Unauthorized; end
34
+ class ExpiredCodeGrant < Unauthorized; end
35
+ class InvalidCredentials < Unauthorized; end
29
36
  end
30
37
  end
@@ -1,37 +1,42 @@
1
1
  require_relative 'error/formatter'
2
- require_relative 'error_handler/conflicting_field'
3
- require_relative 'error_handler/default'
4
- require_relative 'error_handler/expired_access_token'
5
- require_relative 'error_handler/expired_code_grant'
6
- require_relative 'error_handler/invalid_credentials'
7
- require_relative 'error_handler/invalid_event_type'
8
- require_relative 'error_handler/resource_not_found'
2
+ require_relative 'error_handler/bad_request'
9
3
  require_relative 'error_handler/unauthorized'
10
4
 
11
5
  module RDStation
12
6
  class ErrorHandler
13
- ERROR_TYPES = [
14
- ErrorHandler::ConflictingField,
15
- ErrorHandler::ExpiredAccessToken,
16
- ErrorHandler::ExpiredCodeGrant,
17
- ErrorHandler::InvalidCredentials,
18
- ErrorHandler::InvalidEventType,
19
- ErrorHandler::ResourceNotFound,
20
- ErrorHandler::Unauthorized,
21
- ErrorHandler::Default
22
- ].freeze
23
-
24
7
  def initialize(response)
25
8
  @response = response
9
+ @code = response.code
26
10
  end
27
11
 
28
- def raise_errors
29
- error_types.each(&:raise_error)
12
+ def raise_error
13
+ raise error_class, array_of_errors.first if error_class < RDStation::Error
14
+
15
+ error_class.new(array_of_errors).raise_error
30
16
  end
31
17
 
32
18
  private
33
19
 
34
- attr_reader :response
20
+ attr_reader :response, :code
21
+
22
+ def error_class
23
+ case code
24
+ when 400 then RDStation::ErrorHandler::BadRequest
25
+ when 401 then RDStation::ErrorHandler::Unauthorized
26
+ when 403 then RDStation::Error::Forbidden
27
+ when 404 then RDStation::Error::NotFound
28
+ when 405 then RDStation::Error::MethodNotAllowed
29
+ when 406 then RDStation::Error::NotAcceptable
30
+ when 409 then RDStation::Error::Conflict
31
+ when 415 then RDStation::Error::UnsupportedMediaType
32
+ when 422 then RDStation::Error::UnprocessableEntity
33
+ when 500 then RDStation::Error::InternalServerError
34
+ when 501 then RDStation::Error::NotImplemented
35
+ when 502 then RDStation::Error::BadGateway
36
+ when 503 then RDStation::Error::ServiceUnavailable
37
+ when 500..599 then RDStation::Error::ServerError
38
+ end
39
+ end
35
40
 
36
41
  def array_of_errors
37
42
  error_formatter.to_array.map do |error|
@@ -39,10 +44,6 @@ module RDStation
39
44
  end
40
45
  end
41
46
 
42
- def error_types
43
- ERROR_TYPES.map { |error_type| error_type.new(array_of_errors) }
44
- end
45
-
46
47
  def response_errors
47
48
  JSON.parse(response.body)
48
49
  end
@@ -55,7 +56,7 @@ module RDStation
55
56
  {
56
57
  'headers' => response.headers,
57
58
  'body' => JSON.parse(response.body),
58
- 'http_status' => response.code
59
+ 'http_status' => response.code,
59
60
  }
60
61
  end
61
62
  end
@@ -0,0 +1,30 @@
1
+ require_relative 'conflicting_field'
2
+ require_relative 'invalid_event_type'
3
+
4
+ module RDStation
5
+ class ErrorHandler
6
+ class BadRequest
7
+ BAD_REQUEST_ERRORS = [
8
+ ErrorHandler::ConflictingField,
9
+ ErrorHandler::InvalidEventType,
10
+ ].freeze
11
+
12
+ def initialize(array_of_errors)
13
+ @array_of_errors = array_of_errors
14
+ end
15
+
16
+ def raise_error
17
+ error_classes.each(&:raise_error)
18
+ raise RDStation::Error::BadRequest, @array_of_errors.first
19
+ end
20
+
21
+ private
22
+
23
+ def error_classes
24
+ BAD_REQUEST_ERRORS.map do |error|
25
+ error.new(@array_of_errors)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,23 +1,31 @@
1
+ require_relative 'expired_access_token'
2
+ require_relative 'expired_code_grant'
3
+ require_relative 'invalid_credentials'
4
+
1
5
  module RDStation
2
6
  class ErrorHandler
3
7
  class Unauthorized
4
- attr_reader :errors
5
-
6
- ERROR_CODE = 'UNAUTHORIZED'.freeze
8
+ UNAUTHORIZED_ERRORS = [
9
+ ErrorHandler::ExpiredAccessToken,
10
+ ErrorHandler::ExpiredCodeGrant,
11
+ ErrorHandler::InvalidCredentials,
12
+ ].freeze
7
13
 
8
- def initialize(errors)
9
- @errors = errors
14
+ def initialize(array_of_errors)
15
+ @array_of_errors = array_of_errors
10
16
  end
11
17
 
12
18
  def raise_error
13
- return if unauthorized_errors.empty?
14
- raise RDStation::Error::Unauthorized, unauthorized_errors.first
19
+ error_classes.each(&:raise_error)
20
+ raise RDStation::Error::Unauthorized, @array_of_errors.first
15
21
  end
16
22
 
17
23
  private
18
24
 
19
- def unauthorized_errors
20
- errors.select { |error| error['error_type'] == ERROR_CODE }
25
+ def error_classes
26
+ UNAUTHORIZED_ERRORS.map do |error|
27
+ error.new(@array_of_errors)
28
+ end
21
29
  end
22
30
  end
23
31
  end
@@ -4,15 +4,15 @@ module RDStation
4
4
 
5
5
  EVENTS_ENDPOINT = 'https://api.rd.services/platform/events'.freeze
6
6
 
7
- def initialize(auth_token)
8
- @auth_token = auth_token
7
+ def initialize(authorization_header:)
8
+ @authorization_header = authorization_header
9
9
  end
10
10
 
11
11
  def create(payload)
12
- response = self.class.post(EVENTS_ENDPOINT, headers: required_headers, body: payload.to_json)
12
+ response = self.class.post(EVENTS_ENDPOINT, headers: @authorization_header.to_h, body: payload.to_json)
13
13
  response_body = JSON.parse(response.body)
14
14
  return response_body unless errors?(response_body)
15
- RDStation::ErrorHandler.new(response).raise_errors
15
+ RDStation::ErrorHandler.new(response).raise_error
16
16
  end
17
17
 
18
18
  private
@@ -20,12 +20,5 @@ module RDStation
20
20
  def errors?(response_body)
21
21
  response_body.is_a?(Array) || response_body['errors']
22
22
  end
23
-
24
- def required_headers
25
- {
26
- 'Authorization' => "Bearer #{@auth_token}",
27
- 'Content-Type' => 'application/json'
28
- }
29
- end
30
23
  end
31
24
  end
@@ -5,20 +5,15 @@ module RDStation
5
5
  include HTTParty
6
6
 
7
7
  BASE_URL = 'https://api.rd.services/platform/contacts/fields'.freeze
8
-
9
- def initialize(auth_token)
10
- @auth_token = auth_token
8
+
9
+ def initialize(authorization_header:)
10
+ @authorization_header = authorization_header
11
11
  end
12
12
 
13
13
  def all
14
- response = self.class.get(BASE_URL, headers: required_headers)
14
+ response = self.class.get(BASE_URL, headers: @authorization_header.to_h)
15
15
  ApiResponse.build(response)
16
16
  end
17
17
 
18
- private
19
-
20
- def required_headers
21
- { "Authorization" => "Bearer #{@auth_token}", "Content-Type" => "application/json" }
22
- end
23
18
  end
24
19
  end
@@ -1,3 +1,3 @@
1
1
  module RDStation
2
- VERSION = '1.2.1'.freeze
2
+ VERSION = '2.0.0'.freeze
3
3
  end
@@ -2,34 +2,34 @@ module RDStation
2
2
  class Webhooks
3
3
  include HTTParty
4
4
 
5
- def initialize(auth_token)
6
- @auth_token = auth_token
5
+ def initialize(authorization_header:)
6
+ @authorization_header = authorization_header
7
7
  end
8
8
 
9
9
  def all
10
- response = self.class.get(base_url, headers: required_headers)
10
+ response = self.class.get(base_url, headers: @authorization_header.to_h)
11
11
  ApiResponse.build(response)
12
12
  end
13
13
 
14
14
  def by_uuid(uuid)
15
- response = self.class.get(base_url(uuid), headers: required_headers)
15
+ response = self.class.get(base_url(uuid), headers: @authorization_header.to_h)
16
16
  ApiResponse.build(response)
17
17
  end
18
18
 
19
19
  def create(payload)
20
- response = self.class.post(base_url, headers: required_headers, body: payload.to_json)
20
+ response = self.class.post(base_url, headers: @authorization_header.to_h, body: payload.to_json)
21
21
  ApiResponse.build(response)
22
22
  end
23
23
 
24
24
  def update(uuid, payload)
25
- response = self.class.put(base_url(uuid), headers: required_headers, body: payload.to_json)
25
+ response = self.class.put(base_url(uuid), headers: @authorization_header.to_h, body: payload.to_json)
26
26
  ApiResponse.build(response)
27
27
  end
28
28
 
29
29
  def delete(uuid)
30
- response = self.class.delete(base_url(uuid), headers: required_headers)
30
+ response = self.class.delete(base_url(uuid), headers: @authorization_header.to_h)
31
31
  return webhook_deleted_message unless response.body
32
- RDStation::ErrorHandler.new(response).raise_errors
32
+ RDStation::ErrorHandler.new(response).raise_error
33
33
  end
34
34
 
35
35
  private
@@ -41,9 +41,5 @@ module RDStation
41
41
  def base_url(path = '')
42
42
  "https://api.rd.services/integrations/webhooks/#{path}"
43
43
  end
44
-
45
- def required_headers
46
- { 'Authorization' => "Bearer #{@auth_token}", 'Content-Type' => 'application/json' }
47
- end
48
44
  end
49
45
  end
@@ -18,6 +18,8 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
+ spec.required_ruby_version = '>= 2.0.0'
22
+
21
23
  spec.add_development_dependency "bundler", "~> 1.3"
22
24
  spec.add_development_dependency "rake"
23
25
  spec.add_development_dependency 'rspec'
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe RDStation do
4
4
  let(:rdstation_client) { RDStation::Client.new('token','private' ) }
5
5
  let(:lead_email) { "iginosms@gmail.com" }
6
- let(:amount) { 300}
6
+ let(:amount) { 300 }
7
7
 
8
8
 
9
9
  context "#change_lead_status" do
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RDStation::AuthorizationHeader do
4
+
5
+ describe ".initialize" do
6
+ context "when access_token is nil" do
7
+ it "raises an error" do
8
+ expect do
9
+ described_class.new(access_token: nil)
10
+ end.to raise_error(ArgumentError)
11
+ end
12
+ end
13
+ end
14
+
15
+ describe "#to_h" do
16
+ let(:access_token) { 'access_token' }
17
+
18
+ it "generates the correct header" do
19
+ header = described_class.new(access_token: access_token).to_h
20
+ expect(header['Authorization']).to eq "Bearer #{access_token}"
21
+ expect(header['Content-Type']).to eq "application/json"
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RDStation::Client do
4
+ context "when access_token is given" do
5
+ let(:access_token) { 'access_token' }
6
+ let(:client) { described_class.new(access_token: access_token) }
7
+ let(:mock_authorization_header) { double(RDStation::AuthorizationHeader) }
8
+
9
+ before { allow(RDStation::AuthorizationHeader).to receive(:new).and_return mock_authorization_header }
10
+
11
+ it 'returns Contacts endpoint' do
12
+ expect(RDStation::Contacts).to receive(:new).with({ authorization_header: mock_authorization_header }).and_call_original
13
+ expect(client.contacts).to be_instance_of RDStation::Contacts
14
+ end
15
+
16
+ it 'returns Events endpoint' do
17
+ expect(RDStation::Events).to receive(:new).with({ authorization_header: mock_authorization_header }).and_call_original
18
+ expect(client.events).to be_instance_of RDStation::Events
19
+ end
20
+
21
+ it 'returns Fields endpoint' do
22
+ expect(RDStation::Fields).to receive(:new).with({ authorization_header: mock_authorization_header }).and_call_original
23
+ expect(client.fields).to be_instance_of RDStation::Fields
24
+ end
25
+
26
+ it 'returns Webhooks endpoint' do
27
+ expect(RDStation::Webhooks).to receive(:new).with({ authorization_header: mock_authorization_header }).and_call_original
28
+ expect(client.webhooks).to be_instance_of RDStation::Webhooks
29
+ end
30
+ end
31
+
32
+ context "when access_token isn't given" do
33
+ it "raises an ArgumentError exception" do
34
+ expect{ described_class.new(access_token: nil) }.to raise_error(ArgumentError)
35
+ end
36
+ end
37
+ end