client_side_validations 3.0.4 → 3.0.5
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 +2 -3
- data/javascript/rails.validations.js +26 -12
- data/lib/client_side_validations.rb +2 -0
- data/lib/client_side_validations/action_view/form_builder.rb +55 -5
- data/lib/client_side_validations/action_view/form_helper.rb +20 -2
- data/lib/client_side_validations/active_model.rb +22 -13
- 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_record/middleware.rb +5 -1
- data/lib/client_side_validations/active_record/uniqueness.rb +10 -8
- data/lib/client_side_validations/middleware.rb +2 -0
- data/lib/client_side_validations/mongo_mapper.rb +9 -0
- 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/mongoid/uniqueness.rb +10 -8
- data/lib/client_side_validations/version.rb +1 -1
- data/test/action_view/cases/helper.rb +7 -1
- data/test/action_view/cases/test_helpers.rb +263 -0
- data/test/action_view/cases/test_legacy_helpers.rb +11 -0
- data/test/active_model/cases/test_validations.rb +21 -8
- data/test/active_record/cases/test_middleware.rb +25 -0
- data/test/active_record/cases/test_uniqueness_validator.rb +5 -0
- data/test/active_record/models/user.rb +4 -0
- data/test/formtastic/cases/test_form_helper.rb +1 -1
- 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 +1 -1
- 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 +7 -1
- data/test/javascript/views/index.erb +1 -1
- 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 +9 -0
- data/test/mongoid/cases/test_uniqueness_validator.rb +5 -0
- data/test/mongoid/models/book.rb +4 -0
- data/test/simple_form/cases/test_form_helper.rb +1 -1
- metadata +46 -20
@@ -0,0 +1,28 @@
|
|
1
|
+
module ClientSideValidations::MongoMapper
|
2
|
+
module Uniqueness
|
3
|
+
def client_side_hash(model, attribute)
|
4
|
+
hash = {}
|
5
|
+
hash[:message] = model.errors.generate_message(attribute, message_type, options.except(:scope))
|
6
|
+
hash[:case_sensitive] = options[:case_sensitive] if options.key?(:case_sensitive)
|
7
|
+
hash[:id] = model.id unless model.new_record?
|
8
|
+
if options.key?(:scope) && options[:scope].present?
|
9
|
+
hash[:scope] = Array.wrap(options[:scope]).inject({}) do |scope_hash, scope_item|
|
10
|
+
scope_hash.merge!(scope_item => model.send(scope_item))
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
unless model.class.name.demodulize == model.class.name
|
15
|
+
hash[:class] = model.class.name.underscore
|
16
|
+
end
|
17
|
+
|
18
|
+
hash
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def message_type
|
24
|
+
:taken
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -1,16 +1,18 @@
|
|
1
1
|
module ClientSideValidations::Mongoid
|
2
2
|
module Uniqueness
|
3
3
|
def client_side_hash(model, attribute)
|
4
|
-
|
5
|
-
hash
|
6
|
-
hash =
|
7
|
-
|
8
|
-
if
|
9
|
-
hash[:scope] = Array.wrap(
|
4
|
+
hash = {}
|
5
|
+
hash[:message] = model.errors.generate_message(attribute, message_type, options.except(:scope))
|
6
|
+
hash[:case_sensitive] = options[:case_sensitive] if options.key?(:case_sensitive)
|
7
|
+
hash[:id] = model.id unless model.new_record?
|
8
|
+
if options.key?(:scope) && options[:scope].present?
|
9
|
+
hash[:scope] = Array.wrap(options[:scope]).inject({}) do |scope_hash, scope_item|
|
10
10
|
scope_hash.merge!(scope_item => model.send(scope_item))
|
11
11
|
end
|
12
|
-
|
13
|
-
|
12
|
+
end
|
13
|
+
|
14
|
+
unless model.class.name.demodulize == model.class.name
|
15
|
+
hash[:class] = model.class.name.underscore
|
14
16
|
end
|
15
17
|
|
16
18
|
hash
|
@@ -67,6 +67,8 @@ module ActionViewTestSetup
|
|
67
67
|
@post.body = "Back to the hill and over it again!"
|
68
68
|
@post.secret = 1
|
69
69
|
@post.written_on = Date.new(2004, 6, 15)
|
70
|
+
|
71
|
+
@_content_for = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new }
|
70
72
|
end
|
71
73
|
|
72
74
|
def url_for(object)
|
@@ -108,12 +110,16 @@ module ActionViewTestSetup
|
|
108
110
|
html = form_text(action, id, html_class, remote, validators) + snowman(method) + (contents || "") + "</form>"
|
109
111
|
|
110
112
|
if options.is_a?(Hash) && options[:validators]
|
111
|
-
html
|
113
|
+
build_script_tag(html, id, options[:validators])
|
112
114
|
else
|
113
115
|
html
|
114
116
|
end
|
115
117
|
end
|
116
118
|
|
119
|
+
def build_script_tag(html, id, validators)
|
120
|
+
(html || "") + %Q{<script>window['#{id}'] = #{client_side_form_settings_helper.merge(:validators => validators).to_json};</script>}
|
121
|
+
end
|
122
|
+
|
117
123
|
protected
|
118
124
|
def comments_path(post)
|
119
125
|
"/posts/#{post.id}/comments"
|
@@ -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
|
|
@@ -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
|
@@ -59,6 +59,24 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
|
|
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.json', { '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
82
|
get '/validators/uniqueness.json', { 'user[email]' => 'user@test.com', 'scope' => { 'age' => 30 }, 'case_sensitive' => true }
|
@@ -146,5 +164,12 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
|
|
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.json', { '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
|
|