client_side_validations 3.1.0 → 3.2.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.
Files changed (111) hide show
  1. data/client_side_validations.gemspec +4 -16
  2. data/lib/client_side_validations/action_view/form_builder.rb +31 -79
  3. data/lib/client_side_validations/action_view/form_helper.rb +59 -24
  4. data/lib/client_side_validations/active_model/exclusion.rb +14 -2
  5. data/lib/client_side_validations/active_model/format.rb +21 -0
  6. data/lib/client_side_validations/active_model/inclusion.rb +13 -2
  7. data/lib/client_side_validations/active_model/length.rb +4 -2
  8. data/lib/client_side_validations/active_model/numericality.rb +12 -1
  9. data/lib/client_side_validations/active_model.rb +100 -14
  10. data/lib/client_side_validations/active_record/middleware.rb +29 -3
  11. data/lib/client_side_validations/active_record/uniqueness.rb +4 -3
  12. data/lib/client_side_validations/active_record.rb +2 -1
  13. data/lib/client_side_validations/config.rb +9 -0
  14. data/lib/client_side_validations/core_ext/regexp.rb +1 -2
  15. data/lib/client_side_validations/generators/rails_validations.rb +15 -0
  16. data/lib/client_side_validations/generators.rb +12 -0
  17. data/lib/client_side_validations/middleware.rb +63 -24
  18. data/lib/client_side_validations/version.rb +1 -1
  19. data/lib/client_side_validations.rb +2 -2
  20. data/lib/generators/client_side_validations/copy_assets_generator.rb +58 -0
  21. data/lib/generators/client_side_validations/install_generator.rb +9 -21
  22. data/lib/generators/templates/client_side_validations/initializer.rb +2 -2
  23. data/vendor/assets/javascripts/rails.validations.js +474 -282
  24. metadata +156 -301
  25. data/lib/client_side_validations/formtastic.rb +0 -21
  26. data/lib/client_side_validations/mongo_mapper/middleware.rb +0 -20
  27. data/lib/client_side_validations/mongo_mapper/uniqueness.rb +0 -28
  28. data/lib/client_side_validations/mongo_mapper.rb +0 -9
  29. data/lib/client_side_validations/mongoid/middleware.rb +0 -20
  30. data/lib/client_side_validations/mongoid/uniqueness.rb +0 -28
  31. data/lib/client_side_validations/mongoid.rb +0 -9
  32. data/lib/client_side_validations/simple_form.rb +0 -24
  33. data/lib/generators/client_side_validations/copy_asset_generator.rb +0 -23
  34. data/lib/generators/templates/client_side_validations/README.rails.3.0 +0 -6
  35. data/lib/generators/templates/client_side_validations/README.rails.3.1 +0 -7
  36. data/test/action_view/cases/helper.rb +0 -176
  37. data/test/action_view/cases/test_helpers.rb +0 -600
  38. data/test/action_view/cases/test_legacy_helpers.rb +0 -217
  39. data/test/action_view/models/comment.rb +0 -35
  40. data/test/action_view/models/post.rb +0 -35
  41. data/test/action_view/models.rb +0 -3
  42. data/test/active_model/cases/helper.rb +0 -4
  43. data/test/active_model/cases/test_acceptance_validator.rb +0 -16
  44. data/test/active_model/cases/test_base.rb +0 -11
  45. data/test/active_model/cases/test_confirmation_validator.rb +0 -16
  46. data/test/active_model/cases/test_exclusion_validator.rb +0 -20
  47. data/test/active_model/cases/test_format_validator.rb +0 -21
  48. data/test/active_model/cases/test_inclusion_validator.rb +0 -21
  49. data/test/active_model/cases/test_length_validator.rb +0 -61
  50. data/test/active_model/cases/test_numericality_validator.rb +0 -46
  51. data/test/active_model/cases/test_presence_validator.rb +0 -16
  52. data/test/active_model/cases/test_validations.rb +0 -175
  53. data/test/active_model/models/person.rb +0 -17
  54. data/test/active_record/cases/helper.rb +0 -12
  55. data/test/active_record/cases/test_base.rb +0 -11
  56. data/test/active_record/cases/test_middleware.rb +0 -175
  57. data/test/active_record/cases/test_uniqueness_validator.rb +0 -50
  58. data/test/active_record/models/guid.rb +0 -7
  59. data/test/active_record/models/user.rb +0 -14
  60. data/test/base_helper.rb +0 -8
  61. data/test/core_ext/cases/test_core_ext.rb +0 -46
  62. data/test/formtastic/cases/helper.rb +0 -7
  63. data/test/formtastic/cases/test_form_builder.rb +0 -11
  64. data/test/formtastic/cases/test_form_helper.rb +0 -21
  65. data/test/generators/cases/test_generators.rb +0 -31
  66. data/test/javascript/config.ru +0 -3
  67. data/test/javascript/public/test/callbacks/elementAfter.js +0 -54
  68. data/test/javascript/public/test/callbacks/elementBefore.js +0 -54
  69. data/test/javascript/public/test/callbacks/elementFail.js +0 -70
  70. data/test/javascript/public/test/callbacks/elementPass.js +0 -70
  71. data/test/javascript/public/test/callbacks/formAfter.js +0 -45
  72. data/test/javascript/public/test/callbacks/formBefore.js +0 -45
  73. data/test/javascript/public/test/callbacks/formFail.js +0 -51
  74. data/test/javascript/public/test/callbacks/formPass.js +0 -50
  75. data/test/javascript/public/test/form_builders/validateForm.js +0 -66
  76. data/test/javascript/public/test/form_builders/validateFormtastic.js +0 -54
  77. data/test/javascript/public/test/form_builders/validateNestedForm.js +0 -66
  78. data/test/javascript/public/test/form_builders/validateSimpleForm.js +0 -57
  79. data/test/javascript/public/test/settings.js +0 -15
  80. data/test/javascript/public/test/validateElement.js +0 -179
  81. data/test/javascript/public/test/validators/acceptance.js +0 -42
  82. data/test/javascript/public/test/validators/confirmation.js +0 -25
  83. data/test/javascript/public/test/validators/exclusion.js +0 -41
  84. data/test/javascript/public/test/validators/format.js +0 -27
  85. data/test/javascript/public/test/validators/inclusion.js +0 -42
  86. data/test/javascript/public/test/validators/length.js +0 -76
  87. data/test/javascript/public/test/validators/numericality.js +0 -142
  88. data/test/javascript/public/test/validators/presence.js +0 -21
  89. data/test/javascript/public/test/validators/uniqueness.js +0 -96
  90. data/test/javascript/public/vendor/jquery.metadata.js +0 -122
  91. data/test/javascript/public/vendor/qunit.css +0 -196
  92. data/test/javascript/public/vendor/qunit.js +0 -1374
  93. data/test/javascript/server.rb +0 -84
  94. data/test/javascript/views/index.erb +0 -20
  95. data/test/javascript/views/layout.erb +0 -21
  96. data/test/middleware/cases/helper.rb +0 -18
  97. data/test/middleware/cases/test_middleware.rb +0 -8
  98. data/test/mongo_mapper/cases/helper.rb +0 -9
  99. data/test/mongo_mapper/cases/test_base.rb +0 -15
  100. data/test/mongo_mapper/cases/test_middleware.rb +0 -77
  101. data/test/mongo_mapper/cases/test_uniqueness_validator.rb +0 -50
  102. data/test/mongo_mapper/models/magazine.rb +0 -11
  103. data/test/mongoid/cases/helper.rb +0 -16
  104. data/test/mongoid/cases/test_base.rb +0 -15
  105. data/test/mongoid/cases/test_middleware.rb +0 -77
  106. data/test/mongoid/cases/test_uniqueness_validator.rb +0 -49
  107. data/test/mongoid/models/book.rb +0 -12
  108. data/test/simple_form/cases/helper.rb +0 -5
  109. data/test/simple_form/cases/test_form_builder.rb +0 -14
  110. data/test/simple_form/cases/test_form_helper.rb +0 -24
  111. data/test/test_loader.rb +0 -6
