restful_objects 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -2
- data/bin/restful_server +1 -1
- data/lib/restful_objects/domain_model/domain_model.rb +143 -0
- data/lib/restful_objects/{link_generator.rb → domain_model/helpers/link_generator.rb} +0 -0
- data/lib/restful_objects/{object.rb → domain_model/mixins/object.rb} +6 -2
- data/lib/restful_objects/{object_actions.rb → domain_model/mixins/object_actions.rb} +1 -0
- data/lib/restful_objects/{object_base.rb → domain_model/mixins/object_base.rb} +46 -13
- data/lib/restful_objects/{object_collections.rb → domain_model/mixins/object_collections.rb} +1 -0
- data/lib/restful_objects/{object_macros.rb → domain_model/mixins/object_macros.rb} +4 -3
- data/lib/restful_objects/{object_properties.rb → domain_model/mixins/object_properties.rb} +49 -7
- data/lib/restful_objects/{service.rb → domain_model/mixins/service.rb} +3 -2
- data/lib/restful_objects/{action_description.rb → domain_model/types/action_description.rb} +2 -0
- data/lib/restful_objects/{collection_description.rb → domain_model/types/collection_description.rb} +0 -0
- data/lib/restful_objects/{type.rb → domain_model/types/domain_type.rb} +28 -8
- data/lib/restful_objects/{parameter_description.rb → domain_model/types/parameter_description.rb} +0 -0
- data/lib/restful_objects/{parameter_description_list.rb → domain_model/types/parameter_description_list.rb} +3 -0
- data/lib/restful_objects/{property_description.rb → domain_model/types/property_description.rb} +23 -13
- data/lib/restful_objects/domain_model/user.rb +31 -0
- data/lib/restful_objects/router/base.rb +41 -0
- data/lib/restful_objects/router/domain_object_resources.rb +97 -0
- data/lib/restful_objects/router/domain_type_resources.rb +37 -0
- data/lib/restful_objects/router/supporting_resources.rb +39 -0
- data/lib/restful_objects/version.rb +1 -1
- data/lib/restful_objects.rb +3 -25
- data/spec/acceptance/generate_json_representations_spec.rb +102 -0
- data/spec/integration/domain-types_properties_spec.rb +76 -1
- data/spec/integration/domain_model_spec.rb +35 -0
- data/spec/spec_helper.rb +18 -3
- data/spec/unit/object_spec.rb +0 -73
- data/spec/unit/type_list_spec.rb +2 -2
- metadata +26 -26
- data/lib/restful_objects/action_list.rb +0 -17
- data/lib/restful_objects/collection_list.rb +0 -17
- data/lib/restful_objects/domain_model.rb +0 -83
- data/lib/restful_objects/http_response.rb +0 -11
- data/lib/restful_objects/object_list.rb +0 -16
- data/lib/restful_objects/property_list.rb +0 -17
- data/lib/restful_objects/server.rb +0 -131
- data/lib/restful_objects/service_list.rb +0 -55
- data/lib/restful_objects/type_list.rb +0 -30
- data/lib/restful_objects/user.rb +0 -30
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative 'supporting_resources'
|
2
|
+
require_relative 'domain_object_resources'
|
3
|
+
require_relative 'domain_type_resources'
|
4
|
+
|
5
|
+
module RestfulObjects
|
6
|
+
module Router
|
7
|
+
class Base < Sinatra::Base
|
8
|
+
register RestfulObjects::Router::SupportingResources
|
9
|
+
register RestfulObjects::Router::DomainObjectResources
|
10
|
+
register RestfulObjects::Router::DomainTypeResources
|
11
|
+
|
12
|
+
set :bind, '0.0.0.0' # listen at all networks (needed for example using vagrant port forwarding)
|
13
|
+
|
14
|
+
after do
|
15
|
+
headers['Access-Control-Allow-Origin'] = '*'
|
16
|
+
end
|
17
|
+
|
18
|
+
helpers do
|
19
|
+
def model
|
20
|
+
RestfulObjects::DomainModel.current
|
21
|
+
end
|
22
|
+
|
23
|
+
def objects
|
24
|
+
RestfulObjects::DomainModel.current.objects
|
25
|
+
end
|
26
|
+
|
27
|
+
def process_params
|
28
|
+
if request.query_string != ''
|
29
|
+
query_params = CGI.parse(request.query_string)
|
30
|
+
parameters = Hash.new
|
31
|
+
query_params.each { |key, value| parameters[key] = { 'value' => value.first } }
|
32
|
+
parameters.to_json
|
33
|
+
else
|
34
|
+
request.body.read
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module RestfulObjects
|
2
|
+
module Router
|
3
|
+
module DomainObjectResources
|
4
|
+
def self.registered(router)
|
5
|
+
# ** 14 Domain Object Resource & Representation **
|
6
|
+
# 14.1
|
7
|
+
router.get '/objects/:domain_type/:instance_id' do
|
8
|
+
objects[params[:instance_id].to_i].get_representation
|
9
|
+
end
|
10
|
+
|
11
|
+
# 14.2
|
12
|
+
router.put '/objects/:domain_type/:instance_id' do
|
13
|
+
objects[params[:instance_id].to_i].put_properties_and_get_representation(request.body.read)
|
14
|
+
end
|
15
|
+
|
16
|
+
# 14.3
|
17
|
+
router.delete '/objects/:domain_type/:instance_id' do
|
18
|
+
objects[params[:instance_id].to_i].rs_delete
|
19
|
+
end
|
20
|
+
|
21
|
+
# patch to allow cross-origin put & delete requests #
|
22
|
+
router.options "/objects/:domain_type/:instance_id" do
|
23
|
+
headers['Access-Control-Allow-Methods'] = 'GET, DELETE, PUT, OPTIONS'
|
24
|
+
headers['Access-Control-Allow-Headers'] = 'Origin, Content-Type, Methods'
|
25
|
+
end
|
26
|
+
|
27
|
+
# C.15 Domain Services
|
28
|
+
router.get "/services/:service_id" do
|
29
|
+
model.services[params[:service_id]].get_representation
|
30
|
+
end
|
31
|
+
|
32
|
+
# C.16 Property
|
33
|
+
router.get "/objects/:domain_type/:instance_id/properties/:property_id" do
|
34
|
+
objects[params[:instance_id].to_i].get_property_as_json(params[:property_id])
|
35
|
+
end
|
36
|
+
|
37
|
+
router.put "/objects/:domain_type/:instance_id/properties/:property_id" do
|
38
|
+
objects[params[:instance_id].to_i].put_property_as_json(params[:property_id], request.body.read)
|
39
|
+
end
|
40
|
+
|
41
|
+
router.delete "/objects/:domain_type/:instance_id/properties/:property_id" do
|
42
|
+
objects[params[:instance_id].to_i].clear_property(params[:property_id])
|
43
|
+
end
|
44
|
+
|
45
|
+
# C.17 Collection #
|
46
|
+
router.get "/objects/:domain_type/:instance_id/collections/:collection_id" do
|
47
|
+
objects[params[:instance_id].to_i].get_collection_as_json(params[:collection_id])
|
48
|
+
end
|
49
|
+
|
50
|
+
router.post "/objects/:domain_type/:instance_id/collections/:collection_id" do
|
51
|
+
objects[params[:instance_id].to_i].add_to_collection(params[:collection_id], request.body.read)
|
52
|
+
end
|
53
|
+
|
54
|
+
router.put "/objects/:domain_type/:instance_id/collections/:collection_id" do
|
55
|
+
objects[params[:instance_id].to_i].add_to_collection(params[:collection_id], request.body.read)
|
56
|
+
end
|
57
|
+
|
58
|
+
router.delete "/objects/:domain_type/:instance_id/collections/:collection_id" do
|
59
|
+
objects[params[:instance_id].to_i].delete_from_collection(params[:collection_id], request.body.read)
|
60
|
+
end
|
61
|
+
|
62
|
+
# patch to allow cross-origin put & delete requests #
|
63
|
+
router.options "/objects/:domain_type/:instance_id/collections/:collection_id" do
|
64
|
+
headers['Access-Control-Allow-Methods'] = 'GET, DELETE, PUT, OPTIONS'
|
65
|
+
headers['Access-Control-Allow-Headers'] = 'Origin, Content-Type, Methods'
|
66
|
+
end
|
67
|
+
|
68
|
+
# C.18 Action
|
69
|
+
router.get "/objects/:domain_type/:instance_id/actions/:action_id" do
|
70
|
+
objects[params[:instance_id].to_i].get_action(params[:action_id])
|
71
|
+
end
|
72
|
+
|
73
|
+
router.get "/services/:service_id/actions/:action_id" do
|
74
|
+
model.services[params[:service_id]].get_action(params[:action_id])
|
75
|
+
end
|
76
|
+
|
77
|
+
# C.19 Action Invoke
|
78
|
+
router.get "/objects/:domain_type/:instance_id/actions/:action_id/invoke" do
|
79
|
+
objects[params[:instance_id].to_i].get_action_invoke(params[:action_id], process_params)
|
80
|
+
end
|
81
|
+
|
82
|
+
router.get "/services/:service_id/actions/:action_id/invoke" do
|
83
|
+
model.services[params[:service_id]].get_action_invoke(params[:action_id], process_params)
|
84
|
+
end
|
85
|
+
|
86
|
+
router.post "/objects/:domain_type/:instance_id/actions/:action_id/invoke" do
|
87
|
+
objects[params[:instance_id].to_i].get_action_invoke(params[:action_id], request.body.read)
|
88
|
+
end
|
89
|
+
|
90
|
+
router.post "/services/:service_id/actions/:action_id/invoke" do
|
91
|
+
model.services[params[:service_id]].get_action_invoke(params[:action_id], request.body.read)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module RestfulObjects
|
2
|
+
module Router
|
3
|
+
module DomainTypeResources
|
4
|
+
def self.registered(router)
|
5
|
+
# D.21 Domain Types
|
6
|
+
router.get "/domain-types" do
|
7
|
+
model.types.get_representation
|
8
|
+
end
|
9
|
+
|
10
|
+
# D.22 Domain Type
|
11
|
+
router.get "/domain-types/:domain_type" do
|
12
|
+
model.types[params[:domain_type]].get_representation
|
13
|
+
end
|
14
|
+
|
15
|
+
# D.23 Domain Type Property
|
16
|
+
router.get "/domain-types/:domain_type/properties/:property_id" do
|
17
|
+
model.types[params[:domain_type]].properties[params[:property_id]].get_representation
|
18
|
+
end
|
19
|
+
|
20
|
+
# D.24 Domain Type Collection
|
21
|
+
router.get "/domain-types/:domain_type/collections/:collection_id" do
|
22
|
+
model.types[params[:domain_type]].collections[params[:collection_id]].get_representation
|
23
|
+
end
|
24
|
+
|
25
|
+
# D.25 Domain Type Action
|
26
|
+
router.get "/domain-types/:domain_type/actions/:action_id" do
|
27
|
+
model.types[params[:domain_type]].actions[params[:action_id]].get_representation
|
28
|
+
end
|
29
|
+
|
30
|
+
# D.26 Domain Type Action Parameter
|
31
|
+
|
32
|
+
# D.27 Domain Type Action Invoke
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module RestfulObjects
|
2
|
+
module Router
|
3
|
+
module SupportingResources
|
4
|
+
def self.registered(router)
|
5
|
+
# B.5 Homepage
|
6
|
+
router.get '/' do
|
7
|
+
model.get_homepage
|
8
|
+
end
|
9
|
+
|
10
|
+
# B.6 User
|
11
|
+
router.get '/user' do
|
12
|
+
model.get_user_as_json
|
13
|
+
end
|
14
|
+
|
15
|
+
# B.7 Services
|
16
|
+
router.get '/services' do
|
17
|
+
model.get_services
|
18
|
+
end
|
19
|
+
|
20
|
+
# B.8 Version
|
21
|
+
router.get '/version' do
|
22
|
+
model.get_version
|
23
|
+
end
|
24
|
+
|
25
|
+
# B.9 Objects of Type Resource
|
26
|
+
router.post '/objects/:domain_type' do
|
27
|
+
model.types[params[:domain_type]].post_prototype_object(request.body.read)
|
28
|
+
end
|
29
|
+
|
30
|
+
# patch to allow cross-origin put & delete requests #
|
31
|
+
router.options '/objects/:domain_type' do
|
32
|
+
headers['Access-Control-Allow-Methods'] = 'POST, OPTIONS'
|
33
|
+
headers['Access-Control-Allow-Headers'] = 'Origin, Content-Type, Methods'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
data/lib/restful_objects.rb
CHANGED
@@ -6,29 +6,7 @@ require 'bigdecimal'
|
|
6
6
|
require 'forwardable'
|
7
7
|
require 'sinatra/base'
|
8
8
|
|
9
|
-
require_relative
|
10
|
-
require_relative 'restful_objects/
|
11
|
-
require_relative 'restful_objects/
|
12
|
-
require_relative 'restful_objects/http_response'
|
13
|
-
require_relative 'restful_objects/user'
|
14
|
-
require_relative 'restful_objects/property_list'
|
15
|
-
require_relative 'restful_objects/property_description'
|
16
|
-
require_relative 'restful_objects/collection_list'
|
17
|
-
require_relative 'restful_objects/collection_description'
|
18
|
-
require_relative 'restful_objects/action_list'
|
19
|
-
require_relative 'restful_objects/action_description'
|
20
|
-
require_relative 'restful_objects/parameter_description'
|
21
|
-
require_relative 'restful_objects/parameter_description_list'
|
22
|
-
require_relative 'restful_objects/object_list'
|
23
|
-
require_relative 'restful_objects/object'
|
24
|
-
require_relative 'restful_objects/object_base'
|
25
|
-
require_relative 'restful_objects/object_macros'
|
26
|
-
require_relative 'restful_objects/object_properties'
|
27
|
-
require_relative 'restful_objects/object_collections'
|
28
|
-
require_relative 'restful_objects/object_actions'
|
29
|
-
require_relative 'restful_objects/type'
|
30
|
-
require_relative 'restful_objects/type_list'
|
31
|
-
require_relative 'restful_objects/service'
|
32
|
-
require_relative 'restful_objects/service_list'
|
33
|
-
require_relative 'restful_objects/domain_model'
|
9
|
+
require_relative 'restful_objects/version'
|
10
|
+
require_relative 'restful_objects/router/base'
|
11
|
+
require_relative 'restful_objects/domain_model/domain_model'
|
34
12
|
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe RestfulObjects::Object do
|
4
|
+
before :each do
|
5
|
+
RestfulObjects::DomainModel.current.reset
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'generates json representation for a complex object' do
|
9
|
+
class Address
|
10
|
+
end
|
11
|
+
|
12
|
+
class ObjectTest
|
13
|
+
include RestfulObjects::Object
|
14
|
+
|
15
|
+
property :id, :int, read_only: true
|
16
|
+
property :password, :string, max_length: 10
|
17
|
+
|
18
|
+
action :hash_password, return_type: :string
|
19
|
+
|
20
|
+
collection :addresses, Address
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@id = 99
|
24
|
+
super
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
object = ObjectTest.new
|
29
|
+
object.password = 'secret_key'
|
30
|
+
address = Address.new
|
31
|
+
object.addresses.push(address)
|
32
|
+
|
33
|
+
get "/objects/ObjectTest/#{object.object_id}"
|
34
|
+
|
35
|
+
expected = {
|
36
|
+
'instanceId' => object.object_id.to_s,
|
37
|
+
'title' => "ObjectTest (#{object.object_id})",
|
38
|
+
'members' => {
|
39
|
+
'id' =>
|
40
|
+
{ 'memberType' => 'property',
|
41
|
+
'value' => 99,
|
42
|
+
'disabledReason' => 'read-only property',
|
43
|
+
'links' => [
|
44
|
+
{ 'rel' => 'urn:org.restfulobjects:rels/details;property="id"',
|
45
|
+
'href' => "http://localhost/objects/ObjectTest/#{object.object_id}/properties/id",
|
46
|
+
'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object-property"',
|
47
|
+
'method' => 'GET' }
|
48
|
+
],
|
49
|
+
'extensions' => { }
|
50
|
+
},
|
51
|
+
'password' => {
|
52
|
+
'memberType' => 'property',
|
53
|
+
'value' => 'secret_key',
|
54
|
+
'links' => [
|
55
|
+
{ 'rel' => 'urn:org.restfulobjects:rels/details;property="password"',
|
56
|
+
'href' => "http://localhost/objects/ObjectTest/#{object.object_id}/properties/password",
|
57
|
+
'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object-property"',
|
58
|
+
'method' => 'GET' }
|
59
|
+
],
|
60
|
+
'extensions' => { }
|
61
|
+
},
|
62
|
+
'addresses' => {
|
63
|
+
'memberType' => 'collection',
|
64
|
+
'size' => 1,
|
65
|
+
'links' => [
|
66
|
+
{ 'rel' => 'urn:org.restfulobjects:rels/details;collection="addresses"',
|
67
|
+
'href' => "http://localhost/objects/ObjectTest/#{object.object_id}/collections/addresses",
|
68
|
+
'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object-collection"',
|
69
|
+
'method' => 'GET' }
|
70
|
+
],
|
71
|
+
'extensions' => { }
|
72
|
+
},
|
73
|
+
'hash_password' => {
|
74
|
+
'memberType' => 'action',
|
75
|
+
'links' => [
|
76
|
+
{ 'rel' => 'urn:org.restfulobjects:rels/details;action="hash_password"',
|
77
|
+
'href' => "http://localhost/objects/ObjectTest/#{object.object_id}/actions/hash_password",
|
78
|
+
'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object-action"',
|
79
|
+
'method' => 'GET' }
|
80
|
+
],
|
81
|
+
'extensions' => { }
|
82
|
+
}
|
83
|
+
},
|
84
|
+
'links' => [
|
85
|
+
{ 'rel' => 'self',
|
86
|
+
'href' => "http://localhost/objects/ObjectTest/#{object.object_id}",
|
87
|
+
'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object"',
|
88
|
+
'method' => 'GET' },
|
89
|
+
{ 'rel' => 'describedby',
|
90
|
+
'href' => "http://localhost/domain-types/ObjectTest",
|
91
|
+
'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/domain-type"',
|
92
|
+
'method' => 'GET' }
|
93
|
+
],
|
94
|
+
'extensions' => wildcard_matcher
|
95
|
+
}
|
96
|
+
|
97
|
+
CONTENT_TYPE = 'application/json;profile="urn:org.restfulobjects:repr-types/object";x-ro-domain-type="ObjectTest"'
|
98
|
+
expect(last_response.content_type).to eq CONTENT_TYPE
|
99
|
+
expect(last_response.body).to match_json_expression expected
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require_relative '../spec_helper'
|
3
3
|
|
4
|
-
describe '
|
4
|
+
describe 'DomainObject properties' do
|
5
5
|
before(:all) do
|
6
6
|
RestfulObjects::DomainModel.current.reset
|
7
7
|
end
|
@@ -37,5 +37,80 @@ describe '/domain-types/:type/properties/:property' do
|
|
37
37
|
get '/domain-types/PropertyTest/properties/name'
|
38
38
|
last_response.body.should match_json_expression expected
|
39
39
|
end
|
40
|
+
|
41
|
+
describe 'json representation of property reference' do
|
42
|
+
before :each do
|
43
|
+
class ReferenceType
|
44
|
+
include RestfulObjects::Object
|
45
|
+
end
|
46
|
+
class PropertyRefTest
|
47
|
+
include RestfulObjects::Object
|
48
|
+
property :reference, { object: ReferenceType }
|
49
|
+
end
|
50
|
+
@referenced = ReferenceType.new
|
51
|
+
@object = PropertyRefTest.new
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'gets representation' do
|
55
|
+
@object.reference = @referenced
|
56
|
+
expect(@object.get_property_as_json(:reference)).to match_json_expression(
|
57
|
+
{ 'reference' =>
|
58
|
+
{ 'value' =>
|
59
|
+
{ 'rel' => 'urn:org.restfulobjects:rels/value;property="reference"',
|
60
|
+
'href' => "http://localhost/objects/ReferenceType/#{@referenced.object_id}",
|
61
|
+
'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object"',
|
62
|
+
'method' => 'GET',
|
63
|
+
'title' => @referenced.title
|
64
|
+
}
|
65
|
+
}
|
66
|
+
}
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'lists choices' do
|
71
|
+
choices = [ReferenceType.new, ReferenceType.new, ReferenceType.new]
|
72
|
+
@object.define_singleton_method(:reference_choices) { choices }
|
73
|
+
expect(@object.get_property_as_json(:reference)).to match_json_expression(
|
74
|
+
{ 'reference' =>
|
75
|
+
{ 'value' => nil,
|
76
|
+
'choices' => [
|
77
|
+
{ 'rel' => 'urn:org.restfulobjects:rels/value;property="reference"',
|
78
|
+
'href' => "http://localhost/objects/ReferenceType/#{choices[0].object_id}",
|
79
|
+
'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object"',
|
80
|
+
'method' => 'GET',
|
81
|
+
'title' => choices[0].title },
|
82
|
+
{ 'rel' => 'urn:org.restfulobjects:rels/value;property="reference"',
|
83
|
+
'href' => "http://localhost/objects/ReferenceType/#{choices[1].object_id}",
|
84
|
+
'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object"',
|
85
|
+
'method' => 'GET',
|
86
|
+
'title' => choices[1].title },
|
87
|
+
{ 'rel' => 'urn:org.restfulobjects:rels/value;property="reference"',
|
88
|
+
'href' => "http://localhost/objects/ReferenceType/#{choices[2].object_id}",
|
89
|
+
'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object"',
|
90
|
+
'method' => 'GET',
|
91
|
+
'title' => choices[2].title }
|
92
|
+
]
|
93
|
+
}
|
94
|
+
}
|
95
|
+
)
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'puts representation' do
|
99
|
+
json = { 'value' => { 'href' => @referenced.ro_absolute_url } }.to_json
|
100
|
+
expect(@object.put_property_as_json(:reference, json)).to match_json_expression(
|
101
|
+
{ 'reference' =>
|
102
|
+
{ 'value' =>
|
103
|
+
{ 'rel' => 'urn:org.restfulobjects:rels/value;property="reference"',
|
104
|
+
'href' => "http://localhost/objects/ReferenceType/#{@referenced.object_id}",
|
105
|
+
'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object"',
|
106
|
+
'method' => 'GET',
|
107
|
+
'title' => @referenced.title
|
108
|
+
}
|
109
|
+
}
|
110
|
+
}
|
111
|
+
)
|
112
|
+
expect(@object.reference).to eq @referenced
|
113
|
+
end
|
114
|
+
end
|
40
115
|
end
|
41
116
|
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe RestfulObjects::Object do
|
4
|
+
describe '#put_properties_and_get_representation' do
|
5
|
+
it 'updates simple property' do
|
6
|
+
class TestObject
|
7
|
+
include RestfulObjects::Object
|
8
|
+
property :name, :string
|
9
|
+
end
|
10
|
+
test_object = TestObject.new
|
11
|
+
response = test_object.put_properties_and_get_representation({ 'name' => { 'value' => 'john smith' } }.to_json)
|
12
|
+
expect(response.body).to match_json_expression({ 'members' => { 'name' => { 'value' => 'john smith' } } })
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'updates multiple properties' do
|
16
|
+
class TestObject
|
17
|
+
include RestfulObjects::Object
|
18
|
+
property :name, :string
|
19
|
+
property :age, :int
|
20
|
+
property :weight, :decimal
|
21
|
+
end
|
22
|
+
test_object = TestObject.new
|
23
|
+
response = test_object.put_properties_and_get_representation({ 'name' => { 'value' => 'john smith' },
|
24
|
+
'age' => { 'value' => '29' },
|
25
|
+
'weight' => { 'value' => '71.5' } }.to_json)
|
26
|
+
expect(response.body).to match_json_expression({ 'members' => {
|
27
|
+
'name' => { 'value' => 'john smith' },
|
28
|
+
'age' => { 'value' => 29 },
|
29
|
+
'weight' => { 'value' => 71.5 }
|
30
|
+
}
|
31
|
+
})
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -4,9 +4,23 @@ require 'pp'
|
|
4
4
|
|
5
5
|
require_relative '../lib/restful_objects.rb'
|
6
6
|
|
7
|
+
class Array
|
8
|
+
def status
|
9
|
+
self[0]
|
10
|
+
end
|
11
|
+
|
12
|
+
def headers
|
13
|
+
self[1]
|
14
|
+
end
|
15
|
+
|
16
|
+
def body
|
17
|
+
self[2]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
7
21
|
module Helpers
|
8
22
|
def app
|
9
|
-
RestfulObjects::
|
23
|
+
RestfulObjects::Router::Base
|
10
24
|
end
|
11
25
|
|
12
26
|
def model
|
@@ -48,5 +62,6 @@ end
|
|
48
62
|
JsonExpressions::Matcher.assume_strict_arrays = false
|
49
63
|
JsonExpressions::Matcher.assume_strict_hashes = false
|
50
64
|
|
51
|
-
RestfulObjects::
|
52
|
-
RestfulObjects::
|
65
|
+
RestfulObjects::Router::Base.set :show_exceptions, false
|
66
|
+
RestfulObjects::Router::Base.set :raise_errors, true
|
67
|
+
|
data/spec/unit/object_spec.rb
CHANGED
@@ -59,79 +59,6 @@ describe RestfulObjects::Object do
|
|
59
59
|
domain_type.actions['hash_password'].result_type.should eq(:string)
|
60
60
|
end
|
61
61
|
|
62
|
-
it 'should generate json for the object' do
|
63
|
-
@object.password = 'secret_key'
|
64
|
-
address = Address.new
|
65
|
-
@object.addresses.push(address)
|
66
|
-
|
67
|
-
expected = {
|
68
|
-
'instanceId' => @object.object_id.to_s,
|
69
|
-
'title' => "ObjectTest (#{@object.object_id})",
|
70
|
-
'members' => {
|
71
|
-
'id' =>
|
72
|
-
{ 'memberType' => 'property',
|
73
|
-
'value' => 99,
|
74
|
-
'disabledReason' => 'read-only property',
|
75
|
-
'links' => [
|
76
|
-
{ 'rel' => 'urn:org.restfulobjects:rels/details;property="id"',
|
77
|
-
'href' => "http://localhost/objects/ObjectTest/#{@object.object_id}/properties/id",
|
78
|
-
'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object-property"',
|
79
|
-
'method' => 'GET' }
|
80
|
-
],
|
81
|
-
'extensions' => { }
|
82
|
-
},
|
83
|
-
'password' => {
|
84
|
-
'memberType' => 'property',
|
85
|
-
'value' => 'secret_key',
|
86
|
-
'links' => [
|
87
|
-
{ 'rel' => 'urn:org.restfulobjects:rels/details;property="password"',
|
88
|
-
'href' => "http://localhost/objects/ObjectTest/#{@object.object_id}/properties/password",
|
89
|
-
'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object-property"',
|
90
|
-
'method' => 'GET' }
|
91
|
-
],
|
92
|
-
'extensions' => { }
|
93
|
-
},
|
94
|
-
'addresses' => {
|
95
|
-
'memberType' => 'collection',
|
96
|
-
'size' => 1,
|
97
|
-
'links' => [
|
98
|
-
{ 'rel' => 'urn:org.restfulobjects:rels/details;collection="addresses"',
|
99
|
-
'href' => "http://localhost/objects/ObjectTest/#{@object.object_id}/collections/addresses",
|
100
|
-
'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object-collection"',
|
101
|
-
'method' => 'GET' }
|
102
|
-
],
|
103
|
-
'extensions' => { }
|
104
|
-
},
|
105
|
-
'hash_password' => {
|
106
|
-
'memberType' => 'action',
|
107
|
-
'links' => [
|
108
|
-
{ 'rel' => 'urn:org.restfulobjects:rels/details;action="hash_password"',
|
109
|
-
'href' => "http://localhost/objects/ObjectTest/#{@object.object_id}/actions/hash_password",
|
110
|
-
'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object-action"',
|
111
|
-
'method' => 'GET' }
|
112
|
-
],
|
113
|
-
'extensions' => { }
|
114
|
-
}
|
115
|
-
},
|
116
|
-
'links' => [
|
117
|
-
{ 'rel' => 'self',
|
118
|
-
'href' => "http://localhost/objects/ObjectTest/#{@object.object_id}",
|
119
|
-
'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object"',
|
120
|
-
'method' => 'GET' },
|
121
|
-
{ 'rel' => 'describedby',
|
122
|
-
'href' => "http://localhost/domain-types/ObjectTest",
|
123
|
-
'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/domain-type"',
|
124
|
-
'method' => 'GET' }
|
125
|
-
],
|
126
|
-
'extensions' => wildcard_matcher
|
127
|
-
}
|
128
|
-
|
129
|
-
get "/objects/ObjectTest/#{@object.object_id}"
|
130
|
-
|
131
|
-
last_response.body.should match_json_expression expected
|
132
|
-
last_response.content_type.should eq 'application/json;profile="urn:org.restfulobjects:repr-types/object";x-ro-domain-type="ObjectTest"'
|
133
|
-
end
|
134
|
-
|
135
62
|
it 'should generate metadata in extensions' do
|
136
63
|
@object.rs_type.plural_name = 'Test Objects'
|
137
64
|
@object.rs_type.friendly_name = 'Test Object Friendly'
|
data/spec/unit/type_list_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require_relative '../spec_helper'
|
3
3
|
|
4
|
-
describe RestfulObjects::
|
4
|
+
describe RestfulObjects::DomainModel do
|
5
5
|
before(:all) do
|
6
6
|
RestfulObjects::DomainModel.current.reset
|
7
7
|
|
@@ -31,7 +31,7 @@ describe RestfulObjects::TypeList do
|
|
31
31
|
'extensions' => {}
|
32
32
|
}.to_json
|
33
33
|
|
34
|
-
RestfulObjects::DomainModel.current.
|
34
|
+
RestfulObjects::DomainModel.current.get_type_list_representation
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|