url_validation 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ -cfs
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source :rubygems
2
+
3
+ gem 'addressable', :require => 'addressable/uri' # for unicode URIs
4
+ gem 'activesupport'
5
+ gem 'activerecord'
6
+ gem 'httpi'
7
+
8
+ group :development do
9
+ gem 'jeweler'
10
+ gem 'yard'
11
+ gem 'RedCloth', require: 'redcloth'
12
+ gem 'rspec'
13
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,53 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ RedCloth (4.2.7)
5
+ activemodel (3.0.7)
6
+ activesupport (= 3.0.7)
7
+ builder (~> 2.1.2)
8
+ i18n (~> 0.5.0)
9
+ activerecord (3.0.7)
10
+ activemodel (= 3.0.7)
11
+ activesupport (= 3.0.7)
12
+ arel (~> 2.0.2)
13
+ tzinfo (~> 0.3.23)
14
+ activesupport (3.0.7)
15
+ addressable (2.2.6)
16
+ arel (2.0.10)
17
+ builder (2.1.2)
18
+ diff-lcs (1.1.2)
19
+ git (1.2.5)
20
+ httpi (0.9.4)
21
+ pyu-ntlm-http (>= 0.1.3.1)
22
+ rack
23
+ i18n (0.5.0)
24
+ jeweler (1.6.0)
25
+ bundler (~> 1.0.0)
26
+ git (>= 1.2.5)
27
+ rake
28
+ pyu-ntlm-http (0.1.3.1)
29
+ rack (1.3.0)
30
+ rake (0.9.0)
31
+ rspec (2.6.0)
32
+ rspec-core (~> 2.6.0)
33
+ rspec-expectations (~> 2.6.0)
34
+ rspec-mocks (~> 2.6.0)
35
+ rspec-core (2.6.3)
36
+ rspec-expectations (2.6.0)
37
+ diff-lcs (~> 1.1.2)
38
+ rspec-mocks (2.6.0)
39
+ tzinfo (0.3.27)
40
+ yard (0.7.1)
41
+
42
+ PLATFORMS
43
+ ruby
44
+
45
+ DEPENDENCIES
46
+ RedCloth
47
+ activerecord
48
+ activesupport
49
+ addressable
50
+ httpi
51
+ jeweler
52
+ rspec
53
+ yard
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Tim Morgan
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,36 @@
1
+ h1. url_validation -- Simple URL validator for Rails 3
2
+
3
+ | *Author* | Tim Morgan |
4
+ | *Version* | 1.0 (May 9, 2011) |
5
+ | *License* | Released under the MIT license. |
6
+
7
+ h2. About
8
+
9
+ This gem adds a very simple URL format validator to be used with ActiveRecord
10
+ models in Rails 3.0. It supports localized error messages. It can validate many
11
+ different kinds of URLs, including HTTP and HTTPS. It supports advanced
12
+ validation features like sending @HEAD@ requests to URLS to verify that they are
13
+ valid endpoints.
14
+
15
+ h2. Installation
16
+
17
+ Add the gem to your project's @Gemfile@:
18
+
19
+ <pre><code>
20
+ gem 'url_validation'
21
+ </code></pre>
22
+
23
+ h2. Usage
24
+
25
+ This gem is an @EachValidator@, and thus is used with the @validates@ method:
26
+
27
+ <pre><code>
28
+ class User < ActiveRecord::Base
29
+ validates :terms_of_service_link,
30
+ :presence => true,
31
+ :url => true
32
+ end
33
+ </code></pre>
34
+
35
+ There are other options to fine-tune your validation; see the {UrlValidator}
36
+ class for more, and for a list of error message localization keys.
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rake'
11
+
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ gem.name = "url_validation"
15
+ gem.summary = %Q{Simple URL validation in Rails 3}
16
+ gem.description = %Q{A simple, localizable EachValidator for URL fields in ActiveRecord 3.0.}
17
+ gem.email = "git@timothymorgan.info"
18
+ gem.homepage = "http://github.com/riscfuture/url_validation"
19
+ gem.authors = [ "Tim Morgan" ]
20
+ gem.required_ruby_version = '>= 1.8.7'
21
+ end
22
+ Jeweler::RubygemsDotOrgTasks.new
23
+
24
+ require 'yard'
25
+ YARD::Rake::YardocTask.new('doc') do |doc|
26
+ doc.options << "-m" << "textile"
27
+ doc.options << "--protected" << "--no-private"
28
+ doc.options << "-r" << "README.textile"
29
+ doc.options << "-o" << "doc"
30
+ doc.options << "--title" << "url_validation Documentation".inspect
31
+
32
+ doc.files = [ 'lib/*_validator.rb', 'README.textile' ]
33
+ end
34
+
35
+ require 'rspec/core/rake_task'
36
+ RSpec::Core::RakeTask.new
37
+
38
+ task :default => :spec
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,193 @@
1
+ require 'addressable/uri'
2
+ require 'httpi'
3
+ require 'active_support/core_ext/hash/except'
4
+ require 'active_model/validator'
5
+
6
+ # Validates URLs. Uses the following I18n error message keys:
7
+ #
8
+ # | @invalid_url@ | URL is improperly formatted. |
9
+ # | @url_not_accessible@ | Couldn't connect to the URL. |
10
+ # | @url_invalid_response@ | Got a bad HTTP response (not of an acceptable type, e.g., 2xx). |
11
+ #
12
+ # @example Checks the syntax only
13
+ # validates :link, :url => true
14
+ #
15
+ # @example Ensures the host is available but does not check the path
16
+ # validates :link, :url => { :check_host => true }
17
+ #
18
+ # @example Ensures that the host is available and that a request for the path does not return a 4xx or 5xx response
19
+ # validates :link, :url => { :check_path => true }
20
+ #
21
+ # @example Ensures that the host is available and that a request for the path does not return a 3xx, 4xx, or 5xx response
22
+ # validates :link, :url => { :check_path => [ 300..399, 400..499, 500..599 ] }
23
+ #
24
+ # @example Checks for host accessibility with a custom timeout
25
+ # validates :link, :url => {
26
+ # :check_host => true,
27
+ # :request_callback => lambda { |request| request.timeout = 30 }
28
+ # }
29
+ #
30
+ # h2. Options
31
+ #
32
+ # h3. Basic options
33
+ #
34
+ # | @:allow_nil@ | If @true@, @nil@ values are allowed. |
35
+ # | @:allow_blank@ | If @true@, @nil@ or empty values are allowed. |
36
+ #
37
+ # h3. Error messages
38
+ #
39
+ # | @:invalid_url_message@ | A custom message to use in place of @:invalid_url@. |
40
+ # | @:incorrect_url_type_message@ | A custom message to use in place of @:incorrect_url_type@. |
41
+ # | @:url_not_accessible_message@ | A custom message to use in place of @:url_not_accessible@. |
42
+ # | @:url_invalid_response_message@ | A custom message to use in place of @:url_invalid_response@. |
43
+ #
44
+ # h3. Networkless URL validation
45
+ #
46
+ # | @:scheme@ | A string or array of strings, such as "http" or "ftp", indicating which URL schemes are valid. By default only ==HTTP(S)== URLs are accepted. |
47
+ # | @:default_scheme@ | A default URL scheme to try for improper URLs. If this is set to, e.g., "http", then when a URL like "whoops.com" is given (which would otherwise fail due to an improper format), "http://whoops.com" will be tried instead. |
48
+ #
49
+ # h3. Over-the-network URL validation
50
+ #
51
+ # The HTTPI gem is used to provide a generic interface to whatever HTTP client
52
+ # you wish to use. This allows you to drop in, e.g., a Curl client if you want.
53
+ # You can set the HTTPI adapter with the @:httpi_adapter@ option.
54
+ #
55
+ # | @:check_host@ | If @true@, the validator will perform a network test to verify that it can connect to the server and access the host (at the "/" path). This check will only be performed for ==HTTP(S)== URLs. |
56
+ # | @:check_path@ | An integer or symbol (or array of integers or symbols), such as 301 or @:moved_permanently@, indicating what response codes are unacceptable. You can also use ranges, and include them in an array, such as @[ :moved_permanently, 400..404, 500..599 ]@. By default, this is @nil@, and therefore only host accessibility is checked. If @true@ is given, uses a default set of invalid error codes (4xx and 5xx). Implies @:check_host@ is also true. |
57
+ # | @:httpi_adapter@ | The HTTPI adapter to use for checking HTTP and HTTPS URLs (default set by the HTTPI gem). |
58
+ #
59
+ # h3. Other options
60
+ #
61
+ # | @:request_callback@ | A proc that receives the request object (for ==HTTP(S)== requests, the @HTTPI::Request@ object) before it is executed. You can use this proc to set, e.g., custom headers or timeouts on the request. |
62
+
63
+ class UrlValidator < ActiveModel::EachValidator
64
+ # @private
65
+ CODES = {
66
+ :continue => 100,
67
+ :switching_protocols => 101,
68
+ :processing => 102,
69
+ :ok => 200,
70
+ :created => 201,
71
+ :accepted => 202,
72
+ :non_authoritative_information => 203,
73
+ :no_content => 204,
74
+ :reset_content => 205,
75
+ :partial_content => 206,
76
+ :multi_status => 207,
77
+ :im_used => 226,
78
+ :multiple_choices => 300,
79
+ :moved_permanently => 301,
80
+ :found => 302,
81
+ :see_other => 303,
82
+ :not_modified => 304,
83
+ :use_proxy => 305,
84
+ :reserved => 306,
85
+ :temporary_redirect => 307,
86
+ :bad_request => 400,
87
+ :unauthorized => 401,
88
+ :payment_required => 402,
89
+ :forbidden => 403,
90
+ :not_found => 404,
91
+ :method_not_allowed => 405,
92
+ :not_acceptable => 406,
93
+ :proxy_authentication_required => 407,
94
+ :request_timeout => 408,
95
+ :conflict => 409,
96
+ :gone => 410,
97
+ :length_required => 411,
98
+ :precondition_failed => 412,
99
+ :request_entity_too_large => 413,
100
+ :request_uri_too_long => 414,
101
+ :unsupported_media_type => 415,
102
+ :requested_range_not_satisfiable => 416,
103
+ :expectation_failed => 417,
104
+ :unprocessable_entity => 422,
105
+ :locked => 423,
106
+ :failed_dependency => 424,
107
+ :upgrade_required => 426,
108
+ :internal_server_error => 500,
109
+ :not_implemented => 501,
110
+ :bad_gateway => 502,
111
+ :service_unavailable => 503,
112
+ :gateway_timeout => 504,
113
+ :http_version_not_supported => 505,
114
+ :variant_also_negotiates => 506,
115
+ :insufficient_storage => 507,
116
+ :not_extended => 510
117
+ }
118
+
119
+
120
+ # @private
121
+ def validate_each(record, attribute, value)
122
+ return if options[:allow_nil] and value.nil?
123
+ return if options[:allow_blank] and value.blank?
124
+
125
+ uri = Addressable::URI.parse(value)
126
+ if uri.scheme.nil? and options[:default_scheme] then
127
+ uri = Addressable::URI.parse("#{options[:default_scheme]}://#{value}")
128
+ end
129
+
130
+ record.errors.add(attribute, options[:invalid_url_message] || :invalid_url) unless url_format_valid?(uri, options)
131
+ record.errors.add(attribute, options[:url_not_accessible_message] || :url_not_accessible) unless response = url_accessible?(uri, options)
132
+ record.errors.add(attribute, options[:url_invalid_response_message] || :url_invalid_response) unless url_response_valid?(response, options)
133
+ end
134
+
135
+ private
136
+
137
+ def url_format_valid?(uri, options)
138
+ return false unless Array.wrap(options[:scheme] || %w( http https )).include?(uri.scheme)
139
+
140
+ case uri.scheme
141
+ when 'http', 'https'
142
+ return http_url_format_valid?(uri)
143
+ else
144
+ return true
145
+ end
146
+ end
147
+
148
+ def http_url_format_valid?(uri)
149
+ uri.host.present? and not uri.path.nil?
150
+ end
151
+
152
+ def url_accessible?(uri, options)
153
+ return true unless options[:check_host] or options[:check_path]
154
+
155
+ check_host = options[:check_host]
156
+ check_host ||= %w( http https ) if options[:check_path]
157
+ if (schemes = Array.wrap(check_host)) and schemes.all? { |scheme| scheme.kind_of?(String) } then
158
+ return true unless schemes.include?(uri.scheme)
159
+ end
160
+
161
+ case uri.scheme
162
+ when 'http', 'https'
163
+ return http_url_accessible?(uri, options)
164
+ else
165
+ return true
166
+ end
167
+ end
168
+
169
+ def http_url_accessible?(uri, options)
170
+ request = HTTPI::Request.new(uri.to_s)
171
+ options[:request_callback].call(request) if options[:request_callback].respond_to?(:call)
172
+ return HTTPI.get(request, options[:httpi_adapter])
173
+ rescue
174
+ return false
175
+ end
176
+
177
+ def url_response_valid?(response, options)
178
+ return true unless response.kind_of?(HTTPI::Response) and options[:check_path]
179
+ response_codes = options[:check_path] == true ? [400..499, 500..599] : Array.wrap(options[:check_path]).flatten
180
+ return response_codes.none? do |code| # it's good if it's not a bad response
181
+ case code # and it's a bad response if...
182
+ when Range
183
+ code.include? response.code
184
+ when Fixnum
185
+ code == response.code
186
+ when Symbol
187
+ CODES.include?(code) && CODES[code] == response.code
188
+ else # be generous and treat it as a non-match if we don't know what it is
189
+ false
190
+ end
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,13 @@
1
+ require 'bundler'
2
+ Bundler.require :default, :development
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+
7
+ require 'url_validation'
8
+ require 'active_model'
9
+ require 'active_support/core_ext/kernel/singleton_class'
10
+
11
+ RSpec.configure do |c|
12
+
13
+ end
@@ -0,0 +1,231 @@
1
+ require 'spec_helper'
2
+
3
+ class Record
4
+ extend ActiveModel::Translation
5
+ include ActiveModel::Validations
6
+ attr_accessor :field
7
+ end
8
+
9
+ describe UrlValidator do
10
+ before :each do
11
+ @record = Record.new
12
+ end
13
+
14
+ context "[basic]" do
15
+ it "should allow nil if :allow_nil is set" do
16
+ @validator = UrlValidator.new(:attributes => [ :field ], :allow_nil => true)
17
+ @validator.validate_each(@record, :field, nil)
18
+ @record.errors.should be_empty
19
+ end
20
+
21
+ it "should allow \"\" if :allow_blank is set" do
22
+ @validator = UrlValidator.new(:attributes => [ :field ], :allow_blank => true)
23
+ @validator.validate_each(@record, :field, "")
24
+ @record.errors.should be_empty
25
+ end
26
+ end
27
+
28
+ context "[format]" do
29
+ it "should only allow HTTP URLs if :scheme is set to 'http'" do
30
+ @validator = UrlValidator.new(:attributes => [ :field ], :scheme => 'http')
31
+ @validator.validate_each(@record, :field, "http://www.apple.com")
32
+ @record.errors.should be_empty
33
+
34
+ @validator.validate_each(@record, :field, "https://www.apple.com")
35
+ @record.errors[:field].first.should include('invalid_url')
36
+ end
37
+
38
+ it "should only allow HTTP and HTTPS URLs if :scheme is set to %w( http https )" do
39
+ @validator = UrlValidator.new(:attributes => [ :field ], :scheme => %w( http https ))
40
+ @validator.validate_each(@record, :field, "http://www.apple.com")
41
+ @record.errors.should be_empty
42
+ @validator.validate_each(@record, :field, "https://www.apple.com")
43
+ @record.errors.should be_empty
44
+
45
+ @validator.validate_each(@record, :field, "ftp://www.apple.com")
46
+ @record.errors[:field].first.should include('invalid_url')
47
+ end
48
+
49
+ it "should try a default scheme if :default_scheme is set" do
50
+ @validator = UrlValidator.new(:attributes => [ :field ], :scheme => 'http', :default_scheme => 'http')
51
+ @validator.validate_each(@record, :field, "www.apple.com")
52
+ @record.errors.should be_empty
53
+ end
54
+
55
+ context "[HTTP(S)]" do
56
+ it "should not allow garbage URLs that still somehow pass the ridiculously open-ended RFC" do
57
+ @validator = UrlValidator.new(:attributes => [ :field ])
58
+
59
+ [
60
+ 'http:sdg.sdfg/',
61
+ 'http/sdg.d',
62
+ 'http:://dsfg.dsfg/',
63
+ 'http//sdg..g',
64
+ 'http://://sdfg.f',
65
+ 'http://dsaf.com://sdg.com'
66
+ ].each do |uri|
67
+ @record.errors.clear
68
+ @validator.validate_each(@record, :field, "www.apple.com")
69
+ @record.errors[:field].first.should include('invalid_url')
70
+ end
71
+ end
72
+ end
73
+ end
74
+
75
+ context "[accessibility]" do
76
+ context "[:check_host]" do
77
+ it "should only validate if the host is accessible when :check_host is set" do
78
+ @validator = UrlValidator.new(:attributes => [ :field ])
79
+ @validator.validate_each(@record, :field, "http://www.invalid.tld")
80
+ @record.errors.should be_empty
81
+
82
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_host => true)
83
+ @validator.validate_each(@record, :field, "http://www.invalid.tld")
84
+ @record.errors[:field].first.should include('url_not_accessible')
85
+ end
86
+
87
+ it "should not perform the accessibility check if :check_host is set to 'http' and the URL scheme is not HTTP" do
88
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_host => 'http')
89
+ @validator.validate_each(@record, :field, "https://www.invalid.tld")
90
+ @record.errors.should be_empty
91
+ end
92
+
93
+ it "should only validate if the host is accessible when :check_host is set to 'http' and the URL scheme is HTTP" do
94
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_host => 'http')
95
+ @validator.validate_each(@record, :field, "http://www.invalid.tld")
96
+ @record.errors[:field].first.should include('url_not_accessible')
97
+ end
98
+
99
+ it "should not perform the accessibility check if :check_host is set to %w( http https ) and the URL scheme is not HTTP(S)" do
100
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_host => %w( http https ), :scheme => %w( ftp http https ))
101
+ @validator.validate_each(@record, :field, "ftp://www.invalid.tld")
102
+ @record.errors.should be_empty
103
+ end
104
+
105
+ it "should only validate if the host is accessible when :check_host is set to %w( http https ) and the URL scheme is HTTP(S)" do
106
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_host => %w( http https ))
107
+ @validator.validate_each(@record, :field, "http://www.invalid.tld")
108
+ @record.errors[:field].first.should include('url_not_accessible')
109
+
110
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_host => %w( http https ))
111
+ @validator.validate_each(@record, :field, "https://www.invalid.tld")
112
+ @record.errors[:field].first.should include('url_not_accessible')
113
+ end
114
+
115
+ it "should only validate the host" do
116
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_host => true)
117
+ @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf")
118
+ @record.errors.should be_empty
119
+ end
120
+ end
121
+
122
+ context "[:check_path]" do
123
+ it "should not validate if the response code is equal to the Fixnum value of this option" do
124
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_path => 404)
125
+ @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf")
126
+ @record.errors[:field].first.should include('url_invalid_response')
127
+
128
+ @record.errors.clear
129
+
130
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_path => 405)
131
+ @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf")
132
+ @record.errors[:field].should be_empty
133
+ end
134
+
135
+ it "should not validate if the response code is equal to the Symbol value of this option" do
136
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_path => :not_found)
137
+ @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf")
138
+ @record.errors[:field].first.should include('url_invalid_response')
139
+
140
+ @record.errors.clear
141
+
142
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_path => :unauthorized)
143
+ @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf")
144
+ @record.errors[:field].should be_empty
145
+ end
146
+
147
+ it "should not validate if the response code is within the Range value of this option" do
148
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_path => 400..499)
149
+ @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf")
150
+ @record.errors[:field].first.should include('url_invalid_response')
151
+
152
+ @record.errors.clear
153
+
154
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_path => 500..599)
155
+ @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf")
156
+ @record.errors[:field].should be_empty
157
+ end
158
+
159
+ it "should not validate if the response code is equal to the Fixnum value contained in the Array value of this option" do
160
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_path => [ 404, 405 ])
161
+ @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf")
162
+ @record.errors[:field].first.should include('url_invalid_response')
163
+
164
+ @record.errors.clear
165
+
166
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_path => [ 405, 406 ])
167
+ @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf")
168
+ @record.errors[:field].should be_empty
169
+ end
170
+
171
+ it "should not validate if the response code is equal to the Symbol value contained in the Array value of this option" do
172
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_path => [ :not_found, :unauthorized ])
173
+ @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf")
174
+ @record.errors[:field].first.should include('url_invalid_response')
175
+
176
+ @record.errors.clear
177
+
178
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_path => [ :unauthorized, :moved_permanently ])
179
+ @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf")
180
+ @record.errors[:field].should be_empty
181
+ end
182
+
183
+ it "should not validate if the response code is equal to the Range value contained in the Array value of this option" do
184
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_path => [ 400..499, 500..599 ])
185
+ @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf")
186
+ @record.errors[:field].first.should include('url_invalid_response')
187
+
188
+ @record.errors.clear
189
+
190
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_path => [ 500..599, 300..399 ])
191
+ @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf")
192
+ @record.errors[:field].should be_empty
193
+ end
194
+
195
+ it "should skip validation by default" do
196
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_path => nil)
197
+ @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf")
198
+ @record.errors[:field].should be_empty
199
+ end
200
+
201
+ it "should not validate 4xx and 5xx response codes if the value is true" do
202
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_path => true)
203
+ @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf")
204
+ @record.errors[:field].first.should include('url_invalid_response')
205
+ end
206
+
207
+ it "should skip validation for non-HTTP URLs" do
208
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_path => true, :scheme => %w( ftp http https ))
209
+ @validator.validate_each(@record, :field, "ftp://ftp.sdgasdgohaodgh.com/sdgjsdg")
210
+ @record.errors[:field].should be_empty
211
+ end
212
+ end
213
+
214
+ context "[:httpi_adapter]" do
215
+ it "should use the specified HTTPI adapter" do
216
+ @validator = UrlValidator.new(:attributes => [ :field ], :httpi_adapter => :curl, :check_host => true)
217
+ HTTPI.should_receive(:get).once.with(an_instance_of(HTTPI::Request), :curl).and_return(false)
218
+ @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf")
219
+ end
220
+ end
221
+
222
+ context "[:request_callback]" do
223
+ it "should be yielded the HTTPI request" do
224
+ called = false
225
+ @validator = UrlValidator.new(:attributes => [ :field ], :check_host => true, :request_callback => lambda { |request| called = true; request.should be_kind_of(HTTPI::Request) })
226
+ @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf")
227
+ called.should be_true
228
+ end
229
+ end
230
+ end
231
+ end
@@ -0,0 +1,72 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{url_validation}
8
+ s.version = "1.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = [%q{Tim Morgan}]
12
+ s.date = %q{2011-05-27}
13
+ s.description = %q{A simple, localizable EachValidator for URL fields in ActiveRecord 3.0.}
14
+ s.email = %q{git@timothymorgan.info}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.textile"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "LICENSE",
25
+ "README.textile",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "lib/url_validation.rb",
29
+ "spec/spec_helper.rb",
30
+ "spec/url_validator_spec.rb",
31
+ "url_validation.gemspec"
32
+ ]
33
+ s.homepage = %q{http://github.com/riscfuture/url_validation}
34
+ s.require_paths = [%q{lib}]
35
+ s.required_ruby_version = Gem::Requirement.new(">= 1.8.7")
36
+ s.rubygems_version = %q{1.8.3}
37
+ s.summary = %q{Simple URL validation in Rails 3}
38
+
39
+ if s.respond_to? :specification_version then
40
+ s.specification_version = 3
41
+
42
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
43
+ s.add_runtime_dependency(%q<addressable>, [">= 0"])
44
+ s.add_runtime_dependency(%q<activesupport>, [">= 0"])
45
+ s.add_runtime_dependency(%q<activerecord>, [">= 0"])
46
+ s.add_runtime_dependency(%q<httpi>, [">= 0"])
47
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
48
+ s.add_development_dependency(%q<yard>, [">= 0"])
49
+ s.add_development_dependency(%q<RedCloth>, [">= 0"])
50
+ s.add_development_dependency(%q<rspec>, [">= 0"])
51
+ else
52
+ s.add_dependency(%q<addressable>, [">= 0"])
53
+ s.add_dependency(%q<activesupport>, [">= 0"])
54
+ s.add_dependency(%q<activerecord>, [">= 0"])
55
+ s.add_dependency(%q<httpi>, [">= 0"])
56
+ s.add_dependency(%q<jeweler>, [">= 0"])
57
+ s.add_dependency(%q<yard>, [">= 0"])
58
+ s.add_dependency(%q<RedCloth>, [">= 0"])
59
+ s.add_dependency(%q<rspec>, [">= 0"])
60
+ end
61
+ else
62
+ s.add_dependency(%q<addressable>, [">= 0"])
63
+ s.add_dependency(%q<activesupport>, [">= 0"])
64
+ s.add_dependency(%q<activerecord>, [">= 0"])
65
+ s.add_dependency(%q<httpi>, [">= 0"])
66
+ s.add_dependency(%q<jeweler>, [">= 0"])
67
+ s.add_dependency(%q<yard>, [">= 0"])
68
+ s.add_dependency(%q<RedCloth>, [">= 0"])
69
+ s.add_dependency(%q<rspec>, [">= 0"])
70
+ end
71
+ end
72
+
metadata ADDED
@@ -0,0 +1,153 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: url_validation
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 1.0.0
6
+ platform: ruby
7
+ authors:
8
+ - Tim Morgan
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-05-27 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: addressable
17
+ requirement: &id001 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: activesupport
28
+ requirement: &id002 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: activerecord
39
+ requirement: &id003 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: "0"
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: httpi
50
+ requirement: &id004 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: *id004
59
+ - !ruby/object:Gem::Dependency
60
+ name: jeweler
61
+ requirement: &id005 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: *id005
70
+ - !ruby/object:Gem::Dependency
71
+ name: yard
72
+ requirement: &id006 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: *id006
81
+ - !ruby/object:Gem::Dependency
82
+ name: RedCloth
83
+ requirement: &id007 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: "0"
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: *id007
92
+ - !ruby/object:Gem::Dependency
93
+ name: rspec
94
+ requirement: &id008 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: "0"
100
+ type: :development
101
+ prerelease: false
102
+ version_requirements: *id008
103
+ description: A simple, localizable EachValidator for URL fields in ActiveRecord 3.0.
104
+ email: git@timothymorgan.info
105
+ executables: []
106
+
107
+ extensions: []
108
+
109
+ extra_rdoc_files:
110
+ - LICENSE
111
+ - README.textile
112
+ files:
113
+ - .document
114
+ - .rspec
115
+ - Gemfile
116
+ - Gemfile.lock
117
+ - LICENSE
118
+ - README.textile
119
+ - Rakefile
120
+ - VERSION
121
+ - lib/url_validation.rb
122
+ - spec/spec_helper.rb
123
+ - spec/url_validator_spec.rb
124
+ - url_validation.gemspec
125
+ homepage: http://github.com/riscfuture/url_validation
126
+ licenses: []
127
+
128
+ post_install_message:
129
+ rdoc_options: []
130
+
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ none: false
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: 1.8.7
139
+ required_rubygems_version: !ruby/object:Gem::Requirement
140
+ none: false
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: "0"
145
+ requirements: []
146
+
147
+ rubyforge_project:
148
+ rubygems_version: 1.8.3
149
+ signing_key:
150
+ specification_version: 3
151
+ summary: Simple URL validation in Rails 3
152
+ test_files: []
153
+