@@ -1,10 +1,11 @@
1
1
  module ClientSideValidations::ActiveRecord
2
2
  module Uniqueness
3
- def client_side_hash(model, attribute)
3
+ def client_side_hash(model, attribute, force = nil)
4
4
  hash = {}
5
- hash[:message] = model.errors.generate_message(attribute, message_type, options.except(:scope))
5
+ hash[:message] = model.errors.generate_message(attribute, message_type, options.except(:scope))
6
6
  hash[:case_sensitive] = options[:case_sensitive]
7
- hash[:id] = model.id unless model.new_record?
7
+ hash[:id] = model.id unless model.new_record?
8
+ hash[:allow_blank] = true if options[:allow_blank]
8
9
  if options.key?(:scope) && options[:scope].present?
9
10
  hash[:scope] = Array.wrap(options[:scope]).inject({}) do |scope_hash, scope_item|
10
11
  scope_hash.merge!(scope_item => model.send(scope_item))
@@ -1,4 +1,5 @@
1
1
  require 'client_side_validations/active_model'
2
+ require 'client_side_validations/middleware'
2
3
  require 'client_side_validations/active_record/middleware'
3
4
 
4
5
  %w{uniqueness}.each do |validator|
@@ -8,4 +9,4 @@ require 'client_side_validations/active_record/middleware'
8
9
  end
