pluct 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/lib/pluct/extensions/json.rb +9 -0
- data/lib/pluct/helpers/request.rb +5 -5
- data/lib/pluct/resource.rb +32 -14
- data/lib/pluct/schema.rb +17 -7
- data/lib/pluct/version.rb +1 -1
- data/lib/pluct.rb +3 -18
- data/spec/integration/resource_spec.rb +23 -0
- data/spec/pluct/extensions/json_spec.rb +13 -0
- data/spec/pluct/resource_spec.rb +39 -16
- metadata +7 -4
- data/spec/acceptance/pluct_spec.rb +0 -20
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
OTgzNTBjZDdhYmQ0YjcyMTZhMWMzYjM3NDE0YzRjY2E2MWJhMzczZQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZjA1NjdlOWQwOTc3ZDVkNTBlNjA5NDA2NjYxODFhMGRiZTk4ZmMxZQ==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
OTcyZjMzZjVjYTdlZTkwMjNiYzczYmRlNjdmMTcwMzNiM2FhODdkNjhmYzEy
|
10
|
+
NzIwMDY2Mzc3MjMxMjA0ZGYzNTY0NzFlZTUyNzU1NDE4NTI5YzZjZjEyODk1
|
11
|
+
ZDFjZDRlMjJiZGZhNTU2M2YwYmM0NWI0NjIxZmZiMDY0MjU0YWE=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YmRlOGJiZGZkMjg3Y2ZmNWI2NTc3YjA0OTE2Y2I3ODEyMDhhODlhNDU2OWU2
|
14
|
+
MTA5ODYzODE4ZmFhYzg3YjU2OGMxZDM4ODE5MTk5ZWYxZTI1ZGI1OWI1MTE3
|
15
|
+
MTZkYTI4MzMzMjNkYWVjZjA4YWY3YWNmZTYzMTNhNTc1YjI3ODE=
|
@@ -9,7 +9,7 @@ module Pluct
|
|
9
9
|
|
10
10
|
protected
|
11
11
|
def get(url, *opts)
|
12
|
-
options = Hash[
|
12
|
+
options = Hash[opts] if opts
|
13
13
|
resource = RestClient::Resource.new(url)
|
14
14
|
options = (options ? DEFAULT_HEADERS.merge(options) : DEFAULT_HEADERS)
|
15
15
|
resource.get(options)
|
@@ -18,7 +18,7 @@ module Pluct
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def head(url, *opts)
|
21
|
-
options = Hash[
|
21
|
+
options = Hash[opts] if opts
|
22
22
|
resource = RestClient::Resource.new(url)
|
23
23
|
options = (options ? DEFAULT_HEADERS.merge(options) : DEFAULT_HEADERS)
|
24
24
|
resource.head(options)
|
@@ -27,7 +27,7 @@ module Pluct
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def delete(url, *opts)
|
30
|
-
options = Hash[
|
30
|
+
options = Hash[opts] if opts
|
31
31
|
resource = RestClient::Resource.new(url)
|
32
32
|
options = (options ? DEFAULT_HEADERS.merge(options) : DEFAULT_HEADERS)
|
33
33
|
resource.delete(options)
|
@@ -37,7 +37,7 @@ module Pluct
|
|
37
37
|
|
38
38
|
def post(url, *opts)
|
39
39
|
data, options = *opts
|
40
|
-
options = Hash[
|
40
|
+
options = Hash[opts] if options
|
41
41
|
resource = RestClient::Resource.new(url)
|
42
42
|
options = (options ? DEFAULT_HEADERS.merge(options) : DEFAULT_HEADERS)
|
43
43
|
resource.post(data.to_json, options)
|
@@ -57,7 +57,7 @@ module Pluct
|
|
57
57
|
|
58
58
|
def patch(url, *opts)
|
59
59
|
data, options = *opts
|
60
|
-
options = Hash[
|
60
|
+
options = Hash[options] if options
|
61
61
|
resource = RestClient::Resource.new(url)
|
62
62
|
options = (options ? DEFAULT_HEADERS.merge(options) : DEFAULT_HEADERS)
|
63
63
|
resource.patch(data.to_json, options)
|
data/lib/pluct/resource.rb
CHANGED
@@ -1,19 +1,21 @@
|
|
1
|
+
#TODO: Returns Pluct::Response if there is no header, otherwise Pluct::Resource.
|
1
2
|
module Pluct
|
2
3
|
class Resource
|
3
4
|
include Pluct::Helpers::Request
|
4
5
|
|
5
|
-
attr_reader :
|
6
|
+
attr_reader :data, :response, :schema, :uri
|
6
7
|
|
7
|
-
def initialize(
|
8
|
-
@
|
9
|
-
@
|
10
|
-
@
|
8
|
+
def initialize(uri, response = nil)
|
9
|
+
@uri = uri
|
10
|
+
@response = response || get(@uri)
|
11
|
+
@data ||= (JSON.is_json?(@response.body) ? JSON.parse(@response.body, {symbolize_names: true}) : {})
|
12
|
+
|
13
|
+
@schema = Schema.from_header(@response.headers)
|
11
14
|
Resource.create_methods(@schema.links) if @schema
|
12
15
|
end
|
13
16
|
|
14
|
-
|
15
|
-
|
16
|
-
get @url
|
17
|
+
def method_missing(method, *args)
|
18
|
+
@data[method] || super
|
17
19
|
end
|
18
20
|
|
19
21
|
private
|
@@ -23,16 +25,32 @@ module Pluct
|
|
23
25
|
query_string, *options = *args
|
24
26
|
method = link["method"] || "GET"
|
25
27
|
href = link["href"]
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
28
|
+
|
29
|
+
payload = query_string.dup
|
30
|
+
if ['PATCH', 'PUT'].include? method
|
31
|
+
query_string.merge!(@data)
|
30
32
|
end
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
+
uri = define_request_uri(href, query_string)
|
35
|
+
payload = define_request_payload(href, uri, payload)
|
36
|
+
options.unshift(payload)
|
37
|
+
|
38
|
+
response = send(method.downcase, uri, *options)
|
39
|
+
Resource.new(uri, response)
|
34
40
|
end
|
35
41
|
end
|
36
42
|
end
|
43
|
+
|
44
|
+
def define_request_uri(uri_template, query_string)
|
45
|
+
template = Addressable::Template.new(uri_template)
|
46
|
+
Addressable::URI.parse(template.expand(query_string)).to_s
|
47
|
+
end
|
48
|
+
|
49
|
+
def define_request_payload(uri_template, href, payload)
|
50
|
+
template = Addressable::Template.new(uri_template)
|
51
|
+
uri_template = template.extract(href)
|
52
|
+
|
53
|
+
payload.delete_if{ |key, value| uri_template.include?(key) }
|
54
|
+
end
|
37
55
|
end
|
38
56
|
end
|
data/lib/pluct/schema.rb
CHANGED
@@ -2,21 +2,31 @@ module Pluct
|
|
2
2
|
class Schema
|
3
3
|
include Pluct::Helpers::Request
|
4
4
|
|
5
|
-
attr_reader :path, :data
|
5
|
+
attr_reader :path, :data
|
6
6
|
|
7
7
|
def initialize(path)
|
8
8
|
@path = path
|
9
|
-
|
10
|
-
|
9
|
+
end
|
10
|
+
|
11
|
+
def data
|
12
|
+
@data ||= ::MultiJson.decode(get(@path))
|
13
|
+
end
|
14
|
+
|
15
|
+
def links
|
16
|
+
self.data["links"]
|
11
17
|
end
|
12
18
|
|
13
19
|
def to_s
|
14
20
|
@path
|
15
21
|
end
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
22
|
+
|
23
|
+
def self.from_header(headers)
|
24
|
+
return nil unless headers[:content_type]
|
25
|
+
|
26
|
+
schema = headers[:content_type].match('.*profile=([^;]+);?')
|
27
|
+
return nil unless schema
|
28
|
+
|
29
|
+
Schema.new(schema[1])
|
20
30
|
end
|
21
31
|
end
|
22
32
|
end
|
data/lib/pluct/version.rb
CHANGED
data/lib/pluct.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'addressable/template'
|
2
|
-
require 'pluct/version'
|
3
2
|
require 'multi_json'
|
3
|
+
require 'json'
|
4
|
+
require 'pluct/version'
|
4
5
|
|
5
6
|
module Pluct
|
6
7
|
autoload :Errors, "pluct/errors"
|
@@ -9,24 +10,8 @@ module Pluct
|
|
9
10
|
autoload :Schema, "pluct/schema"
|
10
11
|
|
11
12
|
extend Pluct::Helpers::Request
|
12
|
-
|
13
|
-
def self.get_resource(path)
|
14
|
-
request = get(path)
|
15
|
-
schema = schema_from_header(request.headers)
|
16
|
-
resource = Resource.new(path, schema)
|
17
|
-
end
|
18
|
-
|
13
|
+
|
19
14
|
def self.root
|
20
15
|
File.expand_path '../..', __FILE__
|
21
16
|
end
|
22
|
-
|
23
|
-
private
|
24
|
-
def self.schema_from_header(headers)
|
25
|
-
return nil unless headers[:content_type]
|
26
|
-
|
27
|
-
schema = headers[:content_type].match('.*profile=([^;]+);?')
|
28
|
-
return nil unless schema
|
29
|
-
|
30
|
-
Schema.new(schema[1])
|
31
|
-
end
|
32
17
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Pluct::Resource, :integration do
|
4
|
+
|
5
|
+
let(:resource){ Pluct::Resource.new('http://localhost:8888') }
|
6
|
+
|
7
|
+
it 'creates a new instance' do
|
8
|
+
app = resource.collection({context_name: 'baas', collection_name: 'apps'}).create({name: 'my_app', description: 'app_desc'})
|
9
|
+
|
10
|
+
expect(app.response.code).to eq 201
|
11
|
+
expect(app.response.headers[:location]).to_not be_nil
|
12
|
+
expect(app.data).to be_empty
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'expands uri template' do
|
16
|
+
collection = resource.collection({context_name: 'baas', collection_name: 'apps'})
|
17
|
+
expect(collection.uri).to eq 'http://localhost:8888/baas/apps'
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'raises 404 for url not found' do
|
21
|
+
expect {resource.resource({context_name: 'baas', collection_name: 'apps', resource_id: 'invalid'}) }.to raise_error(Pluct::Errors::UrlNotFound)
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.join [Pluct.root, 'lib/pluct/extensions/json']
|
2
|
+
|
3
|
+
describe JSON do
|
4
|
+
it 'returns false for invalid data' do
|
5
|
+
['', ' ', 'string'].each do |s|
|
6
|
+
expect(JSON.is_json?(s)).to be_false
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'returns true for valid data' do
|
11
|
+
expect(JSON.is_json?('{"name" : "foo"}')).to be_true
|
12
|
+
end
|
13
|
+
end
|
data/spec/pluct/resource_spec.rb
CHANGED
@@ -1,11 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Pluct::Resource do
|
4
|
-
let(:schema) { mock(Pluct::Schema) }
|
5
|
-
let(:user) { Pluct::Resource.new 'www.example.com/users/1', schema }
|
6
|
-
let(:user_without_content_type) { Pluct::Resource.new 'www.example.com/users/2' }
|
7
|
-
let(:user_without_schema) { Pluct::Resource.new 'www.example.com/users/3' }
|
8
|
-
let(:user_schema) { MultiJson.decode(File.read('spec/assets/user_schema.json')) }
|
4
|
+
let(:schema) { mock(Pluct::Schema) }
|
9
5
|
|
10
6
|
before(:each) do
|
11
7
|
stub_request(:get, 'www.example.com/users/1').to_return(body: File.read('spec/assets/user.json'),
|
@@ -19,22 +15,49 @@ describe Pluct::Resource do
|
|
19
15
|
stub_request(:get, 'www.example.com/users/3').to_return(body: File.read('spec/assets/user.json'),
|
20
16
|
status: 200,
|
21
17
|
headers: {'content-type' => 'application/json; charset=utf-8;'})
|
22
|
-
|
18
|
+
|
23
19
|
stub_request(:get, 'www.example.com/schemas/user').to_return(body: File.read('spec/assets/user_schema.json'),
|
24
20
|
status: 200)
|
25
|
-
|
26
|
-
schema.stub(:links).and_return(user_schema["links"])
|
27
21
|
end
|
28
22
|
|
29
|
-
|
30
|
-
|
31
|
-
|
23
|
+
context 'schema on header' do
|
24
|
+
it 'has resource data' do
|
25
|
+
resource = Pluct::Resource.new('www.example.com/users/1')
|
26
|
+
resource_data = JSON.parse(File.read('spec/assets/user.json'), {symbolize_names: true})
|
27
|
+
|
28
|
+
expect(resource.data).to eq resource_data
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'retrieves the schema' do
|
32
|
+
resource = Pluct::Resource.new('www.example.com/users/1')
|
33
|
+
|
34
|
+
expect(resource.schema).to_not be_nil
|
35
|
+
expect(resource.schema.to_s).to eq 'http://www.example.com/schemas/user'
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'adds methods dynamically' do
|
39
|
+
resource = Pluct::Resource.new('www.example.com/users/1')
|
40
|
+
|
41
|
+
methods = [:edit, :replace, :self, :delete, :create]
|
42
|
+
methods.each do |method|
|
43
|
+
expect(resource.class.instance_methods(false)).to include(method)
|
44
|
+
end
|
45
|
+
end
|
32
46
|
end
|
33
47
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
48
|
+
context 'invalid header' do
|
49
|
+
it 'does not have content type' do
|
50
|
+
resource = Pluct::Resource.new('www.example.com/users/2')
|
51
|
+
|
52
|
+
expect(resource.data).to_not be_nil
|
53
|
+
expect(resource.schema).to be_nil
|
38
54
|
end
|
55
|
+
|
56
|
+
it 'does not have profile on content type' do
|
57
|
+
resource = Pluct::Resource.new('www.example.com/users/3')
|
58
|
+
|
59
|
+
expect(resource.data).to_not be_nil
|
60
|
+
expect(resource.schema).to be_nil
|
61
|
+
end
|
39
62
|
end
|
40
|
-
end
|
63
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pluct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alberto Leal
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-06-
|
11
|
+
date: 2013-06-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -165,15 +165,17 @@ files:
|
|
165
165
|
- Rakefile
|
166
166
|
- lib/pluct.rb
|
167
167
|
- lib/pluct/errors.rb
|
168
|
+
- lib/pluct/extensions/json.rb
|
168
169
|
- lib/pluct/helpers.rb
|
169
170
|
- lib/pluct/helpers/request.rb
|
170
171
|
- lib/pluct/resource.rb
|
171
172
|
- lib/pluct/schema.rb
|
172
173
|
- lib/pluct/version.rb
|
173
174
|
- pluct.gemspec
|
174
|
-
- spec/acceptance/pluct_spec.rb
|
175
175
|
- spec/assets/user.json
|
176
176
|
- spec/assets/user_schema.json
|
177
|
+
- spec/integration/resource_spec.rb
|
178
|
+
- spec/pluct/extensions/json_spec.rb
|
177
179
|
- spec/pluct/helpers/request_spec.rb
|
178
180
|
- spec/pluct/resource_spec.rb
|
179
181
|
- spec/pluct/schema_spec.rb
|
@@ -206,9 +208,10 @@ signing_key:
|
|
206
208
|
specification_version: 4
|
207
209
|
summary: json-schema hypermedia client
|
208
210
|
test_files:
|
209
|
-
- spec/acceptance/pluct_spec.rb
|
210
211
|
- spec/assets/user.json
|
211
212
|
- spec/assets/user_schema.json
|
213
|
+
- spec/integration/resource_spec.rb
|
214
|
+
- spec/pluct/extensions/json_spec.rb
|
212
215
|
- spec/pluct/helpers/request_spec.rb
|
213
216
|
- spec/pluct/resource_spec.rb
|
214
217
|
- spec/pluct/schema_spec.rb
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Pluct, :acceptance do
|
4
|
-
|
5
|
-
it '', :vcr, cassette_name: 'acceptance/pluct_resource' do
|
6
|
-
resource = Pluct.get_resource 'http://repos.example.com/interatividade/famosos'
|
7
|
-
resource_self = MultiJson.decode(resource.self)
|
8
|
-
|
9
|
-
expect(resource_self).to have_key("items")
|
10
|
-
expect(resource_self["item_count"]).to eq 2
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'creates a new app', :vcr, cassette_name: 'acceptance/creates_new_app' do
|
14
|
-
resource = Pluct.get_resource 'http://localhost:8888/baas/apps'
|
15
|
-
response = resource.create(nil, {name: 'New App', description: 'My Awesome App'})
|
16
|
-
|
17
|
-
expect(response.code).to eq 201
|
18
|
-
expect(response.headers[:location]).to_not be_nil
|
19
|
-
end
|
20
|
-
end
|