shutl_resource 0.9.3 → 0.9.4
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.
- data/lib/shutl/resource/rest_class_methods.rb +36 -29
- data/lib/shutl/resource/version.rb +1 -1
- data/spec/rest_resource_spec.rb +35 -35
- metadata +5 -5
@@ -2,12 +2,12 @@ module Shutl::Resource
|
|
2
2
|
module RestClassMethods
|
3
3
|
def find(args, params = {})
|
4
4
|
unless args.kind_of?(Hash)
|
5
|
-
id
|
5
|
+
id = args
|
6
6
|
args = { resource_id_name => id }
|
7
7
|
end
|
8
8
|
auth_options = { auth: params.delete(:auth), from: params.delete(:from) }
|
9
|
-
url
|
10
|
-
response
|
9
|
+
url = member_url args.dup, params
|
10
|
+
response = get url, headers_with_auth(auth_options)
|
11
11
|
|
12
12
|
|
13
13
|
check_fail response, "Failed to find #{name} with the id #{id}"
|
@@ -24,21 +24,20 @@ module Shutl::Resource
|
|
24
24
|
attributes.delete "response"
|
25
25
|
|
26
26
|
response = post(
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
)
|
27
|
+
url,
|
28
|
+
{ body: { @resource_name => attributes }.to_json }.merge(headers_with_auth(options))
|
29
|
+
)
|
31
30
|
|
32
31
|
check_fail response, "Create failed"
|
33
32
|
|
34
|
-
parsed
|
35
|
-
|
33
|
+
parsed = response.parsed_response || {}
|
36
34
|
attributes = parsed[@resource_name] || {}
|
35
|
+
|
37
36
|
new_object attributes, response
|
38
37
|
end
|
39
38
|
|
40
39
|
def destroy instance, options = {}
|
41
|
-
message =
|
40
|
+
message = "Failed to destroy #{name.downcase.pluralize}"
|
42
41
|
|
43
42
|
perform_action(
|
44
43
|
instance,
|
@@ -52,9 +51,12 @@ module Shutl::Resource
|
|
52
51
|
#TODO: this is sometimes a hash and sometimes a Rest - need to rethink this
|
53
52
|
attributes = instance.attributes rescue instance
|
54
53
|
|
55
|
-
|
56
|
-
|
57
|
-
|
54
|
+
payload = {
|
55
|
+
body: { @resource_name => convert_new_id(attributes) }.to_json
|
56
|
+
}
|
57
|
+
|
58
|
+
payload_with_headers = payload.merge(headers_with_auth options)
|
59
|
+
response = perform_action(instance, :put, payload, "Save failed")
|
58
60
|
|
59
61
|
response.success?
|
60
62
|
end
|
@@ -66,12 +68,12 @@ module Shutl::Resource
|
|
66
68
|
|
67
69
|
def all(args = {})
|
68
70
|
auth_options = { auth: args.delete(:auth), from: args.delete(:from) }
|
69
|
-
partition
|
71
|
+
partition = args.partition { |key, value| !remote_collection_url.index(":#{key}").nil? }
|
70
72
|
|
71
|
-
url_args = partition.first.inject({}) { |h,pair| h[pair.first] = pair.last
|
72
|
-
params = partition.last.
|
73
|
+
url_args = partition.first.inject({}) { |h, pair| h[pair.first] = pair.last; h }
|
74
|
+
params = partition.last.inject({}) { |h, pair| h[pair.first] = pair.last; h }
|
73
75
|
|
74
|
-
url
|
76
|
+
url = generate_collection_url url_args, params
|
75
77
|
response = get url, headers_with_auth(auth_options)
|
76
78
|
|
77
79
|
check_fail response, "Failed to find all #{name.downcase.pluralize}"
|
@@ -94,13 +96,18 @@ module Shutl::Resource
|
|
94
96
|
|
95
97
|
delegate :each, to: :collection
|
96
98
|
|
97
|
-
class Pagination < Struct.new(:page,
|
99
|
+
class Pagination < Struct.new(:page,
|
100
|
+
:items_on_page,
|
101
|
+
:total_count,
|
102
|
+
:number_of_pages)
|
103
|
+
end
|
98
104
|
|
99
105
|
def pagination
|
100
|
-
return unless @pagination
|
106
|
+
return unless @pagination.present?
|
101
107
|
Pagination.new(@pagination['page'],
|
102
|
-
@pagination['
|
103
|
-
@pagination['
|
108
|
+
@pagination['items_on_page'],
|
109
|
+
@pagination['total_count'],
|
110
|
+
@pagination['number_of_pages'])
|
104
111
|
end
|
105
112
|
end
|
106
113
|
|
@@ -134,7 +141,7 @@ module Shutl::Resource
|
|
134
141
|
|
135
142
|
def convert_new_id attributes
|
136
143
|
if attributes[:new_id]
|
137
|
-
attributes = attributes.clone.tap {|h| h[:id] = h[:new_id]; h.delete(:new_id)}
|
144
|
+
attributes = attributes.clone.tap { |h| h[:id] = h[:new_id]; h.delete(:new_id) }
|
138
145
|
end
|
139
146
|
|
140
147
|
attributes
|
@@ -143,7 +150,7 @@ module Shutl::Resource
|
|
143
150
|
def add_resource_id_to args={}
|
144
151
|
args = args.dup.with_indifferent_access
|
145
152
|
unless args.has_key? "id"
|
146
|
-
args.merge!({"id" => args[resource_id_name]})
|
153
|
+
args.merge!({ "id" => args[resource_id_name] })
|
147
154
|
end
|
148
155
|
args
|
149
156
|
end
|
@@ -168,17 +175,17 @@ module Shutl::Resource
|
|
168
175
|
|
169
176
|
def headers_with_auth options = {}
|
170
177
|
headers.tap do |h|
|
171
|
-
|
172
|
-
|
178
|
+
h['Authorization'] = "Bearer #{options[:auth]}" if options[:auth]
|
179
|
+
h['From'] = "#{options[:from]}" if options[:from]
|
173
180
|
end
|
174
181
|
{ headers: headers }
|
175
182
|
end
|
176
183
|
|
177
184
|
def perform_action instance, verb, args, failure_message
|
178
|
-
attributes = instance.is_a?(Hash) ?
|
185
|
+
attributes = instance.is_a?(Hash) ? instance : instance.attributes
|
179
186
|
attributes.delete "response" #used in debugging requests/responses
|
180
187
|
|
181
|
-
url
|
188
|
+
url = member_url attributes
|
182
189
|
response = send verb, url, args
|
183
190
|
|
184
191
|
check_fail response, failure_message
|
@@ -199,7 +206,7 @@ module Shutl::Resource
|
|
199
206
|
end
|
200
207
|
|
201
208
|
def check_fail response, message
|
202
|
-
c
|
209
|
+
c = response.code
|
203
210
|
failure_klass = case c
|
204
211
|
when 299 then Shutl::NoQuotesGenerated
|
205
212
|
when 400 then Shutl::BadRequest
|
@@ -250,7 +257,7 @@ module Shutl::Resource
|
|
250
257
|
|
251
258
|
private
|
252
259
|
def replace_args_from_pattern! args, url
|
253
|
-
args = args.reject! do |key,value|
|
260
|
+
args = args.reject! do |key, value|
|
254
261
|
if s = url[":#{key}"]
|
255
262
|
url.gsub!(s, value.to_s)
|
256
263
|
end
|
data/spec/rest_resource_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Shutl::Resource::Rest do
|
4
4
|
let(:headers) do
|
5
|
-
{'Accept'=>'application/json', 'Content-Type'=>'application/json'}
|
5
|
+
{ 'Accept' => 'application/json', 'Content-Type' => 'application/json' }
|
6
6
|
end
|
7
7
|
|
8
8
|
it 'should include the REST verb' do
|
@@ -12,14 +12,14 @@ describe Shutl::Resource::Rest do
|
|
12
12
|
TestRest.should respond_to :delete
|
13
13
|
end
|
14
14
|
|
15
|
-
let(:resource) { TestRest.new(a: 'a', b: 2)
|
15
|
+
let(:resource) { TestRest.new(a: 'a', b: 2) }
|
16
16
|
|
17
17
|
describe '#find' do
|
18
18
|
context 'with no arguments' do
|
19
19
|
before do
|
20
20
|
@request = stub_request(:get, 'http://host/test_rests/a').
|
21
|
-
to_return(:status
|
22
|
-
:body
|
21
|
+
to_return(:status => 200,
|
22
|
+
:body => '{"test_rest": { "a": "a", "b": 2 }}',
|
23
23
|
:headers => headers)
|
24
24
|
end
|
25
25
|
|
@@ -45,14 +45,14 @@ describe Shutl::Resource::Rest do
|
|
45
45
|
|
46
46
|
Shutl::Resource.raise_exceptions_on_validation = true
|
47
47
|
{
|
48
|
-
400
|
49
|
-
401
|
50
|
-
403
|
51
|
-
404
|
52
|
-
409
|
53
|
-
410
|
54
|
-
422
|
55
|
-
503
|
48
|
+
400 => Shutl::BadRequest,
|
49
|
+
401 => Shutl::UnauthorizedAccess,
|
50
|
+
403 => Shutl::ForbiddenAccess,
|
51
|
+
404 => Shutl::ResourceNotFound,
|
52
|
+
409 => Shutl::ResourceConflict,
|
53
|
+
410 => Shutl::ResourceGone,
|
54
|
+
422 => Shutl::ResourceInvalid,
|
55
|
+
503 => Shutl::ServiceUnavailable,
|
56
56
|
501..502 => Shutl::ServerError,
|
57
57
|
504..599 => Shutl::ServerError
|
58
58
|
}.each do |status, exception|
|
@@ -62,7 +62,7 @@ describe Shutl::Resource::Rest do
|
|
62
62
|
stub_request(:get, 'http://host/test_rests/b').
|
63
63
|
to_return(status: s.to_i)
|
64
64
|
|
65
|
-
expect(->{TestRest.find('b')}).to raise_error(exception)
|
65
|
+
expect(-> { TestRest.find('b') }).to raise_error(exception)
|
66
66
|
end
|
67
67
|
else
|
68
68
|
stub_request(:get, 'http://host/test_rests/b').
|
@@ -83,7 +83,7 @@ describe Shutl::Resource::Rest do
|
|
83
83
|
|
84
84
|
it 'should encode the url to support spaces' do
|
85
85
|
request = stub_request(:get, 'http://host/test_rests/new%20resource').
|
86
|
-
to_return(:status
|
86
|
+
to_return(:status => 200, :body => '{"test_rest": {}}',
|
87
87
|
:headers => headers)
|
88
88
|
|
89
89
|
TestRest.find('new resource')
|
@@ -110,9 +110,9 @@ describe Shutl::Resource::Rest do
|
|
110
110
|
|
111
111
|
context 'with no arguments' do
|
112
112
|
before do
|
113
|
-
body
|
113
|
+
body = '{
|
114
114
|
"test_rests": [{ "a": "a", "b": 2 }],
|
115
|
-
"pagination":{"page": 0,"
|
115
|
+
"pagination":{"page": 0,"items_on_page": 1,"total_count": 3, "number_of_pages": 3}
|
116
116
|
}'
|
117
117
|
@request = stub_request(:get, 'http://host/test_rests').
|
118
118
|
to_return(:status => 200, :body => body, :headers => headers)
|
@@ -139,16 +139,17 @@ describe Shutl::Resource::Rest do
|
|
139
139
|
|
140
140
|
it 'should provide accessor to pagination' do
|
141
141
|
resource = TestRest.all
|
142
|
-
resource.pagination.page
|
143
|
-
resource.pagination.
|
144
|
-
resource.pagination.
|
142
|
+
resource.pagination.page.should == 0
|
143
|
+
resource.pagination.items_on_page.should == 1
|
144
|
+
resource.pagination.total_count.should == 3
|
145
|
+
resource.pagination.number_of_pages.should == 3
|
145
146
|
end
|
146
147
|
|
147
148
|
it 'should raise an error of the request fails' do
|
148
149
|
stub_request(:get, 'http://host/test_rests').
|
149
150
|
to_return(:status => 403)
|
150
151
|
|
151
|
-
lambda { TestRest.all}.should raise_error(Shutl::ForbiddenAccess)
|
152
|
+
lambda { TestRest.all }.should raise_error(Shutl::ForbiddenAccess)
|
152
153
|
|
153
154
|
end
|
154
155
|
end
|
@@ -178,13 +179,13 @@ describe Shutl::Resource::Rest do
|
|
178
179
|
Shutl::Resource.raise_exceptions_on_validation = true
|
179
180
|
end
|
180
181
|
specify do
|
181
|
-
errors = {"base" => "invalid", "some_field" => "some field is invalid"}
|
182
|
-
body
|
182
|
+
errors = { "base" => "invalid", "some_field" => "some field is invalid" }
|
183
|
+
body = { "errors" => errors }.to_json
|
183
184
|
|
184
185
|
@request = stub_request(:post, 'http://host/test_rests').
|
185
186
|
to_return(:status => 422, body: body, :headers => headers)
|
186
187
|
|
187
|
-
expect{@instance = TestRest.create}.to_not raise_error Shutl::ResourceInvalid
|
188
|
+
expect { @instance = TestRest.create }.to_not raise_error Shutl::ResourceInvalid
|
188
189
|
|
189
190
|
@request.should have_been_requested
|
190
191
|
@instance.should_not be_valid
|
@@ -208,7 +209,7 @@ describe Shutl::Resource::Rest do
|
|
208
209
|
|
209
210
|
it 'should raise error if the remote server returns an error' do
|
210
211
|
request = stub_post 403
|
211
|
-
expect(->{TestRest.create}).to raise_error Shutl::ForbiddenAccess
|
212
|
+
expect(-> { TestRest.create }).to raise_error Shutl::ForbiddenAccess
|
212
213
|
|
213
214
|
request.should have_been_requested
|
214
215
|
end
|
@@ -216,7 +217,7 @@ describe Shutl::Resource::Rest do
|
|
216
217
|
|
217
218
|
it 'should post the header content-type: json' do
|
218
219
|
request = stub_request(:post, 'http://host/test_rests').
|
219
|
-
with(:body => "{\"test_rest\":{}}", :headers => headers
|
220
|
+
with(:body => "{\"test_rest\":{}}", :headers => headers)
|
220
221
|
|
221
222
|
TestRest.create
|
222
223
|
|
@@ -227,13 +228,13 @@ describe Shutl::Resource::Rest do
|
|
227
228
|
request = stub_request(:post, 'http://host/test_rests').
|
228
229
|
to_return(:status => 400)
|
229
230
|
|
230
|
-
expect(->{ TestRest.create}).to raise_error(Shutl::BadRequest)
|
231
|
+
expect(-> { TestRest.create }).to raise_error(Shutl::BadRequest)
|
231
232
|
end
|
232
233
|
|
233
234
|
|
234
235
|
it 'shoud create a new ressource with the attributes' do
|
235
236
|
request = stub_request(:post, "http://host/test_rests").
|
236
|
-
with(body:
|
237
|
+
with(body: '{"test_rest":{"a":"a","b":"b"}}',
|
237
238
|
headers: headers)
|
238
239
|
|
239
240
|
TestRest.create(a: 'a', b: 'b')
|
@@ -264,7 +265,7 @@ describe Shutl::Resource::Rest do
|
|
264
265
|
stub_request(:delete, 'http://host/test_rests/a').
|
265
266
|
to_return(status: 400)
|
266
267
|
|
267
|
-
expect(->{TestRest.destroy(id: 'a')}).to raise_error Shutl::BadRequest
|
268
|
+
expect(-> { TestRest.destroy(id: 'a') }).to raise_error Shutl::BadRequest
|
268
269
|
end
|
269
270
|
end
|
270
271
|
|
@@ -288,7 +289,7 @@ describe Shutl::Resource::Rest do
|
|
288
289
|
stub_request(:put, 'http://host/test_rests/a').
|
289
290
|
to_return(status: 400)
|
290
291
|
|
291
|
-
->{resource.save}.should raise_error Shutl::BadRequest
|
292
|
+
-> { resource.save }.should raise_error Shutl::BadRequest
|
292
293
|
end
|
293
294
|
|
294
295
|
|
@@ -307,15 +308,15 @@ describe Shutl::Resource::Rest do
|
|
307
308
|
stub_request(:put, 'http://host/test_rests/a').
|
308
309
|
to_return(status: 400)
|
309
310
|
|
310
|
-
expect(->{ resource.save }).to raise_error(Shutl::BadRequest)
|
311
|
+
expect(-> { resource.save }).to raise_error(Shutl::BadRequest)
|
311
312
|
end
|
312
313
|
end
|
313
314
|
|
314
315
|
describe '#update!' do
|
315
316
|
it 'should post the new json representation' do
|
316
317
|
request = stub_request(:put, "http://host/test_rests/a").
|
317
|
-
with(:body
|
318
|
-
:headers => {'Accept'=>'application/json', 'Content-Type'=>'application/json'}).
|
318
|
+
with(:body => { test_rest: { a: "a", b: "b", id: "a" } },
|
319
|
+
:headers => { 'Accept' => 'application/json', 'Content-Type' => 'application/json' }).
|
319
320
|
to_return(:status => 200, :body => "", :headers => {})
|
320
321
|
|
321
322
|
test_resource = TestRest.new
|
@@ -327,8 +328,8 @@ describe Shutl::Resource::Rest do
|
|
327
328
|
|
328
329
|
it 'should convert new_id to id in attributes' do
|
329
330
|
request = stub_request(:put, "http://host/test_rests/a").
|
330
|
-
with(:body
|
331
|
-
:headers => {'Accept'=>'application/json', 'Content-Type'=>'application/json'}).
|
331
|
+
with(:body => { test_rest: { a: "a", b: "b", id: "xxx" } },
|
332
|
+
:headers => { 'Accept' => 'application/json', 'Content-Type' => 'application/json' }).
|
332
333
|
to_return(:status => 200, :body => "", :headers => {})
|
333
334
|
|
334
335
|
test_resource = TestRest.new
|
@@ -340,5 +341,4 @@ describe Shutl::Resource::Rest do
|
|
340
341
|
end
|
341
342
|
|
342
343
|
|
343
|
-
|
344
344
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shutl_resource
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2013-06-
|
14
|
+
date: 2013-06-18 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: httparty
|
@@ -171,7 +171,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
171
171
|
version: '0'
|
172
172
|
segments:
|
173
173
|
- 0
|
174
|
-
hash:
|
174
|
+
hash: 988710357628793965
|
175
175
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
176
176
|
none: false
|
177
177
|
requirements:
|
@@ -180,10 +180,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
180
180
|
version: '0'
|
181
181
|
segments:
|
182
182
|
- 0
|
183
|
-
hash:
|
183
|
+
hash: 988710357628793965
|
184
184
|
requirements: []
|
185
185
|
rubyforge_project:
|
186
|
-
rubygems_version: 1.8.
|
186
|
+
rubygems_version: 1.8.25
|
187
187
|
signing_key:
|
188
188
|
specification_version: 3
|
189
189
|
summary: Manage Shutl Rest resource. Parse/Serialize JSON
|