9
10
 
10
11
  ActiveRecord::Base.send(:include, ClientSideValidations::ActiveModel::Validations)
11
-
12
+ ClientSideValidations::Middleware::Uniqueness.register_orm(ClientSideValidations::ActiveRecord::Middleware)
@@ -0,0 +1,9 @@
1
+ module ClientSideValidations
2
+ module Config
3
+ class << self
4
+ attr_accessor :disabled_validators
5
+ end
6
+
7
+ self.disabled_validators = []
8
+ end
9
+ end
@@ -1,6 +1,6 @@
1
1
  class Regexp
2
2
  def as_json(options = nil)
3
- Regexp.new inspect.sub("\\A","^").sub("\\Z","$").sub("\\z","$").sub(/^\//,"").sub(/\/[a-z]*$/,""), self.options
3
+ Regexp.new inspect.sub('\\A','^').sub('\\Z','$').sub('\\z','$').sub(/^\//,'').sub(/\/[a-z]*$/,'').gsub(/\(\?#.+\)/, '').gsub(/\(\?-\w+:/,'(').gsub(/\s/,''), self.options & 5
4
4
  end
5
5
 
6
6
  def to_json(options = nil)
@@ -11,4 +11,3 @@ class Regexp
11
11
  inspect
12
12
  end
13
13
  end
14
-
@@ -0,0 +1,15 @@
1
+ module ClientSideValidations
2
+ module Generators
3
+ class RailsValidations
4
+ def self.assets
5
+ [{
6
+ :path => File.expand_path('../../../../vendor/assets/javascripts', __FILE__),
7
+ :file => 'rails.validations.js'
8
+ }]
9
+ end
10
+
11
+ Generators.register_assets(self)
12
+ end
13
+ end
14
+ end
15
+
@@ -0,0 +1,12 @@
1
+ module ClientSideValidations
2
+ module Generators
3
+ Assets = []
4
+
5
+ def self.register_assets(klass)
6
+ Assets.push(*klass.assets)
7
+ end
8
+ end
9
+ end
10
+
11
+ require 'client_side_validations/generators/rails_validations'
12
+
@@ -11,9 +11,12 @@ module ClientSideValidations
11
11
  end
12
12
 
13
13
  def call(env)
14
- case env['PATH_INFO']
15
- when %r{\/validators\/(\w+)}
16
- "::ClientSideValidations::Middleware::#{$1.camelize}".constantize.new(env).response
14
+ if matches = /^\/validators\/(\w+)$/.match(env['PATH_INFO'])
15
+ if ClientSideValidations::Config.disabled_validators.include?(matches[1].to_sym)
16
+ [500, {'Content-Type' => 'application/json', 'Content-Length' => 0}, ['']]
17
+ else
18
+ "::ClientSideValidations::Middleware::#{matches[1].camelize}".constantize.new(env).response
19
+ end
17
20
  else
18
21
  @app.call(env)
19
22
  end
@@ -24,9 +27,11 @@ module ClientSideValidations
24
27
  attr_accessor :request, :body, :status
25
28
 
26
29
  def initialize(env)
27
- self.body = ''
28
- self.status = 200
29
- self.request = ActionDispatch::Request.new(env)
30
+ # Filter out cache buster
31
+ env['QUERY_STRING'] = env['QUERY_STRING'].split('&').select { |p| !p.match(/^_=/) }.join('&')
32
+ self.body = ''
33
+ self.status = 200
34
+ self.request = ActionDispatch::Request.new(env)
30
35
  end
31
36
 
32
37
  def response
@@ -40,35 +45,69 @@ module ClientSideValidations
40
45
 
41
46
  class Uniqueness < Base
42
47
  IGNORE_PARAMS = %w{case_sensitive id scope}
48
+ REGISTERED_ORMS = []
49
+ class NotValidatable < StandardError; end
43
50
 
44
51
  def response
45
- if is_unique?
46
- self.status = 404
47
- self.body = 'true'
48
- else
49
- self.status = 200
50
- self.body = 'false'
52
+ begin
53
+ if is_unique?
54
+ self.status = 404
55
+ self.body = 'true'
56
+ else
57
+ self.status = 200
58
+ self.body = 'false'
59
+ end
60
+ rescue NotValidatable
61
+ self.status = 500
62
+ self.body = ''
51
63
  end
52
64
  super
53
65
  end
54
66
 
67
+ def self.register_orm(orm)
68
+ registered_orms << orm
69
+ end
70
+
71
+ def self.registered_orms
72
+ REGISTERED_ORMS
73
+ end
74
+
75
+ def registered_orms
76
+ self.class.registered_orms
77
+ end
78
+
55
79
  private
56
80
 
57
81
  def is_unique?
58
- resource = extract_resource
59
- klass = resource.classify.constantize
60
- attribute = request.params[resource].keys.first
61
- value = request.params[resource][attribute]
62
-
63
- if (defined?(::ActiveRecord::Base) && klass < ::ActiveRecord::Base)
64
- middleware_klass = ClientSideValidations::ActiveRecord::Middleware
65
- elsif (defined?(::Mongoid::Document) && klass.included_modules.include?(::Mongoid::Document))
66
- middleware_klass = ClientSideValidations::Mongoid::Middleware
67
- elsif (defined?(::MongoMapper::Document) && klass.included_modules.include?(::MongoMapper::Document))
68
- middleware_klass = ClientSideValidations::MongoMapper::Middleware
82
+ convert_scope_value_from_null_to_nil
83
+ resource = extract_resource
84
+ klass = resource.classify.constantize
85
+ attribute = request.params[resource].keys.first
86
+ value = request.params[resource][attribute]
87
+ middleware_class = nil
88
+
89
+ unless Array.wrap(klass._validators[attribute.to_sym]).find { |v| v.kind == :uniqueness }
90
+ raise NotValidatable
91
+ end
92
+
93
+ registered_orms.each do |orm|
94
+ if orm.is_class?(klass)
95
+ middleware_class = orm
96
+ break
97
+ end
69
98
  end
70
99
 
71
- middleware_klass.is_unique?(klass, attribute, value, request.params)
100
+ middleware_class.is_unique?(klass, attribute, value, request.params)
101
+ end
102
+
103
+ def convert_scope_value_from_null_to_nil
104
+ if request.params['scope']
105
+ request.params['scope'].each do |key, value|
106
+ if value == 'null'
107
+ request.params['scope'][key] = nil
108
+ end
109
+ end
110
+ end
72
111
  end
73
112
 
74
113
  def extract_resource
@@ -1,3 +1,3 @@
1
1
  module ClientSideValidations
2
- VERSION = '3.1.0'
2
+ VERSION = '3.2.0'
3
3
  end
@@ -1,12 +1,12 @@
1
1
  module ClientSideValidations
2
2
  end
3
3
 
4
+ require 'client_side_validations/config'
4
5
  require 'client_side_validations/active_model' if defined?(::ActiveModel)
5
6
  require 'client_side_validations/active_record' if defined?(::ActiveRecord)
6
- require 'client_side_validations/mongoid' if defined?(::Mongoid)
7
- require 'client_side_validations/mongo_mapper' if defined?(::MongoMapper)
8
7
  require 'client_side_validations/action_view' if defined?(::ActionView)
9
8
  if defined?(::Rails)
9
+ require 'client_side_validations/generators'
10
10
  require 'client_side_validations/middleware'
11
11
  require 'client_side_validations/engine'
12
12
  end
@@ -0,0 +1,58 @@
1
+ module ClientSideValidations
2
+ module Generators
3
+ class CopyAssetsGenerator < Rails::Generators::Base
4
+
5
+ def copy_javascript_asset
6
+ if self.class == CopyAssetsGenerator || !asset_pipeline_enabled?
7
+ assets.each do |asset|
8
+ source_paths << asset[:path]
9
+ copy_file asset[:file], "#{asset_directory}/#{asset[:file]}"
10
+ end
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def self.asset_directory
17
+ if asset_pipeline_enabled?
18
+ "app#{Rails.configuration.assets.prefix}/javascripts"
19
+ else
20
+ 'public/javascripts'
21
+ end
22
+ end
23
+
24
+ def asset_directory
25
+ CopyAssetsGenerator.asset_directory
26
+ end
27
+
28
+ def self.assets
29
+ Assets
30
+ end
31
+
32
+ def assets
33
+ CopyAssetsGenerator.assets
34
+ end
35
+
36
+ def self.asset_file_names
37
+ assets.map { |asset| asset[:file] }.join(', ')
38
+ end
39
+
40
+ def self.asset_pipeline_enabled?
41
+ if Rails.application
42
+ (Rails.configuration.respond_to?(:assets) ? (Rails.configuration.assets || {}) : {})[:enabled]
43
+ end
44
+ end
45
+
46
+ def asset_pipeline_enabled?
47
+ self.class.asset_pipeline_enabled?
48
+ end
49
+
50
+ def self.installation_message
51
+ "Copies #{asset_file_names} to #{asset_directory}"
52
+ end
53
+
54
+ desc installation_message
55
+ end
56
+ end
57
+ end
58
+
@@ -1,33 +1,21 @@
1
+ require 'generators/client_side_validations/copy_assets_generator'
2
+
1
3
  module ClientSideValidations
2
4
  module Generators
3
- class InstallGenerator < Rails::Generators::Base
4
- source_root File.expand_path('../../templates/client_side_validations', __FILE__)
5
-
6
- if Rails.version >= '3.1'
7
- desc 'Creates a ClientSideValidations initializer.'
8
- else
9
- desc 'Creates a ClientSideValidations initializer and copies rails.validations.js to public/javascripts.'
10
- end
5
+ class InstallGenerator < CopyAssetsGenerator
11
6
 
12
7
  def copy_initializer
8
+ source_paths << File.expand_path('../../templates/client_side_validations', __FILE__)
13
9
  copy_file 'initializer.rb', 'config/initializers/client_side_validations.rb'
14
10
  end
15
11
 
16
- def copy_javascript_asset
17
- if Rails.version >= '3.0'
18
- if Rails.version < '3.1'
19
- copy_file '../../../../vendor/assets/javascripts/rails.validations.js', 'public/javascripts/rails.validations.js'
20
- end
21
- end
22
- end
12
+ private
23
13
 
24
- def show_readme
25
- if Rails.version >= '3.1'
26
- readme 'README.rails.3.1' if behavior == :invoke
27
- else
28
- readme 'README.rails.3.0' if behavior == :invoke
29
- end
14
+ def self.installation_message
15
+ "Copies initializer into config/initializers and #{super.downcase}"
30
16
  end
17
+
18
+ desc installation_message
31
19
  end
32
20
  end
33
21
  end
@@ -1,7 +1,7 @@
1
1
  # ClientSideValidations Initializer
2
2
 
3
- require 'client_side_validations/simple_form' if defined?(::SimpleForm)
4
- require 'client_side_validations/formtastic' if defined?(::Formtastic)
3
+ # Uncomment to disable uniqueness validator, possible security issue
4
+ # ClientSideValidations::Config.disabled_validators = [:uniqueness]
5
5
 
6
6
  # Uncomment the following block if you want each input field to have the validation messages attached.
7
7
  # ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|