missing_validators 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -73,6 +73,8 @@ You can specify domains to which the URL domain should belong in one of the folo
73
73
  validates :url, url: { domains: :com }
74
74
  validates :url, url: { domains: [:com, 'edu'] }
75
75
  validates :url, url: { root: true }
76
+ validates :url, url: { scheme: :http }
77
+ validates :url, url: { scheme: [:http, 'https'] }
76
78
 
77
79
  RSpec matcher is also available for your convenience:
78
80
 
@@ -14,18 +14,32 @@ class UrlValidator < ActiveModel::EachValidator
14
14
  # @param [Object] value attribute value
15
15
  def validate_each(record, attribute, value)
16
16
  uri = URI.parse(value)
17
- raise URI::InvalidURIError unless uri.kind_of?(URI::HTTP)
18
17
 
19
- domains = Array.wrap(options[:domain])
20
- host = uri.host.downcase
21
- in_valid_domain = domains.empty? || domains.any? { |domain| host.end_with?(".#{domain.downcase}") }
22
- raise URI::InvalidURIError unless in_valid_domain
18
+ unless uri.kind_of?(URI::HTTP) \
19
+ && in_valid_top_level_domains?(uri, Array.wrap(options[:domain])) \
20
+ && with_valid_scheme?(uri, Array.wrap(options[:scheme])) \
21
+ && (!!!options[:root] || is_root?(uri))
23
22
 
24
- must_be_domain_root = options[:root] || false
25
- if must_be_domain_root && (!['/', ''].include?(uri.path) || uri.query.present? || uri.fragment.present?)
26
23
  raise URI::InvalidURIError
27
24
  end
25
+
28
26
  rescue URI::InvalidURIError
29
27
  record.errors[attribute] << (options[:message] || I18n.t('errors.messages.url'))
30
28
  end
29
+
30
+ private
31
+
32
+ def in_valid_top_level_domains?(uri, tlds)
33
+ host_downcased = uri.host.downcase
34
+ tlds.empty? || tlds.map(&:downcase).any? { |domain| host_downcased.end_with?(".#{domain}") }
35
+ end
36
+
37
+ def with_valid_scheme?(uri, schemes)
38
+ scheme_downcased = uri.scheme.downcase
39
+ schemes.empty? || schemes.map(&:to_s).map(&:downcase).any? { |scheme| scheme_downcased == scheme }
40
+ end
41
+
42
+ def is_root?(uri)
43
+ ['/', ''].include?(uri.path) && uri.query.blank? && uri.fragment.blank?
44
+ end
31
45
  end
@@ -1,5 +1,5 @@
1
1
  # Provides a collection of custom validators that are often required in Rails applications.
2
2
  module MissingValidators
3
3
  # Gem version.
4
- VERSION = "0.5.2"
4
+ VERSION = "0.6.0"
5
5
  end
@@ -35,62 +35,69 @@ describe UrlValidator do
35
35
  it { should_not allow_value("http://user_example.a").for(:url) }
36
36
  end
37
37
 
38
- context "url is in the specific domain" do
39
- context "url specified as symbol" do
40
- let(:klass) do
41
- Class.new do
42
- include ActiveModel::Validations
43
- attr_accessor :url, :name
44
- validates :url, url: { domain: :org }
45
- end
38
+ describe "url must be in a specific domain" do
39
+ let(:klass) do
40
+ Class.new do
41
+ include ActiveModel::Validations
42
+ attr_accessor :url1, :url2
43
+ validates :url1, url: { domain: :org }
44
+ validates :url2, url: { domain: [:org, 'edu', 'Com.Au'] }
46
45
  end
46
+ end
47
47
 
48
- subject { klass.new }
48
+ subject { klass.new }
49
49
 
50
- it { should ensure_valid_url_format_of(:url) }
51
- it { should_not ensure_valid_url_format_of(:name) }
50
+ it { should allow_value("http://example.org").for(:url1) }
51
+ it { should_not allow_value("http://example.com").for(:url1) }
52
52
 
53
- it { should allow_value("http://example.org").for(:url) }
54
- it { should_not allow_value("http://example.com").for(:url) }
55
- end
53
+ it { should allow_value("http://example.org").for(:url2) }
54
+ it { should allow_value("http://example.edu").for(:url2) }
55
+ it { should allow_value("http://example.com.au").for(:url2) }
56
+ it { should allow_value("http://example.Com.Au").for(:url2) }
57
+ it { should_not allow_value("http://example.com").for(:url2) }
58
+ end
56
59
 
