restful_resource 2.5.0 → 2.5.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 +4 -4
- data/CHANGELOG.md +6 -0
- data/lib/restful_resource/rails_validations.rb +10 -13
- data/lib/restful_resource/version.rb +1 -1
- data/spec/restful_resource/base_spec.rb +51 -0
- data/spec/restful_resource/http_client_spec.rb +44 -0
- data/spec/restful_resource/rails_validations_spec.rb +68 -3
- data/spec/spec_helper.rb +13 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1f405ccf5d3f49ac11166ce73e0268fc4203203a63b3e31999d9f2cfbc416bc
|
4
|
+
data.tar.gz: 6d07fc35aad7fcf4ee6d2a0236476bd30ac68bbea0cc252a85e5b6d79ad216b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff4a2dea42bcc6bdcd56f539757dad0b3c4ab185d4bf73be11d098176b7af030f4cce005addf6d5e9d6f907605de0406f81b53645110549ee67395b56bacc2f9
|
7
|
+
data.tar.gz: 75decbc1a7c0058bc7476efbf05981a6bee4771663e285734b3c587a41c4b61b26f87960717216d0a28ff5e1bcade60e7f025232dc577cb9a273d13844852d5e
|
data/CHANGELOG.md
CHANGED
@@ -1,18 +1,12 @@
|
|
1
1
|
module RestfulResource
|
2
2
|
module RailsValidations
|
3
3
|
module ClassMethods
|
4
|
-
def put(id, data: {}, **)
|
5
|
-
super
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
data.merge(errors)
|
11
|
-
else
|
12
|
-
data.merge(errors: errors)
|
13
|
-
end
|
14
|
-
result = result.merge(id: id)
|
15
|
-
new(result)
|
4
|
+
def put(id, data: {}, **others)
|
5
|
+
with_validations(id, data: data) { super }
|
6
|
+
end
|
7
|
+
|
8
|
+
def patch(id, data: {}, **others)
|
9
|
+
with_validations(id, data: data) { super }
|
16
10
|
end
|
17
11
|
|
18
12
|
def post(data: {}, **)
|
@@ -25,7 +19,7 @@ module RestfulResource
|
|
25
19
|
|
26
20
|
private
|
27
21
|
|
28
|
-
def with_validations(data: {})
|
22
|
+
def with_validations(id = nil, data: {})
|
29
23
|
yield
|
30
24
|
rescue HttpClient::UnprocessableEntity => e
|
31
25
|
errors = parse_json(e.response.body)
|
@@ -35,6 +29,9 @@ module RestfulResource
|
|
35
29
|
else
|
36
30
|
data.merge(errors: errors)
|
37
31
|
end
|
32
|
+
|
33
|
+
result = result.merge(id: id) if id
|
34
|
+
|
38
35
|
new(result)
|
39
36
|
end
|
40
37
|
end
|
@@ -204,6 +204,57 @@ RSpec.describe RestfulResource::Base do
|
|
204
204
|
end
|
205
205
|
end
|
206
206
|
|
207
|
+
describe '#patch' do
|
208
|
+
it 'patchs no data with no params' do
|
209
|
+
expected_response = RestfulResource::Response.new(body: { name: 'Audi' }.to_json, status: 200)
|
210
|
+
expect_patch('http://api.carwow.co.uk/makes/1', expected_response)
|
211
|
+
|
212
|
+
object = Make.patch(1)
|
213
|
+
|
214
|
+
expect(object.name).to eq 'Audi'
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'patchs no data with no params passed' do
|
218
|
+
expected_response = RestfulResource::Response.new(body: { name: 'Audi' }.to_json, status: 200)
|
219
|
+
expect_patch('http://api.carwow.co.uk/makes/1?make_slug=Volkswagen', expected_response)
|
220
|
+
|
221
|
+
object = Make.patch(1, make_slug: 'Volkswagen')
|
222
|
+
|
223
|
+
expect(object.name).to eq 'Audi'
|
224
|
+
end
|
225
|
+
|
226
|
+
it 'patchs data with params passed' do
|
227
|
+
data = { make_slug: 'Audi' }
|
228
|
+
|
229
|
+
expected_response = RestfulResource::Response.new(body: { name: 'Audi' }.to_json, status: 200)
|
230
|
+
expect_patch('http://api.carwow.co.uk/makes/1', expected_response, data: data)
|
231
|
+
|
232
|
+
object = Make.patch(1, data: { make_slug: 'Audi' })
|
233
|
+
|
234
|
+
expect(object.name).to eq 'Audi'
|
235
|
+
end
|
236
|
+
|
237
|
+
it 'patchs data with params passed' do
|
238
|
+
data = { make_slug: 'Audi' }
|
239
|
+
|
240
|
+
expected_response = RestfulResource::Response.new(body: { name: 'Audi' }.to_json, status: 200)
|
241
|
+
expect_patch('http://api.carwow.co.uk/makes/1?make_slug=Volkswagen', expected_response, data: data)
|
242
|
+
|
243
|
+
object = Make.patch(1, data: data, make_slug: 'Volkswagen')
|
244
|
+
|
245
|
+
expect(object.name).to eq 'Audi'
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'accepts custom headers' do
|
249
|
+
expect_patch('http://api.carwow.co.uk/makes/1',
|
250
|
+
RestfulResource::Response.new,
|
251
|
+
headers: { accept: 'application/json' }
|
252
|
+
)
|
253
|
+
|
254
|
+
Make.patch(1, data: {}, headers: { accept: 'application/json' })
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
207
258
|
describe '#put' do
|
208
259
|
it 'puts no data with no params' do
|
209
260
|
expected_response = RestfulResource::Response.new(body: { name: 'Audi' }.to_json, status: 200)
|
@@ -25,6 +25,16 @@ RSpec.describe RestfulResource::HttpClient do
|
|
25
25
|
expect(response.status).to eq 200
|
26
26
|
end
|
27
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
|
37
|
+
|
28
38
|
it 'executes put' do
|
29
39
|
connection = faraday_connection do |stubs|
|
30
40
|
# Note: request body is serialized as url-encoded so the stub body must be in the same format to match
|
@@ -57,6 +67,22 @@ RSpec.describe RestfulResource::HttpClient do
|
|
57
67
|
expect(response.status).to eq 200
|
58
68
|
end
|
59
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
|
77
|
+
|
78
|
+
it 'patch should raise error 422' do
|
79
|
+
connection = faraday_connection do |stubs|
|
80
|
+
stubs.patch('http://httpbin.org/status/422') { |_env| [422, {}, nil] }
|
81
|
+
end
|
82
|
+
|
83
|
+
expect { http_client(connection).patch('http://httpbin.org/status/422') }.to raise_error(RestfulResource::HttpClient::UnprocessableEntity)
|
84
|
+
end
|
85
|
+
|
60
86
|
it 'put should raise error 409' do
|
61
87
|
connection = faraday_connection do |stubs|
|
62
88
|
stubs.put('http://httpbin.org/status/409') { |_env| [409, {}, nil] }
|
@@ -89,6 +115,14 @@ RSpec.describe RestfulResource::HttpClient do
|
|
89
115
|
expect { http_client(connection).post('http://httpbin.org/status/429') }.to raise_error(RestfulResource::HttpClient::TooManyRequests)
|
90
116
|
end
|
91
117
|
|
118
|
+
it 'patch should raise error 502' do
|
119
|
+
connection = faraday_connection do |stubs|
|
120
|
+
stubs.patch('http://httpbin.org/status/502') { |_env| [502, {}, nil] }
|
121
|
+
end
|
122
|
+
|
123
|
+
expect { http_client(connection).patch('http://httpbin.org/status/502') }.to raise_error(RestfulResource::HttpClient::BadGateway)
|
124
|
+
end
|
125
|
+
|
92
126
|
it 'put should raise error 502' do
|
93
127
|
connection = faraday_connection do |stubs|
|
94
128
|
stubs.put('http://httpbin.org/status/502') { |_env| [502, {}, nil] }
|
@@ -105,6 +139,14 @@ RSpec.describe RestfulResource::HttpClient do
|
|
105
139
|
expect { http_client(connection).post('http://httpbin.org/status/502') }.to raise_error(RestfulResource::HttpClient::BadGateway)
|
106
140
|
end
|
107
141
|
|
142
|
+
it 'patch should raise error 503' do
|
143
|
+
connection = faraday_connection do |stubs|
|
144
|
+
stubs.patch('http://httpbin.org/status/503') { |_env| [503, {}, nil] }
|
145
|
+
end
|
146
|
+
|
147
|
+
expect { http_client(connection).patch('http://httpbin.org/status/503') }.to raise_error(RestfulResource::HttpClient::ServiceUnavailable)
|
148
|
+
end
|
149
|
+
|
108
150
|
it 'put should raise error 503' do
|
109
151
|
connection = faraday_connection do |stubs|
|
110
152
|
stubs.put('http://httpbin.org/status/503') { |_env| [503, {}, nil] }
|
@@ -125,12 +167,14 @@ RSpec.describe RestfulResource::HttpClient do
|
|
125
167
|
connection = faraday_connection do |stubs|
|
126
168
|
stubs.get('http://httpbin.org/status/404') { |_env| [404, {}, nil] }
|
127
169
|
stubs.post('http://httpbin.org/status/404') { |_env| [404, {}, nil] }
|
170
|
+
stubs.patch('http://httpbin.org/status/404') { |_env| [404, {}, nil] }
|
128
171
|
stubs.put('http://httpbin.org/status/404') { |_env| [404, {}, nil] }
|
129
172
|
stubs.delete('http://httpbin.org/status/404') { |_env| [404, {}, nil] }
|
130
173
|
end
|
131
174
|
|
132
175
|
expect { http_client(connection).get('http://httpbin.org/status/404') }.to raise_error(RestfulResource::HttpClient::ResourceNotFound)
|
133
176
|
expect { http_client(connection).delete('http://httpbin.org/status/404') }.to raise_error(RestfulResource::HttpClient::ResourceNotFound)
|
177
|
+
expect { http_client(connection).patch('http://httpbin.org/status/404', data: { name: 'Mad cow' }) }.to raise_error(RestfulResource::HttpClient::ResourceNotFound)
|
134
178
|
expect { http_client(connection).put('http://httpbin.org/status/404', data: { name: 'Mad cow' }) }.to raise_error(RestfulResource::HttpClient::ResourceNotFound)
|
135
179
|
expect { http_client(connection).post('http://httpbin.org/status/404', data: { name: 'Mad cow' }) }.to raise_error(RestfulResource::HttpClient::ResourceNotFound)
|
136
180
|
end
|
@@ -7,13 +7,78 @@ RSpec.describe RestfulResource::RailsValidations do
|
|
7
7
|
allow(RestfulResource::Base).to receive(:http).and_return(@mock_http)
|
8
8
|
end
|
9
9
|
|
10
|
-
context '#
|
10
|
+
context '#patch without errors' do
|
11
11
|
before do
|
12
12
|
data = { name: 'Barak' }
|
13
13
|
expected_response = RestfulResource::Response.new(body: { name: 'Barak' }.to_json)
|
14
|
-
|
14
|
+
expect_patch('http://api.carwow.co.uk/dealers/1', expected_response, data: data)
|
15
15
|
|
16
|
-
@object = Dealer.
|
16
|
+
@object = Dealer.patch(1, data: data)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'returns object' do
|
20
|
+
expect(@object.name).to eq 'Barak'
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'returns valid object' do
|
24
|
+
expect(@object).to be_valid
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context '#patch with errors' do
|
29
|
+
before do
|
30
|
+
data = { name: 'Leonardo' }
|
31
|
+
@error = 'Cannot use Ninja Turtles names'
|
32
|
+
expected_response = RestfulResource::Response.new(body: { errors: [@error] }.to_json)
|
33
|
+
expect_patch_with_unprocessable_entity('http://api.carwow.co.uk/dealers/1', expected_response, data: data)
|
34
|
+
|
35
|
+
@object = Dealer.patch(1, data: data)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'has an error' do
|
39
|
+
expect(@object.errors.count).to eq 1
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'has correct error' do
|
43
|
+
expect(@object.errors.first).to eq @error
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'returns properly built object' do
|
47
|
+
expect(@object.name).to eq 'Leonardo'
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'returns not valid object' do
|
51
|
+
expect(@object).not_to be_valid
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'handles errors returned as root object' do
|
55
|
+
data = { name: 'Michelangelo' }
|
56
|
+
expected_response = RestfulResource::Response.new(body: @error.to_json)
|
57
|
+
expect_patch_with_unprocessable_entity('http://api.carwow.co.uk/dealers/1', expected_response, data: data)
|
58
|
+
|
59
|
+
@object = Dealer.patch(1, data: data)
|
60
|
+
expect(@object).not_to be_valid
|
61
|
+
expect(@object.errors).to eq @error
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'returns the resource id as part of the response' do
|
65
|
+
data = { name: 'Michelangelo' }
|
66
|
+
expected_response = RestfulResource::Response.new(body: @error.to_json)
|
67
|
+
expect_patch_with_unprocessable_entity('http://api.carwow.co.uk/dealers/1', expected_response, data: data)
|
68
|
+
|
69
|
+
@object = Dealer.patch(1, data: data)
|
70
|
+
expect(@object).not_to be_valid
|
71
|
+
expect(@object.id).to be(1)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context '#patch without errors' do
|
76
|
+
before do
|
77
|
+
data = { name: 'Barak' }
|
78
|
+
expected_response = RestfulResource::Response.new(body: { name: 'Barak' }.to_json)
|
79
|
+
expect_patch('http://api.carwow.co.uk/dealers/1', expected_response, data: data)
|
80
|
+
|
81
|
+
@object = Dealer.patch(1, data: data)
|
17
82
|
end
|
18
83
|
|
19
84
|
it 'returns object' do
|
data/spec/spec_helper.rb
CHANGED
@@ -20,6 +20,12 @@ def expect_delete(url, response, headers: {}, open_timeout: nil, timeout: nil)
|
|
20
20
|
.and_return(response)
|
21
21
|
end
|
22
22
|
|
23
|
+
def expect_patch(url, response, data: {}, headers: {}, open_timeout: nil, timeout: nil)
|
24
|
+
expect(@mock_http).to receive(:patch)
|
25
|
+
.with(url, data: data, headers: headers, open_timeout: open_timeout, timeout: timeout)
|
26
|
+
.and_return(response)
|
27
|
+
end
|
28
|
+
|
23
29
|
def expect_put(url, response, data: {}, headers: {}, open_timeout: nil, timeout: nil)
|
24
30
|
expect(@mock_http).to receive(:put)
|
25
31
|
.with(url, data: data, headers: headers, open_timeout: open_timeout, timeout: timeout)
|
@@ -39,6 +45,13 @@ def expect_get_with_unprocessable_entity(url, response)
|
|
39
45
|
expect(@mock_http).to receive(:get).with(url, headers: {}, open_timeout: nil, timeout: nil).and_raise(exception)
|
40
46
|
end
|
41
47
|
|
48
|
+
def expect_patch_with_unprocessable_entity(url, response, data: {})
|
49
|
+
request = RestfulResource::Request.new(:patch, url, body: data)
|
50
|
+
rest_client_response = OpenStruct.new(body: response.body, headers: response.headers, code: response.status)
|
51
|
+
exception = RestfulResource::HttpClient::UnprocessableEntity.new(request, rest_client_response)
|
52
|
+
expect(@mock_http).to receive(:patch).with(url, data: data, headers: {}, open_timeout: nil, timeout: nil).and_raise(exception)
|
53
|
+
end
|
54
|
+
|
42
55
|
def expect_put_with_unprocessable_entity(url, response, data: {})
|
43
56
|
request = RestfulResource::Request.new(:put, url, body: data)
|
44
57
|
rest_client_response = OpenStruct.new(body: response.body, headers: response.headers, code: response.status)
|