rdstation-ruby-client 2.1.0 → 2.5.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 +5 -5
- data/CHANGELOG.md +121 -1
- data/README.md +106 -22
- data/Rakefile +4 -0
- data/lib/rdstation-ruby-client.rb +6 -1
- data/lib/rdstation.rb +19 -0
- data/lib/rdstation/api_response.rb +1 -2
- data/lib/rdstation/authentication.rb +8 -3
- data/lib/rdstation/{authorization_header.rb → authorization.rb} +11 -8
- data/lib/rdstation/builder/field.rb +70 -0
- data/lib/rdstation/client.rb +17 -7
- data/lib/rdstation/contacts.rb +22 -13
- data/lib/rdstation/error.rb +3 -0
- data/lib/rdstation/error/format.rb +29 -3
- data/lib/rdstation/error/formatter.rb +69 -8
- data/lib/rdstation/error_handler.rb +6 -1
- data/lib/rdstation/error_handler/invalid_refresh_token.rb +24 -0
- data/lib/rdstation/error_handler/unauthorized.rb +2 -0
- data/lib/rdstation/events.rb +7 -12
- data/lib/rdstation/fields.rb +35 -6
- data/lib/rdstation/retryable_request.rb +35 -0
- data/lib/rdstation/version.rb +1 -1
- data/lib/rdstation/webhooks.rb +25 -13
- data/rdstation-ruby-client.gemspec +2 -1
- data/spec/lib/rdstation/api_response_spec.rb +34 -0
- data/spec/lib/rdstation/authentication_spec.rb +105 -2
- data/spec/lib/rdstation/{authorization_header_spec.rb → authorization_spec.rb} +3 -3
- data/spec/lib/rdstation/builder/field_spec.rb +69 -0
- data/spec/lib/rdstation/client_spec.rb +6 -6
- data/spec/lib/rdstation/contacts_spec.rb +23 -3
- data/spec/lib/rdstation/error/format_spec.rb +63 -0
- data/spec/lib/rdstation/error/formatter_spec.rb +113 -0
- data/spec/lib/rdstation/error_handler/invalid_refresh_token_spec.rb +53 -0
- data/spec/lib/rdstation/error_handler_spec.rb +23 -0
- data/spec/lib/rdstation/events_spec.rb +8 -3
- data/spec/lib/rdstation/fields_spec.rb +6 -1
- data/spec/lib/rdstation/retryable_request_spec.rb +142 -0
- data/spec/lib/rdstation/webhooks_spec.rb +26 -1
- data/spec/lib/rdstation_spec.rb +18 -0
- metadata +36 -8
@@ -4,27 +4,27 @@ RSpec.describe RDStation::Client do
|
|
4
4
|
context "when access_token is given" do
|
5
5
|
let(:access_token) { 'access_token' }
|
6
6
|
let(:client) { described_class.new(access_token: access_token) }
|
7
|
-
let(:
|
7
|
+
let(:mock_authorization) { double(RDStation::Authorization) }
|
8
8
|
|
9
|
-
before { allow(RDStation::
|
9
|
+
before { allow(RDStation::Authorization).to receive(:new).and_return mock_authorization }
|
10
10
|
|
11
11
|
it 'returns Contacts endpoint' do
|
12
|
-
expect(RDStation::Contacts).to receive(:new).with({
|
12
|
+
expect(RDStation::Contacts).to receive(:new).with({ authorization: mock_authorization }).and_call_original
|
13
13
|
expect(client.contacts).to be_instance_of RDStation::Contacts
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'returns Events endpoint' do
|
17
|
-
expect(RDStation::Events).to receive(:new).with({
|
17
|
+
expect(RDStation::Events).to receive(:new).with({ authorization: mock_authorization }).and_call_original
|
18
18
|
expect(client.events).to be_instance_of RDStation::Events
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'returns Fields endpoint' do
|
22
|
-
expect(RDStation::Fields).to receive(:new).with({
|
22
|
+
expect(RDStation::Fields).to receive(:new).with({ authorization: mock_authorization }).and_call_original
|
23
23
|
expect(client.fields).to be_instance_of RDStation::Fields
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'returns Webhooks endpoint' do
|
27
|
-
expect(RDStation::Webhooks).to receive(:new).with({
|
27
|
+
expect(RDStation::Webhooks).to receive(:new).with({ authorization: mock_authorization }).and_call_original
|
28
28
|
expect(client.webhooks).to be_instance_of RDStation::Webhooks
|
29
29
|
end
|
30
30
|
end
|
@@ -16,13 +16,13 @@ RSpec.describe RDStation::Contacts do
|
|
16
16
|
let(:expired_access_token) { 'expired_access_token' }
|
17
17
|
|
18
18
|
let(:contact_with_valid_token) do
|
19
|
-
described_class.new(
|
19
|
+
described_class.new(authorization: RDStation::Authorization.new(access_token: valid_access_token))
|
20
20
|
end
|
21
21
|
let(:contact_with_expired_token) do
|
22
|
-
described_class.new(
|
22
|
+
described_class.new(authorization: RDStation::Authorization.new(access_token: expired_access_token))
|
23
23
|
end
|
24
24
|
let(:contact_with_invalid_token) do
|
25
|
-
described_class.new(
|
25
|
+
described_class.new(authorization: RDStation::Authorization.new(access_token: invalid_access_token))
|
26
26
|
end
|
27
27
|
|
28
28
|
|
@@ -109,6 +109,11 @@ RSpec.describe RDStation::Contacts do
|
|
109
109
|
end
|
110
110
|
|
111
111
|
describe '#by_uuid' do
|
112
|
+
it 'calls retryable_request' do
|
113
|
+
expect(contact_with_valid_token).to receive(:retryable_request)
|
114
|
+
contact_with_valid_token.by_uuid('valid_uuid')
|
115
|
+
end
|
116
|
+
|
112
117
|
context 'with a valid auth token' do
|
113
118
|
context 'when the contact exists' do
|
114
119
|
let(:contact) do
|
@@ -172,6 +177,11 @@ RSpec.describe RDStation::Contacts do
|
|
172
177
|
end
|
173
178
|
|
174
179
|
describe '#by_email' do
|
180
|
+
it 'calls retryable_request' do
|
181
|
+
expect(contact_with_valid_token).to receive(:retryable_request)
|
182
|
+
contact_with_valid_token.by_email('x@xpto.com')
|
183
|
+
end
|
184
|
+
|
175
185
|
context 'with a valid auth token' do
|
176
186
|
context 'when the contact exists' do
|
177
187
|
let(:contact) do
|
@@ -235,6 +245,11 @@ RSpec.describe RDStation::Contacts do
|
|
235
245
|
end
|
236
246
|
|
237
247
|
describe '#update' do
|
248
|
+
it 'calls retryable_request' do
|
249
|
+
expect(contact_with_valid_token).to receive(:retryable_request)
|
250
|
+
contact_with_valid_token.update('valid_uuid', {})
|
251
|
+
end
|
252
|
+
|
238
253
|
context 'with a valid access_token' do
|
239
254
|
let(:valid_access_token) { 'valid_access_token' }
|
240
255
|
let(:headers) do
|
@@ -322,6 +337,11 @@ RSpec.describe RDStation::Contacts do
|
|
322
337
|
end
|
323
338
|
|
324
339
|
describe '#upsert' do
|
340
|
+
it 'calls retryable_request' do
|
341
|
+
expect(contact_with_valid_token).to receive(:retryable_request)
|
342
|
+
contact_with_valid_token.upsert('email', 'valid@email.com', {})
|
343
|
+
end
|
344
|
+
|
325
345
|
context 'with a valid access_token' do
|
326
346
|
let(:valid_access_token) { 'valid_access_token' }
|
327
347
|
|
@@ -52,5 +52,68 @@ RSpec.describe RDStation::Error::Format do
|
|
52
52
|
expect(result).to eq(RDStation::Error::Format::ARRAY_OF_HASHES)
|
53
53
|
end
|
54
54
|
end
|
55
|
+
|
56
|
+
context 'when receives a mixed type of errors' do
|
57
|
+
let(:errors) do
|
58
|
+
{
|
59
|
+
'label': {
|
60
|
+
'pt-BR': [
|
61
|
+
{
|
62
|
+
'error_type': 'CANNOT_BE_BLANK',
|
63
|
+
'error_message': 'cannot be blank'
|
64
|
+
}
|
65
|
+
]
|
66
|
+
},
|
67
|
+
'api_identifier': [
|
68
|
+
{
|
69
|
+
'error_type': 'CANNOT_BE_BLANK',
|
70
|
+
'error_message': 'cannot be blank'
|
71
|
+
}
|
72
|
+
]
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'returns the HASH_OF_MULTIPLE_TYPES format' do
|
77
|
+
result = error_format.format
|
78
|
+
expect(result).to eq(RDStation::Error::Format::HASH_OF_MULTIPLE_TYPES)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'when receives a hash of hashes errors' do
|
83
|
+
let(:errors) do
|
84
|
+
{
|
85
|
+
label: {
|
86
|
+
'pt-BR': [
|
87
|
+
{
|
88
|
+
'error_type': 'CANNOT_BE_BLANK',
|
89
|
+
'error_message': 'cannot be blank'
|
90
|
+
}
|
91
|
+
]
|
92
|
+
}
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'returns the HASH_OF_MULTILINGUAL format' do
|
97
|
+
result = error_format.format
|
98
|
+
expect(result).to eq(RDStation::Error::Format::HASH_OF_HASHES)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'when receives a single hash with error' do
|
103
|
+
let(:errors) do
|
104
|
+
{
|
105
|
+
'error' => "'lead_limiter' rate limit exceeded for 86400 second(s) period for key ...",
|
106
|
+
'max' => 24,
|
107
|
+
'usage' => 55,
|
108
|
+
'remaining_time' => 20745,
|
109
|
+
}
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'returns the SINGLE_HASH format' do
|
113
|
+
result = error_format.format
|
114
|
+
expect(result).to eq(RDStation::Error::Format::SINGLE_HASH)
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
55
118
|
end
|
56
119
|
end
|
@@ -132,5 +132,118 @@ RSpec.describe RDStation::Error::Formatter do
|
|
132
132
|
expect(result).to eq(expected_result)
|
133
133
|
end
|
134
134
|
end
|
135
|
+
|
136
|
+
context 'when receives a hash of multiple type errors' do
|
137
|
+
let(:error_format) { instance_double(RDStation::Error::Format, format: RDStation::Error::Format::HASH_OF_MULTIPLE_TYPES) }
|
138
|
+
|
139
|
+
let(:error_response) do
|
140
|
+
{
|
141
|
+
'errors' => {
|
142
|
+
'label' => {
|
143
|
+
'pt-BR' => [
|
144
|
+
{
|
145
|
+
'error_type' => 'CANNOT_BE_BLANK',
|
146
|
+
'error_message' => 'cannot be blank'
|
147
|
+
}
|
148
|
+
]
|
149
|
+
},
|
150
|
+
'api_identifier' => [
|
151
|
+
{
|
152
|
+
'error_type' => 'CANNOT_BE_BLANK',
|
153
|
+
'error_message' => 'cannot be blank'
|
154
|
+
}
|
155
|
+
]
|
156
|
+
}
|
157
|
+
}
|
158
|
+
end
|
159
|
+
|
160
|
+
let(:error_formatter) { described_class.new(error_response) }
|
161
|
+
|
162
|
+
let(:expected_result) do
|
163
|
+
[
|
164
|
+
{
|
165
|
+
'error_type' => 'CANNOT_BE_BLANK',
|
166
|
+
'error_message' => 'cannot be blank',
|
167
|
+
'path' => 'body.label.pt-BR'
|
168
|
+
},
|
169
|
+
{
|
170
|
+
'error_type' => 'CANNOT_BE_BLANK',
|
171
|
+
'error_message' => 'cannot be blank',
|
172
|
+
'path' => 'body.api_identifier'
|
173
|
+
}
|
174
|
+
]
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'returns an array of errors' do
|
178
|
+
result = error_formatter.to_array
|
179
|
+
expect(result).to eq(expected_result)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
context 'when receives a hash of hashes type errors' do
|
184
|
+
let(:error_format) { instance_double(RDStation::Error::Format, format: RDStation::Error::Format::HASH_OF_HASHES) }
|
185
|
+
|
186
|
+
let(:error_response) do
|
187
|
+
{
|
188
|
+
'errors' => {
|
189
|
+
'label' => {
|
190
|
+
'pt-BR' => [
|
191
|
+
{
|
192
|
+
'error_type' => 'CANNOT_BE_BLANK',
|
193
|
+
'error_message' => 'cannot be blank'
|
194
|
+
}
|
195
|
+
]
|
196
|
+
}
|
197
|
+
}
|
198
|
+
}
|
199
|
+
end
|
200
|
+
|
201
|
+
let(:error_formatter) { described_class.new(error_response) }
|
202
|
+
|
203
|
+
let(:expected_result) do
|
204
|
+
[
|
205
|
+
{
|
206
|
+
'error_type' => 'CANNOT_BE_BLANK',
|
207
|
+
'error_message' => 'cannot be blank',
|
208
|
+
'path' => 'body.label.pt-BR'
|
209
|
+
}
|
210
|
+
]
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'returns an array of errors' do
|
214
|
+
result = error_formatter.to_array
|
215
|
+
expect(result).to eq(expected_result)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
context 'when receives a single hash of errors' do
|
220
|
+
let(:error_format) { instance_double(RDStation::Error::Format, format: RDStation::Error::Format::SINGLE_HASH) }
|
221
|
+
|
222
|
+
let(:error_response) do
|
223
|
+
{
|
224
|
+
'error' => "'lead_limiter' rate limit exceeded for 86400 second(s) period for key",
|
225
|
+
'max' => 24,
|
226
|
+
'usage' => 55,
|
227
|
+
'remaining_time' => 20745
|
228
|
+
}
|
229
|
+
end
|
230
|
+
|
231
|
+
let(:error_formatter) { described_class.new(error_response) }
|
232
|
+
|
233
|
+
let(:expected_result) do
|
234
|
+
[
|
235
|
+
{
|
236
|
+
'error_type' => 'TOO_MANY_REQUESTS',
|
237
|
+
'error_message' => "'lead_limiter' rate limit exceeded for 86400 second(s) period for key",
|
238
|
+
'details' => { 'max' => 24, 'usage' => 55, 'remaining_time' => 20745 }
|
239
|
+
}
|
240
|
+
]
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'returns an array of errors' do
|
244
|
+
result = error_formatter.to_array
|
245
|
+
expect(result).to eq(expected_result)
|
246
|
+
end
|
247
|
+
end
|
135
248
|
end
|
136
249
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RDStation::ErrorHandler::InvalidRefreshToken do
|
4
|
+
describe '#raise_error' do
|
5
|
+
subject(:invalid_refresh_token) { described_class.new(errors) }
|
6
|
+
|
7
|
+
context 'when the refresh token is invalid or was revoked' do
|
8
|
+
let(:errors) do
|
9
|
+
[
|
10
|
+
{
|
11
|
+
'error_type' => 'INVALID_REFRESH_TOKEN',
|
12
|
+
'error_message' => 'Error Message',
|
13
|
+
}
|
14
|
+
]
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'raises an InvalidRefreshToken error' do
|
18
|
+
expect do
|
19
|
+
invalid_refresh_token.raise_error
|
20
|
+
end.to raise_error(RDStation::Error::InvalidRefreshToken, 'Error Message')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when none of the errors are invalid refresh token errors' do
|
25
|
+
let(:errors) do
|
26
|
+
[
|
27
|
+
{
|
28
|
+
'error_message' => 'Error Message',
|
29
|
+
'error_type' => 'RANDOM_ERROR_TYPE'
|
30
|
+
},
|
31
|
+
{
|
32
|
+
'error_message' => 'Another Error Message',
|
33
|
+
'error_type' => 'ANOTHER_RANDOM_ERROR_TYPE'
|
34
|
+
}
|
35
|
+
]
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'does not raise an InvalidRefreshToken error' do
|
39
|
+
result = invalid_refresh_token.raise_error
|
40
|
+
expect(result).to be_nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when there are no errors' do
|
45
|
+
let(:errors) { [] }
|
46
|
+
|
47
|
+
it 'does not raise an InvalidRefreshToken error' do
|
48
|
+
result = invalid_refresh_token.raise_error
|
49
|
+
expect(result).to be_nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -151,6 +151,7 @@ RSpec.describe RDStation::ErrorHandler do
|
|
151
151
|
expect { error_handler.raise_error }.to raise_error(RDStation::Error::ServiceUnavailable, 'Error Message')
|
152
152
|
end
|
153
153
|
end
|
154
|
+
|
154
155
|
context 'with 5xx error' do
|
155
156
|
let(:http_status) { 505 }
|
156
157
|
|
@@ -158,5 +159,27 @@ RSpec.describe RDStation::ErrorHandler do
|
|
158
159
|
expect { error_handler.raise_error }.to raise_error(RDStation::Error::ServerError, 'Error Message')
|
159
160
|
end
|
160
161
|
end
|
162
|
+
|
163
|
+
context "when response body is not JSON-parseable" do
|
164
|
+
let(:error_response) do
|
165
|
+
OpenStruct.new(
|
166
|
+
code: 502,
|
167
|
+
headers: { 'error' => 'header' },
|
168
|
+
body: '<html><body>HTML error response</body></html>'
|
169
|
+
)
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'raises the correct error' do
|
173
|
+
expect { error_handler.raise_error }.to raise_error(RDStation::Error::BadGateway, '<html><body>HTML error response</body></html>')
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
context 'with an unknown error' do
|
178
|
+
let(:http_status) { 123 }
|
179
|
+
|
180
|
+
it 'raises a unknown error' do
|
181
|
+
expect { error_handler.raise_error }.to raise_error(RDStation::Error::UnknownError, 'Error Message')
|
182
|
+
end
|
183
|
+
end
|
161
184
|
end
|
162
185
|
end
|
@@ -6,13 +6,13 @@ RSpec.describe RDStation::Events do
|
|
6
6
|
let(:expired_access_token) { 'expired_access_token' }
|
7
7
|
|
8
8
|
let(:event_with_valid_token) do
|
9
|
-
described_class.new(
|
9
|
+
described_class.new(authorization: RDStation::Authorization.new(access_token: valid_access_token))
|
10
10
|
end
|
11
11
|
let(:event_with_expired_token) do
|
12
|
-
described_class.new(
|
12
|
+
described_class.new(authorization: RDStation::Authorization.new(access_token: expired_access_token))
|
13
13
|
end
|
14
14
|
let(:event_with_invalid_token) do
|
15
|
-
described_class.new(
|
15
|
+
described_class.new(authorization: RDStation::Authorization.new(access_token: invalid_access_token))
|
16
16
|
end
|
17
17
|
|
18
18
|
let(:events_endpoint) { 'https://api.rd.services/platform/events' }
|
@@ -108,6 +108,11 @@ RSpec.describe RDStation::Events do
|
|
108
108
|
}
|
109
109
|
end
|
110
110
|
|
111
|
+
it 'calls retryable_request' do
|
112
|
+
expect(event_with_valid_token).to receive(:retryable_request)
|
113
|
+
event_with_valid_token.create({})
|
114
|
+
end
|
115
|
+
|
111
116
|
context 'with a valid auth token' do
|
112
117
|
before do
|
113
118
|
stub_request(:post, events_endpoint)
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
RSpec.describe RDStation::Fields do
|
4
4
|
let(:valid_access_token) { 'valid_access_token' }
|
5
5
|
let(:rdstation_fields_with_valid_token) do
|
6
|
-
described_class.new(
|
6
|
+
described_class.new(authorization: RDStation::Authorization.new(access_token: valid_access_token))
|
7
7
|
end
|
8
8
|
|
9
9
|
let(:valid_headers) do
|
@@ -38,6 +38,11 @@ RSpec.describe RDStation::Fields do
|
|
38
38
|
}
|
39
39
|
end
|
40
40
|
|
41
|
+
it 'calls retryable_request' do
|
42
|
+
expect(rdstation_fields_with_valid_token).to receive(:retryable_request)
|
43
|
+
rdstation_fields_with_valid_token.all
|
44
|
+
end
|
45
|
+
|
41
46
|
context 'with a valid auth token' do
|
42
47
|
before do
|
43
48
|
stub_request(:get, fields_endpoint)
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class DummyClass
|
4
|
+
include ::RDStation::RetryableRequest
|
5
|
+
end
|
6
|
+
|
7
|
+
RSpec.describe RDStation::RetryableRequest do
|
8
|
+
let(:subject) { DummyClass.new }
|
9
|
+
describe '.retryable_request' do
|
10
|
+
context 'when authorization has a valid refresh_token and config is provided' do
|
11
|
+
let (:access_token) { 'access_token' }
|
12
|
+
let (:new_access_token) { 'new_access_token' }
|
13
|
+
let (:refresh_token) { 'refresh_token' }
|
14
|
+
let (:auth) do
|
15
|
+
::RDStation::Authorization.new(access_token: access_token,
|
16
|
+
refresh_token: refresh_token
|
17
|
+
)
|
18
|
+
end
|
19
|
+
context 'original request was successful' do
|
20
|
+
it 'yields control to the given block' do
|
21
|
+
expect do |block|
|
22
|
+
subject.retryable_request(auth, &block)
|
23
|
+
end.to yield_with_args(auth)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'original request raised a retryable exception' do
|
28
|
+
let (:auth_new_access_token) do
|
29
|
+
::RDStation::Authorization.new(access_token: new_access_token,
|
30
|
+
refresh_token: refresh_token
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
let(:new_credentials) do
|
35
|
+
{
|
36
|
+
'access_token' => new_access_token,
|
37
|
+
'expires_in' => 86_400,
|
38
|
+
'refresh_token' => refresh_token
|
39
|
+
}
|
40
|
+
end
|
41
|
+
let(:authentication_client) {instance_double(::RDStation::Authentication) }
|
42
|
+
|
43
|
+
before do
|
44
|
+
RDStation.configure do |config|
|
45
|
+
config.client_id = "123"
|
46
|
+
config.client_secret = "312"
|
47
|
+
config.on_access_token_refresh do
|
48
|
+
'callback code'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
allow(::RDStation::Authentication).to receive(:new)
|
52
|
+
.with(no_args)
|
53
|
+
.and_return(authentication_client)
|
54
|
+
allow(authentication_client).to receive(:update_access_token)
|
55
|
+
.with(auth.refresh_token).
|
56
|
+
and_return(new_credentials)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'refreshes the access_token and retries the request' do
|
60
|
+
dummy_request = double("dummy_request")
|
61
|
+
expect(dummy_request).to receive(:call).twice do |auth|
|
62
|
+
expired_token = ::RDStation::Error::ExpiredAccessToken.new({'error_message' => 'x'})
|
63
|
+
raise expired_token unless auth.access_token == new_access_token
|
64
|
+
end
|
65
|
+
|
66
|
+
expect(RDStation.configuration.access_token_refresh_callback)
|
67
|
+
.to receive(:call)
|
68
|
+
.once do |authorization|
|
69
|
+
expect(authorization.access_token).to eq new_access_token
|
70
|
+
end
|
71
|
+
|
72
|
+
expect do
|
73
|
+
subject.retryable_request(auth) { |yielded_auth| dummy_request.call(yielded_auth) }
|
74
|
+
end.not_to raise_error
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'and keeps raising retryable exception event after token refreshed' do
|
78
|
+
it 'retries only once' do
|
79
|
+
dummy_request = double("dummy_request")
|
80
|
+
expect(dummy_request).to receive(:call).twice do |_|
|
81
|
+
raise ::RDStation::Error::ExpiredAccessToken.new({'error_message' => 'x'})
|
82
|
+
end
|
83
|
+
|
84
|
+
expect do
|
85
|
+
subject.retryable_request(auth) { |yielded_auth| dummy_request.call(yielded_auth) }
|
86
|
+
end.to raise_error ::RDStation::Error::ExpiredAccessToken
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'and access token refresh callback is not set' do
|
91
|
+
before do
|
92
|
+
RDStation.configure do |config|
|
93
|
+
config.on_access_token_refresh(&nil)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'executes the refresh and retry without raising an error' do
|
98
|
+
dummy_request = double("dummy_request")
|
99
|
+
expect(dummy_request).to receive(:call).twice do |auth|
|
100
|
+
expired_token = ::RDStation::Error::ExpiredAccessToken.new({'error_message' => 'x'})
|
101
|
+
raise expired_token unless auth.access_token == new_access_token
|
102
|
+
end
|
103
|
+
|
104
|
+
expect do
|
105
|
+
subject.retryable_request(auth) { |yielded_auth| dummy_request.call(yielded_auth) }
|
106
|
+
end.not_to raise_error
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'original request raised a non retryable exception' do
|
112
|
+
it 'raises error' do
|
113
|
+
dummy_request = double("dummy_request")
|
114
|
+
expect(dummy_request).to receive(:call).once do |_|
|
115
|
+
raise RuntimeError.new("a non retryable error")
|
116
|
+
end
|
117
|
+
|
118
|
+
expect do
|
119
|
+
subject.retryable_request(auth) { |yielded_auth| dummy_request.call(yielded_auth) }
|
120
|
+
end.to raise_error RuntimeError
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'all legacy scenarios' do
|
126
|
+
let (:access_token) { 'access_token' }
|
127
|
+
let (:auth) { ::RDStation::Authorization.new(access_token: access_token) }
|
128
|
+
|
129
|
+
it 'implement me' do
|
130
|
+
dummy_request = double("dummy_request")
|
131
|
+
expect(dummy_request).to receive(:call).once do |_|
|
132
|
+
raise ::RDStation::Error::ExpiredAccessToken.new({'error_message' => 'x'})
|
133
|
+
end
|
134
|
+
|
135
|
+
expect do
|
136
|
+
subject.retryable_request(auth) { |yielded_auth| dummy_request.call(yielded_auth) }
|
137
|
+
end.to raise_error ::RDStation::Error::ExpiredAccessToken
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
end
|