acts_as_sdata 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/MIT-LICENSE +20 -0
- data/README.textile +200 -0
- data/Rakefile +20 -0
- data/VERSION +1 -0
- data/config/sdata.yml +13 -0
- data/config/sdata.yml.example +20 -0
- data/config/sdata.yml.tmpl.staging +14 -0
- data/generators/acts_as_sdata/acts_as_sdata_generator.rb +9 -0
- data/generators/acts_as_sdata/templates/migration.rb +69 -0
- data/init.rb +36 -0
- data/lib/s_data/active_record_extensions/base.rb +7 -0
- data/lib/s_data/active_record_extensions/mixin.rb +157 -0
- data/lib/s_data/active_record_extensions/sdata_uuid_mixin.rb +133 -0
- data/lib/s_data/atom_extensions/content_mixin.rb +14 -0
- data/lib/s_data/atom_extensions/entry_mixin.rb +41 -0
- data/lib/s_data/atom_extensions/nodes/digest.rb +48 -0
- data/lib/s_data/atom_extensions/nodes/payload.rb +34 -0
- data/lib/s_data/atom_extensions/nodes/sync_state.rb +14 -0
- data/lib/s_data/conditions_builder.rb +59 -0
- data/lib/s_data/controller_mixin.rb +11 -0
- data/lib/s_data/controller_mixin/actions.rb +87 -0
- data/lib/s_data/controller_mixin/collection_scope.rb +57 -0
- data/lib/s_data/controller_mixin/s_data_feed.rb +87 -0
- data/lib/s_data/controller_mixin/s_data_instance.rb +35 -0
- data/lib/s_data/diagnosis/application_controller_mixin.rb +16 -0
- data/lib/s_data/diagnosis/diagnosis.rb +130 -0
- data/lib/s_data/diagnosis/diagnosis_mapper.rb +39 -0
- data/lib/s_data/exceptions.rb +10 -0
- data/lib/s_data/formatting.rb +13 -0
- data/lib/s_data/namespace_definitions.rb +19 -0
- data/lib/s_data/payload.rb +158 -0
- data/lib/s_data/payload_map.rb +0 -0
- data/lib/s_data/payload_map/payload_map.rb +136 -0
- data/lib/s_data/payload_map/payload_map_hash.rb +39 -0
- data/lib/s_data/predicate.rb +31 -0
- data/lib/s_data/route_mapper.rb +143 -0
- data/lib/s_data/router_mixin.rb +10 -0
- data/lib/s_data/sync/controller_mixin.rb +122 -0
- data/lib/s_data/sync/sdata_syncing_mixin.rb +17 -0
- data/lib/s_data/virtual_base.rb +114 -0
- data/test/functional/Rakefile +0 -0
- data/test/unit/active_record_mixin/active_record_mixin_spec.rb +20 -0
- data/test/unit/active_record_mixin/acts_as_sdata_spec.rb +41 -0
- data/test/unit/active_record_mixin/find_by_sdata_instance_id_spec.rb +34 -0
- data/test/unit/active_record_mixin/payload_spec.rb +622 -0
- data/test/unit/active_record_mixin/to_atom_spec.rb +85 -0
- data/test/unit/atom_entry_mixin/atom_entry_mixin_spec.rb +11 -0
- data/test/unit/atom_entry_mixin/to_attributes_spec.rb +30 -0
- data/test/unit/class_stubs/address.rb +19 -0
- data/test/unit/class_stubs/contact.rb +25 -0
- data/test/unit/class_stubs/customer.rb +70 -0
- data/test/unit/class_stubs/model_base.rb +17 -0
- data/test/unit/class_stubs/payload.rb +15 -0
- data/test/unit/class_stubs/sd_uuid.rb +28 -0
- data/test/unit/class_stubs/user.rb +40 -0
- data/test/unit/conditions_builder_spec.rb +54 -0
- data/test/unit/controller_mixin/acts_as_sdata_spec.rb +29 -0
- data/test/unit/controller_mixin/build_sdata_feed_spec.rb +50 -0
- data/test/unit/controller_mixin/controller_mixin_spec.rb +22 -0
- data/test/unit/controller_mixin/diagnosis_spec.rb +232 -0
- data/test/unit/controller_mixin/sdata_collection_spec.rb +78 -0
- data/test/unit/controller_mixin/sdata_create_instance_spec.rb +173 -0
- data/test/unit/controller_mixin/sdata_opensearch_and_links_spec.rb +382 -0
- data/test/unit/controller_mixin/sdata_scope/linked_model_spec.rb +58 -0
- data/test/unit/controller_mixin/sdata_scope/non_linked_model_spec.rb +66 -0
- data/test/unit/controller_mixin/sdata_scope/scoping_in_config_spec.rb +64 -0
- data/test/unit/controller_mixin/sdata_show_instance_spec.rb +98 -0
- data/test/unit/controller_mixin/sdata_update_instance_spec.rb +65 -0
- data/test/unit/payload_map/payload_map_hash_spec.rb +84 -0
- data/test/unit/payload_map/payload_map_spec.rb +144 -0
- data/test/unit/predicate_spec.rb +59 -0
- data/test/unit/router_mixin/routes_spec.rb +138 -0
- data/test/unit/spec.opts +4 -0
- data/test/unit/spec_helper.rb +47 -0
- data/test/unit/spec_helpers/nokogiri_extensions.rb +16 -0
- data/test/unit/sync_controller_mixin/controller_mixin_spec.rb +22 -0
- data/test/unit/sync_controller_mixin/sdata_collection_sync_feed_spec.rb +69 -0
- metadata +175 -0
@@ -0,0 +1,382 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
module Atom
|
4
|
+
class Feed
|
5
|
+
def opensearch(key)
|
6
|
+
simple_extensions["{#{SData.config[:schemas]["opensearch"]},#{key}}"][0]
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe SData::ControllerMixin, "#sdata_collection" do
|
12
|
+
describe "given a model which acts as sdata" do
|
13
|
+
before :all do
|
14
|
+
@time = Time.now - 1.day
|
15
|
+
|
16
|
+
class Model
|
17
|
+
extend SData::ActiveRecordExtensions::Mixin
|
18
|
+
acts_as_sdata
|
19
|
+
def id
|
20
|
+
1
|
21
|
+
end
|
22
|
+
def attributes; {} end
|
23
|
+
def updated_at
|
24
|
+
@time
|
25
|
+
end
|
26
|
+
def created_by
|
27
|
+
OpenStruct.new(:id => 1, :sage_username => 'sage_user')
|
28
|
+
end
|
29
|
+
|
30
|
+
def name=(a_name)
|
31
|
+
@name=a_name
|
32
|
+
end
|
33
|
+
def name
|
34
|
+
@name || "John Smith"
|
35
|
+
end
|
36
|
+
def sdata_content
|
37
|
+
"contains #{self.name}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def stub_params(params,query=true)
|
43
|
+
@controller.request.query_parameters = params if query
|
44
|
+
@controller.stub! :params => params.merge({:dataset => '-'})
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "given a controller which acts as sdata" do
|
48
|
+
before :all do
|
49
|
+
Base = Class.new(ActionController::Base)
|
50
|
+
Base.extend SData::ControllerMixin
|
51
|
+
|
52
|
+
|
53
|
+
Base.acts_as_sdata :model => Model,
|
54
|
+
:feed => { :id => 'some-unique-id',
|
55
|
+
:author => 'Test Author',
|
56
|
+
:path => '/test_resource',
|
57
|
+
:title => 'List of Test Items',
|
58
|
+
:default_items_per_page => 5,
|
59
|
+
:maximum_items_per_page => 100}
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
before :each do
|
64
|
+
@controller = Base.new
|
65
|
+
@controller.stub! :request => OpenStruct.new(
|
66
|
+
:protocol => 'http://',
|
67
|
+
:host_with_port => 'http://example.com',
|
68
|
+
:request_uri => Base.sdata_options[:feed][:path],
|
69
|
+
:query_parameters => {}),
|
70
|
+
:params => {}
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "given an empty record collection" do
|
74
|
+
before :each do
|
75
|
+
@controller.sdata_options[:model].stub! :all => []
|
76
|
+
|
77
|
+
end
|
78
|
+
it "should display default opensearch values" do
|
79
|
+
stub_params({:dataset => '-'}, false)
|
80
|
+
@controller.should_receive(:render) do |hash|
|
81
|
+
hash[:xml].opensearch("itemsPerPage").should == Base.sdata_options[:feed][:default_items_per_page]
|
82
|
+
hash[:xml].opensearch("totalResults").should == 0
|
83
|
+
hash[:xml].opensearch("startIndex").should == 1
|
84
|
+
hash[:xml].entries.size.should == 0
|
85
|
+
hash[:xml].links.size.should == 1
|
86
|
+
hash[:xml].links[0].rel.should == 'self'
|
87
|
+
hash[:xml].links[0].href.should == "http://www.example.com/sdata/example/myContract/-/models"
|
88
|
+
end
|
89
|
+
@controller.sdata_collection
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should correctly parse opensearch values to xml" do
|
93
|
+
@controller.should_receive(:render) do |hash|
|
94
|
+
hash[:xml].to_xml.gsub(/\n\s*/, '').match(/<feed.*<opensearch:itemsPerPage>5<\/opensearch:itemsPerPage>.*<\/feed>$/).should_not == nil
|
95
|
+
hash[:xml].to_xml.gsub(/\n\s*/, '').match(/<feed.*<opensearch:totalResults>0<\/opensearch:totalResults>.*<\/feed>$/).should_not == nil
|
96
|
+
hash[:xml].to_xml.gsub(/\n\s*/, '').match(/<feed.*<opensearch:startIndex>1<\/opensearch:startIndex>.*<\/feed>$/).should_not == nil
|
97
|
+
end
|
98
|
+
@controller.sdata_collection
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "given a non empty record collection of 15 records" do
|
104
|
+
|
105
|
+
def models_with_serial_names
|
106
|
+
models = []
|
107
|
+
for i in 1..15 do
|
108
|
+
model = Model.new
|
109
|
+
model.name = i.to_s
|
110
|
+
models << model
|
111
|
+
end
|
112
|
+
models
|
113
|
+
end
|
114
|
+
|
115
|
+
def verify_content_for(entries, range)
|
116
|
+
counter = 0
|
117
|
+
range.entries.size.should == entries.size
|
118
|
+
range.each do |num|
|
119
|
+
entries[counter].content.should == "contains #{num}"
|
120
|
+
counter+=1
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def verify_links_for(links, conditions)
|
125
|
+
present_types = links.collect{|l|l.rel}
|
126
|
+
%w{self first last previous next}.each do |type|
|
127
|
+
if conditions[type.to_sym].nil?
|
128
|
+
present_types.include?(type).should == false
|
129
|
+
else
|
130
|
+
link = links.detect{|l|(l.rel==type)}
|
131
|
+
link.should_not == nil
|
132
|
+
link.href.split('?')[0].should == conditions[:path] if conditions[:path]
|
133
|
+
query = link.href.split('?')[1]
|
134
|
+
|
135
|
+
if conditions[:count]
|
136
|
+
value = query.match(/count=\-?(\w|\d)*/).to_s.split('=')[1].to_s
|
137
|
+
value.should == conditions[:count]
|
138
|
+
elsif conditions[:count] == false #not nil
|
139
|
+
(query.nil? || !query.include?('count')).should == true
|
140
|
+
end
|
141
|
+
|
142
|
+
if conditions[type.to_sym] == false
|
143
|
+
(query.nil? || !query.include?('startIndex')).should == true
|
144
|
+
else
|
145
|
+
page = query.match(/startIndex=\-?\d*/).to_s.split('=')[1].to_s
|
146
|
+
page.should == conditions[type.to_sym]
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
before :each do
|
152
|
+
@controller.sdata_options[:model].stub! :all => models_with_serial_names
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should display default opensearch and link values" do
|
157
|
+
stub_params({})
|
158
|
+
@controller.should_receive(:render) do |hash|
|
159
|
+
hash[:xml].opensearch("itemsPerPage").should == Base.sdata_options[:feed][:default_items_per_page]
|
160
|
+
hash[:xml].opensearch("totalResults").should == 15
|
161
|
+
hash[:xml].opensearch("startIndex").should == 1
|
162
|
+
hash[:xml].entries.size.should == 5
|
163
|
+
verify_content_for(hash[:xml].entries, 1..5)
|
164
|
+
verify_links_for(hash[:xml].links, :path => "http://www.example.com/sdata/example/myContract/-/models",
|
165
|
+
:count => false, :self => false, :first => '1', :last => '11', :next => '6')
|
166
|
+
end
|
167
|
+
@controller.sdata_collection
|
168
|
+
end
|
169
|
+
|
170
|
+
it "properly calculate last page when itemsPerPage is not exact multiple of totalResults" do
|
171
|
+
stub_params({:count => '4'})
|
172
|
+
@controller.should_receive(:render) do |hash|
|
173
|
+
hash[:xml].opensearch("itemsPerPage").should == 4
|
174
|
+
hash[:xml].opensearch("totalResults").should == 15
|
175
|
+
hash[:xml].opensearch("startIndex").should == 1
|
176
|
+
hash[:xml].entries.size.should == 4
|
177
|
+
verify_content_for(hash[:xml].entries, 1..4)
|
178
|
+
verify_links_for(hash[:xml].links,
|
179
|
+
:count => '4', :self => false, :first => '1', :last => '13', :next => '5')
|
180
|
+
end
|
181
|
+
@controller.sdata_collection
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should reject zero start index" do
|
185
|
+
stub_params({:startIndex => '0'})
|
186
|
+
@controller.should_receive(:render) do |hash|
|
187
|
+
hash[:xml].opensearch("itemsPerPage").should == Base.sdata_options[:feed][:default_items_per_page]
|
188
|
+
hash[:xml].opensearch("totalResults").should == 15
|
189
|
+
hash[:xml].opensearch("startIndex").should == 1
|
190
|
+
hash[:xml].entries.size.should == 5
|
191
|
+
verify_content_for(hash[:xml].entries, 1..5)
|
192
|
+
verify_links_for(hash[:xml].links, :self => '0', :first => '1', :last => '11', :next => '6')
|
193
|
+
end
|
194
|
+
@controller.sdata_collection
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should reject negative start index" do
|
198
|
+
stub_params({:startIndex => '-5'})
|
199
|
+
@controller.should_receive(:render) do |hash|
|
200
|
+
hash[:xml].opensearch("itemsPerPage").should == Base.sdata_options[:feed][:default_items_per_page]
|
201
|
+
hash[:xml].opensearch("totalResults").should == 15
|
202
|
+
hash[:xml].opensearch("startIndex").should == 1
|
203
|
+
hash[:xml].entries.size.should == 5
|
204
|
+
verify_content_for(hash[:xml].entries, 1..5)
|
205
|
+
verify_links_for(hash[:xml].links, :self => '-5', :first => '1', :last => '11', :next => '6')
|
206
|
+
end
|
207
|
+
@controller.sdata_collection
|
208
|
+
end
|
209
|
+
|
210
|
+
it "should accept positive start index which is not greater than totalResults-itemsPerPage+1 and return itemsPerPage records" do
|
211
|
+
stub_params({:startIndex => '11'})
|
212
|
+
@controller.should_receive(:render) do |hash|
|
213
|
+
hash[:xml].opensearch("itemsPerPage").should == Base.sdata_options[:feed][:default_items_per_page]
|
214
|
+
hash[:xml].opensearch("totalResults").should == 15
|
215
|
+
hash[:xml].opensearch("startIndex").should == 11
|
216
|
+
hash[:xml].entries.size.should == 5
|
217
|
+
verify_content_for(hash[:xml].entries, 11..15)
|
218
|
+
verify_links_for(hash[:xml].links, :self => '11', :first => '1', :last => '11', :previous => '6')
|
219
|
+
end
|
220
|
+
@controller.sdata_collection
|
221
|
+
end
|
222
|
+
|
223
|
+
it "should accept positive start index which is greater than totalResults-itemsPerPage+1 but not greater than totalResults, and return fitting itemsPerPage" do
|
224
|
+
stub_params({:startIndex => '12'})
|
225
|
+
@controller.should_receive(:render) do |hash|
|
226
|
+
hash[:xml].opensearch("itemsPerPage").should == Base.sdata_options[:feed][:default_items_per_page]
|
227
|
+
hash[:xml].opensearch("totalResults").should == 15
|
228
|
+
hash[:xml].opensearch("startIndex").should == 12
|
229
|
+
hash[:xml].entries.size.should == 4
|
230
|
+
verify_content_for(hash[:xml].entries, 12..15)
|
231
|
+
verify_links_for(hash[:xml].links, :self => '12', :first => '1', :last => '12', :previous => '7')
|
232
|
+
end
|
233
|
+
@controller.sdata_collection
|
234
|
+
|
235
|
+
stub_params({:startIndex => '15'})
|
236
|
+
@controller.should_receive(:render) do |hash|
|
237
|
+
hash[:xml].opensearch("itemsPerPage").should == Base.sdata_options[:feed][:default_items_per_page]
|
238
|
+
hash[:xml].opensearch("totalResults").should == 15
|
239
|
+
hash[:xml].opensearch("startIndex").should == 15
|
240
|
+
hash[:xml].entries.size.should == 1
|
241
|
+
verify_content_for(hash[:xml].entries, 15..15)
|
242
|
+
verify_links_for(hash[:xml].links, :self => '15', :first => '1', :last => '15', :previous => '10')
|
243
|
+
end
|
244
|
+
@controller.sdata_collection
|
245
|
+
|
246
|
+
end
|
247
|
+
|
248
|
+
#RADAR: if this should generate error (e.g. OutOfBounds exception), this spec needs to change
|
249
|
+
it "should accept positive start index which is greater than totalResults-itemsPerPage+1 but return nothing" do
|
250
|
+
stub_params({:startIndex => '16'})
|
251
|
+
@controller.should_receive(:render) do |hash|
|
252
|
+
hash[:xml].opensearch("itemsPerPage").should == Base.sdata_options[:feed][:default_items_per_page]
|
253
|
+
hash[:xml].opensearch("totalResults").should == 15
|
254
|
+
hash[:xml].opensearch("startIndex").should == 16
|
255
|
+
hash[:xml].entries.size.should == 0
|
256
|
+
verify_links_for(hash[:xml].links, :self => '16', :first => '1', :last => '11', :previous => '11')
|
257
|
+
end
|
258
|
+
@controller.sdata_collection
|
259
|
+
end
|
260
|
+
|
261
|
+
it "should combine start index with count" do
|
262
|
+
stub_params({:startIndex => '9', :count => '10'})
|
263
|
+
@controller.should_receive(:render) do |hash|
|
264
|
+
hash[:xml].opensearch("itemsPerPage").should == 10
|
265
|
+
hash[:xml].opensearch("totalResults").should == 15
|
266
|
+
hash[:xml].opensearch("startIndex").should == 9
|
267
|
+
hash[:xml].entries.size.should == 7
|
268
|
+
verify_content_for(hash[:xml].entries, 9..15)
|
269
|
+
verify_links_for(hash[:xml].links, :count => '10', :self => '9', :first => '1', :last => '9', :previous => '1')
|
270
|
+
end
|
271
|
+
@controller.sdata_collection
|
272
|
+
end
|
273
|
+
|
274
|
+
it "should accept query to return no records" do
|
275
|
+
stub_params({:count => '0'})
|
276
|
+
@controller.should_receive(:render) do |hash|
|
277
|
+
hash[:xml].opensearch("itemsPerPage").should == 0
|
278
|
+
hash[:xml].opensearch("totalResults").should == 15
|
279
|
+
hash[:xml].opensearch("startIndex").should == 1
|
280
|
+
hash[:xml].entries.size.should == 0
|
281
|
+
verify_links_for(hash[:xml].links, :count => '0', :self => false)
|
282
|
+
end
|
283
|
+
@controller.sdata_collection
|
284
|
+
end
|
285
|
+
|
286
|
+
it "should accept query to return more records than default value but less than maximum value" do
|
287
|
+
stub_params({:count => '50'})
|
288
|
+
@controller.should_receive(:render) do |hash|
|
289
|
+
hash[:xml].opensearch("itemsPerPage").should == 50
|
290
|
+
hash[:xml].opensearch("totalResults").should == 15
|
291
|
+
hash[:xml].opensearch("startIndex").should == 1
|
292
|
+
hash[:xml].entries.size.should == 15
|
293
|
+
verify_content_for(hash[:xml].entries, 1..15)
|
294
|
+
verify_links_for(hash[:xml].links,
|
295
|
+
:count => '50', :self => false)
|
296
|
+
end
|
297
|
+
@controller.sdata_collection
|
298
|
+
end
|
299
|
+
|
300
|
+
it "should reject query to return more records than maximum value, and use maximum instead" do
|
301
|
+
stub_params({:count => '300'})
|
302
|
+
@controller.should_receive(:render) do |hash|
|
303
|
+
hash[:xml].opensearch("itemsPerPage").should == 100
|
304
|
+
hash[:xml].opensearch("totalResults").should == 15
|
305
|
+
hash[:xml].opensearch("startIndex").should == 1
|
306
|
+
hash[:xml].entries.size.should == 15
|
307
|
+
verify_content_for(hash[:xml].entries, 1..15)
|
308
|
+
verify_links_for(hash[:xml].links,
|
309
|
+
:count => '300', :self => false)
|
310
|
+
end
|
311
|
+
@controller.sdata_collection
|
312
|
+
end
|
313
|
+
|
314
|
+
#FIXME: breaks right now. would be nice to fix without breaking any other tests
|
315
|
+
#find out what's a method to determine whether a string is numerical ('asdf'.to_i returns 0 which is bad)
|
316
|
+
it "should reject invalid value and return default instead" do
|
317
|
+
stub_params({:count => 'asdf'})
|
318
|
+
@controller.should_receive(:render) do |hash|
|
319
|
+
hash[:xml].opensearch("itemsPerPage").should == 5
|
320
|
+
hash[:xml].opensearch("totalResults").should == 15
|
321
|
+
hash[:xml].opensearch("startIndex").should == 1
|
322
|
+
hash[:xml].entries.size.should == 5
|
323
|
+
verify_content_for(hash[:xml].entries, 1..5)
|
324
|
+
verify_links_for(hash[:xml].links, :path => "http://www.example.com/sdata/example/myContract/-/models",
|
325
|
+
:count => 'asdf', :self => false, :first => '1', :last => '11', :next => '6')
|
326
|
+
end
|
327
|
+
@controller.sdata_collection
|
328
|
+
end
|
329
|
+
|
330
|
+
it "should reject negative value and return default instead" do
|
331
|
+
stub_params({:count => '-3'})
|
332
|
+
@controller.should_receive(:render) do |hash|
|
333
|
+
hash[:xml].opensearch("itemsPerPage").should == 5
|
334
|
+
hash[:xml].opensearch("totalResults").should == 15
|
335
|
+
hash[:xml].opensearch("startIndex").should == 1
|
336
|
+
hash[:xml].entries.size.should == 5
|
337
|
+
verify_content_for(hash[:xml].entries, 1..5)
|
338
|
+
verify_links_for(hash[:xml].links, :path => "http://www.example.com/sdata/example/myContract/-/models",
|
339
|
+
:count => '-3', :self => false, :first => '1', :last => '11', :next => '6')
|
340
|
+
end
|
341
|
+
@controller.sdata_collection
|
342
|
+
end
|
343
|
+
|
344
|
+
#RADAR: in this case, going from initial page to previous page will show 'next' page as not equal
|
345
|
+
#to initial page, since startIndex is currently not supported to be negative (and show X records on
|
346
|
+
#first page where X = itemsPerPage+startIndex, and startIndex is negative and thus substracted)
|
347
|
+
#if this is needed, spec will change (but in theory this would conflict with SData spec which
|
348
|
+
#specifies that ALL pages must have exactly the same items as itemsPerPage with possible exception
|
349
|
+
#of ONLY the last page, and not the first one.
|
350
|
+
it "should combine start index with count not exceeding totals" do
|
351
|
+
stub_params({:startIndex => '3', :count => '5'})
|
352
|
+
@controller.should_receive(:render) do |hash|
|
353
|
+
hash[:xml].opensearch("itemsPerPage").should == 5
|
354
|
+
hash[:xml].opensearch("totalResults").should == 15
|
355
|
+
hash[:xml].opensearch("startIndex").should == 3
|
356
|
+
hash[:xml].entries.size.should == 5
|
357
|
+
verify_content_for(hash[:xml].entries, 3..7)
|
358
|
+
verify_links_for(hash[:xml].links, :path => "http://www.example.com/sdata/example/myContract/-/models",
|
359
|
+
:count => '5', :self => '3', :first => '1', :last => '13', :previous => '1', :next => '8')
|
360
|
+
end
|
361
|
+
@controller.sdata_collection
|
362
|
+
end
|
363
|
+
|
364
|
+
it "should combine start index with count exceeding totals" do
|
365
|
+
stub_params({:startIndex => '9', :count => '10'})
|
366
|
+
@controller.should_receive(:render) do |hash|
|
367
|
+
hash[:xml].opensearch("itemsPerPage").should == 10
|
368
|
+
hash[:xml].opensearch("totalResults").should == 15
|
369
|
+
hash[:xml].opensearch("startIndex").should == 9
|
370
|
+
hash[:xml].entries.size.should == 7
|
371
|
+
verify_content_for(hash[:xml].entries, 9..15)
|
372
|
+
verify_links_for(hash[:xml].links, :path => "http://www.example.com/sdata/example/myContract/-/models",
|
373
|
+
:count => '10', :self => '9', :first => '1', :last => '9', :previous => '1')
|
374
|
+
end
|
375
|
+
@controller.sdata_collection
|
376
|
+
end
|
377
|
+
|
378
|
+
end
|
379
|
+
|
380
|
+
end
|
381
|
+
end
|
382
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe SData::ControllerMixin, "#sdata_scope" do
|
4
|
+
context "given a controller which acts as sdata and accesses a linked model" do
|
5
|
+
context "being configured without user scoping" do
|
6
|
+
before :all do
|
7
|
+
BaseModel = Class.new(ActiveRecord::Base)
|
8
|
+
|
9
|
+
Object.__send__ :remove_const, :Model if defined?(Model)
|
10
|
+
class Model < SData::VirtualBase
|
11
|
+
self.baze_class = BaseModel
|
12
|
+
|
13
|
+
define_payload_map :born_at => { :baze_field => :born_at }
|
14
|
+
|
15
|
+
acts_as_sdata :link => :simply_guid
|
16
|
+
end
|
17
|
+
|
18
|
+
class Controller < ActionController::Base
|
19
|
+
extend SData::ControllerMixin
|
20
|
+
|
21
|
+
acts_as_sdata :model => Model, :feed =>
|
22
|
+
{:author => 'Billing Boss',
|
23
|
+
:path => '/trading_accounts',
|
24
|
+
:title => 'Billing Boss | Trading Accounts',
|
25
|
+
:default_items_per_page => 10,
|
26
|
+
:maximum_items_per_page => 100}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
before :each do
|
31
|
+
@controller = Controller.new
|
32
|
+
Model.stub! :all => []
|
33
|
+
end
|
34
|
+
|
35
|
+
context "when params contain :condition key and where clause" do
|
36
|
+
before :each do
|
37
|
+
@controller.stub! :params => { 'where born_at gt 1900' => nil, :condition => '$linked' }
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should apply to SData::Predicate for conditions and append requirement for simply guid" do
|
41
|
+
Model.should_receive(:all).with :conditions => ['"born_at" > ? and id IN (SELECT bb_model_id FROM sd_uuids WHERE bb_model_type = \'BaseModel\' and sd_class = \'Model\')', '1900']
|
42
|
+
@controller.send :sdata_scope
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "when params contain :condition key but does not contain where clause" do
|
47
|
+
before :each do
|
48
|
+
@controller.stub! :params => {:condition => '$linked'}
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should return all entity records with simply guid" do
|
52
|
+
Model.should_receive(:all).with :conditions => ['id IN (SELECT bb_model_id FROM sd_uuids WHERE bb_model_type = \'BaseModel\' and sd_class = \'Model\')']
|
53
|
+
@controller.send :sdata_scope
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe SData::ControllerMixin, "#sdata_scope" do
|
4
|
+
context "given a controller which acts as sdata and accesses a non-linked model" do
|
5
|
+
before :all do
|
6
|
+
|
7
|
+
Object.__send__ :remove_const, :Model if defined?(Model)
|
8
|
+
class Model < SData::VirtualBase
|
9
|
+
self.baze_class = Class.new
|
10
|
+
|
11
|
+
define_payload_map :born_at => { :baze_field => :born_at }
|
12
|
+
|
13
|
+
acts_as_sdata
|
14
|
+
end
|
15
|
+
|
16
|
+
class Controller < ActionController::Base
|
17
|
+
extend SData::ControllerMixin
|
18
|
+
|
19
|
+
acts_as_sdata :model => Model, :feed =>
|
20
|
+
{:author => 'Billing Boss',
|
21
|
+
:path => '/trading_accounts',
|
22
|
+
:title => 'Billing Boss | Trading Accounts',
|
23
|
+
:default_items_per_page => 10,
|
24
|
+
:maximum_items_per_page => 100}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
before :each do
|
29
|
+
@controller = Controller.new
|
30
|
+
Model.stub! :all => []
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when params contain where clause" do
|
34
|
+
before :each do
|
35
|
+
@controller.stub! :params => { 'where bornAt gt 1900' => nil }
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should apply to SData::Predicate for conditions" do
|
39
|
+
Model.should_receive(:all).with :conditions => ['"born_at" > ?', '1900']
|
40
|
+
@controller.send :sdata_scope
|
41
|
+
end
|
42
|
+
|
43
|
+
context "when condition contain 'ne' relation" do
|
44
|
+
before :each do
|
45
|
+
@controller.stub! :params => { 'where born_at ne 1900' => nil }
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should parse it correctly" do
|
49
|
+
Model.should_receive(:all).with :conditions => ['"born_at" <> ?', '1900']
|
50
|
+
@controller.send :sdata_scope
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "when params do not contain :predicate key" do
|
56
|
+
before :each do
|
57
|
+
@controller.stub! :params => {}
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should return all entity records" do
|
61
|
+
Model.should_receive(:all).with({})
|
62
|
+
@controller.send :sdata_scope
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|