restful_resource 2.8.0 → 2.11.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/.circleci/config.yml +1 -1
- data/.rubocop_todo.yml +119 -70
- data/CHANGELOG.md +20 -0
- data/Gemfile +0 -2
- data/Gemfile.lock +74 -64
- data/lib/restful_resource.rb +2 -1
- data/lib/restful_resource/base.rb +20 -24
- data/lib/restful_resource/http_client.rb +5 -0
- data/lib/restful_resource/open_object.rb +1 -1
- data/lib/restful_resource/rails_validations.rb +4 -1
- data/lib/restful_resource/redirections.rb +6 -4
- data/lib/restful_resource/strict_open_struct.rb +5 -0
- data/lib/restful_resource/version.rb +1 -1
- data/restful_resource.gemspec +9 -8
- data/spec/restful_resource/associations_spec.rb +0 -2
- data/spec/restful_resource/base_spec.rb +14 -14
- data/spec/restful_resource/http_client_configuration_spec.rb +8 -8
- data/spec/restful_resource/http_client_spec.rb +61 -147
- data/spec/restful_resource/rails_validations_spec.rb +59 -10
- data/spec/spec_helper.rb +8 -0
- metadata +48 -33
data/lib/restful_resource.rb
CHANGED
@@ -8,12 +8,13 @@ require 'faraday_cdn_metrics'
|
|
8
8
|
require 'faraday/encoding'
|
9
9
|
require 'active_support'
|
10
10
|
require 'active_support/all'
|
11
|
-
require 'resolv-replace
|
11
|
+
require 'resolv-replace'
|
12
12
|
require_relative 'restful_resource/version'
|
13
13
|
require_relative 'restful_resource/null_logger'
|
14
14
|
require_relative 'restful_resource/paginated_array'
|
15
15
|
require_relative 'restful_resource/parameter_missing_error'
|
16
16
|
require_relative 'restful_resource/resource_id_missing_error'
|
17
|
+
require_relative 'restful_resource/strict_open_struct'
|
17
18
|
require_relative 'restful_resource/open_object'
|
18
19
|
require_relative 'restful_resource/response'
|
19
20
|
require_relative 'restful_resource/request'
|
@@ -34,58 +34,58 @@ module RestfulResource
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def self.find(id, **params)
|
37
|
-
params_without_options, options = format_params(params)
|
37
|
+
params_without_options, options = format_params(**params)
|
38
38
|
|
39
|
-
response = http.get(member_url(id, params_without_options), **options)
|
39
|
+
response = http.get(member_url(id, **params_without_options), **options)
|
40
40
|
new(parse_json(response.body))
|
41
41
|
end
|
42
42
|
|
43
43
|
def self.where(**params)
|
44
|
-
params_without_options, options = format_params(params)
|
44
|
+
params_without_options, options = format_params(**params)
|
45
45
|
|
46
|
-
url = collection_url(params_without_options)
|
46
|
+
url = collection_url(**params_without_options)
|
47
47
|
response = http.get(url, **options)
|
48
48
|
paginate_response(response)
|
49
49
|
end
|
50
50
|
|
51
51
|
def self.get(**params)
|
52
|
-
params_without_options, options = format_params(params)
|
52
|
+
params_without_options, options = format_params(**params)
|
53
53
|
|
54
|
-
response = http.get(collection_url(params_without_options), **options)
|
54
|
+
response = http.get(collection_url(**params_without_options), **options)
|
55
55
|
new(parse_json(response.body))
|
56
56
|
end
|
57
57
|
|
58
58
|
def self.delete(id, **params)
|
59
|
-
params_without_options, options = format_params(params)
|
60
|
-
response = http.delete(member_url(id, params_without_options), **options)
|
61
|
-
|
59
|
+
params_without_options, options = format_params(**params)
|
60
|
+
response = http.delete(member_url(id, **params_without_options), **options)
|
61
|
+
new(parse_json(response.body))
|
62
62
|
end
|
63
63
|
|
64
64
|
def self.patch(id, data: {}, headers: {}, **params)
|
65
|
-
params_without_options, options = format_params(params)
|
65
|
+
params_without_options, options = format_params(**params)
|
66
66
|
options.delete(:headers)
|
67
67
|
|
68
|
-
url = member_url(id, params_without_options)
|
68
|
+
url = member_url(id, **params_without_options)
|
69
69
|
|
70
70
|
response = http.patch(url, data: data, headers: headers, **options)
|
71
71
|
new(parse_json(response.body))
|
72
72
|
end
|
73
73
|
|
74
74
|
def self.put(id, data: {}, headers: {}, **params)
|
75
|
-
params_without_options, options = format_params(params)
|
75
|
+
params_without_options, options = format_params(**params)
|
76
76
|
options.delete(:headers)
|
77
77
|
|
78
|
-
url = member_url(id, params_without_options)
|
78
|
+
url = member_url(id, **params_without_options)
|
79
79
|
|
80
80
|
response = http.put(url, data: data, headers: headers, **options)
|
81
81
|
new(parse_json(response.body))
|
82
82
|
end
|
83
83
|
|
84
84
|
def self.post(data: {}, headers: {}, **params)
|
85
|
-
params_without_options, options = format_params(params)
|
85
|
+
params_without_options, options = format_params(**params)
|
86
86
|
options.delete(:headers)
|
87
87
|
|
88
|
-
url = collection_url(params_without_options)
|
88
|
+
url = collection_url(**params_without_options)
|
89
89
|
|
90
90
|
response = http.post(url, data: data, headers: headers, **options)
|
91
91
|
|
@@ -93,7 +93,7 @@ module RestfulResource
|
|
93
93
|
end
|
94
94
|
|
95
95
|
def self.all(**params)
|
96
|
-
where(params)
|
96
|
+
where(**params)
|
97
97
|
end
|
98
98
|
|
99
99
|
def self.action(action_name)
|
@@ -119,8 +119,6 @@ module RestfulResource
|
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
122
|
-
protected
|
123
|
-
|
124
122
|
def self.http
|
125
123
|
@http || superclass.http
|
126
124
|
end
|
@@ -135,11 +133,9 @@ module RestfulResource
|
|
135
133
|
|
136
134
|
def self.collection_url(**params)
|
137
135
|
url = merge_url_paths(base_url, @resource_path, @action_prefix)
|
138
|
-
replace_parameters(url, params)
|
136
|
+
replace_parameters(url, **params)
|
139
137
|
end
|
140
138
|
|
141
|
-
private
|
142
|
-
|
143
139
|
def self.format_params(**params)
|
144
140
|
headers = params.delete(:headers) || {}
|
145
141
|
|
@@ -147,7 +143,7 @@ module RestfulResource
|
|
147
143
|
open_timeout = params.delete(:open_timeout)
|
148
144
|
timeout = params.delete(:timeout)
|
149
145
|
|
150
|
-
[params, headers: headers, open_timeout: open_timeout, timeout: timeout]
|
146
|
+
[params, { headers: headers, open_timeout: open_timeout, timeout: timeout }]
|
151
147
|
end
|
152
148
|
|
153
149
|
def self.merge_url_paths(uri, *paths)
|
@@ -158,7 +154,7 @@ module RestfulResource
|
|
158
154
|
raise ResourceIdMissingError if id.blank?
|
159
155
|
|
160
156
|
url = merge_url_paths(base_url, @resource_path, CGI.escape(id.to_s), @action_prefix)
|
161
|
-
replace_parameters(url, params)
|
157
|
+
replace_parameters(url, **params)
|
162
158
|
end
|
163
159
|
|
164
160
|
def self.new_collection(json)
|
@@ -177,7 +173,7 @@ module RestfulResource
|
|
177
173
|
missing_params = []
|
178
174
|
params = params.with_indifferent_access
|
179
175
|
|
180
|
-
url_params = url.scan(
|
176
|
+
url_params = url.scan(%r{:([A-Za-z][^/]*)}).flatten
|
181
177
|
url_params.each do |key|
|
182
178
|
value = params.delete(key)
|
183
179
|
if value.nil?
|
@@ -265,6 +265,11 @@ module RestfulResource
|
|
265
265
|
response = e.response
|
266
266
|
raise ClientError, request unless response
|
267
267
|
|
268
|
+
handle_error(request, response)
|
269
|
+
rescue Faraday::ServerError => e
|
270
|
+
response = e.response
|
271
|
+
raise ClientError, request unless response
|
272
|
+
|
268
273
|
handle_error(request, response)
|
269
274
|
end
|
270
275
|
|
@@ -17,13 +17,16 @@ module RestfulResource
|
|
17
17
|
with_validations { super }
|
18
18
|
end
|
19
19
|
|
20
|
+
def delete(*)
|
21
|
+
with_validations { super }
|
22
|
+
end
|
23
|
+
|
20
24
|
private
|
21
25
|
|
22
26
|
def with_validations(id = nil, data: {})
|
23
27
|
yield
|
24
28
|
rescue HttpClient::UnprocessableEntity => e
|
25
29
|
errors = parse_json(e.response.body)
|
26
|
-
result = nil
|
27
30
|
result = if errors.is_a?(Hash) && errors.key?('errors')
|
28
31
|
data.merge(errors)
|
29
32
|
else
|
@@ -9,15 +9,17 @@ module RestfulResource
|
|
9
9
|
def self.included(base)
|
10
10
|
base.instance_eval do
|
11
11
|
def post(data: {}, delay: 1.0, max_attempts: 10, headers: {}, open_timeout: nil, timeout: nil, **params)
|
12
|
-
url = collection_url(params)
|
12
|
+
url = collection_url(**params)
|
13
13
|
|
14
|
-
response = accept_redirected_result(
|
14
|
+
response = accept_redirected_result(
|
15
|
+
response: http.post(url, data: data, headers: headers, open_timeout: nil, timeout: nil),
|
16
|
+
delay: delay,
|
17
|
+
max_attempts: max_attempts
|
18
|
+
)
|
15
19
|
|
16
20
|
new(parse_json(response.body))
|
17
21
|
end
|
18
22
|
|
19
|
-
private
|
20
|
-
|
21
23
|
def self.accept_redirected_result(response:, delay:, max_attempts:)
|
22
24
|
new_response = response
|
23
25
|
if response.status == 303
|
data/restful_resource.gemspec
CHANGED
@@ -20,18 +20,19 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_development_dependency 'bundler'
|
22
22
|
spec.add_development_dependency 'carwow_rubocop'
|
23
|
+
spec.add_development_dependency 'pry'
|
23
24
|
spec.add_development_dependency 'rake'
|
24
25
|
spec.add_development_dependency 'rspec'
|
25
|
-
spec.add_development_dependency 'rspec_junit_formatter'
|
26
26
|
spec.add_development_dependency 'rspec-its'
|
27
|
+
spec.add_development_dependency 'rspec_junit_formatter'
|
27
28
|
|
28
|
-
spec.add_dependency 'activesupport'
|
29
|
-
spec.add_dependency 'faraday', '~>
|
30
|
-
spec.add_dependency 'faraday-cdn-metrics'
|
29
|
+
spec.add_dependency 'activesupport', '~> 6.0'
|
30
|
+
spec.add_dependency 'faraday', '~> 1.0'
|
31
|
+
spec.add_dependency 'faraday-cdn-metrics', '~> 0.2'
|
31
32
|
spec.add_dependency 'faraday-encoding'
|
32
|
-
spec.add_dependency 'faraday-http-cache'
|
33
|
-
spec.add_dependency 'faraday_middleware'
|
33
|
+
spec.add_dependency 'faraday-http-cache', '~> 2.2'
|
34
|
+
spec.add_dependency 'faraday_middleware', '~> 1.0'
|
34
35
|
spec.add_dependency 'link_header'
|
35
|
-
spec.add_dependency 'rack'
|
36
|
-
spec.add_dependency 'typhoeus'
|
36
|
+
spec.add_dependency 'rack', '~> 2.2'
|
37
|
+
spec.add_dependency 'typhoeus', '~> 1.4'
|
37
38
|
end
|
@@ -11,7 +11,6 @@ describe RestfulResource::Associations do
|
|
11
11
|
{ first_name: 'David', second_name: 'Doe' },
|
12
12
|
{ first_name: 'Mary', second_name: 'Doe' }
|
13
13
|
]
|
14
|
-
|
15
14
|
)
|
16
15
|
end
|
17
16
|
|
@@ -39,7 +38,6 @@ describe RestfulResource::Associations do
|
|
39
38
|
@child = ComplicatedModule::Child.new(
|
40
39
|
first_name: 'David', second_name: 'Smith',
|
41
40
|
parent: { name: 'John Smith' }
|
42
|
-
|
43
41
|
)
|
44
42
|
end
|
45
43
|
|
@@ -365,17 +365,17 @@ RSpec.describe RestfulResource::Base do
|
|
365
365
|
end
|
366
366
|
|
367
367
|
it 'does not return inner object table' do
|
368
|
-
expect(@makes.first.as_json).to eq
|
368
|
+
expect(@makes.first.as_json).to eq({ 'name' => 'Audi', 'slug' => 'Audi-Slug' })
|
369
369
|
end
|
370
370
|
|
371
371
|
it 'returns inner object table on selected fields' do
|
372
|
-
expect(@makes.last.as_json(only: [:name])).to eq
|
372
|
+
expect(@makes.last.as_json(only: [:name])).to eq({ 'name' => 'Fiat' })
|
373
373
|
end
|
374
374
|
end
|
375
375
|
|
376
376
|
describe '.member_url' do
|
377
377
|
it 'requires a member ID' do
|
378
|
-
expect { described_class.member_url(''
|
378
|
+
expect { described_class.member_url('') }.to raise_error(RestfulResource::ResourceIdMissingError)
|
379
379
|
end
|
380
380
|
end
|
381
381
|
|
@@ -406,17 +406,17 @@ RSpec.describe RestfulResource::Base do
|
|
406
406
|
)
|
407
407
|
|
408
408
|
client.configure(base_url: 'http://foo.bar',
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
409
|
+
username: username,
|
410
|
+
password: password,
|
411
|
+
auth_token: auth_token,
|
412
|
+
logger: logger,
|
413
|
+
cache_store: cache_store,
|
414
|
+
instrumentation: instrumentation,
|
415
|
+
timeout: timeout,
|
416
|
+
open_timeout: open_timeout,
|
417
|
+
faraday_config: faraday_config,
|
418
|
+
faraday_options: faraday_options
|
419
|
+
)
|
420
420
|
end
|
421
421
|
end
|
422
422
|
|
@@ -19,7 +19,7 @@ describe RestfulResource::HttpClient do
|
|
19
19
|
|
20
20
|
describe 'Builder configuration' do
|
21
21
|
it 'uses the typhoeus adapter' do
|
22
|
-
expect(
|
22
|
+
expect(connection.adapter).to eq Faraday::Adapter::Typhoeus
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'url_encodes requests' do
|
@@ -81,13 +81,13 @@ describe RestfulResource::HttpClient do
|
|
81
81
|
described_class.new(instrumentation: { app_name: 'rails', api_name: 'api', metric_class: FakeMetrics })
|
82
82
|
|
83
83
|
expect(RestfulResource::Instrumentation).to have_received(:new)
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
84
|
+
.with(app_name: 'rails',
|
85
|
+
api_name: 'api',
|
86
|
+
request_instrument_name: 'http.api',
|
87
|
+
cache_instrument_name: 'http_cache.api',
|
88
|
+
server_cache_instrument_name: 'cdn_metrics.api',
|
89
|
+
metric_class: FakeMetrics
|
90
|
+
)
|
91
91
|
end
|
92
92
|
|
93
93
|
it 'subscribes to the notifications' do
|
@@ -16,175 +16,97 @@ RSpec.describe RestfulResource::HttpClient do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
describe 'Basic HTTP' do
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
response = http_client(connection).get('http://httpbin.org/get')
|
25
|
-
expect(response.status).to eq 200
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'executes patch' do
|
29
|
-
connection = faraday_connection do |stubs|
|
30
|
-
# Note: request body is serialized as url-encoded so the stub body must be in the same format to match
|
31
|
-
stubs.patch('http://httpbin.org/patch', 'name=Alfred') { |_env| [200, {}, nil] }
|
32
|
-
end
|
33
|
-
|
34
|
-
response = http_client(connection).patch('http://httpbin.org/patch', data: { name: 'Alfred' })
|
35
|
-
expect(response.status).to eq 200
|
36
|
-
end
|
19
|
+
shared_examples 'error codes throw exception' do |verb, status, exception_class|
|
20
|
+
it "raises an error #{status}" do
|
21
|
+
url = "http://httpbin.org/status/#{status}"
|
37
22
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
stubs.put('http://httpbin.org/put', 'name=Alfred') { |_env| [200, {}, nil] }
|
42
|
-
end
|
43
|
-
|
44
|
-
response = http_client(connection).put('http://httpbin.org/put', data: { name: 'Alfred' })
|
45
|
-
expect(response.status).to eq 200
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'executes post' do
|
49
|
-
connection = faraday_connection do |stubs|
|
50
|
-
# Note: request body is serialized as url-encoded so the stub body must be in the same format to match
|
51
|
-
stubs.post('http://httpbin.org/post', 'name=Alfred') { |_env| [200, {}, %("name": "Alfred")] }
|
52
|
-
end
|
53
|
-
|
54
|
-
response = http_client(connection).post('http://httpbin.org/post', data: { name: 'Alfred' })
|
55
|
-
|
56
|
-
expect(response.body).to include 'name": "Alfred'
|
57
|
-
expect(response.status).to eq 200
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'executes delete' do
|
61
|
-
connection = faraday_connection do |stubs|
|
62
|
-
stubs.delete('http://httpbin.org/delete') { |_env| [200, {}, nil] }
|
63
|
-
end
|
64
|
-
|
65
|
-
response = http_client(connection).delete('http://httpbin.org/delete')
|
66
|
-
|
67
|
-
expect(response.status).to eq 200
|
68
|
-
end
|
69
|
-
|
70
|
-
it 'patch should raise error 409' do
|
71
|
-
connection = faraday_connection do |stubs|
|
72
|
-
stubs.patch('http://httpbin.org/status/409') { |_env| [409, {}, nil] }
|
73
|
-
end
|
74
|
-
|
75
|
-
expect { http_client(connection).patch('http://httpbin.org/status/409') }.to raise_error(RestfulResource::HttpClient::Conflict)
|
76
|
-
end
|
23
|
+
connection = faraday_connection do |stubs|
|
24
|
+
stubs.send(verb, url) { [status, {}, nil] }
|
25
|
+
end
|
77
26
|
|
78
|
-
|
79
|
-
connection = faraday_connection do |stubs|
|
80
|
-
stubs.patch('http://httpbin.org/status/422') { |_env| [422, {}, nil] }
|
27
|
+
expect { http_client(connection).send(verb, url) }.to raise_error(exception_class)
|
81
28
|
end
|
82
|
-
|
83
|
-
expect { http_client(connection).patch('http://httpbin.org/status/422') }.to raise_error(RestfulResource::HttpClient::UnprocessableEntity)
|
84
29
|
end
|
85
30
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
31
|
+
shared_examples 'raise an exception on error responses' do |verb|
|
32
|
+
include_examples 'error codes throw exception', verb, 409, RestfulResource::HttpClient::Conflict
|
33
|
+
include_examples 'error codes throw exception', verb, 404, RestfulResource::HttpClient::ResourceNotFound
|
34
|
+
include_examples 'error codes throw exception', verb, 422, RestfulResource::HttpClient::UnprocessableEntity
|
35
|
+
include_examples 'error codes throw exception', verb, 429, RestfulResource::HttpClient::TooManyRequests
|
36
|
+
include_examples 'error codes throw exception', verb, 502, RestfulResource::HttpClient::BadGateway
|
37
|
+
include_examples 'error codes throw exception', verb, 503, RestfulResource::HttpClient::ServiceUnavailable
|
38
|
+
include_examples 'error codes throw exception', verb, 504, RestfulResource::HttpClient::GatewayTimeout
|
90
39
|
|
91
|
-
|
40
|
+
include_examples 'error codes throw exception', verb, 418, RestfulResource::HttpClient::OtherHttpError
|
92
41
|
end
|
93
42
|
|
94
|
-
|
95
|
-
|
96
|
-
stubs.put('http://httpbin.org/status/422') { |_env| [422, {}, nil] }
|
97
|
-
end
|
43
|
+
context 'GET' do
|
44
|
+
include_examples 'raise an exception on error responses', :get
|
98
45
|
|
99
|
-
|
100
|
-
|
46
|
+
it 'executes get' do
|
47
|
+
connection = faraday_connection do |stubs|
|
48
|
+
stubs.get('http://httpbin.org/get') { |_env| [200, {}, nil] }
|
49
|
+
end
|
101
50
|
|
102
|
-
|
103
|
-
|
104
|
-
stubs.post('http://httpbin.org/status/422') { |_env| [422, {}, nil] }
|
51
|
+
response = http_client(connection).get('http://httpbin.org/get')
|
52
|
+
expect(response.status).to eq 200
|
105
53
|
end
|
106
|
-
|
107
|
-
expect { http_client(connection).post('http://httpbin.org/status/422') }.to raise_error(RestfulResource::HttpClient::UnprocessableEntity)
|
108
54
|
end
|
109
55
|
|
110
|
-
|
111
|
-
|
112
|
-
stubs.post('http://httpbin.org/status/429') { |_env| [429, {}, nil] }
|
113
|
-
end
|
56
|
+
context 'PATCH' do
|
57
|
+
include_examples 'raise an exception on error responses', :patch
|
114
58
|
|
115
|
-
|
116
|
-
|
59
|
+
it 'executes patch' do
|
60
|
+
connection = faraday_connection do |stubs|
|
61
|
+
# NOTE: request body is serialized as url-encoded so the stub body must be in the same format to match
|
62
|
+
stubs.patch('http://httpbin.org/patch', 'name=Alfred') { |_env| [200, {}, nil] }
|
63
|
+
end
|
117
64
|
|
118
|
-
|
119
|
-
|
120
|
-
stubs.patch('http://httpbin.org/status/502') { |_env| [502, {}, nil] }
|
65
|
+
response = http_client(connection).patch('http://httpbin.org/patch', data: { name: 'Alfred' })
|
66
|
+
expect(response.status).to eq 200
|
121
67
|
end
|
122
|
-
|
123
|
-
expect { http_client(connection).patch('http://httpbin.org/status/502') }.to raise_error(RestfulResource::HttpClient::BadGateway)
|
124
68
|
end
|
125
69
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
70
|
+
context 'PUT' do
|
71
|
+
include_examples 'raise an exception on error responses', :put
|
72
|
+
it 'executes put' do
|
73
|
+
connection = faraday_connection do |stubs|
|
74
|
+
# NOTE: request body is serialized as url-encoded so the stub body must be in the same format to match
|
75
|
+
stubs.put('http://httpbin.org/put', 'name=Alfred') { |_env| [200, {}, nil] }
|
76
|
+
end
|
133
77
|
|
134
|
-
|
135
|
-
|
136
|
-
stubs.post('http://httpbin.org/status/502') { |_env| [502, {}, nil] }
|
78
|
+
response = http_client(connection).put('http://httpbin.org/put', data: { name: 'Alfred' })
|
79
|
+
expect(response.status).to eq 200
|
137
80
|
end
|
138
|
-
|
139
|
-
expect { http_client(connection).post('http://httpbin.org/status/502') }.to raise_error(RestfulResource::HttpClient::BadGateway)
|
140
81
|
end
|
141
82
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
83
|
+
context 'POST' do
|
84
|
+
include_examples 'raise an exception on error responses', :post
|
85
|
+
it 'executes post' do
|
86
|
+
connection = faraday_connection do |stubs|
|
87
|
+
# NOTE: request body is serialized as url-encoded so the stub body must be in the same format to match
|
88
|
+
stubs.post('http://httpbin.org/post', 'name=Alfred') { |_env| [200, {}, %("name": "Alfred")] }
|
89
|
+
end
|
146
90
|
|
147
|
-
|
148
|
-
end
|
91
|
+
response = http_client(connection).post('http://httpbin.org/post', data: { name: 'Alfred' })
|
149
92
|
|
150
|
-
|
151
|
-
|
152
|
-
stubs.put('http://httpbin.org/status/503') { |_env| [503, {}, nil] }
|
93
|
+
expect(response.body).to include 'name": "Alfred'
|
94
|
+
expect(response.status).to eq 200
|
153
95
|
end
|
154
|
-
|
155
|
-
expect { http_client(connection).put('http://httpbin.org/status/503') }.to raise_error(RestfulResource::HttpClient::ServiceUnavailable)
|
156
96
|
end
|
157
97
|
|
158
|
-
|
159
|
-
|
160
|
-
stubs.post('http://httpbin.org/status/503') { |_env| [503, {}, nil] }
|
161
|
-
end
|
98
|
+
context 'DELETE' do
|
99
|
+
include_examples 'raise an exception on error responses', :delete
|
162
100
|
|
163
|
-
|
164
|
-
|
101
|
+
it 'executes delete' do
|
102
|
+
connection = faraday_connection do |stubs|
|
103
|
+
stubs.delete('http://httpbin.org/delete') { |_env| [200, {}, nil] }
|
104
|
+
end
|
165
105
|
|
166
|
-
|
167
|
-
connection = faraday_connection do |stubs|
|
168
|
-
stubs.post('http://httpbin.org/status/504') { |_env| [504, {}, nil] }
|
169
|
-
end
|
106
|
+
response = http_client(connection).delete('http://httpbin.org/delete')
|
170
107
|
|
171
|
-
|
172
|
-
end
|
173
|
-
|
174
|
-
it 'raises error on 404' do
|
175
|
-
connection = faraday_connection do |stubs|
|
176
|
-
stubs.get('http://httpbin.org/status/404') { |_env| [404, {}, nil] }
|
177
|
-
stubs.post('http://httpbin.org/status/404') { |_env| [404, {}, nil] }
|
178
|
-
stubs.patch('http://httpbin.org/status/404') { |_env| [404, {}, nil] }
|
179
|
-
stubs.put('http://httpbin.org/status/404') { |_env| [404, {}, nil] }
|
180
|
-
stubs.delete('http://httpbin.org/status/404') { |_env| [404, {}, nil] }
|
108
|
+
expect(response.status).to eq 200
|
181
109
|
end
|
182
|
-
|
183
|
-
expect { http_client(connection).get('http://httpbin.org/status/404') }.to raise_error(RestfulResource::HttpClient::ResourceNotFound)
|
184
|
-
expect { http_client(connection).delete('http://httpbin.org/status/404') }.to raise_error(RestfulResource::HttpClient::ResourceNotFound)
|
185
|
-
expect { http_client(connection).patch('http://httpbin.org/status/404', data: { name: 'Mad cow' }) }.to raise_error(RestfulResource::HttpClient::ResourceNotFound)
|
186
|
-
expect { http_client(connection).put('http://httpbin.org/status/404', data: { name: 'Mad cow' }) }.to raise_error(RestfulResource::HttpClient::ResourceNotFound)
|
187
|
-
expect { http_client(connection).post('http://httpbin.org/status/404', data: { name: 'Mad cow' }) }.to raise_error(RestfulResource::HttpClient::ResourceNotFound)
|
188
110
|
end
|
189
111
|
|
190
112
|
it 'raises Faraday::ConnectionFailed errors' do
|
@@ -210,14 +132,6 @@ RSpec.describe RestfulResource::HttpClient do
|
|
210
132
|
|
211
133
|
expect { http_client(connection).get('https://localhost:3005') }.to raise_error(RestfulResource::HttpClient::ClientError)
|
212
134
|
end
|
213
|
-
|
214
|
-
it 'raises OtherHttpError for other status response codes' do
|
215
|
-
connection = faraday_connection do |stubs|
|
216
|
-
stubs.get('http://httpbin.org/status/418') { |_env| [418, {}, nil] }
|
217
|
-
end
|
218
|
-
|
219
|
-
expect { http_client(connection).get('http://httpbin.org/status/418') }.to raise_error(RestfulResource::HttpClient::OtherHttpError)
|
220
|
-
end
|
221
135
|
end
|
222
136
|
|
223
137
|
describe 'Authentication' do
|
@@ -305,10 +219,10 @@ RSpec.describe RestfulResource::HttpClient do
|
|
305
219
|
conn
|
306
220
|
end
|
307
221
|
|
308
|
-
|
309
222
|
context 'when explicit timeout set on connection' do
|
310
223
|
let(:timeout) { 5 }
|
311
224
|
let(:required_headers) { { 'X-Client-Timeout' => 5 } }
|
225
|
+
|
312
226
|
it 'sets X-Client-Timeout correctly' do
|
313
227
|
response = http_client.get('http://httpbin.org/get')
|
314
228
|
|