client_side_validations 3.0.4 → 3.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/client_side_validations.gemspec +2 -3
  2. data/javascript/rails.validations.js +26 -12
  3. data/lib/client_side_validations.rb +2 -0
  4. data/lib/client_side_validations/action_view/form_builder.rb +55 -5
  5. data/lib/client_side_validations/action_view/form_helper.rb +20 -2
  6. data/lib/client_side_validations/active_model.rb +22 -13
  7. data/lib/client_side_validations/active_model/length.rb +12 -10
  8. data/lib/client_side_validations/active_model/numericality.rb +14 -9
  9. data/lib/client_side_validations/active_record/middleware.rb +5 -1
  10. data/lib/client_side_validations/active_record/uniqueness.rb +10 -8
  11. data/lib/client_side_validations/middleware.rb +2 -0
  12. data/lib/client_side_validations/mongo_mapper.rb +9 -0
  13. data/lib/client_side_validations/mongo_mapper/middleware.rb +20 -0
  14. data/lib/client_side_validations/mongo_mapper/uniqueness.rb +28 -0
  15. data/lib/client_side_validations/mongoid/uniqueness.rb +10 -8
  16. data/lib/client_side_validations/version.rb +1 -1
  17. data/test/action_view/cases/helper.rb +7 -1
  18. data/test/action_view/cases/test_helpers.rb +263 -0
  19. data/test/action_view/cases/test_legacy_helpers.rb +11 -0
  20. data/test/active_model/cases/test_validations.rb +21 -8
  21. data/test/active_record/cases/test_middleware.rb +25 -0
  22. data/test/active_record/cases/test_uniqueness_validator.rb +5 -0
  23. data/test/active_record/models/user.rb +4 -0
  24. data/test/formtastic/cases/test_form_helper.rb +1 -1
  25. data/test/javascript/public/test/callbacks/elementAfter.js +1 -1
  26. data/test/javascript/public/test/callbacks/elementBefore.js +1 -1
  27. data/test/javascript/public/test/callbacks/elementFail.js +1 -1
  28. data/test/javascript/public/test/callbacks/elementPass.js +1 -1
  29. data/test/javascript/public/test/callbacks/formAfter.js +1 -1
  30. data/test/javascript/public/test/callbacks/formBefore.js +1 -1
  31. data/test/javascript/public/test/callbacks/formFail.js +1 -1
  32. data/test/javascript/public/test/callbacks/formPass.js +1 -1
  33. data/test/javascript/public/test/form_builders/validateForm.js +1 -1
  34. data/test/javascript/public/test/form_builders/validateFormtastic.js +1 -1
  35. data/test/javascript/public/test/form_builders/validateNestedForm.js +66 -0
  36. data/test/javascript/public/test/form_builders/validateSimpleForm.js +1 -1
  37. data/test/javascript/public/test/validateElement.js +36 -1
  38. data/test/javascript/public/test/validators/length.js +7 -1
  39. data/test/javascript/public/test/validators/numericality.js +7 -0
  40. data/test/javascript/public/test/validators/presence.js +6 -0
  41. data/test/javascript/public/test/validators/uniqueness.js +8 -1
  42. data/test/javascript/server.rb +7 -1
  43. data/test/javascript/views/index.erb +1 -1
  44. data/test/mongo_mapper/cases/helper.rb +9 -0
  45. data/test/mongo_mapper/cases/test_base.rb +15 -0
  46. data/test/mongo_mapper/cases/test_middleware.rb +77 -0
  47. data/test/mongo_mapper/cases/test_uniqueness_validator.rb +50 -0
  48. data/test/mongo_mapper/models/magazine.rb +11 -0
  49. data/test/mongoid/cases/test_middleware.rb +9 -0
  50. data/test/mongoid/cases/test_uniqueness_validator.rb +5 -0
  51. data/test/mongoid/models/book.rb +4 -0
  52. data/test/simple_form/cases/test_form_helper.rb +1 -1
  53. metadata +46 -20
@@ -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
 
@@ -8,3 +8,7 @@ end
8
8
  class IneptWizard < User; end
9
9
  class Conjurer < IneptWizard; end
10
10
  class Thaumaturgist < Conjurer; end
11
+
12
+ module ActiveRecordTestModule
13
+ class User2 < User; end
14
+ end
@@ -14,7 +14,7 @@ class ClientSideValidations::Formtastic::FormHelperTest < ActionView::TestCase
14
14
  concat f.input(:cost)
15
15
  end
16
16
 
