rdstation-ruby-client 0.1.1 → 1.0.0
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 +12 -12
- data/README.md +13 -13
- data/lib/rdstation-ruby-client.rb +11 -4
- data/lib/rdstation/authentication.rb +34 -21
- data/lib/rdstation/contacts.rb +26 -14
- data/lib/rdstation/error.rb +21 -0
- data/lib/rdstation/error_handler.rb +38 -0
- data/lib/rdstation/error_handler/conflicting_field.rb +26 -0
- data/lib/rdstation/error_handler/default.rb +19 -0
- data/lib/rdstation/error_handler/expired_access_token.rb +30 -0
- data/lib/rdstation/error_handler/expired_code_grant.rb +27 -0
- data/lib/rdstation/error_handler/invalid_credentials.rb +26 -0
- data/lib/rdstation/error_handler/resource_not_found.rb +26 -0
- data/lib/rdstation/error_handler/unauthorized.rb +26 -0
- data/lib/rdstation/fields.rb +26 -0
- data/lib/rdstation/version.rb +1 -1
- data/rdstation-ruby-client.gemspec +1 -2
- data/spec/lib/rdstation/authentication_spec.rb +177 -0
- data/spec/lib/rdstation/contacts_spec.rb +434 -0
- data/spec/lib/rdstation/fields_spec.rb +52 -0
- data/spec/spec_helper.rb +1 -13
- metadata +22 -20
@@ -0,0 +1,27 @@
|
|
1
|
+
module RDStation
|
2
|
+
class ErrorHandler
|
3
|
+
class ExpiredCodeGrant
|
4
|
+
attr_reader :api_response, :response_headers, :error
|
5
|
+
|
6
|
+
ERROR_CODE = 'EXPIRED_CODE_GRANT'.freeze
|
7
|
+
EXCEPTION_CLASS = RDStation::Error::ExpiredCodeGrant
|
8
|
+
|
9
|
+
def initialize(api_response)
|
10
|
+
@api_response = api_response
|
11
|
+
@error = JSON.parse(api_response.body)['errors']
|
12
|
+
@response_headers = api_response.headers
|
13
|
+
end
|
14
|
+
|
15
|
+
def raise_error
|
16
|
+
return unless expired_code?
|
17
|
+
raise EXCEPTION_CLASS.new(error['error_message'], api_response)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def expired_code?
|
23
|
+
error['error_type'] == ERROR_CODE
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module RDStation
|
2
|
+
class ErrorHandler
|
3
|
+
class InvalidCredentials
|
4
|
+
attr_reader :api_response, :error
|
5
|
+
|
6
|
+
ERROR_CODE = 'ACCESS_DENIED'.freeze
|
7
|
+
EXCEPTION_CLASS = RDStation::Error::InvalidCredentials
|
8
|
+
|
9
|
+
def initialize(api_response)
|
10
|
+
@api_response = api_response
|
11
|
+
@error = JSON.parse(api_response.body)['errors']
|
12
|
+
end
|
13
|
+
|
14
|
+
def raise_error
|
15
|
+
return unless credentials_errors?
|
16
|
+
raise EXCEPTION_CLASS.new(error['error_message'], api_response)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def credentials_errors?
|
22
|
+
error['error_type'] == ERROR_CODE
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module RDStation
|
2
|
+
class ErrorHandler
|
3
|
+
class ResourceNotFound
|
4
|
+
attr_reader :api_response, :error
|
5
|
+
|
6
|
+
ERROR_CODE = 'RESOURCE_NOT_FOUND'.freeze
|
7
|
+
EXCEPTION_CLASS = RDStation::Error::ResourceNotFound
|
8
|
+
|
9
|
+
def initialize(api_response)
|
10
|
+
@api_response = api_response
|
11
|
+
@error = JSON.parse(api_response.body)['errors']
|
12
|
+
end
|
13
|
+
|
14
|
+
def raise_error
|
15
|
+
return unless resource_not_found?
|
16
|
+
raise EXCEPTION_CLASS.new(error['error_message'], api_response)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def resource_not_found?
|
22
|
+
error['error_type'] == ERROR_CODE
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module RDStation
|
2
|
+
class ErrorHandler
|
3
|
+
class Unauthorized
|
4
|
+
attr_reader :api_response, :response_body, :error
|
5
|
+
|
6
|
+
ERROR_CODE = 'UNAUTHORIZED'.freeze
|
7
|
+
EXCEPTION_CLASS = RDStation::Error::Unauthorized
|
8
|
+
|
9
|
+
def initialize(api_response)
|
10
|
+
@api_response = api_response
|
11
|
+
@error = JSON.parse(api_response.body)['errors']
|
12
|
+
end
|
13
|
+
|
14
|
+
def raise_error
|
15
|
+
return unless unauthorized?
|
16
|
+
raise EXCEPTION_CLASS.new(error['error_message'], api_response)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def unauthorized?
|
22
|
+
error['error_type'] == ERROR_CODE
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module RDStation
|
3
|
+
# More info: https://developers.rdstation.com/pt-BR/reference/contacts
|
4
|
+
class Fields
|
5
|
+
include HTTParty
|
6
|
+
|
7
|
+
BASE_URL = 'https://api.rd.services/platform/contacts/fields'.freeze
|
8
|
+
|
9
|
+
def initialize(auth_token)
|
10
|
+
@auth_token = auth_token
|
11
|
+
end
|
12
|
+
|
13
|
+
def all
|
14
|
+
response = self.class.get(BASE_URL, headers: required_headers)
|
15
|
+
response_body = JSON.parse(response.body)
|
16
|
+
return response_body unless response_body['errors']
|
17
|
+
RDStation::ErrorHandler.new(response).raise_errors
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def required_headers
|
23
|
+
{ "Authorization" => "Bearer #{@auth_token}", "Content-Type" => "application/json" }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/rdstation/version.rb
CHANGED
@@ -21,8 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
22
|
spec.add_development_dependency "rake"
|
23
23
|
spec.add_development_dependency 'rspec'
|
24
|
-
spec.add_development_dependency '
|
25
|
-
spec.add_development_dependency 'webmock'
|
24
|
+
spec.add_development_dependency 'webmock', '~> 2.1'
|
26
25
|
spec.add_development_dependency 'turn'
|
27
26
|
|
28
27
|
spec.add_dependency "httparty", "~> 0.12"
|
@@ -0,0 +1,177 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RDStation::Authentication do
|
4
|
+
let(:token_endpoint) { 'https://api.rd.services/auth/token' }
|
5
|
+
let(:request_headers) { { 'Content-Type' => 'application/json' } }
|
6
|
+
|
7
|
+
let(:token_request_with_valid_code) do
|
8
|
+
{
|
9
|
+
client_id: 'client_id',
|
10
|
+
client_secret: 'client_secret',
|
11
|
+
code: 'valid_code'
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:token_request_with_invalid_code) do
|
16
|
+
{
|
17
|
+
client_id: 'client_id',
|
18
|
+
client_secret: 'client_secret',
|
19
|
+
code: 'invalid_code'
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
let(:token_request_with_expired_code) do
|
24
|
+
{
|
25
|
+
client_id: 'client_id',
|
26
|
+
client_secret: 'client_secret',
|
27
|
+
code: 'expired_code'
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
let(:token_request_with_valid_refresh_token) do
|
32
|
+
{
|
33
|
+
client_id: 'client_id',
|
34
|
+
client_secret: 'client_secret',
|
35
|
+
refresh_token: 'valid_refresh_token'
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
let(:token_request_with_invalid_refresh_token) do
|
40
|
+
{
|
41
|
+
client_id: 'client_id',
|
42
|
+
client_secret: 'client_secret',
|
43
|
+
refresh_token: 'invalid_refresh_token'
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
let(:credentials) do
|
48
|
+
{
|
49
|
+
'access_token' => '123456',
|
50
|
+
'expires_in' => 86_400,
|
51
|
+
'refresh_token' => 'refreshtoken'
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
let(:credentials_response) do
|
56
|
+
{
|
57
|
+
status: 200,
|
58
|
+
headers: { 'Content-Type' => 'application/json' },
|
59
|
+
body: credentials.to_json
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
let(:invalid_code_response) do
|
64
|
+
{
|
65
|
+
status: 401,
|
66
|
+
headers: { 'Content-Type' => 'application/json' },
|
67
|
+
body: {
|
68
|
+
errors: {
|
69
|
+
error_type: 'ACCESS_DENIED',
|
70
|
+
error_message: 'Wrong credentials provided.'
|
71
|
+
}
|
72
|
+
}.to_json
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
let(:expired_code_response) do
|
77
|
+
{
|
78
|
+
status: 401,
|
79
|
+
headers: { 'Content-Type' => 'application/json' },
|
80
|
+
body: {
|
81
|
+
errors: {
|
82
|
+
error_type: 'EXPIRED_CODE_GRANT',
|
83
|
+
error_message: 'The authorization code grant has expired.'
|
84
|
+
}
|
85
|
+
}.to_json
|
86
|
+
}
|
87
|
+
end
|
88
|
+
|
89
|
+
let(:authentication) { described_class.new('client_id', 'client_secret') }
|
90
|
+
|
91
|
+
describe '#authenticate' do
|
92
|
+
context 'when the code is valid' do
|
93
|
+
before do
|
94
|
+
stub_request(:post, token_endpoint)
|
95
|
+
.with(
|
96
|
+
headers: request_headers,
|
97
|
+
body: token_request_with_valid_code.to_json
|
98
|
+
)
|
99
|
+
.to_return(credentials_response)
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'returns the credentials' do
|
103
|
+
credentials_request = authentication.authenticate('valid_code')
|
104
|
+
expect(credentials_request).to eq(credentials)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'when the code is invalid' do
|
109
|
+
before do
|
110
|
+
stub_request(:post, token_endpoint)
|
111
|
+
.with(
|
112
|
+
headers: request_headers,
|
113
|
+
body: token_request_with_invalid_code.to_json
|
114
|
+
)
|
115
|
+
.to_return(invalid_code_response)
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'returns an auth error' do
|
119
|
+
expect do
|
120
|
+
authentication.authenticate('invalid_code')
|
121
|
+
end.to raise_error(RDStation::Error::InvalidCredentials)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'when the code has expired' do
|
126
|
+
before do
|
127
|
+
stub_request(:post, token_endpoint)
|
128
|
+
.with(
|
129
|
+
headers: request_headers,
|
130
|
+
body: token_request_with_expired_code.to_json
|
131
|
+
)
|
132
|
+
.to_return(expired_code_response)
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'returns an expired code error' do
|
136
|
+
expect do
|
137
|
+
authentication.authenticate('expired_code')
|
138
|
+
end.to raise_error(RDStation::Error::ExpiredCodeGrant)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe '#update_access_token' do
|
144
|
+
context 'when the refresh token is valid' do
|
145
|
+
before do
|
146
|
+
stub_request(:post, token_endpoint)
|
147
|
+
.with(
|
148
|
+
headers: request_headers,
|
149
|
+
body: token_request_with_valid_refresh_token.to_json
|
150
|
+
)
|
151
|
+
.to_return(credentials_response)
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'returns the credentials' do
|
155
|
+
credentials_request = authentication.update_access_token('valid_refresh_token')
|
156
|
+
expect(credentials_request).to eq(credentials)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context 'when the refresh token is invalid' do
|
161
|
+
before do
|
162
|
+
stub_request(:post, token_endpoint)
|
163
|
+
.with(
|
164
|
+
headers: request_headers,
|
165
|
+
body: token_request_with_invalid_refresh_token.to_json
|
166
|
+
)
|
167
|
+
.to_return(invalid_code_response)
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'returns an auth error' do
|
171
|
+
expect do
|
172
|
+
authentication.update_access_token('invalid_refresh_token')
|
173
|
+
end.to raise_error(RDStation::Error::InvalidCredentials)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
@@ -0,0 +1,434 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RDStation::Contacts do
|
4
|
+
let(:valid_uuid) { 'valid_uuid' }
|
5
|
+
let(:invalid_uuid) { 'invalid_uuid' }
|
6
|
+
let(:valid_email) { 'valid@email.com' }
|
7
|
+
let(:invalid_email) { 'invalid@email.com' }
|
8
|
+
|
9
|
+
let(:endpoint_with_valid_uuid) { "https://api.rd.services/platform/contacts/#{valid_uuid}" }
|
10
|
+
let(:endpoint_with_invalid_uuid) { "https://api.rd.services/platform/contacts/#{invalid_uuid}" }
|
11
|
+
let(:endpoint_with_valid_email) { "https://api.rd.services/platform/contacts/email:#{valid_email}" }
|
12
|
+
let(:endpoint_with_invalid_email) { "https://api.rd.services/platform/contacts/email:#{invalid_email}" }
|
13
|
+
|
14
|
+
let(:valid_auth_token) { 'valid_auth_token' }
|
15
|
+
let(:invalid_auth_token) { 'invalid_auth_token' }
|
16
|
+
let(:expired_auth_token) { 'expired_auth_token' }
|
17
|
+
|
18
|
+
let(:contact_with_valid_token) { described_class.new(valid_auth_token) }
|
19
|
+
let(:contact_with_expired_token) { described_class.new(expired_auth_token) }
|
20
|
+
let(:contact_with_invalid_token) { described_class.new(invalid_auth_token) }
|
21
|
+
|
22
|
+
let(:valid_headers) do
|
23
|
+
{
|
24
|
+
'Authorization' => "Bearer #{valid_auth_token}",
|
25
|
+
'Content-Type' => 'application/json'
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
let(:invalid_token_headers) do
|
30
|
+
{
|
31
|
+
'Authorization' => "Bearer #{invalid_auth_token}",
|
32
|
+
'Content-Type' => 'application/json'
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
let(:expired_token_headers) do
|
37
|
+
{
|
38
|
+
'Authorization' => "Bearer #{expired_auth_token}",
|
39
|
+
'Content-Type' => 'application/json'
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
let(:not_found_response) do
|
44
|
+
{
|
45
|
+
status: 404,
|
46
|
+
body: {
|
47
|
+
errors: {
|
48
|
+
error_type: 'RESOURCE_NOT_FOUND',
|
49
|
+
error_message: 'Lead not found.'
|
50
|
+
}
|
51
|
+
}.to_json
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
let(:invalid_token_response) do
|
56
|
+
{
|
57
|
+
status: 401,
|
58
|
+
body: {
|
59
|
+
errors: {
|
60
|
+
error_type: 'UNAUTHORIZED',
|
61
|
+
error_message: 'Invalid token.'
|
62
|
+
}
|
63
|
+
}.to_json
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
let(:conflicting_field_response) do
|
68
|
+
{
|
69
|
+
status: 400,
|
70
|
+
body: {
|
71
|
+
errors: {
|
72
|
+
error_type: 'CONFLICTING_FIELD',
|
73
|
+
error_message: 'The payload contains an attribute that was used to identify the resource.'
|
74
|
+
}
|
75
|
+
}.to_json
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
let(:unrecognized_error) do
|
80
|
+
{
|
81
|
+
status: 400,
|
82
|
+
body: {
|
83
|
+
errors: {
|
84
|
+
error_type: 'unrecognized error',
|
85
|
+
error_message: 'Unexpected error.'
|
86
|
+
}
|
87
|
+
}.to_json
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
let(:expired_token_response) do
|
92
|
+
{
|
93
|
+
status: 401,
|
94
|
+
headers: { 'WWW-Authenticate' => 'Bearer realm="https://api.rd.services/", error="expired_token", error_description="The access token expired"' },
|
95
|
+
body: {
|
96
|
+
errors: {
|
97
|
+
error_type: 'UNAUTHORIZED',
|
98
|
+
error_message: 'Invalid token.'
|
99
|
+
}
|
100
|
+
}.to_json
|
101
|
+
}
|
102
|
+
end
|
103
|
+
|
104
|
+
describe '#by_uuid' do
|
105
|
+
context 'with a valid auth token' do
|
106
|
+
context 'when the contact exists' do
|
107
|
+
let(:contact) do
|
108
|
+
{ 'name' => 'Lead', 'email' => 'valid@email.com' }
|
109
|
+
end
|
110
|
+
|
111
|
+
before do
|
112
|
+
stub_request(:get, endpoint_with_valid_uuid)
|
113
|
+
.with(headers: valid_headers)
|
114
|
+
.to_return(status: 200, body: contact.to_json)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'returns the contact' do
|
118
|
+
response = contact_with_valid_token.by_uuid('valid_uuid')
|
119
|
+
expect(response).to eq(contact)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context 'when the contact does not exist' do
|
124
|
+
before do
|
125
|
+
stub_request(:get, endpoint_with_invalid_uuid)
|
126
|
+
.with(headers: valid_headers)
|
127
|
+
.to_return(not_found_response)
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'raises a not found error' do
|
131
|
+
expect do
|
132
|
+
contact_with_valid_token.by_uuid(invalid_uuid)
|
133
|
+
end.to raise_error(RDStation::Error::ResourceNotFound)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'with an invalid auth token' do
|
139
|
+
before do
|
140
|
+
stub_request(:get, endpoint_with_valid_uuid)
|
141
|
+
.with(headers: invalid_token_headers)
|
142
|
+
.to_return(invalid_token_response)
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'raises an invalid token error' do
|
146
|
+
expect do
|
147
|
+
contact_with_invalid_token.by_uuid(valid_uuid)
|
148
|
+
end.to raise_error(RDStation::Error::Unauthorized)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
context 'with an expired auth token' do
|
153
|
+
before do
|
154
|
+
stub_request(:get, endpoint_with_valid_uuid)
|
155
|
+
.with(headers: expired_token_headers)
|
156
|
+
.to_return(expired_token_response)
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'raises a expired token error' do
|
160
|
+
expect do
|
161
|
+
contact_with_expired_token.by_uuid(valid_uuid)
|
162
|
+
end.to raise_error(RDStation::Error::ExpiredAccessToken)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe '#by_email' do
|
168
|
+
context 'with a valid auth token' do
|
169
|
+
context 'when the contact exists' do
|
170
|
+
let(:contact) do
|
171
|
+
{ 'name' => 'Lead', 'email' => 'valid@email.com' }
|
172
|
+
end
|
173
|
+
|
174
|
+
before do
|
175
|
+
stub_request(:get, endpoint_with_valid_email)
|
176
|
+
.with(headers: valid_headers)
|
177
|
+
.to_return(status: 200, body: contact.to_json)
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'returns the contact' do
|
181
|
+
response = contact_with_valid_token.by_email(valid_email)
|
182
|
+
expect(response).to eq(contact)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
context 'when the contact does not exist' do
|
187
|
+
before do
|
188
|
+
stub_request(:get, endpoint_with_invalid_email)
|
189
|
+
.with(headers: valid_headers)
|
190
|
+
.to_return(not_found_response)
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'raises a not found error' do
|
194
|
+
expect do
|
195
|
+
contact_with_valid_token.by_email(invalid_email)
|
196
|
+
end.to raise_error(RDStation::Error::ResourceNotFound)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
context 'with an invalid auth token' do
|
202
|
+
before do
|
203
|
+
stub_request(:get, endpoint_with_valid_email)
|
204
|
+
.with(headers: invalid_token_headers)
|
205
|
+
.to_return(invalid_token_response)
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'raises an invalid token error' do
|
209
|
+
expect do
|
210
|
+
contact_with_invalid_token.by_email(valid_email)
|
211
|
+
end.to raise_error(RDStation::Error::Unauthorized)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
context 'with an expired auth token' do
|
216
|
+
before do
|
217
|
+
stub_request(:get, endpoint_with_valid_email)
|
218
|
+
.with(headers: expired_token_headers)
|
219
|
+
.to_return(expired_token_response)
|
220
|
+
end
|
221
|
+
|
222
|
+
it 'raises a expired token error' do
|
223
|
+
expect do
|
224
|
+
contact_with_expired_token.by_email(valid_email)
|
225
|
+
end.to raise_error(RDStation::Error::ExpiredAccessToken)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
describe '#update' do
|
231
|
+
context 'with a valid auth_token' do
|
232
|
+
let(:valid_auth_token) { 'valid_auth_token' }
|
233
|
+
let(:headers) do
|
234
|
+
{
|
235
|
+
'Authorization' => "Bearer #{valid_auth_token}",
|
236
|
+
'Content-Type' => 'application/json'
|
237
|
+
}
|
238
|
+
end
|
239
|
+
|
240
|
+
context 'with valid params' do
|
241
|
+
let(:contact) do
|
242
|
+
{ 'name' => 'Lead', 'email' => 'valid@email.com' }
|
243
|
+
end
|
244
|
+
|
245
|
+
before do
|
246
|
+
stub_request(:patch, endpoint_with_valid_uuid)
|
247
|
+
.with(headers: headers)
|
248
|
+
.to_return(status: 200, body: contact.to_json)
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'returns the updated contact' do
|
252
|
+
updated_contact = contact_with_valid_token.update('valid_uuid', contact)
|
253
|
+
expect(updated_contact).to eq(contact)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
context 'when the contact does not exist' do
|
258
|
+
before do
|
259
|
+
stub_request(:patch, endpoint_with_invalid_uuid)
|
260
|
+
.with(headers: headers)
|
261
|
+
.to_return(not_found_response)
|
262
|
+
end
|
263
|
+
|
264
|
+
it 'raises a not found error' do
|
265
|
+
expect do
|
266
|
+
contact_with_valid_token.update(invalid_uuid, {})
|
267
|
+
end.to raise_error(RDStation::Error::ResourceNotFound)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
context 'with an invalid auth token' do
|
273
|
+
let(:invalid_auth_token) { 'invalid_auth_token' }
|
274
|
+
let(:headers) do
|
275
|
+
{
|
276
|
+
'Authorization' => "Bearer #{invalid_auth_token}",
|
277
|
+
'Content-Type' => 'application/json'
|
278
|
+
}
|
279
|
+
end
|
280
|
+
|
281
|
+
before do
|
282
|
+
stub_request(:patch, endpoint_with_valid_uuid)
|
283
|
+
.with(headers: headers)
|
284
|
+
.to_return(invalid_token_response)
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'raises an invalid token error' do
|
288
|
+
expect do
|
289
|
+
contact_with_invalid_token.update('valid_uuid', {})
|
290
|
+
end.to raise_error(RDStation::Error::Unauthorized)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
context 'with an expired auth token' do
|
295
|
+
let(:expired_auth_token) { 'expired_auth_token' }
|
296
|
+
let(:headers) do
|
297
|
+
{
|
298
|
+
'Authorization' => "Bearer #{expired_auth_token}",
|
299
|
+
'Content-Type' => 'application/json'
|
300
|
+
}
|
301
|
+
end
|
302
|
+
|
303
|
+
before do
|
304
|
+
stub_request(:patch, endpoint_with_valid_uuid)
|
305
|
+
.with(headers: headers)
|
306
|
+
.to_return(expired_token_response)
|
307
|
+
end
|
308
|
+
|
309
|
+
it 'raises a expired token error' do
|
310
|
+
expect do
|
311
|
+
contact_with_expired_token.update('valid_uuid', {})
|
312
|
+
end.to raise_error(RDStation::Error::ExpiredAccessToken)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
describe '#upsert' do
|
318
|
+
context 'with a valid auth_token' do
|
319
|
+
let(:valid_auth_token) { 'valid_auth_token' }
|
320
|
+
|
321
|
+
let(:headers) do
|
322
|
+
{
|
323
|
+
'Authorization' => "Bearer #{valid_auth_token}",
|
324
|
+
'Content-Type' => 'application/json'
|
325
|
+
}
|
326
|
+
end
|
327
|
+
|
328
|
+
context 'with valid params' do
|
329
|
+
let(:contact) do
|
330
|
+
{ 'name' => 'Lead', 'job_title' => 'Developer' }
|
331
|
+
end
|
332
|
+
|
333
|
+
before do
|
334
|
+
stub_request(:patch, endpoint_with_valid_email)
|
335
|
+
.with(headers: headers)
|
336
|
+
.to_return(status: 200, body: contact.to_json)
|
337
|
+
end
|
338
|
+
|
339
|
+
it 'returns the updated contact' do
|
340
|
+
updated_contact = contact_with_valid_token.upsert('email', 'valid@email.com', contact)
|
341
|
+
expect(updated_contact).to eq(contact)
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
context 'when the contact does not exist' do
|
346
|
+
before do
|
347
|
+
stub_request(:patch, endpoint_with_invalid_email)
|
348
|
+
.with(headers: headers)
|
349
|
+
.to_return(not_found_response)
|
350
|
+
end
|
351
|
+
|
352
|
+
it 'raises a not found error' do
|
353
|
+
expect do
|
354
|
+
contact_with_valid_token.upsert('email', invalid_email, {})
|
355
|
+
end.to raise_error(RDStation::Error::ResourceNotFound)
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
context 'when the payload has a conflicting field' do
|
360
|
+
let(:conflicting_payload) { { 'email' => valid_email } }
|
361
|
+
|
362
|
+
before do
|
363
|
+
stub_request(:patch, endpoint_with_valid_email)
|
364
|
+
.with(headers: headers)
|
365
|
+
.to_return(conflicting_field_response)
|
366
|
+
end
|
367
|
+
|
368
|
+
it 'raises a conflicting field error' do
|
369
|
+
expect do
|
370
|
+
contact_with_valid_token.upsert('email', valid_email, conflicting_payload)
|
371
|
+
end.to raise_error(RDStation::Error::ConflictingField)
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
context 'when an unrecognized error occurs' do
|
376
|
+
before do
|
377
|
+
stub_request(:patch, endpoint_with_valid_email)
|
378
|
+
.with(headers: headers)
|
379
|
+
.to_return(unrecognized_error)
|
380
|
+
end
|
381
|
+
|
382
|
+
it 'raises an default error' do
|
383
|
+
expect do
|
384
|
+
contact_with_valid_token.upsert('email', valid_email, {})
|
385
|
+
end.to raise_error(RDStation::Error::Default)
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
context 'with an invalid auth token' do
|
391
|
+
let(:invalid_auth_token) { 'invalid_auth_token' }
|
392
|
+
let(:headers) do
|
393
|
+
{
|
394
|
+
'Authorization' => "Bearer #{invalid_auth_token}",
|
395
|
+
'Content-Type' => 'application/json'
|
396
|
+
}
|
397
|
+
end
|
398
|
+
|
399
|
+
before do
|
400
|
+
stub_request(:patch, endpoint_with_valid_email)
|
401
|
+
.with(headers: headers)
|
402
|
+
.to_return(invalid_token_response)
|
403
|
+
end
|
404
|
+
|
405
|
+
it 'raises an invalid token error' do
|
406
|
+
expect do
|
407
|
+
contact_with_invalid_token.upsert('email', valid_email, {})
|
408
|
+
end.to raise_error(RDStation::Error::Unauthorized)
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
context 'with an expired auth token' do
|
413
|
+
let(:expired_auth_token) { 'expired_auth_token' }
|
414
|
+
let(:headers) do
|
415
|
+
{
|
416
|
+
'Authorization' => "Bearer #{expired_auth_token}",
|
417
|
+
'Content-Type' => 'application/json'
|
418
|
+
}
|
419
|
+
end
|
420
|
+
|
421
|
+
before do
|
422
|
+
stub_request(:patch, endpoint_with_valid_email)
|
423
|
+
.with(headers: headers)
|
424
|
+
.to_return(expired_token_response)
|
425
|
+
end
|
426
|
+
|
427
|
+
it 'raises an expired token error' do
|
428
|
+
expect do
|
429
|
+
contact_with_expired_token.upsert('email', valid_email, {})
|
430
|
+
end.to raise_error(RDStation::Error::ExpiredAccessToken)
|
431
|
+
end
|
432
|
+
end
|
433
|
+
end
|
434
|
+
end
|