autoforme 0.5.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.
@@ -0,0 +1,505 @@
1
+ require './spec/spec_helper'
2
+
3
+ describe AutoForme do
4
+ before(:all) do
5
+ db_setup(:artists=>[[:name, :string]], :albums=>[[:name, :string], [:artist_id, :integer, {:table=>:artists}]])
6
+ model_setup(:Artist=>[:artists, [[:one_to_many, :albums]]], :Album=>[:albums, [[:many_to_one, :artist]]])
7
+ end
8
+ after(:all) do
9
+ Object.send(:remove_const, :Album)
10
+ Object.send(:remove_const, :Artist)
11
+ end
12
+
13
+ it "should have basic many to one associations working" do
14
+ app_setup do
15
+ model Artist
16
+ model Album do
17
+ columns [:name, :artist]
18
+ end
19
+ end
20
+
21
+ visit("/Artist/new")
22
+ fill_in 'Name', :with=>'Artist1'
23
+ click_button 'Create'
24
+ fill_in 'Name', :with=>'Artist2'
25
+ click_button 'Create'
26
+
27
+ visit("/Album/new")
28
+ fill_in 'Name', :with=>'Album1'
29
+ select 'Artist1'
30
+ click_button 'Create'
31
+
32
+ click_link 'Show'
33
+ select 'Album1'
34
+ click_button 'Show'
35
+ page.html.should =~ /Name.+Album1/m
36
+ page.html.should =~ /Artist.+Artist1/m
37
+
38
+ click_link 'Edit'
39
+ select 'Album1'
40
+ click_button 'Edit'
41
+ fill_in 'Name', :with=>'Album1b'
42
+ select 'Artist2'
43
+ click_button 'Update'
44
+
45
+ click_link 'Search'
46
+ fill_in 'Name', :with=>'1b'
47
+ select 'Artist2'
48
+ click_button 'Search'
49
+ all('td').map{|s| s.text}.should == ["Album1b", "Artist2", "Show", "Edit", "Delete"]
50
+
51
+ click_link 'Album'
52
+ all('td').map{|s| s.text}.should == ["Album1b", "Artist2", "Show", "Edit", "Delete"]
53
+ end
54
+
55
+ it "should use text boxes for associated objects on new/edit/search forms if associated model uses autocompleting" do
56
+ app_setup do
57
+ model Artist do
58
+ autocomplete_options({})
59
+ end
60
+ model Album do
61
+ columns [:name, :artist]
62
+ end
63
+ end
64
+
65
+ a = Artist.create(:name=>'TestArtist')
66
+ b = Artist.create(:name=>'TestArtist2')
67
+
68
+ visit("/Album/new")
69
+ fill_in 'Name', :with=>'Album1'
70
+ fill_in 'Artist', :with=>a.id.to_s
71
+ click_button 'Create'
72
+ Album.first.artist_id.should == a.id
73
+
74
+ click_link 'Edit'
75
+ select 'Album1'
76
+ click_button 'Edit'
77
+ fill_in 'Name', :with=>'Album1b'
78
+ fill_in 'Artist', :with=>b.id.to_s
79
+ click_button 'Update'
80
+ Album.first.artist_id.should == b.id
81
+
82
+ click_link 'Search'
83
+ fill_in 'Name', :with=>'1b'
84
+ fill_in 'Artist', :with=>b.id.to_s
85
+ click_button 'Search'
86
+ all('td').map{|s| s.text}.should == ["Album1b", "TestArtist2", "Show", "Edit", "Delete"]
87
+ end
88
+
89
+ it "should be able to used specified name formatting in other model" do
90
+ app_setup do
91
+ model Artist do
92
+ display_name{|obj| obj.name * 2}
93
+ end
94
+ model Album do
95
+ columns [:name, :artist]
96
+ end
97
+ end
98
+
99
+ visit("/Artist/new")
100
+ fill_in 'Name', :with=>'A1'
101
+ click_button 'Create'
102
+ fill_in 'Name', :with=>'A2'
103
+ click_button 'Create'
104
+
105
+ visit("/Album/new")
106
+ fill_in 'Name', :with=>'Album1'
107
+ select 'A1A1'
108
+ click_button 'Create'
109
+
110
+ click_link 'Show'
111
+ select 'Album1'
112
+ click_button 'Show'
113
+ page.html.should =~ /Name.+Album1/m
114
+ page.html.should =~ /Artist.+A1A1/m
115
+
116
+ click_link 'Edit'
117
+ select 'Album1'
118
+ click_button 'Edit'
119
+ fill_in 'Name', :with=>'Album1b'
120
+ select 'A2A2'
121
+ click_button 'Update'
122
+
123
+ click_link 'Search'
124
+ fill_in 'Name', :with=>'1b'
125
+ select 'A2A2'
126
+ click_button 'Search'
127
+ all('td').map{|s| s.text}.should == ["Album1b", "A2A2", "Show", "Edit", "Delete"]
128
+
129
+ click_link 'Album'
130
+ all('td').map{|s| s.text}.should == ["Album1b", "A2A2", "Show", "Edit", "Delete"]
131
+ end
132
+
133
+ it "should be able to used specified name formatting for current association" do
134
+ app_setup do
135
+ model Artist
136
+ model Album do
137
+ columns [:name, :artist]
138
+ column_options :artist=>{:name_method=>lambda{|obj| obj.name * 2}}
139
+ end
140
+ end
141
+
142
+ visit("/Artist/new")
143
+ fill_in 'Name', :with=>'A1'
144
+ click_button 'Create'
145
+ fill_in 'Name', :with=>'A2'
146
+ click_button 'Create'
147
+
148
+ visit("/Album/new")
149
+ fill_in 'Name', :with=>'Album1'
150
+ select 'A1A1'
151
+ click_button 'Create'
152
+
153
+ click_link 'Show'
154
+ select 'Album1'
155
+ click_button 'Show'
156
+ page.html.should =~ /Name.+Album1/m
157
+ page.html.should =~ /Artist.+A1A1/m
158
+
159
+ click_link 'Edit'
160
+ select 'Album1'
161
+ click_button 'Edit'
162
+ fill_in 'Name', :with=>'Album1b'
163
+ select 'A2A2'
164
+ click_button 'Update'
165
+
166
+ click_link 'Search'
167
+ fill_in 'Name', :with=>'1b'
168
+ select 'A2A2'
169
+ click_button 'Search'
170
+ all('td').map{|s| s.text}.should == ["Album1b", "A2A2", "Show", "Edit", "Delete"]
171
+
172
+ click_link 'Album'
173
+ all('td').map{|s| s.text}.should == ["Album1b", "A2A2", "Show", "Edit", "Delete"]
174
+ end
175
+
176
+ it "should be able to eager load associations when loading model" do
177
+ app_setup do
178
+ model Artist
179
+ model Album do
180
+ columns [:name, :artist]
181
+ eager :artist
182
+ display_name{|obj| "#{obj.associations[:artist].name}-#{obj.name}"}
183
+ end
184
+ end
185
+
186
+ visit("/Artist/new")
187
+ fill_in 'Name', :with=>'A1'
188
+ click_button 'Create'
189
+ fill_in 'Name', :with=>'A2'
190
+ click_button 'Create'
191
+
192
+ visit("/Album/new")
193
+ fill_in 'Name', :with=>'Album1'
194
+ select 'A1'
195
+ click_button 'Create'
196
+
197
+ click_link 'Show'
198
+ select 'A1-Album1'
199
+ click_button 'Show'
200
+ page.html.should =~ /Name.+Album1/m
201
+ page.html.should =~ /Artist.+A1/m
202
+
203
+ click_link 'Edit'
204
+ select 'A1-Album1'
205
+ click_button 'Edit'
206
+ fill_in 'Name', :with=>'Album1b'
207
+ select 'A2'
208
+ click_button 'Update'
209
+
210
+ click_link 'Search'
211
+ fill_in 'Name', :with=>'1b'
212
+ select 'A2'
213
+ click_button 'Search'
214
+ all('td').map{|s| s.text}.should == ["Album1b", "A2", "Show", "Edit", "Delete"]
215
+
216
+ click_link 'Album'
217
+ all('td').map{|s| s.text}.should == ["Album1b", "A2", "Show", "Edit", "Delete"]
218
+
219
+ click_link 'Delete'
220
+ select 'A2-Album1b'
221
+ click_button 'Delete'
222
+ end
223
+
224
+ it "should handle case when setting many_to_one association for associated class that eagerly graphs" do
225
+ app_setup do
226
+ model Artist do
227
+ eager_graph :albums
228
+ end
229
+ model Album do
230
+ columns [:name, :artist]
231
+ eager_graph :artist
232
+ order{|type, req| type == :edit ? [:albums__name, :artist__name] : [:artist__name, :albums__name]}
233
+ display_name{|obj, type| type == :edit ? "#{obj.name} (#{obj.artist.name})" : "#{obj.artist.name}-#{obj.name}"}
234
+ end
235
+ end
236
+
237
+ visit("/Artist/new")
238
+ fill_in 'Name', :with=>'B'
239
+ click_button 'Create'
240
+ visit("/Album/new")
241
+ fill_in 'Name', :with=>'A'
242
+ select 'B'
243
+ click_button 'Create'
244
+ end
245
+
246
+ it "should be able to order on eager_graphed associations when loading model" do
247
+ app_setup do
248
+ model Artist
249
+ model Album do
250
+ columns [:name, :artist]
251
+ eager_graph :artist
252
+ order{|type, req| type == :edit ? [:albums__name, :artist__name] : [:artist__name, :albums__name]}
253
+ display_name{|obj, type| type == :edit ? "#{obj.name} (#{obj.artist.name})" : "#{obj.artist.name}-#{obj.name}"}
254
+ end
255
+ end
256
+
257
+ visit("/Artist/new")
258
+ fill_in 'Name', :with=>'B'
259
+ click_button 'Create'
260
+ fill_in 'Name', :with=>'A'
261
+ click_button 'Create'
262
+
263
+ visit("/Album/new")
264
+ fill_in 'Name', :with=>'Z'
265
+ select 'B'
266
+ click_button 'Create'
267
+ fill_in 'Name', :with=>'Y'
268
+ select 'A'
269
+ click_button 'Create'
270
+ fill_in 'Name', :with=>'X'
271
+ select 'B'
272
+ click_button 'Create'
273
+
274
+ click_link 'Show'
275
+ all('select option').map{|s| s.text}.should == ['', 'A-Y', 'B-X', 'B-Z']
276
+ select 'B-X'
277
+ click_button 'Show'
278
+ page.html.should =~ /Name.+X/m
279
+ page.html.should =~ /Artist.+B/m
280
+
281
+ click_link 'Edit'
282
+ all('select option').map{|s| s.text}.should == ['', 'X (B)', 'Y (A)', 'Z (B)']
283
+ select 'Z (B)'
284
+ click_button 'Edit'
285
+ fill_in 'Name', :with=>'ZZ'
286
+ select 'A'
287
+ click_button 'Update'
288
+
289
+ click_link 'Search'
290
+ select 'A'
291
+ click_button 'Search'
292
+ all('tr td:first-child').map{|s| s.text}.should == %w'Y ZZ'
293
+
294
+ click_link 'Album'
295
+ all('tr td:first-child').map{|s| s.text}.should == %w'Y ZZ X'
296
+
297
+ click_link 'Delete'
298
+ all('select option').map{|s| s.text}.should == ['', 'A-Y', 'A-ZZ', 'B-X']
299
+ select 'B-X'
300
+ click_button 'Delete'
301
+ end
302
+
303
+ it "should have many_to_one association lookup use order/eager/eager_graph/filter for associated model" do
304
+ app_setup do
305
+ model Artist do
306
+ order :name
307
+ eager :albums
308
+ filter{|ds, action| ds.where{name > 'M'}}
309
+ display_name{|obj| "#{obj.name} #{obj.albums.length}"}
310
+ end
311
+ model Album do
312
+ columns [:name, :artist]
313
+ order [:name]
314
+ end
315
+ end
316
+
317
+ visit("/Artist/new")
318
+ fill_in 'Name', :with=>'J'
319
+ click_button 'Create'
320
+ fill_in 'Name', :with=>'Z'
321
+ click_button 'Create'
322
+ fill_in 'Name', :with=>'Y'
323
+ click_button 'Create'
324
+ fill_in 'Name', :with=>'X'
325
+ click_button 'Create'
326
+
327
+ visit("/Album/new")
328
+ fill_in 'Name', :with=>'E'
329
+ all('select option').map{|s| s.text}.should == ['', 'X 0', 'Y 0', 'Z 0']
330
+ select 'X 0'
331
+ click_button 'Create'
332
+ fill_in 'Name', :with=>'D'
333
+ all('select option').map{|s| s.text}.should == ['', 'X 1', 'Y 0', 'Z 0']
334
+ select 'Y 0'
335
+ click_button 'Create'
336
+ fill_in 'Name', :with=>'C'
337
+ all('select option').map{|s| s.text}.should == ['', 'X 1', 'Y 1', 'Z 0']
338
+ select 'Y 1'
339
+ click_button 'Create'
340
+
341
+ click_link 'Show'
342
+ select 'D'
343
+ click_button 'Show'
344
+ page.html.should =~ /Name.+D/m
345
+ page.html.should =~ /Artist.+Y 2/m
346
+
347
+ click_link 'Edit'
348
+ select 'C'
349
+ click_button 'Edit'
350
+ all('select option').map{|s| s.text}.should == ['', 'X 1', 'Y 2', 'Z 0']
351
+ select 'X 1'
352
+ click_button 'Update'
353
+
354
+ click_link 'Search'
355
+ all('select option').map{|s| s.text}.should == ['', 'X 2', 'Y 1', 'Z 0']
356
+ select 'X 2'
357
+ click_button 'Search'
358
+ all('tr td:first-child').map{|s| s.text}.should == %w'C E'
359
+
360
+ click_link 'Album'
361
+ all('tr td:first-child').map{|s| s.text}.should == %w'C D E'
362
+
363
+ click_link 'Delete'
364
+ all('select option').map{|s| s.text}.should == ['', 'C', 'D', 'E']
365
+ select 'C'
366
+ click_button 'Delete'
367
+ click_button 'Delete'
368
+
369
+ visit("/Album/new")
370
+ Artist.where(:name=>'Y').update(:name=>'A')
371
+ fill_in 'Name', :with=>'F'
372
+ select 'Y 1'
373
+ proc{click_button 'Create'}.should raise_error(Sequel::NoMatchingRow)
374
+
375
+ visit("/Album/search")
376
+ select 'X 1'
377
+ Artist.where(:name=>'X').update(:name=>'B')
378
+ click_button 'Search'
379
+ all('tr td:first-child').map{|s| s.text}.should == []
380
+ end
381
+
382
+ it "should have working one to many and many to one association links on show and edit pages" do
383
+ app_setup do
384
+ model Artist do
385
+ association_links :all
386
+ end
387
+ model Album do
388
+ association_links :all
389
+ columns [:name, :artist]
390
+ end
391
+ end
392
+
393
+ visit("/Artist/new")
394
+ fill_in 'Name', :with=>'Artist1'
395
+ click_button 'Create'
396
+
397
+ click_link 'Edit'
398
+ select 'Artist1'
399
+ click_button 'Edit'
400
+ click_link 'create'
401
+ fill_in 'Name', :with=>'Album1'
402
+ click_button 'Create'
403
+
404
+ click_link 'Show'
405
+ select 'Album1'
406
+ click_button 'Show'
407
+ click_link 'Artist1'
408
+ page.current_path.should =~ %r{Artist/show/\d+}
409
+ click_link 'Album1'
410
+ page.current_path.should =~ %r{Album/show/\d+}
411
+ click_link 'Artist'
412
+ page.current_path.should == '/Artist/browse'
413
+
414
+ click_link 'Edit'
415
+ select 'Artist1'
416
+ click_button 'Edit'
417
+ click_link 'Album1'
418
+ page.current_path.should =~ %r{Album/edit/\d+}
419
+ click_link 'Artist1'
420
+ page.current_path.should =~ %r{Artist/edit/\d+}
421
+ click_link 'Albums'
422
+ page.current_path.should == '/Album/browse'
423
+ end
424
+
425
+ it "should support lazy loading association links on show and edit pages" do
426
+ app_setup do
427
+ model Artist do
428
+ lazy_load_association_links true
429
+ association_links :all
430
+ end
431
+ model Album do
432
+ lazy_load_association_links true
433
+ association_links :all
434
+ columns [:name, :artist]
435
+ end
436
+ end
437
+
438
+ visit("/Artist/new")
439
+ fill_in 'Name', :with=>'Artist1'
440
+ click_button 'Create'
441
+
442
+ click_link 'Edit'
443
+ select 'Artist1'
444
+ click_button 'Edit'
445
+ page.html.should_not =~ /create/
446
+ click_link 'Show Associations'
447
+ click_link 'create'
448
+ fill_in 'Name', :with=>'Album1'
449
+ click_button 'Create'
450
+
451
+ click_link 'Show'
452
+ select 'Album1'
453
+ click_button 'Show'
454
+ click_link 'Show Associations'
455
+ click_link 'Artist1'
456
+ page.current_path.should =~ %r{Artist/show/\d+}
457
+ click_link 'Show Associations'
458
+ click_link 'Album1'
459
+ page.current_path.should =~ %r{Album/show/\d+}
460
+ click_link 'Show Associations'
461
+ click_link 'Artist'
462
+ page.current_path.should == '/Artist/browse'
463
+
464
+ click_link 'Edit'
465
+ select 'Artist1'
466
+ click_button 'Edit'
467
+ click_link 'Show Associations'
468
+ click_link 'Album1'
469
+ page.current_path.should =~ %r{Album/edit/\d+}
470
+ click_link 'Show Associations'
471
+ click_link 'Artist1'
472
+ page.current_path.should =~ %r{Artist/edit/\d+}
473
+ click_link 'Show Associations'
474
+ click_link 'Albums'
475
+ page.current_path.should == '/Album/browse'
476
+ end
477
+ end
478
+
479
+ describe AutoForme do
480
+ before(:all) do
481
+ db_setup(:artists=>[[:name, :string]], :albums=>[[:name, :string], [:artist_id, :integer, {:table=>:artists}]])
482
+ model_setup(:Artist=>[:artists, [[:one_to_many, :albums]]], :Album=>[:albums, [[:many_to_one, :artist, {:conditions=>{:name=>'A'..'M'}, :order=>:name}]]])
483
+ end
484
+ after(:all) do
485
+ Object.send(:remove_const, :Album)
486
+ Object.send(:remove_const, :Artist)
487
+ end
488
+
489
+ it "should have select options respect association options" do
490
+ app_setup do
491
+ model Artist
492
+ model Album do
493
+ columns [:name, :artist]
494
+ column_options{|col, type, req| {:dataset=>proc{|ds| ds.where(:name=>'B'..'O').reverse_order(:name)}} if type == :edit && col == :artist}
495
+ end
496
+ end
497
+
498
+ %w'A1 E1 L1 N1'.each{|n| Artist.create(:name=>n)}
499
+ visit("/Album/new")
500
+ all('select option').map{|s| s.text}.should == ["", "A1", "E1", "L1"]
501
+
502
+ visit("/Album/edit/#{Album.create(:name=>'Album1').id}")
503
+ all('select option').map{|s| s.text}.should == ["", "L1", "E1"]
504
+ end
505
+ end