17
- expected = %{<form accept-charset="UTF-8" action="/posts/123" class="formtastic 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="&#x2713;" /><input name="_method" type="hidden" value="put" /></div><li class="string required" id="post_cost_input"><label for="post_cost">Cost<abbr title="required">*</abbr></label><input data-validate="true" id="post_cost" name="post[cost]" type="text" /></li></form><script>var edit_post_123 = {"type":"Formtastic::SemanticFormBuilder","inline_error_class":"inline-errors","validators":{"post[cost]":{"presence":{"message":"can't be blank"}}}};</script>}
17
+ expected = %{<form accept-charset="UTF-8" action="/posts/123" class="formtastic 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="&#x2713;" /><input name="_method" type="hidden" value="put" /></div><li class="string required" id="post_cost_input"><label for="post_cost">Cost<abbr title="required">*</abbr></label><input data-validate="true" id="post_cost" name="post[cost]" type="text" /></li></form><script>window['edit_post_123'] = {"type":"Formtastic::SemanticFormBuilder","inline_error_class":"inline-errors","validators":{"post[cost]":{"presence":{"message":"can't be blank"}}}};</script>}
18
18
  assert_equal expected, output_buffer, "\n\n *** If you're running Ruby 1.8 and this test fails is is most likely due to 1.8's lack of insertion order persistence with Hashes ***\n"
19
19
  end
20
20
 
@@ -1,6 +1,6 @@
1
1
  module('Element Validate After Callback', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -1,6 +1,6 @@
1
1
  module('Element Validate Before Callback', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -1,6 +1,6 @@
1
1
  module('Element Validate Fail Callback', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -1,6 +1,6 @@
1
1
  module('Element Validate Pass Callback', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -1,6 +1,6 @@
1
1
  module('Form Validate After Callback', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -1,6 +1,6 @@
1
1
  module('Form Validate Before Callback', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -1,6 +1,6 @@
1
1
  module('Form Validate Fail Callback', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -1,6 +1,6 @@
1
1
  module('Form Validate Pass Callback', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -1,6 +1,6 @@
1
1
  module('Validate Form', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -1,6 +1,6 @@
1
1
  module('Validate Formtastic', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'Formtastic::SemanticFormBuilder',
5
5
  inline_error_class: 'inline-errors',
6
6
  validators: {
@@ -0,0 +1,66 @@
1
+ module('Validate Form', {
2
+ setup: function() {
3
+ window['new_user'] = {
4
+ type: 'NestedForm::Builder',
5
+ input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
+ label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
7
+ validators: {'user[name]':{"presence":{"message": "must be present"}}}
8
+ }
9
+
10
+ $('#qunit-fixture')
11
+ .append($('<form />', {
12
+ action: '/users',
13
+ 'data-validate': true,
14
+ method: 'post',
15
+ id: 'new_user'
16
+ }))
17
+ .find('form')
18
+ .append($('<input />', {
19
+ name: 'user[name]',
20
+ id: 'user_name',
21
+ 'data-validate': 'true',
22
+ type: 'text'
23
+ }))
24
+ .append($('<label for="user_name">Name</label>'));
25
+ $('form#new_user').validate();
26
+ }
27
+ });
28
+
29
+ asyncTest('Validate form with invalid form', 4, function() {
30
+ var form = $('form#new_user'), input = form.find('input#user_name');
31
+ var label = $('label[for="user_name"]');
32
+
33
+ form.trigger('submit');
34
+ setTimeout(function() {
35
+ start();
36
+ ok(input.parent().hasClass('field_with_errors'));
37
+ ok(label.parent().hasClass('field_with_errors'));
38
+ ok(input.parent().find('label:contains("must be present")')[0]);
39
+ ok(!$('iframe').contents().find('p:contains("Form submitted")')[0]);
40
+ }, 30);
41
+ });
42
+
43
+ asyncTest('Validate form with valid form', 1, function() {
44
+ var form = $('form#new_user'), input = form.find('input#user_name');
45
+ input.val('Test');
46
+
47
+ form.trigger('submit');
48
+ setTimeout(function() {
49
+ start();
50
+ ok($('iframe').contents().find('p:contains("Form submitted")')[0]);
51
+ }, 30);
52
+ });
53
+
54
+ asyncTest('Validate form with an input changed to false', 1, function() {
55
+ var form = $('form#new_user'), input = form.find('input#user_name');
56
+ input.val('Test');
57
+ input.attr('changed', false);
58
+ input.attr('data-valid', true);
59
+
60
+ form.trigger('submit');
61
+ setTimeout(function() {
62
+ start();
63
+ ok($('iframe').contents().find('p:contains("Form submitted")')[0]);
64
+ }, 30);
65
+ });
66
+
@@ -1,6 +1,6 @@
1
1
  module('Validate SimpleForm', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'SimpleForm::FormBuilder',
5
5
  error_class: 'error',
6
6
  error_tag: 'span',
@@ -1,6 +1,6 @@
1
1
  module('Validate Element', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -140,5 +140,40 @@ test('Validate when error message needs to change', function() {
140
140
  input.trigger('change')
141
141
  input.trigger('focusout');
142
142
  equal(input.parent().find('label.message').text(), "is invalid");
143
+ })
144
+
145
+ test("Don't validate confirmation when not a validatable input", function() {
146
+ $('#qunit-fixture')
147
+ .append($('<form />', {
148
+ action: '/users',
149
+ 'data-validate': true,
150
+ method: 'post',
151
+ id: 'new_user_2'
152
+ }))
153
+ .find('form')
154
+ .append($('<label for="user_2_password">Password</label>'))
155
+ .append($('<input />', {
156
+ name: 'user_2[password]',
157
+ id: 'user_2_password',
158
+ type: 'password'
159
+ }))
160
+ .append($('<label for="user_2_password_confirmation">Password Confirmation</label>'))
161
+ .append($('<input />', {
162
+ name: 'user_2[password_confirmation]',
163
+ id: 'user_2_password_confirmation',
164
+ type: 'password'
165
+ }))
166
+ new_user_2 = {
167
+ type: 'ActionView::Helpers::FormBuilder',
168
+ input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
169
+ label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
170
+ validators: {
171
+ }
172
+ }
173
+ $('form#new_user_2').validate();
174
+ var form = $('form#new_user_2'), input = form.find('input#user_2_password_confirmation');
175
+ input.val('123');
176
+ input.trigger('focusout');
177
+ ok(!input.parent().hasClass('field_with_errors'));
143
178
  });
144
179
 
@@ -27,7 +27,13 @@ test('when allowing blank and allowed length is 3', function() {
27
27
  equal(clientSideValidations.validators.local.length(element, options), undefined);
28
28
  });
29
29
 
30
- test('when allowing blank and allowed length is 3', function() {
30
+ test('when allowing blank and minimum length is 3 and maximum length is 100', function() {
31
+ var element = $('<input type="text" />');
32
+ var options = { messages: { minimum: "failed minimum validation", maximum: "failed maximum validation" }, minimum: 3, maximum: 100, allow_blank: true };
33
+ equal(clientSideValidations.validators.local.length(element, options), undefined);
34
+ });
35
+
36
+ test('when not allowing blank and allowed length is 3', function() {
31
37
  var element = $('<input type="text" />');
32
38
  var options = { messages: { is: "failed validation" }, is: 3 };
33
39
  equal(clientSideValidations.validators.local.length(element, options), "failed validation");
@@ -105,6 +105,13 @@ test('when only allowing values equal to 10 and value is 11', function() {
105
105
  equal(clientSideValidations.validators.local.numericality(element, options), "failed validation");
106
106
  });
107
107
 
108
+ test('when only allowing value equal to 0 and value is 1', function() {
109
+ var element = $('<input type="text" />');
110
+ var options = { messages: { equal_to: "failed validation" }, equal_to: 0 };
111
+ element.val('1');
112
+ equal(clientSideValidations.validators.local.numericality(element, options), "failed validation");
113
+ });
114
+
108
115
  test('when only allowing odd values and the value is odd', function() {
109
116
  var element = $('<input type="text" />');
110
117
  var options = { messages: { odd: "failed validation" }, odd: true };
@@ -13,3 +13,9 @@ test('when value is empty', function() {
13
13
  equal(clientSideValidations.validators.local.presence(element, options), "failed validation");
14
14
  });
15
15
 
16
+ test('when value is null from non-selected multi-select element', function() {
17
+ var element = $('<select multiple="multiple />');
18
+ var options = { message: "failed validation" };
19
+ equal(clientSideValidations.validators.local.presence(element, options), "failed validation");
20
+ });
21
+
@@ -1,6 +1,6 @@
1
1
  module('Uniqueness options', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -87,3 +87,10 @@ test('when validating by scope and mixed focus order', function() {
87
87
  equal($('.message[for="user_email"]').text(), 'must be unique');
88
88
  });
89
89
 
90
+ test('when matching uniqueness on a resource with a defined class name', function() {
91
+ var element = $('<input type="text" name="user2[email]"/>');
92
+ var options = { 'message': "failed validation", 'class': "active_record_test_module/user2" };
93
+ element.val('nottaken@test.com');
94
+ equal(clientSideValidations.validators.remote.uniqueness(element, options), 'failed validation');
95
+ });
96
+
@@ -46,7 +46,13 @@ end
46
46
  get '/validators/uniqueness.json' do
47
47
  content_type 'application/json'
48
48
 
49
- if scope = params[:scope]
49
+ if user = params[:user2]
50
+ status 500
51
+ 'error'
52
+ elsif user = params['active_record_test_module/user2']
53
+ status 200
54
+ 'false'
55
+ elsif scope = params[:scope]
50
56
  if scope[:name] == 'test name' || scope[:name] == 'taken name'
51
57
  status 200
52
58
  'false'
@@ -7,7 +7,7 @@
7
7
  <h1 id="qunit-header"><%= @title %></h1>
8
8
  <div id="jquery-version">
9
9
  jQuery version:
10
- <% %w{1.4.1 1.4.2 1.4.3 1.4.4 1.5 1.5.1}.each do |version| %>
10
+ <% %w{1.4.1 1.4.2 1.4.3 1.4.4 1.5 1.5.1 1.6}.each do |version| %>
11
11
  <%= jquery_link version %> •
12
12
  <% end %>
13
13
  <%= jquery_link 'edge' if File.exist?(settings.root + '/public/vendor/jquery.js') %>
@@ -0,0 +1,9 @@
1
+ require 'base_helper'
2
+ require 'mongo_mapper'
3
+ require 'client_side_validations/mongo_mapper'
4
+
5
+ MongoMapper.database = "client_side_validations_development"
6
+ MongoMapper.connection = Mongo::Connection.new('127.0.0.1', 27017)
7
+
8
+ require 'mongo_mapper/models/magazine'
9
+
@@ -0,0 +1,15 @@
1
+ require 'mongo_mapper/cases/helper'
2
+
3
+ class ClientSideValidations::MongoMapperTestBase < Test::Unit::TestCase
4
+ include MongoMapper::Plugins::Validations
5
+
6
+ def setup
7
+ @magazine = Magazine.new
8
+ end
9
+
10
+ def test_uniqueness_client_side_hash
11
+ expected_hash = { :message => "has already been taken", :case_sensitive => true}
12
+ assert_equal expected_hash, UniquenessValidator.new(:attributes => [:name]).client_side_hash(@magazine, :age)
13
+ end
14
+ end
15
+
@@ -0,0 +1,77 @@
1
+ require 'middleware/cases/helper'
2
+ require 'mongo_mapper/cases/helper'
3
+
4
+ class ClientSideValidationsMongoMapperMiddlewareTest < Test::Unit::TestCase
5
+ include Rack::Test::Methods
6
+
7
+ def setup
8
+ # I've been burned enough times with not having the db clear
9
+ # I should probably use a db cleaner instead of this
10
+ Magazine.delete_all
11
+ end
12
+
13
+ def teardown
14
+ Magazine.delete_all
15
+ end
16
+
17
+ def app
18
+ app = Proc.new { |env| [200, {}, ['success']] }
19
+ ClientSideValidations::Middleware::Validators.new(app)
20
+ end
21
+
22
+ def test_uniqueness_when_resource_exists
23
+ Magazine.create(:author_email => 'magazine@test.com')
24
+ get '/validators/uniqueness.json', { 'magazine[author_email]' => 'magazine@test.com' }
25
+
26
+ assert_equal 'false', last_response.body
27
+ assert last_response.ok?
28
+ end
29
+
30
+ def test_uniqueness_when_resource_does_not_exist
31
+ get '/validators/uniqueness.json', { 'magazine[author_email]' => 'magazine@test.com' }
32
+
33
+ assert_equal 'true', last_response.body
34
+ assert last_response.not_found?
35
+ end
36
+
37
+ def test_uniqueness_when_id_is_given
38
+ magazine = Magazine.create(:author_email => 'magazine@test.com')
39
+ get '/validators/uniqueness.json', { 'magazine[author_email]' => 'magazine@test.com', 'id' => magazine.id }
40
+
41
+ assert_equal 'true', last_response.body
42
+ assert last_response.not_found?
43
+ end
44
+
45
+ def test_uniqueness_when_scope_is_given
46
+ Magazine.create(:author_email => 'magazine@test.com', :age => 25)
47
+ get '/validators/uniqueness.json', { 'magazine[author_email]' => 'magazine@test.com', 'scope' => { 'age' => 30 } }
48
+
49
+ assert_equal 'true', last_response.body
50
+ assert last_response.not_found?
51
+ end
52
+
53
+ def test_uniqueness_when_multiple_scopes_are_given
54
+ Magazine.create(:author_email => 'magazine@test.com', :age => 30, :author_name => 'Brian')
55
+ get '/validators/uniqueness.json', { 'magazine[author_email]' => 'magazine@test.com', 'scope' => { 'age' => 30, 'author_name' => 'Robert' } }
56
+
57
+ assert_equal 'true', last_response.body
58
+ assert last_response.not_found?
59
+ end
60
+
61
+ def test_uniqueness_when_case_insensitive
62
+ Magazine.create(:author_name => 'Brian')
63
+ get '/validators/uniqueness.json', { 'magazine[author_name]' => 'BRIAN', 'case_sensitive' => false }
64
+
65
+ assert_equal 'false', last_response.body
66
+ assert last_response.ok?
67
+ end
68
+
69
+ def test_uniqueness_when_resource_exists
70
+ MongoMapperTestModule::Magazine2.create(:author_email => 'magazine@test.com')
71
+ get '/validators/uniqueness.json', { 'mongo_mapper_test_module/magazine2[author_email]' => 'magazine@test.com' }
72
+
73
+ assert_equal 'false', last_response.body
74
+ assert last_response.ok?
75
+ end
76
+ end
77
+
@@ -0,0 +1,50 @@
1
+ require 'mongo_mapper/cases/test_base'
2
+
3
+ class MongoMapper::UniqunessValidatorTest < ClientSideValidations::MongoMapperTestBase
4
+
5
+ def test_uniqueness_client_side_hash
6
+ expected_hash = { :message => "has already been taken" }
7
+ assert_equal expected_hash, UniquenessValidator.new(:attributes => [:name]).client_side_hash(@magazine, :age)
8
+ end
9
+
10
+ def test_uniqueness_client_side_hash_with_custom_message
11
+ expected_hash = { :message => "is not available" , :case_sensitive => true }
12
+ assert_equal expected_hash, UniquenessValidator.new(:attributes => [:name], :message => "is not available").client_side_hash(@magazine, :age)
13
+ end
14
+
15
+ def test_uniqueness_client_side_hash
16
+ @magazine.stubs(:new_record?).returns(false)
17
+ @magazine.stubs(:id).returns(1)
18
+ expected_hash = { :message => "has already been taken", :case_sensitive => true , :id => 1 }
19
+ assert_equal expected_hash, UniquenessValidator.new(:attributes => [:name]).client_side_hash(@magazine, :age)
20
+ end
21
+
22
+ def test_uniqueness_client_side_hash_with_single_scope_item
23
+ @magazine.stubs(:author_email).returns("test@test.com")
24
+ expected_hash = { :message => "has already been taken", :case_sensitive => true , :scope => {:author_email => "test@test.com"} }
25
+ result_hash = UniquenessValidator.new(:attributes => [:author_name], :scope => :author_email).client_side_hash(@magazine, :author_name)
26
+ assert_equal expected_hash, result_hash
27
+ end
28
+
29
+ def test_uniqueness_client_side_hash_with_multiple_scope_items
30
+ @magazine.stubs(:age).returns(30)
31
+ @magazine.stubs(:author_email).returns("test@test.com")
32
+ expected_hash = { :message => "has already been taken", :case_sensitive => true , :scope => {:age => 30, :author_email => "test@test.com"} }
33
+ result_hash = UniquenessValidator.new(:attributes => [:author_name], :scope => [:age, :author_email]).client_side_hash(@magazine, :author_name)
34
+ assert_equal expected_hash, result_hash
35
+ end
36
+
37
+ def test_uniqueness_client_side_hash_with_empty_scope_array
38
+ expected_hash = { :message => "has already been taken" , :case_sensitive => true }
39
+ result_hash = UniquenessValidator.new(:attributes => [:author_name], :scope => []).client_side_hash(@magazine, :author_name)
40
+ assert_equal expected_hash, result_hash
41
+ end
42
+
43
+ def test_uniqueness_client_side_hash_when_nested_module
44
+ @magazine = MongoMapperTestModule::Magazine2.new
45
+ expected_hash = { :message => "has already been taken", :case_sensitive => true, :class => 'mongo_mapper_test_module/magazine2' }
46
+ assert_equal expected_hash, UniquenessValidator.new(:attributes => [:name]).client_side_hash(@magazine, :age)
47
+ end
48
+
49
+ end
50
+