restful_objects 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +8 -8
  2. data/README.md +3 -2
  3. data/bin/restful_server.rb +0 -0
  4. data/lib/restful_objects/action_description.rb +96 -82
  5. data/lib/restful_objects/action_list.rb +17 -17
  6. data/lib/restful_objects/collection_description.rb +47 -47
  7. data/lib/restful_objects/collection_list.rb +17 -17
  8. data/lib/restful_objects/domain_model.rb +83 -79
  9. data/lib/restful_objects/http_response.rb +11 -11
  10. data/lib/restful_objects/link_generator.rb +104 -104
  11. data/lib/restful_objects/object.rb +20 -20
  12. data/lib/restful_objects/object_actions.rb +134 -134
  13. data/lib/restful_objects/object_base.rb +10 -0
  14. data/lib/restful_objects/object_collections.rb +84 -84
  15. data/lib/restful_objects/object_list.rb +16 -16
  16. data/lib/restful_objects/object_macros.rb +35 -35
  17. data/lib/restful_objects/object_properties.rb +78 -78
  18. data/lib/restful_objects/parameter_description.rb +60 -60
  19. data/lib/restful_objects/parameter_description_list.rb +15 -15
  20. data/lib/restful_objects/property_description.rb +68 -68
  21. data/lib/restful_objects/property_list.rb +17 -17
  22. data/lib/restful_objects/service.rb +21 -21
  23. data/lib/restful_objects/service_list.rb +55 -55
  24. data/lib/restful_objects/type.rb +110 -110
  25. data/lib/restful_objects/type_list.rb +30 -30
  26. data/lib/restful_objects/user.rb +30 -30
  27. data/lib/restful_objects/version.rb +1 -1
  28. data/spec/integration/domain-types_actions_spec.rb +43 -43
  29. data/spec/integration/domain-types_collections_spec.rb +45 -45
  30. data/spec/integration/domain-types_properties_spec.rb +41 -41
  31. data/spec/integration/server-root_spec.rb +98 -98
  32. data/spec/spec_helper.rb +52 -52
  33. data/spec/unit/object_actions_spec.rb +380 -380
  34. data/spec/unit/object_collections_spec.rb +190 -190
  35. data/spec/unit/object_properties_spec.rb +215 -206
  36. data/spec/unit/object_spec.rb +228 -228
  37. data/spec/unit/service_spec.rb +125 -125
  38. data/spec/unit/type_list_spec.rb +37 -37
  39. metadata +2 -2
