autoforme 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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