57
- context "url specified as array of strings and symbols" do
58
- let(:klass) do
59
- Class.new do
60
- include ActiveModel::Validations
61
- attr_accessor :url, :name
62
- validates :url, url: { domain: [:org, 'edu', 'Com.Au'] }
63
- end
60
+ describe "url must be domain root" do
61
+ let(:klass) do
62
+ Class.new do
63
+ include ActiveModel::Validations
64
+ attr_accessor :url1, :url2
65
+ validates :url1, url: { root: true }
66
+ validates :url2, url: { root: false }
64
67
  end
68
+ end
65
69
 
66
- subject { klass.new }
70
+ subject { klass.new }
67
71
 
68
- it { should ensure_valid_url_format_of(:url) }
69
- it { should_not ensure_valid_url_format_of(:name) }
72
+ it { should allow_value("http://example.org").for(:url1) }
73
+ it { should allow_value("http://example.org/").for(:url1) }
74
+ it { should_not allow_value("http://example.com/test").for(:url1) }
75
+ it { should_not allow_value("http://example.com/#fragment").for(:url1) }
76
+ it { should_not allow_value("http://example.com/?key=value").for(:url1) }
70
77
 
71
- it { should allow_value("http://example.org").for(:url) }
72
- it { should allow_value("http://example.edu").for(:url) }
73
- it { should allow_value("http://example.com.au").for(:url) }
74
- it { should allow_value("http://example.Com.Au").for(:url) }
75
- it { should_not allow_value("http://example.com").for(:url) }
76
- end
78
+
79
+ it { should allow_value("http://example.org").for(:url2) }
80
+ it { should allow_value("http://example.org/lorem").for(:url2) }
77
81
  end
78
82
 
79
- context "url must be domain root" do
83
+ describe "url must have a specific scheme" do
80
84
  let(:klass) do
81
85
  Class.new do
82
86
  include ActiveModel::Validations
83
- attr_accessor :url, :name
84
- validates :url, url: { root: true }
87
+ attr_accessor :url1, :url2
88
+ validates :url1, url: { scheme: 'http' }
89
+ validates :url2, url: { scheme: ['HTTP', :https] }
85
90
  end
86
91
  end
87
92
 
88
93
  subject { klass.new }
89
94
 
90
- it { should allow_value("http://example.org").for(:url) }
91
- it { should allow_value("http://example.org/").for(:url) }
92
- it { should_not allow_value("http://example.com/test").for(:url) }
93
- it { should_not allow_value("http://example.com/#fragment").for(:url) }
94
- it { should_not allow_value("http://example.com/?key=value").for(:url) }
95
+ it { should allow_value("http://example.org").for(:url1) }
96
+ it { should_not allow_value("https://example.org").for(:url1) }
97
+
98
+ it { should allow_value("http://example.org").for(:url2) }
99
+ it { should allow_value("https://example.org").for(:url2) }
100
+ it { should allow_value("HTTPS://example.org").for(:url2) }
101
+ it { should_not allow_value("ftp://example.org").for(:url2) }
95
102
  end
96
103
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: missing_validators
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.6.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-11 00:00:00.000000000 Z
12
+ date: 2013-10-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70277040464020 !ruby/object:Gem::Requirement
16
+ requirement: &70348494356240 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70277040464020
24
+ version_requirements: *70348494356240
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: shoulda-matchers
27
- requirement: &70277040463440 !ruby/object:Gem::Requirement
27
+ requirement: &70348494355460 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70277040463440
35
+ version_requirements: *70348494355460
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: activemodel
38
- requirement: &70277040462560 !ruby/object:Gem::Requirement
38
+ requirement: &70348494354760 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 3.0.0
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70277040462560
46
+ version_requirements: *70348494354760
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: activesupport
49
- requirement: &70277040461820 !ruby/object:Gem::Requirement
49
+ requirement: &70348494353960 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: 3.0.0
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70277040461820
57
+ version_requirements: *70348494353960
58
58
  description: Validates email addresses, URLs, and inequality of attributes.
59
59
  email:
60
60
  - andrew.gridnev@gmail.com