-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
form_builder_test.rb
550 lines (459 loc) · 18.6 KB
/
form_builder_test.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
require 'test_helper'
class FormBuilderTest < ActionView::TestCase
def with_form_for(object, *args, &block)
simple_form_for object do |f|
concat f.input(*args, &block)
end
end
def with_button_for(object, *args)
simple_form_for object do |f|
concat f.button(*args)
end
end
def with_error_for(object, *args)
simple_form_for object do |f|
concat f.error(*args)
end
end
def with_hint_for(object, *args)
simple_form_for object do |f|
concat f.hint(*args)
end
end
def with_label_for(object, *args)
simple_form_for object do |f|
concat f.label(*args)
end
end
def with_association_for(object, *args)
simple_form_for object do |f|
concat f.association(*args)
end
end
# All
test 'nested simple fields should yields an instance of FormBuilder' do
simple_form_for :user do |f|
f.simple_fields_for :posts do |posts_form|
assert posts_form.instance_of?(SimpleForm::FormBuilder)
end
end
end
test 'builder input is html safe' do
simple_form_for @user do |f|
assert f.input(:name).html_safe?
end
end
test 'builder input should allow a block to configure input' do
with_form_for @user, :name do
concat text_field_tag :foo, :bar, :id => :cool
end
assert_no_select 'input.string'
assert_select 'input#cool'
end
# INPUT TYPES
test 'builder should generate text fields for string columns' do
with_form_for @user, :name
assert_select 'form input#user_name.string'
end
test 'builder should generate text areas for text columns' do
with_form_for @user, :description
assert_select 'form textarea#user_description.text'
end
test 'builder should generate a checkbox for boolean columns' do
with_form_for @user, :active
assert_select 'form input[type=checkbox]#user_active.boolean'
end
test 'builder should use integer text field for integer columns' do
with_form_for @user, :age
assert_select 'form input#user_age.integer'
end
test 'builder should generate decimal text field for decimal columns' do
with_form_for @user, :credit_limit
assert_select 'form input#user_credit_limit.decimal'
end
test 'builder should generate password fields for columns that matches password' do
with_form_for @user, :password
assert_select 'form input#user_password.password'
end
test 'builder should generate country fields for columns that matches country' do
with_form_for @user, :residence_country
assert_select 'form select#user_residence_country.country'
end
test 'builder should generate time_zone fields for columns that matches time_zone' do
with_form_for @user, :time_zone
assert_select 'form select#user_time_zone.time_zone'
end
test 'builder should generate date select for date columns' do
with_form_for @user, :born_at
assert_select 'form select#user_born_at_1i.date'
end
test 'builder should generate time select for time columns' do
with_form_for @user, :delivery_time
assert_select 'form select#user_delivery_time_4i.time'
end
test 'builder should generate datetime select for datetime columns' do
with_form_for @user, :created_at
assert_select 'form select#user_created_at_1i.datetime'
end
test 'builder should generate datetime select for timestamp columns' do
with_form_for @user, :updated_at
assert_select 'form select#user_updated_at_1i.datetime'
end
test 'builder should generate file for file columns' do
@user.avatar = mock("file")
@user.avatar.expects(:respond_to?).with(:mounted_as).returns(false)
@user.avatar.expects(:respond_to?).with(:file?).returns(false)
@user.avatar.expects(:respond_to?).with(:public_filename).returns(true)
with_form_for @user, :avatar
assert_select 'form input#user_avatar.file'
end
test 'build should generate select if a collection is given' do
with_form_for @user, :age, :collection => 1..60
assert_select 'form select#user_age.select'
end
test 'builder should allow overriding default input type for text' do
with_form_for @user, :name, :as => :text
assert_no_select 'form input#user_name'
assert_select 'form textarea#user_name.text'
with_form_for @user, :active, :as => :radio
assert_no_select 'form input[type=checkbox]'
assert_select 'form input.radio[type=radio]', :count => 2
with_form_for @user, :born_at, :as => :string
assert_no_select 'form select'
assert_select 'form input#user_born_at.string'
end
# COMMON OPTIONS
test 'builder should allow passing options to input' do
with_form_for @user, :name, :input_html => { :class => 'my_input', :id => 'my_input' }
assert_select 'form input#my_input.my_input.string'
end
test 'builder should generate a input with label' do
with_form_for @user, :name
assert_select 'form label.string[for=user_name]', /Name/
end
test 'builder should be able to disable the label for a input' do
with_form_for @user, :name, :label => false
assert_no_select 'form label'
end
test 'builder should use custom label' do
with_form_for @user, :name, :label => 'Yay!'
assert_select 'form label', /Yay!/
end
test 'builder should pass options to label' do
with_form_for @user, :name, :label_html => { :id => "cool" }
assert_select 'form label#cool', /Name/
end
test 'builder should not generate hints for a input' do
with_form_for @user, :name
assert_no_select 'span.hint'
end
test 'builder should be able to add a hint for a input' do
with_form_for @user, :name, :hint => 'test'
assert_select 'span.hint', 'test'
end
test 'builder should be able to disable a hint even if it exists in i18n' do
store_translations(:en, :simple_form => { :hints => { :name => 'Hint test' } }) do
with_form_for @user, :name, :hint => false
assert_no_select 'span.hint'
end
end
test 'builder should pass options to hint' do
with_form_for @user, :name, :hint => 'test', :hint_html => { :id => "cool" }
assert_select 'span.hint#cool', 'test'
end
test 'builder should generate errors for attribute without errors' do
with_form_for @user, :credit_limit
assert_no_select 'span.errors'
end
test 'builder should generate errors for attribute with errors' do
with_form_for @user, :name
assert_select 'span.error', "can't be blank"
end
test 'builder should be able to disable showing errors for a input' do
with_form_for @user, :name, :error => false
assert_no_select 'span.error'
end
test 'builder should pass options to errors' do
with_form_for @user, :name, :error_html => { :id => "cool" }
assert_select 'span.error#cool', "can't be blank"
end
test 'builder input should be required by default' do
with_form_for @user, :name
assert_select 'input.required#user_name'
end
test 'builder input should allow disabling required' do
with_form_for @user, :name, :required => false
assert_no_select 'input.required'
assert_select 'input.optional#user_name'
end
# WRAPPERS
test 'builder support wrapping around an specific tag' do
swap SimpleForm, :wrapper_tag => :p do
with_form_for @user, :name
assert_select 'form p label[for=user_name]'
assert_select 'form p input#user_name.string'
end
end
test 'builder wrapping tag adds default css classes' do
swap SimpleForm, :wrapper_tag => :p do
with_form_for @user, :name
assert_select 'form p.required.string'
with_form_for @user, :age, :required => false
assert_select 'form p.optional.integer'
end
end
test 'builder wrapping tag allow custom options to be given' do
swap SimpleForm, :wrapper_tag => :p do
with_form_for @user, :name, :wrapper_html => { :id => "super_cool", :class => 'yay' }
assert_select 'form p#super_cool.required.string.yay'
end
end
test 'builder allows wrapper tag to be given on demand' do
simple_form_for @user do |f|
concat f.input :name, :wrapper_tag => :b
end
assert_select 'form b.required.string'
end
# WITHOUT OBJECT
test 'builder should generate properly when object is not present' do
with_form_for :project, :name
assert_select 'form input.string#project_name'
end
test 'builder should generate password fields based on attribute name when object is not present' do
with_form_for :project, :password_confirmation
assert_select 'form input[type=password].password#project_password_confirmation'
end
test 'builder should generate text fields by default for all attributes when object is not present' do
with_form_for :project, :created_at
assert_select 'form input.string#project_created_at'
with_form_for :project, :budget
assert_select 'form input.string#project_budget'
end
test 'builder should allow overriding input type when object is not present' do
with_form_for :project, :created_at, :as => :datetime
assert_select 'form select.datetime#project_created_at_1i'
with_form_for :project, :budget, :as => :decimal
assert_select 'form input.decimal#project_budget'
end
# ERRORS
test 'builder should generate an error tag for the attribute' do
with_error_for @user, :name
assert_select 'span.error', "can't be blank"
end
test 'builder should allow passing options to error tag' do
with_error_for @user, :name, :id => 'name_error'
assert_select 'span.error#name_error', "can't be blank"
end
# HINTS
test 'builder should generate a hint tag for the attribute' do
store_translations(:en, :simple_form => { :hints => { :user => { :name => "Add your name" }}}) do
with_hint_for @user, :name
assert_select 'span.hint', 'Add your name'
end
end
test 'builder should generate a hint component tag for the given text' do
with_hint_for @user, 'Hello World!'
assert_select 'span.hint', 'Hello World!'
end
test 'builder should allow passing options to hint tag' do
with_hint_for @user, :name, :hint => 'Hello World!', :id => 'name_hint'
assert_select 'span.hint#name_hint', 'Hello World!'
end
# LABELS
test 'builder should generate a label for the attribute' do
with_label_for @user, :name
assert_select 'label.string[for=user_name]', /Name/
end
test 'builder should allow passing options to label tag' do
with_label_for @user, :name, :label => 'My label', :id => 'name_label'
assert_select 'label.string.required#name_label', /My label/
end
test 'builder should fallback to default label when string is given' do
with_label_for @user, :name, 'Nome do usuário'
assert_select 'label', 'Nome do usuário'
assert_no_select 'label.string'
end
test 'builder allows label order to be changed' do
swap SimpleForm, :label_text => lambda { |l, r| "#{l}:" } do
with_label_for @user, :age
assert_select 'label.integer[for=user_age]', "Age:"
end
end
# BUTTONS
test 'builder should create buttons' do
with_button_for :post, :submit
assert_select 'form input.submit[type=submit][value=Submit Post]'
end
test 'builder should create buttons for new records' do
@user.new_record!
with_button_for @user, :submit
assert_select 'form input.create[type=submit][value=Create User]'
end
test 'builder should create buttons for existing records' do
with_button_for @user, :submit
assert_select 'form input.update[type=submit][value=Update User]'
end
test 'builder should create buttons using human_name' do
@user.class.expects(:human_name).returns("Usuario")
with_button_for @user, :submit
assert_select 'form input[type=submit][value=Update Usuario]'
end
test 'builder should create object buttons with localized labels' do
store_translations(:en, :simple_form => { :buttons => {
:create => "Criar %{model}", :update => "Atualizar %{model}" }}) do
with_button_for @user, :submit
assert_select 'form input[type=submit][value=Atualizar User]'
@user.new_record!
with_button_for @user, :submit
assert_select 'form input[type=submit][value=Criar User]'
end
end
test 'builder should create non object buttons with localized labels' do
store_translations(:en, :simple_form => { :buttons => { :submit => "Enviar %{model}" }}) do
with_button_for :post, :submit
assert_select 'form input[type=submit][value=Enviar Post]'
end
end
test 'builder forwards first options as button text' do
with_button_for :post, :submit, "Send it!"
assert_select 'form input[type=submit][value=Send it!]'
end
test 'builder forwards label option as button text' do
with_button_for :post, :submit, :label => "Send it!"
assert_select 'form input[type=submit][value=Send it!]'
end
test 'builder forwards all options except label to button' do
with_button_for :post, :submit, :class => "cool", :id => "super"
assert_select 'form input#super.submit.cool[type=submit]'
end
test 'builder calls any button tag' do
with_button_for :post, :image_submit, "/image/foo/bar"
assert_select 'form input[src=/image/foo/bar][type=image]'
end
# ASSOCIATIONS
test 'builder should not allow creating an association input when no object exists' do
assert_raise ArgumentError do
with_association_for :post, :author
end
end
test 'builder association with a block call simple_fields_for' do
simple_form_for @user do |f|
f.association :posts do |posts_form|
assert posts_form.instance_of?(SimpleForm::FormBuilder)
end
end
end
test 'builder association forwards collection to simple_fields_for' do
calls = 0
simple_form_for @user do |f|
f.association :company, :collection => Company.all do |c|
calls += 1
end
end
assert_equal calls, 3
end
# ASSOCIATIONS - BELONGS TO
test 'builder creates a select for belongs_to associations' do
with_association_for @user, :company
assert_select 'form select.select#user_company_id'
assert_select 'form select option[value=1]', 'Company 1'
assert_select 'form select option[value=2]', 'Company 2'
assert_select 'form select option[value=3]', 'Company 3'
end
test 'builder allows collection radio for belongs_to associations' do
with_association_for @user, :company, :as => :radio
assert_select 'form input.radio#user_company_id_1'
assert_select 'form input.radio#user_company_id_2'
assert_select 'form input.radio#user_company_id_3'
end
test 'builder marks the record which already belongs to the user' do
@user.company_id = 2
with_association_for @user, :company, :as => :radio
assert_no_select 'form input.radio#user_company_id_1[checked=checked]'
assert_select 'form input.radio#user_company_id_2[checked=checked]'
assert_no_select 'form input.radio#user_company_id_3[checked=checked]'
end
# ASSOCIATIONS - FINDERS
test 'builder should allow passing conditions to find collection' do
with_association_for @user, :company, :conditions => { :id => 1 }
assert_select 'form select.select#user_company_id'
assert_select 'form select option[value=1]'
assert_no_select 'form select option[value=2]'
assert_no_select 'form select option[value=3]'
end
test 'builder should use reflection conditions to find collection' do
with_association_for @user, :special_company
assert_select 'form select.select#user_special_company_id'
assert_select 'form select option[value=1]'
assert_no_select 'form select option[value=2]'
assert_no_select 'form select option[value=3]'
end
test 'builder should allow passing order to find collection' do
with_association_for @user, :company, :order => 'name'
assert_select 'form select.select#user_company_id'
assert_no_select 'form select option[value=1]'
assert_no_select 'form select option[value=2]'
assert_select 'form select option[value=3]'
end
test 'builder should allow passing include option to find collection' do
with_association_for @user, :company, :include => :city
assert_select 'form select.select#user_company_id'
assert_select 'form select option[value=1]'
assert_select 'form select option[value=2]'
assert_no_select 'form select option[value=3]'
end
test 'builder should allow passing joins option to find collection' do
with_association_for @user, :company, :joins => :city
assert_select 'form select.select#user_company_id'
assert_select 'form select option[value=2]'
assert_select 'form select option[value=3]'
assert_no_select 'form select option[value=1]'
end
test 'builder should allow overriding collection to association input' do
with_association_for @user, :company, :include_blank => false,
:collection => [Company.new(999, 'Teste')]
assert_select 'form select.select#user_company_id'
assert_no_select 'form select option[value=1]'
assert_select 'form select option[value=999]', 'Teste'
assert_select 'form select option', :count => 1
end
# ASSOCIATIONS - has_*
test 'builder does not allow has_one associations' do
assert_raise RuntimeError do
with_association_for @user, :first_company, :as => :radio
end
end
test 'builder creates a select with multiple options for collection associations' do
with_association_for @user, :tags
assert_select 'form select.select#user_tag_ids'
assert_select 'form select[multiple=multiple][size=5]'
assert_select 'form select option[value=1]', 'Tag 1'
assert_select 'form select option[value=2]', 'Tag 2'
assert_select 'form select option[value=3]', 'Tag 3'
end
test 'builder allows size to be overwritten for collection associations' do
with_association_for @user, :tags, :input_html => { :size => 10 }
assert_select 'form select[multiple=multiple][size=10]'
end
test 'builder marks all selected records which already belongs to user' do
@user.tag_ids = [1, 2]
with_association_for @user, :tags
assert_select 'form select option[value=1][selected=selected]'
assert_select 'form select option[value=2][selected=selected]'
assert_no_select 'form select option[value=3][selected=selected]'
end
test 'builder allows a collection of check boxes for collection associations' do
@user.tag_ids = [1, 2]
with_association_for @user, :tags, :as => :check_boxes
assert_select 'form input#user_tag_ids_1[type=checkbox]'
assert_select 'form input#user_tag_ids_2[type=checkbox]'
assert_select 'form input#user_tag_ids_3[type=checkbox]'
end
test 'builder marks all selected records for collection boxes' do
@user.tag_ids = [1, 2]
with_association_for @user, :tags, :as => :check_boxes
assert_select 'form input[type=checkbox][value=1][checked=checked]'
assert_select 'form input[type=checkbox][value=2][checked=checked]'
assert_no_select 'form input[type=checkbox][value=3][checked=checked]'
end
end