pluct 0.0.6 → 0.0.7

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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NmZiMjRiNWU4Y2YyMzQwYWZmZDE5ZjI0NjJmMzg3ZmI0NzY4OTBiMQ==
4
+ OTgzNTBjZDdhYmQ0YjcyMTZhMWMzYjM3NDE0YzRjY2E2MWJhMzczZQ==
5
5
  data.tar.gz: !binary |-
6
- OWY0Mzc4NTUxYTk3YmJhZmJlMmY2ZWI5NTM3YzhmODdlYzk1OTBmYg==
6
+ ZjA1NjdlOWQwOTc3ZDVkNTBlNjA5NDA2NjYxODFhMGRiZTk4ZmMxZQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- OTdjYzQ3M2IxNGU4NWYzMWU3YmY0MjZhM2U0OGEzNDBjYTFjMzc5NDg5MGE0
10
- NDlkMzFmNmIxZDU4MjYzOTc5YzdiMTMzMmRjNTE0MjVkNzg1YWFmY2JmZmU4
11
- NTRjZDM1MzUyODc1N2MyZTYwZWIwODQxMWY5ZGJmMTcwMThjMzk=
9
+ OTcyZjMzZjVjYTdlZTkwMjNiYzczYmRlNjdmMTcwMzNiM2FhODdkNjhmYzEy
10
+ NzIwMDY2Mzc3MjMxMjA0ZGYzNTY0NzFlZTUyNzU1NDE4NTI5YzZjZjEyODk1
11
+ ZDFjZDRlMjJiZGZhNTU2M2YwYmM0NWI0NjIxZmZiMDY0MjU0YWE=
12
12
  data.tar.gz: !binary |-
13
- MWZhOWQzZDVkMWY5OWI2ZWRkNDE3ZmEyM2Q0MTcxYzlkZGU5MGVjMmI5MmE4
14
- MmE0NmZiMDU5NTNmZTRlNmIyYjhiNjYxNjdhOWYyNWE4OWZiNTkwOWQxMTU4
15
- MWM4ZGFiMzcxZDE1NmY1MDcyZTBhYWI5YzFjYzg5YmE0YWZhMmI=
13
+ YmRlOGJiZGZkMjg3Y2ZmNWI2NTc3YjA0OTE2Y2I3ODEyMDhhODlhNDU2OWU2
14
+ MTA5ODYzODE4ZmFhYzg3YjU2OGMxZDM4ODE5MTk5ZWYxZTI1ZGI1OWI1MTE3
15
+ MTZkYTI4MzMzMjNkYWVjZjA4YWY3YWNmZTYzMTNhNTc1YjI3ODE=
@@ -0,0 +1,9 @@
1
+ module JSON
2
+ def self.is_json?(string)
3
+ begin
4
+ parse(string)
5
+ rescue ParserError
6
+ false
7
+ end
8
+ end
9
+ end
@@ -9,7 +9,7 @@ module Pluct
9
9
 
10
10
  protected
11
11
  def get(url, *opts)
12
- options = Hash[*opts]
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[*opts]
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[*opts]
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[*opts] if options
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[*opts] if options
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)
@@ -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 :url, :data, :schema
6
+ attr_reader :data, :response, :schema, :uri
6
7
 
7
- def initialize(url, schema)
8
- @url = url
9
- @data = get_data
10
- @schema = schema
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
- #TODO: Authenticate the request if necessary.
15
- def get_data
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
- if query_string
28
- href = Addressable::Template.new(href)
29
- href = href.expand(query_string).to_s
28
+
29
+ payload = query_string.dup
30
+ if ['PATCH', 'PUT'].include? method
31
+ query_string.merge!(@data)
30
32
  end
31
33
 
32
- #query_string (uri_template), payload, headers
33
- send(method.downcase, href, *options)
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, :links
5
+ attr_reader :path, :data
6
6
 
7
7
  def initialize(path)
8
8
  @path = path
9
- @data = get_content
10
- @links = @data["links"]
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
- private
18
- def get_content
19
- ::MultiJson.decode(get(@path))
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
@@ -1,3 +1,3 @@
1
1
  module Pluct
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  end
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
@@ -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
- it 'has resource data' do
30
- resource_data = File.read('spec/assets/user.json')
31
- expect(user.data).to eq resource_data
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
- it 'adds methods' do
35
- methods = [:edit, :replace, :self, :delete, :create]
36
- methods.each do |method|
37
- expect(user.class.instance_methods(false)).to include(method)
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.6
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-22 00:00:00.000000000 Z
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