acts_as_sdata 1.0.0
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.
- 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
|