@@ -1,41 +1,41 @@
1
- # encoding: utf-8
2
- require_relative '../spec_helper'
3
-
4
- describe '/domain-types/:type/properties/:property' do
5
- before(:all) do
6
- RestfulObjects::DomainModel.current.reset
7
- end
8
-
9
- it 'should generate a property description representation' do
10
- class PropertyTest
11
- include RestfulObjects::Object
12
- property :name, :string, friendly_name: 'a friendly name', description: 'name description'
13
- end
14
-
15
- expected = {
16
- 'id' => 'name',
17
- 'friendlyName' => 'a friendly name',
18
- 'description' => 'name description',
19
- 'optional' => true,
20
- 'memberOrder' => :integer,
21
- 'links' => [
22
- { 'rel' => 'self',
23
- 'href' => 'http://localhost/domain-types/PropertyTest/properties/name',
24
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/property-description"',
25
- 'method' => 'GET' },
26
- { 'rel' => 'up',
27
- 'href' => 'http://localhost/domain-types/PropertyTest',
28
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/domain-type"',
29
- 'method' => 'GET' },
30
- { 'rel' => 'urn:org.restfulobjects:rels/return-type',
31
- 'href' => 'http://localhost/domain-types/string',
32
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/domain-type"',
33
- 'method' => 'GET' }
34
- ]
35
- }
36
-
37
- get '/domain-types/PropertyTest/properties/name'
38
- last_response.body.should match_json_expression expected
39
- end
40
- end
41
-
1
+ # encoding: utf-8
2
+ require_relative '../spec_helper'
3
+
4
+ describe '/domain-types/:type/properties/:property' do
5
+ before(:all) do
6
+ RestfulObjects::DomainModel.current.reset
7
+ end
8
+
9
+ it 'should generate a property description representation' do
10
+ class PropertyTest
11
+ include RestfulObjects::Object
12
+ property :name, :string, friendly_name: 'a friendly name', description: 'name description'
13
+ end
14
+
15
+ expected = {
16
+ 'id' => 'name',
17
+ 'friendlyName' => 'a friendly name',
18
+ 'description' => 'name description',
19
+ 'optional' => true,
20
+ 'memberOrder' => :integer,
21
+ 'links' => [
22
+ { 'rel' => 'self',
23
+ 'href' => 'http://localhost/domain-types/PropertyTest/properties/name',
24
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/property-description"',
25
+ 'method' => 'GET' },
26
+ { 'rel' => 'up',
27
+ 'href' => 'http://localhost/domain-types/PropertyTest',
28
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/domain-type"',
29
+ 'method' => 'GET' },
30
+ { 'rel' => 'urn:org.restfulobjects:rels/return-type',
31
+ 'href' => 'http://localhost/domain-types/string',
32
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/domain-type"',
33
+ 'method' => 'GET' }
34
+ ]
35
+ }
36
+
37
+ get '/domain-types/PropertyTest/properties/name'
38
+ last_response.body.should match_json_expression expected
39
+ end
40
+ end
41
+
@@ -1,98 +1,98 @@
1
- # encoding: utf-8
2
- require_relative '../spec_helper'
3
-
4
- describe '/' do
5
- before(:all) do
6
- RestfulObjects::DomainModel.current.reset
7
- end
8
-
9
- it 'should generate a homepage resource' do
10
- homepage = {
11
- 'links' => [
12
- { 'rel' => 'self',
13
- 'href' => 'http://localhost/',
14
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/homepage"',
15
- 'method' => 'GET' },
16
- { 'rel' => 'urn:org.restfulobjects:rels/user',
17
- 'href' => 'http://localhost/user',
18
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/user"',
19
- 'method' => 'GET' },
20
- { 'rel' => 'urn:org.restfulobjects:rels/services',
21
- 'href' => 'http://localhost/services',
22
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/list"',
23
- 'method' => 'GET' },
24
- { 'rel' => 'urn:org.restfulobjects:rels/version',
25
- 'href' => 'http://localhost/version',
26
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/version"',
27
- 'method' => 'GET' },
28
- { 'rel' => 'urn:org.restfulobjects:rels/domain-types',
29
- 'href' => 'http://localhost/domain-types',
30
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/type-list"',
31
- 'method' => 'GET' },
32
- ],
33
- 'extensions' => { }
34
- }
35
-
36
- get '/'
37
- last_response.body.should match_json_expression homepage
38
- end
39
-
40
- it 'should generate a version resource' do
41
- version = {
42
- 'links' => [
43
- { 'rel' => 'self',
44
- 'href' => 'http://localhost/version',
45
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/version"',
46
- 'method' => 'GET' },
47
- { 'rel' => 'up',
48
- 'href' => 'http://localhost/',
49
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/homepage"',
50
- 'method' => 'GET' }
51
- ],
52
- 'specVersion' => '1.0',
53
- 'optionalCapabilities' => {
54
- 'blobsClobs' => true,
55
- 'deleteObjects' => true,
56
- 'domainModel' => 'selectable',
57
- 'protoPersistentObjects' => true,
58
- 'validateOnly' => false
59
- },
60
- 'extensions' => {}
61
- }
62
-
63
- get '/version'
64
- last_response.body.should match_json_expression version
65
- end
66
-
67
- it 'should generate a services list resource' do
68
- class ServiceTest
69
- include RestfulObjects::Service
70
- end
71
-
72
- RestfulObjects::DomainModel.current.services['ServiceTest'].title = 'Service Test Title'
73
-
74
- services_list = {
75
- 'links' => [
76
- { 'rel' => 'self',
77
- 'href' => 'http://localhost/services',
78
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/services"',
79
- 'method' => 'GET' },
80
- { 'rel' => 'up',
81
- 'href' => 'http://localhost/',
82
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/homepage"',
83
- 'method' => 'GET' }
84
- ],
85
- 'value' => [
86
- { 'rel' => 'urn:org.restfulobjects:rels/service;serviceId="ServiceTest"',
87
- 'href' => 'http://localhost/services/ServiceTest',
88
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object"',
89
- 'method' => 'GET',
90
- 'title' => 'Service Test Title' }
91
- ],
92
- 'extensions' => { }
93
- }
94
-
95
- get '/services'
96
- last_response.body.should match_json_expression services_list
97
- end
98
- end
1
+ # encoding: utf-8
2
+ require_relative '../spec_helper'
3
+
4
+ describe '/' do
5
+ before(:all) do
6
+ RestfulObjects::DomainModel.current.reset
7
+ end
8
+
9
+ it 'should generate a homepage resource' do
10
+ homepage = {
11
+ 'links' => [
12
+ { 'rel' => 'self',
13
+ 'href' => 'http://localhost/',
14
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/homepage"',
15
+ 'method' => 'GET' },
16
+ { 'rel' => 'urn:org.restfulobjects:rels/user',
17
+ 'href' => 'http://localhost/user',
18
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/user"',
19
+ 'method' => 'GET' },
20
+ { 'rel' => 'urn:org.restfulobjects:rels/services',
21
+ 'href' => 'http://localhost/services',
22
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/list"',
23
+ 'method' => 'GET' },
24
+ { 'rel' => 'urn:org.restfulobjects:rels/version',
25
+ 'href' => 'http://localhost/version',
26
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/version"',
27
+ 'method' => 'GET' },
28
+ { 'rel' => 'urn:org.restfulobjects:rels/domain-types',
29
+ 'href' => 'http://localhost/domain-types',
30
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/type-list"',
31
+ 'method' => 'GET' },
32
+ ],
33
+ 'extensions' => { }
34
+ }
35
+
36
+ get '/'
37
+ last_response.body.should match_json_expression homepage
38
+ end
39
+
40
+ it 'should generate a version resource' do
41
+ version = {
42
+ 'links' => [
43
+ { 'rel' => 'self',
44
+ 'href' => 'http://localhost/version',
45
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/version"',
46
+ 'method' => 'GET' },
47
+ { 'rel' => 'up',
48
+ 'href' => 'http://localhost/',
49
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/homepage"',
50
+ 'method' => 'GET' }
51
+ ],
52
+ 'specVersion' => '1.0',
53
+ 'optionalCapabilities' => {
54
+ 'blobsClobs' => true,
55
+ 'deleteObjects' => true,
56
+ 'domainModel' => 'selectable',
57
+ 'protoPersistentObjects' => true,
58
+ 'validateOnly' => false
59
+ },
60
+ 'extensions' => {}
61
+ }
62
+
63
+ get '/version'
64
+ last_response.body.should match_json_expression version
65
+ end
66
+
67
+ it 'should generate a services list resource' do
68
+ class ServiceTest
69
+ include RestfulObjects::Service
70
+ end
71
+
72
+ RestfulObjects::DomainModel.current.services['ServiceTest'].title = 'Service Test Title'
73
+
74
+ services_list = {
75
+ 'links' => [
76
+ { 'rel' => 'self',
77
+ 'href' => 'http://localhost/services',
78
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/services"',
79
+ 'method' => 'GET' },
80
+ { 'rel' => 'up',
81
+ 'href' => 'http://localhost/',
82
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/homepage"',
83
+ 'method' => 'GET' }
84
+ ],
85
+ 'value' => [
86
+ { 'rel' => 'urn:org.restfulobjects:rels/service;serviceId="ServiceTest"',
87
+ 'href' => 'http://localhost/services/ServiceTest',
88
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object"',
89
+ 'method' => 'GET',
90
+ 'title' => 'Service Test Title' }
91
+ ],
92
+ 'extensions' => { }
93
+ }
94
+
95
+ get '/services'
96
+ last_response.body.should match_json_expression services_list
97
+ end
98
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,52 +1,52 @@
1
- require 'json_expressions/rspec'
2
- require 'rack/test'
3
- require 'pp'
4
-
5
- require_relative '../lib/restful_objects.rb'
6
-
7
- module Helpers
8
- def app
9
- RestfulObjects::Server
10
- end
11
-
12
- def model
13
- RestfulObjects::DomainModel.current
14
- end
15
-
16
- def pretty_print_json(json_string)
17
- puts JSON.pretty_generate(JSON.parse(json_string))
18
- end
19
- end
20
-
21
- module JsonExpressions
22
- module RSpec
23
- module Matchers
24
- class MatchJsonExpression
25
- def failure_message_for_should
26
- "expected:\n#{JSON.pretty_generate @target}\n to match JSON expression:\n#{@expected.inspect}\n\n" +
27
- @expected.last_error
28
- end
29
-
30
- def failure_message_for_should_not
31
- "expected:\n#{JSON.pretty_generate @target}\n not to match JSON expression:\n#{@expected.inspect}\n"
32
- end
33
-
34
- def description
35
- "should equal JSON expression:\n#{@expected.inspect}\n"
36
- end
37
- end
38
- end
39
- end
40
- end
41
-
42
-
43
- RSpec::configure do |config|
44
- config.include(Helpers)
45
- config.include Rack::Test::Methods
46
- end
47
-
48
- JsonExpressions::Matcher.assume_strict_arrays = false
49
- JsonExpressions::Matcher.assume_strict_hashes = false
50
-
51
- RestfulObjects::Server.set :show_exceptions, false
52
- RestfulObjects::Server.set :raise_errors, true
1
+ require 'json_expressions/rspec'
2
+ require 'rack/test'
3
+ require 'pp'
4
+
5
+ require_relative '../lib/restful_objects.rb'
6
+
7
+ module Helpers
8
+ def app
9
+ RestfulObjects::Server
10
+ end
11
+
12
+ def model
13
+ RestfulObjects::DomainModel.current
14
+ end
15
+
16
+ def pretty_print_json(json_string)
17
+ puts JSON.pretty_generate(JSON.parse(json_string))
18
+ end
19
+ end
20
+
21
+ module JsonExpressions
22
+ module RSpec
23
+ module Matchers
24
+ class MatchJsonExpression
25
+ def failure_message_for_should
26
+ "expected:\n#{JSON.pretty_generate @target}\n to match JSON expression:\n#{@expected.inspect}\n\n" +
27
+ @expected.last_error
28
+ end
29
+
30
+ def failure_message_for_should_not
31
+ "expected:\n#{JSON.pretty_generate @target}\n not to match JSON expression:\n#{@expected.inspect}\n"
32
+ end
33
+
34
+ def description
35
+ "should equal JSON expression:\n#{@expected.inspect}\n"
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+
43
+ RSpec::configure do |config|
44
+ config.include(Helpers)
45
+ config.include Rack::Test::Methods
46
+ end
47
+
48
+ JsonExpressions::Matcher.assume_strict_arrays = false
49
+ JsonExpressions::Matcher.assume_strict_hashes = false
50
+
51
+ RestfulObjects::Server.set :show_exceptions, false
52
+ RestfulObjects::Server.set :raise_errors, true
@@ -1,380 +1,380 @@
1
- # encoding: utf-8
2
- require_relative '../spec_helper'
3
-
4
- describe RestfulObjects::ObjectActions do
5
- before :all do
6
- RestfulObjects::DomainModel.current.reset
7
-
8
- class ActionResult
9
- include RestfulObjects::Object
10
- end
11
-
12
- class ActionsTest
13
- include RestfulObjects::Object
14
-
15
- property :string_prop, :string
16
- property :int_prop, :int
17
- property :decimal_prop, :decimal
18
- property :date_prop, :date
19
- property :blob_prop, :blob
20
-
21
- action :string_action, :string
22
- action :int_action, :int
23
- action :decimal_action, :decimal
24
- action :date_action, :date
25
- action :blob_action, :blob
26
-
27
- def string_action
28
- string_prop
29
- end
30
-
31
- def int_action
32
- int_prop
33
- end
34
-
35
- def decimal_action
36
- decimal_prop
37
- end
38
-
39
- def date_action
40
- date_prop
41
- end
42
-
43
- def blob_action
44
- blob_prop
45
- end
46
-
47
- action :multiply, :int, { 'arg1' => :int, 'arg2' => :int }
48
- action :get_nil_scalar, :int
49
- action :get_object, [:object, ActionResult]
50
- action :get_nil_object, [:object, ActionResult]
51
- action :get_list, [:list, ActionResult]
52
- action :get_nil_list, [:list, ActionResult]
53
-
54
- def multiply(arg1, arg2)
55
- arg1 * arg2
56
- end
57
-
58
- def get_nil_scalar
59
- nil
60
- end
61
-
62
- def get_object
63
- @cached ||= ActionResult.new
64
- end
65
-
66
- def get_nil_object
67
- nil
68
- end
69
-
70
- def get_list
71
- @cached ||= [ActionResult.new, ActionResult.new]
72
- end
73
-
74
- def get_nil_list
75
- nil
76
- end
77
- end
78
- end
79
-
80
- before :each do
81
- @object = ActionsTest.new
82
- end
83
-
84
- it 'should get action' do
85
- expected = {
86
- 'id' => 'multiply',
87
- 'parameters' => {
88
- 'arg1' => {
89
- 'links' => [],
90
- 'extensions' => { }
91
- },
92
- 'arg2' => {
93
- 'links' => [],
94
- 'extensions' => { }
95
- },
96
- },
97
- 'links' => [
98
- { 'rel' => 'self',
99
- 'href' => "http://localhost/objects/ActionsTest/#{@object.object_id}/actions/multiply",
100
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object-action"',
101
- 'method' => 'GET' },
102
- { 'rel' => 'up',
103
- 'href' => "http://localhost/objects/ActionsTest/#{@object.object_id}",
104
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object"',
105
- 'method' => 'GET' },
106
- {
107
- 'rel' => 'urn:org.restfulobjects:rels/invoke;action="multiply"',
108
- 'href' => "http://localhost/objects/ActionsTest/#{@object.object_id}/actions/multiply/invoke",
109
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/action-result"',
110
- 'method' => 'GET',
111
- 'arguments' => {
112
- 'arg1' => { 'value' => nil },
113
- 'arg2' => { 'value' => nil }
114
- }
115
- }
116
- ]
117
- }
118
-
119
- get "/objects/ActionsTest/#{@object.object_id}/actions/multiply"
120
-
121
- last_response.body.should match_json_expression expected
122
- end
123
-
124
- it 'should process different actions result types' do
125
- @object.string_prop = 'A string'
126
- @object.int_prop = 1234
127
- @object.decimal_prop = 333.33
128
- @object.date_prop = Date.new(2012, 2, 29)
129
- @object.blob_prop = "\xE5\xA5\xB4\x30\xF2\x8C\x71\xD9"
130
-
131
- expected = {
132
- 'string_action' => 'A string',
133
- 'int_action' => 1234,
134
- 'decimal_action' => 333.33,
135
- 'date_action' => '2012-02-29',
136
- 'blob_action' => '5aW0MPKMcdk=' }
137
-
138
- expected.each do |action, value|
139
- get "/objects/ActionsTest/#{@object.object_id}/actions/#{action}/invoke"
140
- JSON.parse(last_response.body)['result']['value'].should eq value
141
- end
142
- end
143
-
144
- it 'should invoke action (get) with simple arguments as a query string' do
145
- expected = {
146
- 'resultType' => 'scalar',
147
- 'result' => {
148
- 'value' => 28,
149
- }
150
- }
151
-
152
- get "/objects/ActionsTest/#{@object.object_id}/actions/multiply/invoke?arg1=4&arg2=7"
153
-
154
- last_response.body.should match_json_expression expected
155
- end
156
-
157
- it 'should invoke action get with arguments returning scalar' do
158
- arguments = { 'arg1' => { 'value' => 3 },
159
- 'arg2' => { 'value' => 9 } }.to_json
160
-
161
- expected = {
162
- 'links' => [
163
- { 'rel' => 'self',
164
- 'href' => "http://localhost/objects/ActionsTest/#{@object.object_id}/actions/multiply/invoke",
165
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/action-result"',
166
- 'arguments' =>
167
- { 'arg1' => { 'value' => 3 },
168
- 'arg2' => { 'value' => 9 } },
169
- 'method' => 'GET' }
170
- ],
171
- 'resultType' => 'scalar',
172
- 'result' => {
173
- 'links' => [
174
- { 'rel' => 'urn:org.restfulobjects:rels/return-type',
175
- 'href' => 'http://localhost/domain-types/int',
176
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/domain-type"',
177
- 'method' => 'GET' } ],
178
- 'value' => 27,
179
- 'extensions' => { }
180
- },
181
- 'extensions' => {}
182
- }
183
-
184
- get "/objects/ActionsTest/#{@object.object_id}/actions/multiply/invoke", {}, {input: arguments}
185
-
186
- last_response.body.should match_json_expression expected
187
- end
188
-
189
- it 'should invoke action and return a null scalar representation' do
190
- expected = {
191
- 'links' => [
192
- { 'rel' => 'self',
193
- 'href' => "http://localhost/objects/ActionsTest/#{@object.object_id}/actions/get_nil_scalar/invoke",
194
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/action-result"',
195
- 'method' => 'GET',
196
- 'arguments' => nil }
197
- ],
198
- 'resultType' => 'scalar',
199
- 'result' => nil,
200
- 'extensions' => {}
201
- }
202
-
203
- get "/objects/ActionsTest/#{@object.object_id}/actions/get_nil_scalar/invoke"
204
-
205
- last_response.body.should match_json_expression expected
206
- end
207
-
208
- it 'should invoke action and return an object representation' do
209
- action_result = @object.get_object
210
-
211
- expected = {
212
- 'links' => [
213
- { 'rel' => 'self',
214
- 'href' => "http://localhost/objects/ActionsTest/#{@object.object_id}/actions/get_object/invoke",
215
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/action-result"',
216
- 'method' => 'GET',
217
- 'arguments' => nil }
218
- ],
219
- 'resultType' => 'object',
220
- 'result' => {
221
- 'instanceId' => "#{action_result.object_id}",
222
- 'links' => [
223
- { 'rel' => 'self',
224
- 'href' => "http://localhost/objects/ActionResult/#{action_result.object_id}",
225
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object"',
226
- 'method' => 'GET' },
227
- { 'rel' => 'describedby',
228
- 'href' => "http://localhost/domain-types/ActionResult",
229
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/domain-type"',
230
- 'method' => 'GET' }
231
- ],
232
- 'members' => wildcard_matcher
233
- }
234
- }
235
-
236
- get "/objects/ActionsTest/#{@object.object_id}/actions/get_object/invoke"
237
-
238
- last_response.body.should match_json_expression expected
239
- end
240
-
241
- it 'should invoke action and return a null object representation' do
242
- expected = {
243
- 'links' => [
244
- { 'rel' => 'self',
245
- 'href' => "http://localhost/objects/ActionsTest/#{@object.object_id}/actions/get_nil_object/invoke",
246
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/action-result"',
247
- 'method' => 'GET',
248
- 'arguments' => nil }
249
- ],
250
- 'resultType' => 'object',
251
- 'result' => nil,
252
- 'extensions' => { }
253
- }
254
-
255
- get "/objects/ActionsTest/#{@object.object_id}/actions/get_nil_object/invoke"
256
-
257
- last_response.body.should match_json_expression expected
258
- end
259
-
260
- it 'should invoke action and return a list representation' do
261
- action_result = @object.get_list
262
-
263
- expected = {
264
- 'links' => [
265
- { 'rel' => 'self',
266
- 'href' => "http://localhost/objects/ActionsTest/#{@object.object_id}/actions/get_list/invoke",
267
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/action-result"',
268
- 'method' => 'GET',
269
- 'arguments' => nil }
270
- ],
271
- 'resultType' => 'list',
272
- 'result' => {
273
- 'links' => [
274
- { 'rel' => 'urn:org.restfulobjects:rels/element-type',
275
- 'href' => "http://localhost/domain-types/ActionResult",
276
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/domain-type"',
277
- 'method' => 'GET' } ],
278
- 'value' => [
279
- { 'rel' =>'urn:org.restfulobjects:rels/element',
280
- 'href' => "http://localhost/objects/ActionResult/#{action_result[0].object_id}",
281
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object"',
282
- 'method' => 'GET' },
283
- { 'rel' =>'urn:org.restfulobjects:rels/element',
284
- 'href' => "http://localhost/objects/ActionResult/#{action_result[1].object_id}",
285
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object"',
286
- 'method' => 'GET' }
287
- ],
288
- 'extensions' => { }
289
- },
290
- 'extensions' => { }
291
- }
292
-
293
- get "/objects/ActionsTest/#{@object.object_id}/actions/get_list/invoke"
294
-
295
- last_response.body.should match_json_expression expected
296
- end
297
-
298
- it 'should invoke action and return a null list respresentation' do
299
- expected = {
300
- 'links' => [
301
- { 'rel' => 'self',
302
- 'href' => "http://localhost/objects/ActionsTest/#{@object.object_id}/actions/get_nil_list/invoke",
303
- 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/action-result"',
304
- 'method' => 'GET',
305
- 'arguments' => nil }
306
- ],
307
- 'resultType' => 'list',
308
- 'result' => nil,
309
- 'extensions' => { }
310
- }
311
-
312
- get "/objects/ActionsTest/#{@object.object_id}/actions/get_nil_list/invoke"
313
-
314
- last_response.body.should match_json_expression expected
315
- end
316
-
317
- it 'should generate metadata in extensions' do
318
- class ActionsTest
319
- action :action_full_metadata, :string, {}, friendly_name: 'Meta Action', description: 'To Test Metadata'
320
- end
321
-
322
- expected = {
323
- 'id' => 'action_full_metadata',
324
- 'extensions' => {
325
- 'friendlyName' => 'Meta Action',
326
- 'description' => 'To Test Metadata',
327
- 'returnType' => 'string',
328
- 'hasParams' => false,
329
- 'memberOrder' => Fixnum
330
- }.strict!
331
- }
332
-
333
- get "/objects/ActionsTest/#{@object.object_id}/actions/action_full_metadata"
334
-
335
- last_response.body.should match_json_expression expected
336
- end
337
-
338
- it 'should generate metadata for parameters in extensions' do
339
- class ActionsTest
340
- action :metadata_test, :void, { param1: :string,
341
- param2: [:int, { optional: false, friendly_name: 'friendly', description: 'description' }],
342
- param3: ActionResult }
343
- end
344
-
345
- expected = {
346
- 'id' => 'metadata_test',
347
- 'parameters' => {
348
- 'param1' => {
349
- 'extensions' => {
350
- 'friendlyName' => 'param1',
351
- 'description' => 'param1',
352
- 'returnType' => 'string',
353
- 'optional' => true
354
- }
355
- },
356
- 'param2' => {
357
- 'extensions' => {
358
- 'friendlyName' => 'friendly',
359
- 'description' => 'description',
360
- 'returnType' => 'int',
361
- 'optional' => false
362
- },
363
- },
364
- 'param3' => {
365
- 'extensions' => {
366
- 'friendlyName' => 'param3',
367
- 'description' => 'param3',
368
- 'returnType' => 'ActionResult',
369
- 'optional' => true
370
- }
371
- }
372
- }
373
- }
374
-
375
- get "/objects/ActionsTest/#{@object.object_id}/actions/metadata_test"
376
-
377
- last_response.body.should match_json_expression expected
378
- end
379
- end
380
-
1
+ # encoding: utf-8
2
+ require_relative '../spec_helper'
3
+
4
+ describe RestfulObjects::ObjectActions do
5
+ before :all do
6
+ RestfulObjects::DomainModel.current.reset
7
+
8
+ class ActionResult
9
+ include RestfulObjects::Object
10
+ end
11
+
12
+ class ActionsTest
13
+ include RestfulObjects::Object
14
+
15
+ property :string_prop, :string
16
+ property :int_prop, :int
17
+ property :decimal_prop, :decimal
18
+ property :date_prop, :date
19
+ property :blob_prop, :blob
20
+
21
+ action :string_action, return_type: :string
22
+ action :int_action, return_type: :int
23
+ action :decimal_action, return_type: :decimal
24
+ action :date_action, return_type: :date
25
+ action :blob_action, return_type: :blob
26
+
27
+ def string_action
28
+ string_prop
29
+ end
30
+
31
+ def int_action
32
+ int_prop
33
+ end
34
+
35
+ def decimal_action
36
+ decimal_prop
37
+ end
38
+
39
+ def date_action
40
+ date_prop
41
+ end
42
+
43
+ def blob_action
44
+ blob_prop
45
+ end
46
+
47
+ action :multiply, return_type: :int, parameters: { 'arg1' => :int, 'arg2' => :int }
48
+ action :get_nil_scalar, return_type: :int
49
+ action :get_object, return_type: { object: ActionResult }
50
+ action :get_nil_object, return_type: { object: ActionResult }
51
+ action :get_list, return_type: { list: ActionResult }
52
+ action :get_nil_list, return_type: { list: ActionResult }
53
+
54
+ def multiply(arg1, arg2)
55
+ arg1 * arg2
56
+ end
57
+
58
+ def get_nil_scalar
59
+ nil
60
+ end
61
+
62
+ def get_object
63
+ @cached ||= ActionResult.new
64
+ end
65
+
66
+ def get_nil_object
67
+ nil
68
+ end
69
+
70
+ def get_list
71
+ @cached ||= [ActionResult.new, ActionResult.new]
72
+ end
73
+
74
+ def get_nil_list
75
+ nil
76
+ end
77
+ end
78
+ end
79
+
80
+ before :each do
81
+ @object = ActionsTest.new
82
+ end
83
+
84
+ it 'should get action' do
85
+ expected = {
86
+ 'id' => 'multiply',
87
+ 'parameters' => {
88
+ 'arg1' => {
89
+ 'links' => [],
90
+ 'extensions' => { }
91
+ },
92
+ 'arg2' => {
93
+ 'links' => [],
94
+ 'extensions' => { }
95
+ },
96
+ },
97
+ 'links' => [
98
+ { 'rel' => 'self',
99
+ 'href' => "http://localhost/objects/ActionsTest/#{@object.object_id}/actions/multiply",
100
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object-action"',
101
+ 'method' => 'GET' },
102
+ { 'rel' => 'up',
103
+ 'href' => "http://localhost/objects/ActionsTest/#{@object.object_id}",
104
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object"',
105
+ 'method' => 'GET' },
106
+ {
107
+ 'rel' => 'urn:org.restfulobjects:rels/invoke;action="multiply"',
108
+ 'href' => "http://localhost/objects/ActionsTest/#{@object.object_id}/actions/multiply/invoke",
109
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/action-result"',
110
+ 'method' => 'GET',
111
+ 'arguments' => {
112
+ 'arg1' => { 'value' => nil },
113
+ 'arg2' => { 'value' => nil }
114
+ }
115
+ }
116
+ ]
117
+ }
118
+
119
+ get "/objects/ActionsTest/#{@object.object_id}/actions/multiply"
120
+
121
+ last_response.body.should match_json_expression expected
122
+ end
123
+
124
+ it 'should process different actions result types' do
125
+ @object.string_prop = 'A string'
126
+ @object.int_prop = 1234
127
+ @object.decimal_prop = 333.33
128
+ @object.date_prop = Date.new(2012, 2, 29)
129
+ @object.blob_prop = "\xE5\xA5\xB4\x30\xF2\x8C\x71\xD9"
130
+
131
+ expected = {
132
+ 'string_action' => 'A string',
133
+ 'int_action' => 1234,
134
+ 'decimal_action' => 333.33,
135
+ 'date_action' => '2012-02-29',
136
+ 'blob_action' => '5aW0MPKMcdk=' }
137
+
138
+ expected.each do |action, value|
139
+ get "/objects/ActionsTest/#{@object.object_id}/actions/#{action}/invoke"
140
+ JSON.parse(last_response.body)['result']['value'].should eq value
141
+ end
142
+ end
143
+
144
+ it 'should invoke action (get) with simple arguments as a query string' do
145
+ expected = {
146
+ 'resultType' => 'scalar',
147
+ 'result' => {
148
+ 'value' => 28,
149
+ }
150
+ }
151
+
152
+ get "/objects/ActionsTest/#{@object.object_id}/actions/multiply/invoke?arg1=4&arg2=7"
153
+
154
+ last_response.body.should match_json_expression expected
155
+ end
156
+
157
+ it 'should invoke action get with arguments returning scalar' do
158
+ arguments = { 'arg1' => { 'value' => 3 },
159
+ 'arg2' => { 'value' => 9 } }.to_json
160
+
161
+ expected = {
162
+ 'links' => [
163
+ { 'rel' => 'self',
164
+ 'href' => "http://localhost/objects/ActionsTest/#{@object.object_id}/actions/multiply/invoke",
165
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/action-result"',
166
+ 'arguments' =>
167
+ { 'arg1' => { 'value' => 3 },
168
+ 'arg2' => { 'value' => 9 } },
169
+ 'method' => 'GET' }
170
+ ],
171
+ 'resultType' => 'scalar',
172
+ 'result' => {
173
+ 'links' => [
174
+ { 'rel' => 'urn:org.restfulobjects:rels/return-type',
175
+ 'href' => 'http://localhost/domain-types/int',
176
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/domain-type"',
177
+ 'method' => 'GET' } ],
178
+ 'value' => 27,
179
+ 'extensions' => { }
180
+ },
181
+ 'extensions' => {}
182
+ }
183
+
184
+ get "/objects/ActionsTest/#{@object.object_id}/actions/multiply/invoke", {}, {input: arguments}
185
+
186
+ last_response.body.should match_json_expression expected
187
+ end
188
+
189
+ it 'should invoke action and return a null scalar representation' do
190
+ expected = {
191
+ 'links' => [
192
+ { 'rel' => 'self',
193
+ 'href' => "http://localhost/objects/ActionsTest/#{@object.object_id}/actions/get_nil_scalar/invoke",
194
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/action-result"',
195
+ 'method' => 'GET',
196
+ 'arguments' => nil }
197
+ ],
198
+ 'resultType' => 'scalar',
199
+ 'result' => nil,
200
+ 'extensions' => {}
201
+ }
202
+
203
+ get "/objects/ActionsTest/#{@object.object_id}/actions/get_nil_scalar/invoke"
204
+
205
+ last_response.body.should match_json_expression expected
206
+ end
207
+
208
+ it 'should invoke action and return an object representation' do
209
+ action_result = @object.get_object
210
+
211
+ expected = {
212
+ 'links' => [
213
+ { 'rel' => 'self',
214
+ 'href' => "http://localhost/objects/ActionsTest/#{@object.object_id}/actions/get_object/invoke",
215
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/action-result"',
216
+ 'method' => 'GET',
217
+ 'arguments' => nil }
218
+ ],
219
+ 'resultType' => 'object',
220
+ 'result' => {
221
+ 'instanceId' => "#{action_result.object_id}",
222
+ 'links' => [
223
+ { 'rel' => 'self',
224
+ 'href' => "http://localhost/objects/ActionResult/#{action_result.object_id}",
225
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object"',
226
+ 'method' => 'GET' },
227
+ { 'rel' => 'describedby',
228
+ 'href' => "http://localhost/domain-types/ActionResult",
229
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/domain-type"',
230
+ 'method' => 'GET' }
231
+ ],
232
+ 'members' => wildcard_matcher
233
+ }
234
+ }
235
+
236
+ get "/objects/ActionsTest/#{@object.object_id}/actions/get_object/invoke"
237
+
238
+ last_response.body.should match_json_expression expected
239
+ end
240
+
241
+ it 'should invoke action and return a null object representation' do
242
+ expected = {
243
+ 'links' => [
244
+ { 'rel' => 'self',
245
+ 'href' => "http://localhost/objects/ActionsTest/#{@object.object_id}/actions/get_nil_object/invoke",
246
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/action-result"',
247
+ 'method' => 'GET',
248
+ 'arguments' => nil }
249
+ ],
250
+ 'resultType' => 'object',
251
+ 'result' => nil,
252
+ 'extensions' => { }
253
+ }
254
+
255
+ get "/objects/ActionsTest/#{@object.object_id}/actions/get_nil_object/invoke"
256
+
257
+ last_response.body.should match_json_expression expected
258
+ end
259
+
260
+ it 'should invoke action and return a list representation' do
261
+ action_result = @object.get_list
262
+
263
+ expected = {
264
+ 'links' => [
265
+ { 'rel' => 'self',
266
+ 'href' => "http://localhost/objects/ActionsTest/#{@object.object_id}/actions/get_list/invoke",
267
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/action-result"',
268
+ 'method' => 'GET',
269
+ 'arguments' => nil }
270
+ ],
271
+ 'resultType' => 'list',
272
+ 'result' => {
273
+ 'links' => [
274
+ { 'rel' => 'urn:org.restfulobjects:rels/element-type',
275
+ 'href' => "http://localhost/domain-types/ActionResult",
276
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/domain-type"',
277
+ 'method' => 'GET' } ],
278
+ 'value' => [
279
+ { 'rel' =>'urn:org.restfulobjects:rels/element',
280
+ 'href' => "http://localhost/objects/ActionResult/#{action_result[0].object_id}",
281
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object"',
282
+ 'method' => 'GET' },
283
+ { 'rel' =>'urn:org.restfulobjects:rels/element',
284
+ 'href' => "http://localhost/objects/ActionResult/#{action_result[1].object_id}",
285
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/object"',
286
+ 'method' => 'GET' }
287
+ ],
288
+ 'extensions' => { }
289
+ },
290
+ 'extensions' => { }
291
+ }
292
+
293
+ get "/objects/ActionsTest/#{@object.object_id}/actions/get_list/invoke"
294
+
295
+ last_response.body.should match_json_expression expected
296
+ end
297
+
298
+ it 'should invoke action and return a null list respresentation' do
299
+ expected = {
300
+ 'links' => [
301
+ { 'rel' => 'self',
302
+ 'href' => "http://localhost/objects/ActionsTest/#{@object.object_id}/actions/get_nil_list/invoke",
303
+ 'type' => 'application/json;profile="urn:org.restfulobjects:repr-types/action-result"',
304
+ 'method' => 'GET',
305
+ 'arguments' => nil }
306
+ ],
307
+ 'resultType' => 'list',
308
+ 'result' => nil,
309
+ 'extensions' => { }
310
+ }
311
+
312
+ get "/objects/ActionsTest/#{@object.object_id}/actions/get_nil_list/invoke"
313
+
314
+ last_response.body.should match_json_expression expected
315
+ end
316
+
317
+ it 'should generate metadata in extensions' do
318
+ class ActionsTest
319
+ action :action_full_metadata, return_type: :string, friendly_name: 'Meta Action', description: 'To Test Metadata'
320
+ end
321
+
322
+ expected = {
323
+ 'id' => 'action_full_metadata',
324
+ 'extensions' => {
325
+ 'friendlyName' => 'Meta Action',
326
+ 'description' => 'To Test Metadata',
327
+ 'returnType' => 'string',
328
+ 'hasParams' => false,
329
+ 'memberOrder' => Fixnum
330
+ }.strict!
331
+ }
332
+
333
+ get "/objects/ActionsTest/#{@object.object_id}/actions/action_full_metadata"
334
+
335
+ last_response.body.should match_json_expression expected
336
+ end
337
+
338
+ it 'should generate metadata for parameters in extensions' do
339
+ class ActionsTest
340
+ action :metadata_test, parameters: { param1: :string,
341
+ param2: [:int, { optional: false, friendly_name: 'friendly', description: 'description' }],
342
+ param3: ActionResult }
343
+ end
344
+
345
+ expected = {
346
+ 'id' => 'metadata_test',
347
+ 'parameters' => {
348
+ 'param1' => {
349
+ 'extensions' => {
350
+ 'friendlyName' => 'param1',
351
+ 'description' => 'param1',
352
+ 'returnType' => 'string',
353
+ 'optional' => true
354
+ }
355
+ },
356
+ 'param2' => {
357
+ 'extensions' => {
358
+ 'friendlyName' => 'friendly',
359
+ 'description' => 'description',
360
+ 'returnType' => 'int',
361
+ 'optional' => false
362
+ },
363
+ },
364
+ 'param3' => {
365
+ 'extensions' => {
366
+ 'friendlyName' => 'param3',
367
+ 'description' => 'param3',
368
+ 'returnType' => 'ActionResult',
369
+ 'optional' => true
370
+ }
371
+ }
372
+ }
373
+ }
374
+
375
+ get "/objects/ActionsTest/#{@object.object_id}/actions/metadata_test"
376
+
377
+ last_response.body.should match_json_expression expected
378
+ end
379
+ end
380
+