client_side_validations 3.0.4 → 3.1.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/client_side_validations.gemspec +4 -7
- data/lib/client_side_validations/action_view/form_builder.rb +56 -6
- data/lib/client_side_validations/action_view/form_helper.rb +21 -3
- data/lib/client_side_validations/action_view.rb +4 -3
- data/lib/client_side_validations/active_model/length.rb +12 -10
- data/lib/client_side_validations/active_model/numericality.rb +14 -9
- data/lib/client_side_validations/active_model.rb +21 -13
- data/lib/client_side_validations/active_record/middleware.rb +5 -1
- data/lib/client_side_validations/active_record/uniqueness.rb +10 -8
- data/lib/client_side_validations/engine.rb +6 -0
- data/lib/client_side_validations/files.rb +8 -0
- data/lib/client_side_validations/formtastic.rb +3 -3
- data/lib/client_side_validations/middleware.rb +5 -7
- data/lib/client_side_validations/mongo_mapper/middleware.rb +20 -0
- data/lib/client_side_validations/mongo_mapper/uniqueness.rb +28 -0
- data/lib/client_side_validations/mongo_mapper.rb +9 -0
- data/lib/client_side_validations/mongoid/uniqueness.rb +10 -8
- data/lib/client_side_validations/version.rb +1 -1
- data/lib/client_side_validations.rb +8 -3
- data/lib/generators/client_side_validations/copy_asset_generator.rb +23 -0
- data/lib/generators/client_side_validations/install_generator.rb +18 -6
- data/lib/generators/templates/client_side_validations/README.rails.3.0 +6 -0
- data/lib/generators/templates/client_side_validations/README.rails.3.1 +7 -0
- data/lib/generators/templates/{client_side_validations.rb → client_side_validations/initializer.rb} +1 -1
- data/test/action_view/cases/helper.rb +34 -12
- data/test/action_view/cases/test_helpers.rb +264 -1
- data/test/action_view/cases/test_legacy_helpers.rb +12 -1
- data/test/active_model/cases/test_validations.rb +21 -8
- data/test/active_record/cases/test_middleware.rb +41 -16
- data/test/active_record/cases/test_uniqueness_validator.rb +5 -0
- data/test/active_record/models/user.rb +4 -0
- data/test/base_helper.rb +2 -0
- data/test/core_ext/cases/test_core_ext.rb +1 -0
- data/test/formtastic/cases/helper.rb +5 -0
- data/test/formtastic/cases/test_form_builder.rb +3 -3
- data/test/formtastic/cases/test_form_helper.rb +3 -4
- data/test/generators/cases/test_generators.rb +31 -0
- data/test/javascript/public/test/callbacks/elementAfter.js +1 -1
- data/test/javascript/public/test/callbacks/elementBefore.js +1 -1
- data/test/javascript/public/test/callbacks/elementFail.js +1 -1
- data/test/javascript/public/test/callbacks/elementPass.js +1 -1
- data/test/javascript/public/test/callbacks/formAfter.js +1 -1
- data/test/javascript/public/test/callbacks/formBefore.js +1 -1
- data/test/javascript/public/test/callbacks/formFail.js +1 -1
- data/test/javascript/public/test/callbacks/formPass.js +1 -1
- data/test/javascript/public/test/form_builders/validateForm.js +1 -1
- data/test/javascript/public/test/form_builders/validateFormtastic.js +2 -2
- data/test/javascript/public/test/form_builders/validateNestedForm.js +66 -0
- data/test/javascript/public/test/form_builders/validateSimpleForm.js +1 -1
- data/test/javascript/public/test/validateElement.js +36 -1
- data/test/javascript/public/test/validators/length.js +7 -1
- data/test/javascript/public/test/validators/numericality.js +7 -0
- data/test/javascript/public/test/validators/presence.js +6 -0
- data/test/javascript/public/test/validators/uniqueness.js +8 -1
- data/test/javascript/server.rb +9 -3
- data/test/javascript/views/index.erb +1 -1
- data/test/javascript/views/layout.erb +1 -1
- data/test/middleware/cases/helper.rb +3 -0
- data/test/mongo_mapper/cases/helper.rb +9 -0
- data/test/mongo_mapper/cases/test_base.rb +15 -0
- data/test/mongo_mapper/cases/test_middleware.rb +77 -0
- data/test/mongo_mapper/cases/test_uniqueness_validator.rb +50 -0
- data/test/mongo_mapper/models/magazine.rb +11 -0
- data/test/mongoid/cases/test_middleware.rb +15 -6
- data/test/mongoid/cases/test_uniqueness_validator.rb +5 -0
- data/test/mongoid/models/book.rb +4 -0
- data/test/simple_form/cases/helper.rb +3 -0
- data/test/simple_form/cases/test_form_helper.rb +3 -1
- data/test/test_loader.rb +6 -0
- data/{javascript → vendor/assets/javascripts}/rails.validations.js +31 -17
- metadata +44 -23
- data/lib/generators/templates/README +0 -7
- data/test/generators/cases/test_install_generator.rb +0 -15
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
require 'base_helper'
|
|
2
2
|
require 'action_view'
|
|
3
|
-
require '
|
|
4
|
-
require 'action_view/template/handlers/erb'
|
|
3
|
+
require 'action_view/template'
|
|
5
4
|
require 'action_view/models'
|
|
5
|
+
require 'client_side_validations/action_view'
|
|
6
|
+
|
|
7
|
+
module ActionController
|
|
8
|
+
class Base
|
|
9
|
+
include ActionDispatch::Routing::RouteSet.new.url_helpers
|
|
10
|
+
end
|
|
11
|
+
end
|
|
6
12
|
|
|
7
13
|
module ActionViewTestSetup
|
|
8
14
|
include ::ClientSideValidations::ActionView::Helpers::FormHelper
|
|
@@ -12,6 +18,19 @@ module ActionViewTestSetup
|
|
|
12
18
|
@output_buffer = super
|
|
13
19
|
end
|
|
14
20
|
|
|
21
|
+
Routes = ActionDispatch::Routing::RouteSet.new
|
|
22
|
+
Routes.draw do
|
|
23
|
+
resources :posts do
|
|
24
|
+
resources :comments
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def _routes
|
|
29
|
+
Routes
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
include Routes.url_helpers
|
|
33
|
+
|
|
15
34
|
def setup
|
|
16
35
|
super
|
|
17
36
|
|
|
@@ -67,14 +86,11 @@ module ActionViewTestSetup
|
|
|
67
86
|
@post.body = "Back to the hill and over it again!"
|
|
68
87
|
@post.secret = 1
|
|
69
88
|
@post.written_on = Date.new(2004, 6, 15)
|
|
70
|
-
end
|
|
71
89
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if object.is_a?(Hash)
|
|
75
|
-
"http://www.example.com"
|
|
90
|
+
if defined?(ActionView::OutputFlow)
|
|
91
|
+
@view_flow = ActionView::OutputFlow.new
|
|
76
92
|
else
|
|
77
|
-
|
|
93
|
+
@_content_for = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new }
|
|
78
94
|
end
|
|
79
95
|
end
|
|
80
96
|
|
|
@@ -85,11 +101,12 @@ module ActionViewTestSetup
|
|
|
85
101
|
txt << %{</div>}
|
|
86
102
|
end
|
|
87
103
|
|
|
88
|
-
def form_text(action = "http://www.example.com", id = nil, html_class = nil, remote = nil, validators = nil)
|
|
104
|
+
def form_text(action = "http://www.example.com", id = nil, html_class = nil, remote = nil, validators = nil, file = nil)
|
|
89
105
|
txt = %{<form accept-charset="UTF-8" action="#{action}"}
|
|
90
106
|
txt << %{ data-remote="true"} if remote
|
|
91
107
|
txt << %{ class="#{html_class}"} if html_class
|
|
92
108
|
txt << %{ data-validate="true"} if validators
|
|
109
|
+
txt << %{ enctype="multipart/form-data"} if file
|
|
93
110
|
txt << %{ id="#{id}"} if id
|
|
94
111
|
txt << %{ method="post"}
|
|
95
112
|
txt << %{ novalidate="novalidate"} if validators
|
|
@@ -100,20 +117,24 @@ module ActionViewTestSetup
|
|
|
100
117
|
contents = block_given? ? yield : ""
|
|
101
118
|
|
|
102
119
|
if options.is_a?(Hash)
|
|
103
|
-
method, remote, validators = options.values_at(:method, :remote, :validators)
|
|
120
|
+
method, remote, validators, file = options.values_at(:method, :remote, :validators, :file)
|
|
104
121
|
else
|
|
105
122
|
method = options
|
|
106
123
|
end
|
|
107
124
|
|
|
108
|
-
html = form_text(action, id, html_class, remote, validators) + snowman(method) + (contents || "") + "</form>"
|
|
125
|
+
html = form_text(action, id, html_class, remote, validators, file) + snowman(method) + (contents || "") + "</form>"
|
|
109
126
|
|
|
110
127
|
if options.is_a?(Hash) && options[:validators]
|
|
111
|
-
html
|
|
128
|
+
build_script_tag(html, id, options[:validators])
|
|
112
129
|
else
|
|
113
130
|
html
|
|
114
131
|
end
|
|
115
132
|
end
|
|
116
133
|
|
|
134
|
+
def build_script_tag(html, id, validators)
|
|
135
|
+
(html || "") + %Q{<script>window['#{id}'] = #{client_side_form_settings_helper.merge(:validators => validators).to_json};</script>}
|
|
136
|
+
end
|
|
137
|
+
|
|
117
138
|
protected
|
|
118
139
|
def comments_path(post)
|
|
119
140
|
"/posts/#{post.id}/comments"
|
|
@@ -152,3 +173,4 @@ module ActionViewTestSetup
|
|
|
152
173
|
end
|
|
153
174
|
|
|
154
175
|
end
|
|
176
|
+
|
|
@@ -44,7 +44,7 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
|
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
|
|
47
|
-
expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
|
|
47
|
+
expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators, :file => true) do
|
|
48
48
|
%{<input data-validate="true" id="post_cost" name="post[cost]" type="file" />}
|
|
49
49
|
end
|
|
50
50
|
assert_equal expected, output_buffer
|
|
@@ -296,6 +296,18 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
|
|
|
296
296
|
assert_equal expected, output_buffer
|
|
297
297
|
end
|
|
298
298
|
|
|
299
|
+
def test_select_multiple
|
|
300
|
+
form_for(@post, :validate => true) do |f|
|
|
301
|
+
concat f.select(:cost, [], {}, :multiple => true)
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
validators = {'post[cost][]' => {:presence => {:message => "can't be blank"}}}
|
|
305
|
+
expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
|
|
306
|
+
%{<select data-validate="true" id="post_cost" multiple="multiple" name="post[cost][]"></select>}
|
|
307
|
+
end
|
|
308
|
+
assert_equal expected, output_buffer
|
|
309
|
+
end
|
|
310
|
+
|
|
299
311
|
def test_collection_select
|
|
300
312
|
form_for(@post, :validate => true) do |f|
|
|
301
313
|
concat f.collection_select(:cost, [], :id, :name)
|
|
@@ -333,5 +345,256 @@ class ClientSideValidations::ActionViewHelpersTest < ActionView::TestCase
|
|
|
333
345
|
end
|
|
334
346
|
assert_equal expected, output_buffer
|
|
335
347
|
end
|
|
348
|
+
|
|
349
|
+
def test_conditional_validator_filters
|
|
350
|
+
hash = {
|
|
351
|
+
:cost => {
|
|
352
|
+
:presence => {
|
|
353
|
+
:message => "can't be blank",
|
|
354
|
+
:unless => :cannot_validate?
|
|
355
|
+
}
|
|
356
|
+
},
|
|
357
|
+
:title => {
|
|
358
|
+
:presence => {
|
|
359
|
+
:message => "can't be blank",
|
|
360
|
+
:if => :can_validate?
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
@post.title = nil
|
|
366
|
+
@post.stubs(:cannot_validate?).returns(false)
|
|
367
|
+
@post.stubs(:can_validate?).returns(true)
|
|
368
|
+
@post.stubs(:client_side_validation_hash).returns(hash)
|
|
369
|
+
form_for(@post, :validate => true) do |f|
|
|
370
|
+
concat f.text_field(:cost)
|
|
371
|
+
concat f.text_field(:title)
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
validators = {}
|
|
375
|
+
expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
|
|
376
|
+
%{<input id="post_cost" name="post[cost]" size="30" type="text" />} +
|
|
377
|
+
%{<input id="post_title" name="post[title]" size="30" type="text" />}
|
|
378
|
+
end
|
|
379
|
+
assert_equal expected, output_buffer
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
def test_conditional_validators_should_be_filtered
|
|
383
|
+
hash = {
|
|
384
|
+
:cost => {
|
|
385
|
+
:presence => {
|
|
386
|
+
:message => "can't be blank",
|
|
387
|
+
:unless => :cannot_validate?
|
|
388
|
+
}
|
|
389
|
+
},
|
|
390
|
+
:title => {
|
|
391
|
+
:presence => {
|
|
392
|
+
:message => "can't be blank",
|
|
393
|
+
:if => :can_validate?
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
@post.title = nil
|
|
399
|
+
@post.stubs(:cannot_validate?).returns(false)
|
|
400
|
+
@post.stubs(:can_validate?).returns(true)
|
|
401
|
+
@post.stubs(:client_side_validation_hash).returns(hash)
|
|
402
|
+
form_for(@post, :validate => true) do |f|
|
|
403
|
+
concat f.text_field(:cost)
|
|
404
|
+
concat f.text_field(:title)
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
validators = {}
|
|
408
|
+
expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
|
|
409
|
+
%{<input id="post_cost" name="post[cost]" size="30" type="text" />} +
|
|
410
|
+
%{<input id="post_title" name="post[title]" size="30" type="text" />}
|
|
411
|
+
end
|
|
412
|
+
assert_equal expected, output_buffer
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
def test_conditional_validator_filters_being_forced
|
|
416
|
+
hash = {
|
|
417
|
+
:cost => {
|
|
418
|
+
:presence => {
|
|
419
|
+
:message => "can't be blank",
|
|
420
|
+
:unless => :cannot_validate?
|
|
421
|
+
}
|
|
422
|
+
},
|
|
423
|
+
:title => {
|
|
424
|
+
:presence => {
|
|
425
|
+
:message => "can't be blank",
|
|
426
|
+
:if => :can_validate?
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
@post.title = nil
|
|
432
|
+
@post.stubs(:cannot_validate?).returns(false)
|
|
433
|
+
@post.stubs(:can_validate?).returns(true)
|
|
434
|
+
@post.stubs(:client_side_validation_hash).returns(hash)
|
|
435
|
+
form_for(@post, :validate => true) do |f|
|
|
436
|
+
concat f.text_field(:cost, :validate => true)
|
|
437
|
+
concat f.text_field(:title, :validate => true)
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
validators = {
|
|
441
|
+
'post[cost]' => {:presence => {:message => "can't be blank"}},
|
|
442
|
+
'post[title]' => {:presence => {:message => "can't be blank"}}
|
|
443
|
+
}
|
|
444
|
+
expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
|
|
445
|
+
%{<input data-validate="true" id="post_cost" name="post[cost]" size="30" type="text" />} +
|
|
446
|
+
%{<input data-validate="true" id="post_title" name="post[title]" size="30" type="text" />}
|
|
447
|
+
end
|
|
448
|
+
assert_equal expected, output_buffer
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
def test_conditional_validator_filters_being_forced_and_not_meeting_condition
|
|
452
|
+
hash = {
|
|
453
|
+
:cost => {
|
|
454
|
+
:presence => {
|
|
455
|
+
:message => "can't be blank",
|
|
456
|
+
:unless => :cannot_validate?
|
|
457
|
+
}
|
|
458
|
+
},
|
|
459
|
+
:title => {
|
|
460
|
+
:presence => {
|
|
461
|
+
:message => "can't be blank",
|
|
462
|
+
:if => :can_validate?
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
@post.title = nil
|
|
468
|
+
@post.stubs(:cannot_validate?).returns(true)
|
|
469
|
+
@post.stubs(:can_validate?).returns(false)
|
|
470
|
+
@post.stubs(:client_side_validation_hash).returns(hash)
|
|
471
|
+
form_for(@post, :validate => true) do |f|
|
|
472
|
+
concat f.text_field(:cost, :validate => true)
|
|
473
|
+
concat f.text_field(:title, :validate => true)
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
validators = {}
|
|
477
|
+
expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
|
|
478
|
+
%{<input id="post_cost" name="post[cost]" size="30" type="text" />} +
|
|
479
|
+
%{<input id="post_title" name="post[title]" size="30" type="text" />}
|
|
480
|
+
end
|
|
481
|
+
assert_equal expected, output_buffer
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
def test_conditional_validator_filters_being_forced_individually
|
|
485
|
+
hash = {
|
|
486
|
+
:cost => {
|
|
487
|
+
:presence => {
|
|
488
|
+
:message => "can't be blank",
|
|
489
|
+
:unless => :cannot_validate?
|
|
490
|
+
}
|
|
491
|
+
},
|
|
492
|
+
:title => {
|
|
493
|
+
:presence => {
|
|
494
|
+
:message => "can't be blank",
|
|
495
|
+
:if => :can_validate?
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
@post.title = nil
|
|
501
|
+
@post.stubs(:cannot_validate?).returns(false)
|
|
502
|
+
@post.stubs(:can_validate?).returns(true)
|
|
503
|
+
@post.stubs(:client_side_validation_hash).returns(hash)
|
|
504
|
+
form_for(@post, :validate => true) do |f|
|
|
505
|
+
concat f.text_field(:cost, :validate => { :presence => true })
|
|
506
|
+
concat f.text_field(:title, :validate => { :presence => true })
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
validators = {
|
|
510
|
+
'post[cost]' => {:presence => {:message => "can't be blank"}},
|
|
511
|
+
'post[title]' => {:presence => {:message => "can't be blank"}}
|
|
512
|
+
}
|
|
513
|
+
expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
|
|
514
|
+
%{<input data-validate="true" id="post_cost" name="post[cost]" size="30" type="text" />} +
|
|
515
|
+
%{<input data-validate="true" id="post_title" name="post[title]" size="30" type="text" />}
|
|
516
|
+
end
|
|
517
|
+
assert_equal expected, output_buffer
|
|
518
|
+
end
|
|
519
|
+
|
|
520
|
+
def test_conditional_validator_filters_being_forced_and_not_meeting_condition_individually
|
|
521
|
+
hash = {
|
|
522
|
+
:cost => {
|
|
523
|
+
:presence => {
|
|
524
|
+
:message => "can't be blank",
|
|
525
|
+
:unless => :cannot_validate?
|
|
526
|
+
}
|
|
527
|
+
},
|
|
528
|
+
:title => {
|
|
529
|
+
:presence => {
|
|
530
|
+
:message => "can't be blank",
|
|
531
|
+
:if => :can_validate?
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
@post.title = nil
|
|
537
|
+
@post.stubs(:cannot_validate?).returns(true)
|
|
538
|
+
@post.stubs(:can_validate?).returns(false)
|
|
539
|
+
@post.stubs(:client_side_validation_hash).returns(hash)
|
|
540
|
+
form_for(@post, :validate => true) do |f|
|
|
541
|
+
concat f.text_field(:cost, :validate => { :presence => true })
|
|
542
|
+
concat f.text_field(:title, :validate => { :presence => true })
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
validators = {}
|
|
546
|
+
expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
|
|
547
|
+
%{<input id="post_cost" name="post[cost]" size="30" type="text" />} +
|
|
548
|
+
%{<input id="post_title" name="post[title]" size="30" type="text" />}
|
|
549
|
+
end
|
|
550
|
+
assert_equal expected, output_buffer
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
def test_conditional_validator_filters_being_forced_with_procs
|
|
554
|
+
hash = {
|
|
555
|
+
:cost => {
|
|
556
|
+
:presence => {
|
|
557
|
+
:message => "can't be blank",
|
|
558
|
+
:unless => Proc.new { |post| post.cannot_validate? }
|
|
559
|
+
}
|
|
560
|
+
},
|
|
561
|
+
:title => {
|
|
562
|
+
:presence => {
|
|
563
|
+
:message => "can't be blank",
|
|
564
|
+
:if => Proc.new { |post| post.can_validate? }
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
@post.title = nil
|
|
570
|
+
@post.stubs(:cannot_validate?).returns(false)
|
|
571
|
+
@post.stubs(:can_validate?).returns(true)
|
|
572
|
+
@post.stubs(:client_side_validation_hash).returns(hash)
|
|
573
|
+
form_for(@post, :validate => true) do |f|
|
|
574
|
+
concat f.text_field(:cost, :validate => true)
|
|
575
|
+
concat f.text_field(:title, :validate => true)
|
|
576
|
+
end
|
|
577
|
+
|
|
578
|
+
validators = {
|
|
579
|
+
'post[cost]' => {:presence => {:message => "can't be blank"}},
|
|
580
|
+
'post[title]' => {:presence => {:message => "can't be blank"}}
|
|
581
|
+
}
|
|
582
|
+
expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => "put", :validators => validators) do
|
|
583
|
+
%{<input data-validate="true" id="post_cost" name="post[cost]" size="30" type="text" />} +
|
|
584
|
+
%{<input data-validate="true" id="post_title" name="post[title]" size="30" type="text" />}
|
|
585
|
+
end
|
|
586
|
+
assert_equal expected, output_buffer
|
|
587
|
+
end
|
|
588
|
+
|
|
589
|
+
def test_pushing_script_to_content_for
|
|
590
|
+
form_for(@post, :validate => :post) do |f|
|
|
591
|
+
concat f.text_field(:cost)
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
validators = {'post[cost]' => {:presence => {:message => "can't be blank"}}}
|
|
595
|
+
expected = %{<form accept-charset="UTF-8" action="/posts/123" class="edit_post" data-validate="true" id="edit_post_123" method="post" novalidate="novalidate"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="_method" type="hidden" value="put" /></div><input data-validate="true" id="post_cost" name="post[cost]" size="30" type="text" /></form>}
|
|
596
|
+
assert_equal expected, output_buffer
|
|
597
|
+
assert_equal build_script_tag(nil, "edit_post_123", validators), content_for(:post)
|
|
598
|
+
end
|
|
336
599
|
end
|
|
337
600
|
|
|
@@ -30,7 +30,7 @@ class ClientSideValidations::LegacyActionViewHelpersTest < ActionView::TestCase
|
|
|
30
30
|
concat f.file_field(:cost)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
expected = whole_form("/posts/123", "edit_post_123", "edit_post",
|
|
33
|
+
expected = whole_form("/posts/123", "edit_post_123", "edit_post", :method => :put, :file => true) do
|
|
34
34
|
%{<input id="post_cost" name="post[cost]" type="file" />}
|
|
35
35
|
end
|
|
36
36
|
assert_equal expected, output_buffer
|
|
@@ -168,6 +168,17 @@ class ClientSideValidations::LegacyActionViewHelpersTest < ActionView::TestCase
|
|
|
168
168
|
assert_equal expected, output_buffer
|
|
169
169
|
end
|
|
170
170
|
|
|
171
|
+
def test_select_multiple
|
|
172
|
+
form_for(@post) do |f|
|
|
173
|
+
concat f.select(:cost, [], {}, :multiple => true)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
expected = whole_form("/posts/123", "edit_post_123", "edit_post", "put") do
|
|
177
|
+
%{<select id="post_cost" multiple="multiple" name="post[cost][]"></select>}
|
|
178
|
+
end
|
|
179
|
+
assert_equal expected, output_buffer
|
|
180
|
+
end
|
|
181
|
+
|
|
171
182
|
def test_collection_select
|
|
172
183
|
form_for(@post) do |f|
|
|
173
184
|
concat f.collection_select(:cost, [], :id, :name)
|
|
@@ -138,24 +138,37 @@ class ActiveModel::ValidationsTest < ClientSideValidations::ActiveModelTestBase
|
|
|
138
138
|
assert_equal expected_hash, person.client_side_validation_hash
|
|
139
139
|
end
|
|
140
140
|
|
|
141
|
-
def
|
|
141
|
+
def test_generic_block_validators_should_be_ignored
|
|
142
142
|
person = new_person do |p|
|
|
143
|
-
p.
|
|
144
|
-
|
|
143
|
+
p.validates_each(:first_name) do |record, attr, value|
|
|
144
|
+
record.errors.add(:first_name, "failed")
|
|
145
|
+
end
|
|
145
146
|
end
|
|
146
147
|
|
|
147
148
|
expected_hash = {}
|
|
148
149
|
assert_equal expected_hash, person.client_side_validation_hash
|
|
149
150
|
end
|
|
150
151
|
|
|
151
|
-
def
|
|
152
|
+
def test_conditionals_persist_on_validator
|
|
152
153
|
person = new_person do |p|
|
|
153
|
-
p.
|
|
154
|
-
|
|
155
|
-
end
|
|
154
|
+
p.validates :first_name, :presence => { :if => :can_validate? }
|
|
155
|
+
p.validates :last_name, :presence => { :unless => :cannot_validate? }
|
|
156
156
|
end
|
|
157
157
|
|
|
158
|
-
expected_hash = {
|
|
158
|
+
expected_hash = {
|
|
159
|
+
:first_name => {
|
|
160
|
+
:presence => {
|
|
161
|
+
:message => "can't be blank",
|
|
162
|
+
:if => :can_validate?
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
:last_name => {
|
|
166
|
+
:presence => {
|
|
167
|
+
:message => "can't be blank",
|
|
168
|
+
:unless => :cannot_validate?
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
159
172
|
assert_equal expected_hash, person.client_side_validation_hash
|
|
160
173
|
end
|
|
161
174
|
end
|
|
@@ -30,7 +30,7 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
|
|
|
30
30
|
|
|
31
31
|
def test_uniqueness_when_resource_exists
|
|
32
32
|
User.create(:email => 'user@test.com')
|
|
33
|
-
get '/validators/uniqueness
|
|
33
|
+
get '/validators/uniqueness', { 'user[email]' => 'user@test.com', 'case_sensitive' => true }
|
|
34
34
|
|
|
35
35
|
assert_equal 'false', last_response.body
|
|
36
36
|
assert last_response.ok?
|
|
@@ -38,14 +38,14 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
|
|
|
38
38
|
|
|
39
39
|
def test_uniqueness_when_resource_exists_and_param_order_is_backwards
|
|
40
40
|
User.create(:email => 'user@test.com')
|
|
41
|
-
get '/validators/uniqueness
|
|
41
|
+
get '/validators/uniqueness', { 'case_sensitive' => true, 'user[email]' => 'user@test.com' }
|
|
42
42
|
|
|
43
43
|
assert_equal 'false', last_response.body
|
|
44
44
|
assert last_response.ok?
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def test_uniqueness_when_resource_does_not_exist
|
|
48
|
-
get '/validators/uniqueness
|
|
48
|
+
get '/validators/uniqueness', { 'user[email]' => 'user@test.com', 'case_sensitive' => true }
|
|
49
49
|
|
|
50
50
|
assert_equal 'true', last_response.body
|
|
51
51
|
assert last_response.not_found?
|
|
@@ -53,15 +53,33 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
|
|
|
53
53
|
|
|
54
54
|
def test_uniqueness_when_id_is_given
|
|
55
55
|
user = User.create(:email => 'user@test.com')
|
|
56
|
-
get '/validators/uniqueness
|
|
56
|
+
get '/validators/uniqueness', { 'user[email]' => 'user@test.com', 'id' => user.id, 'case_sensitive' => true }
|
|
57
57
|
|
|
58
58
|
assert_equal 'true', last_response.body
|
|
59
59
|
assert last_response.not_found?
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
+
def test_mysql_adapter_uniqueness_when_id_is_given
|
|
63
|
+
user = User.create(:email => 'user@test.com')
|
|
64
|
+
ActiveRecord::ConnectionAdapters::SQLite3Adapter.
|
|
65
|
+
any_instance.expects(:instance_variable_get).
|
|
66
|
+
with("@config").
|
|
67
|
+
returns({:adapter => "mysql"})
|
|
68
|
+
|
|
69
|
+
sql_without_binary = "#{User.arel_table["email"].eq(user.email).to_sql} AND #{User.arel_table.primary_key.not_eq(user.id).to_sql}"
|
|
70
|
+
relation = Arel::Nodes::SqlLiteral.new("BINARY #{sql_without_binary}")
|
|
71
|
+
|
|
72
|
+
#NOTE: Stubs User#where because SQLite3 don't know BINARY
|
|
73
|
+
result = User.where(sql_without_binary)
|
|
74
|
+
User.expects(:where).with(relation).returns(result)
|
|
75
|
+
|
|
76
|
+
get '/validators/uniqueness', { 'user[email]' => user.email, 'case_sensitive' => true, 'id' => user.id}
|
|
77
|
+
assert_equal 'true', last_response.body
|
|
78
|
+
end
|
|
79
|
+
|
|
62
80
|
def test_uniqueness_when_scope_is_given
|
|
63
81
|
User.create(:email => 'user@test.com', :age => 25)
|
|
64
|
-
get '/validators/uniqueness
|
|
82
|
+
get '/validators/uniqueness', { 'user[email]' => 'user@test.com', 'scope' => { 'age' => 30 }, 'case_sensitive' => true }
|
|
65
83
|
|
|
66
84
|
assert_equal 'true', last_response.body
|
|
67
85
|
assert last_response.not_found?
|
|
@@ -69,7 +87,7 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
|
|
|
69
87
|
|
|
70
88
|
def test_uniqueness_when_multiple_scopes_are_given
|
|
71
89
|
User.create(:email => 'user@test.com', :age => 30, :name => 'Brian')
|
|
72
|
-
get '/validators/uniqueness
|
|
90
|
+
get '/validators/uniqueness', { 'user[email]' => 'user@test.com', 'scope' => { 'age' => 30, 'name' => 'Robert' }, 'case_sensitive' => true }
|
|
73
91
|
|
|
74
92
|
assert_equal 'true', last_response.body
|
|
75
93
|
assert last_response.not_found?
|
|
@@ -77,7 +95,7 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
|
|
|
77
95
|
|
|
78
96
|
def test_uniqueness_when_case_insensitive
|
|
79
97
|
User.create(:name => 'Brian')
|
|
80
|
-
get '/validators/uniqueness
|
|
98
|
+
get '/validators/uniqueness', { 'user[name]' => 'BRIAN', 'case_sensitive' => false }
|
|
81
99
|
|
|
82
100
|
assert_equal 'false', last_response.body
|
|
83
101
|
assert last_response.ok?
|
|
@@ -85,7 +103,7 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
|
|
|
85
103
|
|
|
86
104
|
def test_uniqueness_when_attribute_passes_as_an_integer
|
|
87
105
|
User.create(:name => 123)
|
|
88
|
-
get '/validators/uniqueness
|
|
106
|
+
get '/validators/uniqueness', { 'user[name]' => 123, 'case_sensitive' => true }
|
|
89
107
|
|
|
90
108
|
assert_equal 'false', last_response.body
|
|
91
109
|
assert last_response.ok?
|
|
@@ -93,7 +111,7 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
|
|
|
93
111
|
|
|
94
112
|
def test_uniqueness_when_attribute_passes_as_an_integer
|
|
95
113
|
User.create(:name => 123)
|
|
96
|
-
get '/validators/uniqueness
|
|
114
|
+
get '/validators/uniqueness', { 'user[name]' => 123, 'case_sensitive' => true }
|
|
97
115
|
|
|
98
116
|
assert_equal 'false', last_response.body
|
|
99
117
|
assert last_response.ok?
|
|
@@ -102,14 +120,14 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
|
|
|
102
120
|
def test_uniqueness_with_columns_which_are_sql_keywords
|
|
103
121
|
Guid.validates_uniqueness_of :key
|
|
104
122
|
assert_nothing_raised do
|
|
105
|
-
get '/validators/uniqueness
|
|
123
|
+
get '/validators/uniqueness', { 'guid[key]' => 'test', 'case_sensitive' => true }
|
|
106
124
|
end
|
|
107
125
|
end
|
|
108
126
|
|
|
109
127
|
def test_uniqueness_with_limit
|
|
110
128
|
# User.title is limited to 5 characters
|
|
111
129
|
User.create(:title => "abcde")
|
|
112
|
-
get '/validators/uniqueness
|
|
130
|
+
get '/validators/uniqueness', { 'user[title]' => 'abcdefgh', 'case_sensitive' => true }
|
|
113
131
|
|
|
114
132
|
assert_equal 'false', last_response.body
|
|
115
133
|
assert last_response.ok?
|
|
@@ -119,7 +137,7 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
|
|
|
119
137
|
with_kcode('UTF8') do
|
|
120
138
|
# User.title is limited to 5 characters
|
|
121
139
|
User.create(:title => "一二三四五")
|
|
122
|
-
get '/validators/uniqueness
|
|
140
|
+
get '/validators/uniqueness', { 'user[title]' => '一二三四五六七八', 'case_sensitive' => true }
|
|
123
141
|
|
|
124
142
|
assert_equal 'false', last_response.body
|
|
125
143
|
assert last_response.ok?
|
|
@@ -127,24 +145,31 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
|
|
|
127
145
|
end
|
|
128
146
|
|
|
129
147
|
def test_validate_straight_inheritance_uniqueness
|
|
130
|
-
get '/validators/uniqueness
|
|
148
|
+
get '/validators/uniqueness', { 'inept_wizard[name]' => 'Rincewind', 'case_sensitive' => true }
|
|
131
149
|
assert_equal 'true', last_response.body
|
|
132
150
|
assert last_response.not_found?
|
|
133
151
|
|
|
134
152
|
IneptWizard.create(:name => 'Rincewind')
|
|
135
|
-
get '/validators/uniqueness
|
|
153
|
+
get '/validators/uniqueness', { 'inept_wizard[name]' => 'Rincewind', 'case_sensitive' => true }
|
|
136
154
|
assert_equal 'false', last_response.body
|
|
137
155
|
assert last_response.ok?
|
|
138
156
|
|
|
139
|
-
get '/validators/uniqueness
|
|
157
|
+
get '/validators/uniqueness', { 'conjurer[name]' => 'Rincewind', 'case_sensitive' => true }
|
|
140
158
|
assert_equal 'false', last_response.body
|
|
141
159
|
assert last_response.ok?
|
|
142
160
|
|
|
143
161
|
Conjurer.create(:name => 'The Amazing Bonko')
|
|
144
|
-
get '/validators/uniqueness
|
|
162
|
+
get '/validators/uniqueness', { 'thaumaturgist[name]' => 'The Amazing Bonko', 'case_sensitive' => true }
|
|
145
163
|
assert_equal 'false', last_response.body
|
|
146
164
|
assert last_response.ok?
|
|
147
165
|
end
|
|
148
166
|
|
|
167
|
+
def test_uniqueness_when_resource_is_a_nested_module
|
|
168
|
+
ActiveRecordTestModule::User2.create(:email => 'user@test.com')
|
|
169
|
+
get '/validators/uniqueness', { 'active_record_test_module/user2[email]' => 'user@test.com', 'case_sensitive' => true }
|
|
170
|
+
|
|
171
|
+
assert_equal 'false', last_response.body
|
|
172
|
+
assert last_response.ok?
|
|
173
|
+
end
|
|
149
174
|
end
|
|
150
175
|
|
|
@@ -41,5 +41,10 @@ class ActiveRecord::UniquenessValidatorTest < ClientSideValidations::ActiveRecor
|
|
|
41
41
|
assert_equal expected_hash, result_hash
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
def test_uniqueness_client_side_hash_when_nested_module
|
|
45
|
+
@user = ActiveRecordTestModule::User2.new
|
|
46
|
+
expected_hash = { :message => "has already been taken", :case_sensitive => true, :class => 'active_record_test_module/user2' }
|
|
47
|
+
assert_equal expected_hash, UniquenessValidator.new(:attributes => [:name]).client_side_hash(@user, :name)
|
|
48
|
+
end
|
|
44
49
|
end
|
|
45
50
|
|
data/test/base_helper.rb
CHANGED