From 7321c8fd96b22c6806b36263aa00dad117106bcc Mon Sep 17 00:00:00 2001 From: Tim Morgan Date: Tue, 23 Apr 2013 20:53:21 -0700 Subject: [PATCH 01/14] Update Gemfile source --- Gemfile | 2 +- Gemfile.lock | 72 +++++++++++++++++++++++++++------------------------- 2 files changed, 39 insertions(+), 35 deletions(-) diff --git a/Gemfile b/Gemfile index b6a9705..f35b878 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,4 @@ -source :rubygems +source 'https://rubygems.org' gem 'addressable', :require => 'addressable/uri' # for unicode URIs gem 'activesupport' diff --git a/Gemfile.lock b/Gemfile.lock index bbf69f5..b39355a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,43 +1,47 @@ GEM - remote: http://rubygems.org/ + remote: https://rubygems.org/ specs: - RedCloth (4.2.7) - activemodel (3.0.7) - activesupport (= 3.0.7) - builder (~> 2.1.2) - i18n (~> 0.5.0) - activerecord (3.0.7) - activemodel (= 3.0.7) - activesupport (= 3.0.7) - arel (~> 2.0.2) - tzinfo (~> 0.3.23) - activesupport (3.0.7) - addressable (2.2.6) - arel (2.0.10) - builder (2.1.2) - diff-lcs (1.1.2) + RedCloth (4.2.9) + activemodel (3.2.13) + activesupport (= 3.2.13) + builder (~> 3.0.0) + activerecord (3.2.13) + activemodel (= 3.2.13) + activesupport (= 3.2.13) + arel (~> 3.0.2) + tzinfo (~> 0.3.29) + activesupport (3.2.13) + i18n (= 0.6.1) + multi_json (~> 1.0) + addressable (2.3.4) + arel (3.0.2) + builder (3.0.4) + diff-lcs (1.2.4) git (1.2.5) - httpi (0.9.4) - pyu-ntlm-http (>= 0.1.3.1) + httpi (2.0.2) rack - i18n (0.5.0) - jeweler (1.6.0) - bundler (~> 1.0.0) + i18n (0.6.1) + jeweler (1.8.4) + bundler (~> 1.0) git (>= 1.2.5) rake - pyu-ntlm-http (0.1.3.1) - rack (1.3.0) - rake (0.9.0) - rspec (2.6.0) - rspec-core (~> 2.6.0) - rspec-expectations (~> 2.6.0) - rspec-mocks (~> 2.6.0) - rspec-core (2.6.3) - rspec-expectations (2.6.0) - diff-lcs (~> 1.1.2) - rspec-mocks (2.6.0) - tzinfo (0.3.27) - yard (0.7.1) + rdoc + json (1.7.7) + multi_json (1.7.2) + rack (1.5.2) + rake (10.0.4) + rdoc (4.0.1) + json (~> 1.4) + rspec (2.13.0) + rspec-core (~> 2.13.0) + rspec-expectations (~> 2.13.0) + rspec-mocks (~> 2.13.0) + rspec-core (2.13.1) + rspec-expectations (2.13.0) + diff-lcs (>= 1.1.3, < 2.0) + rspec-mocks (2.13.1) + tzinfo (0.3.37) + yard (0.8.6.1) PLATFORMS ruby From 97e31165e75a96ec5457b13eefd362e75cf896c4 Mon Sep 17 00:00:00 2001 From: Tim Morgan Date: Fri, 7 Nov 2014 17:21:43 -0800 Subject: [PATCH 02/14] Gem updates --- Gemfile.lock | 107 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 73 insertions(+), 34 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index b39355a..e66d772 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,46 +2,85 @@ GEM remote: https://rubygems.org/ specs: RedCloth (4.2.9) - activemodel (3.2.13) - activesupport (= 3.2.13) - builder (~> 3.0.0) - activerecord (3.2.13) - activemodel (= 3.2.13) - activesupport (= 3.2.13) - arel (~> 3.0.2) - tzinfo (~> 0.3.29) - activesupport (3.2.13) - i18n (= 0.6.1) - multi_json (~> 1.0) - addressable (2.3.4) - arel (3.0.2) - builder (3.0.4) - diff-lcs (1.2.4) - git (1.2.5) - httpi (2.0.2) + activemodel (4.1.7) + activesupport (= 4.1.7) + builder (~> 3.1) + activerecord (4.1.7) + activemodel (= 4.1.7) + activesupport (= 4.1.7) + arel (~> 5.0.0) + activesupport (4.1.7) + i18n (~> 0.6, >= 0.6.9) + json (~> 1.7, >= 1.7.7) + minitest (~> 5.1) + thread_safe (~> 0.1) + tzinfo (~> 1.1) + addressable (2.3.6) + arel (5.0.1.20140414130214) + builder (3.2.2) + descendants_tracker (0.0.4) + thread_safe (~> 0.3, >= 0.3.1) + diff-lcs (1.2.5) + faraday (0.9.0) + multipart-post (>= 1.2, < 3) + git (1.2.8) + github_api (0.12.2) + addressable (~> 2.3) + descendants_tracker (~> 0.0.4) + faraday (~> 0.8, < 0.10) + hashie (>= 3.3) + multi_json (>= 1.7.5, < 2.0) + nokogiri (~> 1.6.3) + oauth2 + hashie (3.3.1) + highline (1.6.21) + httpi (2.2.7) rack - i18n (0.6.1) - jeweler (1.8.4) - bundler (~> 1.0) + i18n (0.6.11) + jeweler (2.0.1) + builder + bundler (>= 1.0) git (>= 1.2.5) + github_api + highline (>= 1.6.15) + nokogiri (>= 1.5.10) rake rdoc - json (1.7.7) - multi_json (1.7.2) + json (1.8.1) + jwt (1.0.0) + mini_portile (0.6.1) + minitest (5.4.2) + multi_json (1.10.1) + multi_xml (0.5.5) + multipart-post (2.0.0) + nokogiri (1.6.4.1) + mini_portile (~> 0.6.0) + oauth2 (1.0.0) + faraday (>= 0.8, < 0.10) + jwt (~> 1.0) + multi_json (~> 1.3) + multi_xml (~> 0.5) + rack (~> 1.2) rack (1.5.2) - rake (10.0.4) - rdoc (4.0.1) + rake (10.3.2) + rdoc (4.1.2) json (~> 1.4) - rspec (2.13.0) - rspec-core (~> 2.13.0) - rspec-expectations (~> 2.13.0) - rspec-mocks (~> 2.13.0) - rspec-core (2.13.1) - rspec-expectations (2.13.0) - diff-lcs (>= 1.1.3, < 2.0) - rspec-mocks (2.13.1) - tzinfo (0.3.37) - yard (0.8.6.1) + rspec (3.1.0) + rspec-core (~> 3.1.0) + rspec-expectations (~> 3.1.0) + rspec-mocks (~> 3.1.0) + rspec-core (3.1.7) + rspec-support (~> 3.1.0) + rspec-expectations (3.1.2) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.1.0) + rspec-mocks (3.1.3) + rspec-support (~> 3.1.0) + rspec-support (3.1.2) + thread_safe (0.3.4) + tzinfo (1.2.2) + thread_safe (~> 0.1) + yard (0.8.7.6) PLATFORMS ruby From c0e3d74f87823ca41250b1a85bafa57685c50b7c Mon Sep 17 00:00:00 2001 From: Tim Morgan Date: Fri, 7 Nov 2014 17:22:16 -0800 Subject: [PATCH 03/14] Delete response callback option --- lib/url_validation.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/url_validation.rb b/lib/url_validation.rb index 0313568..05b5cfb 100644 --- a/lib/url_validation.rb +++ b/lib/url_validation.rb @@ -59,7 +59,6 @@ # h3. Other options # # | @: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. | -# | @:response_callback@ | A proc that receives the response object after it is executed by @:check_path@, when it is enabled. This is useful for checking redirect URL's, etc. | class UrlValidator < ActiveModel::EachValidator # @private @@ -130,7 +129,7 @@ def validate_each(record, attribute, value) record.errors.add(attribute, options[:invalid_url_message] || :invalid_url) unless url_format_valid?(uri, options) record.errors.add(attribute, options[:url_not_accessible_message] || :url_not_accessible) unless response = url_accessible?(uri, options) - record.errors.add(attribute, options[:url_invalid_response_message] || :url_invalid_response) unless url_response_valid?(response, record, attribute, value, options) + record.errors.add(attribute, options[:url_invalid_response_message] || :url_invalid_response) unless url_response_valid?(response, options) end private @@ -175,9 +174,8 @@ def http_url_accessible?(uri, options) return false end - def url_response_valid?(response, record, attribute, value, options) + def url_response_valid?(response, options) return true unless response.kind_of?(HTTPI::Response) and options[:check_path] - options[:response_callback].call(response, record, attribute, value) if options[:response_callback].respond_to?(:call) response_codes = options[:check_path] == true ? [400..499, 500..599] : Array.wrap(options[:check_path]).flatten return response_codes.none? do |code| # it's good if it's not a bad response case code # and it's a bad response if... From f8ef65e26961215420cc9212d82e0c76bb2e5a3e Mon Sep 17 00:00:00 2001 From: Tim Morgan Date: Fri, 7 Nov 2014 17:25:14 -0800 Subject: [PATCH 04/14] Don't attempt to validate blank URLs; Better URL validation --- lib/url_validation.rb | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/url_validation.rb b/lib/url_validation.rb index 05b5cfb..39ba082 100644 --- a/lib/url_validation.rb +++ b/lib/url_validation.rb @@ -119,12 +119,16 @@ class UrlValidator < ActiveModel::EachValidator # @private def validate_each(record, attribute, value) - return if options[:allow_nil] and value.nil? - return if options[:allow_blank] and value.blank? - - uri = Addressable::URI.parse(value) - if uri.scheme.nil? and options[:default_scheme] then - uri = Addressable::URI.parse("#{options[:default_scheme]}://#{value}") + return if value.blank? + + begin + uri = Addressable::URI.parse(value) + if uri.scheme.nil? and options[:default_scheme] then + uri = Addressable::URI.parse("#{options[:default_scheme]}://#{value}") + end + rescue Addressable::URI::InvalidURIError + record.errors.add(attribute, options[:invalid_url_message] || :invalid_url) unless url_format_valid?(uri, options) + return end record.errors.add(attribute, options[:invalid_url_message] || :invalid_url) unless url_format_valid?(uri, options) From cd0c6d593d18cb4cd8bd721bddc0bba5cd3469ae Mon Sep 17 00:00:00 2001 From: Tim Morgan Date: Fri, 7 Nov 2014 17:25:23 -0800 Subject: [PATCH 05/14] RVM/rbenv files --- .ruby-gemset | 1 + .ruby-version | 1 + 2 files changed, 2 insertions(+) create mode 100644 .ruby-gemset create mode 100644 .ruby-version diff --git a/.ruby-gemset b/.ruby-gemset new file mode 100644 index 0000000..f26935d --- /dev/null +++ b/.ruby-gemset @@ -0,0 +1 @@ +url_validation diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..7d2ed7c --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +2.1.4 From d50bbd944c40b913998ae7871fab52a0888f2b1e Mon Sep 17 00:00:00 2001 From: Tim Morgan Date: Fri, 7 Nov 2014 17:31:59 -0800 Subject: [PATCH 06/14] Update RSpec and fix specs --- .rspec | 3 +- lib/url_validation.rb | 1 + spec/url_validator_spec.rb | 79 +++++++++++++++++--------------------- 3 files changed, 38 insertions(+), 45 deletions(-) diff --git a/.rspec b/.rspec index 62c58f0..8c18f1a 100644 --- a/.rspec +++ b/.rspec @@ -1 +1,2 @@ --cfs +--format documentation +--color diff --git a/lib/url_validation.rb b/lib/url_validation.rb index 39ba082..bcb710b 100644 --- a/lib/url_validation.rb +++ b/lib/url_validation.rb @@ -2,6 +2,7 @@ require 'httpi' require 'active_support/core_ext/hash/except' require 'active_model/validator' +require 'active_support/core_ext/array/wrap' # Validates URLs. Uses the following I18n error message keys: # diff --git a/spec/url_validator_spec.rb b/spec/url_validator_spec.rb index 5e6a365..6b2d6d5 100644 --- a/spec/url_validator_spec.rb +++ b/spec/url_validator_spec.rb @@ -15,13 +15,13 @@ class Record it "should allow nil if :allow_nil is set" do @validator = UrlValidator.new(:attributes => [ :field ], :allow_nil => true) @validator.validate_each(@record, :field, nil) - @record.errors.should be_empty + expect(@record.errors).to be_empty end it "should allow \"\" if :allow_blank is set" do @validator = UrlValidator.new(:attributes => [ :field ], :allow_blank => true) @validator.validate_each(@record, :field, "") - @record.errors.should be_empty + expect(@record.errors).to be_empty end end @@ -29,27 +29,27 @@ class Record it "should only allow HTTP URLs if :scheme is set to 'http'" do @validator = UrlValidator.new(:attributes => [ :field ], :scheme => 'http') @validator.validate_each(@record, :field, "http://www.apple.com") - @record.errors.should be_empty + expect(@record.errors).to be_empty @validator.validate_each(@record, :field, "https://www.apple.com") - @record.errors[:field].first.should include('invalid_url') + expect(@record.errors[:field].first).to include('invalid_url') end it "should only allow HTTP and HTTPS URLs if :scheme is set to %w( http https )" do @validator = UrlValidator.new(:attributes => [ :field ], :scheme => %w( http https )) @validator.validate_each(@record, :field, "http://www.apple.com") - @record.errors.should be_empty + expect(@record.errors).to be_empty @validator.validate_each(@record, :field, "https://www.apple.com") - @record.errors.should be_empty + expect(@record.errors).to be_empty @validator.validate_each(@record, :field, "ftp://www.apple.com") - @record.errors[:field].first.should include('invalid_url') + expect(@record.errors[:field].first).to include('invalid_url') end it "should try a default scheme if :default_scheme is set" do @validator = UrlValidator.new(:attributes => [ :field ], :scheme => 'http', :default_scheme => 'http') @validator.validate_each(@record, :field, "www.apple.com") - @record.errors.should be_empty + expect(@record.errors).to be_empty end context "[HTTP(S)]" do @@ -66,7 +66,7 @@ class Record ].each do |uri| @record.errors.clear @validator.validate_each(@record, :field, "www.apple.com") - @record.errors[:field].first.should include('invalid_url') + expect(@record.errors[:field].first).to include('invalid_url') end end end @@ -77,45 +77,45 @@ class Record it "should only validate if the host is accessible when :check_host is set" do @validator = UrlValidator.new(:attributes => [ :field ]) @validator.validate_each(@record, :field, "http://www.invalid.tld") - @record.errors.should be_empty + expect(@record.errors).to be_empty @validator = UrlValidator.new(:attributes => [ :field ], :check_host => true) @validator.validate_each(@record, :field, "http://www.invalid.tld") - @record.errors[:field].first.should include('url_not_accessible') + expect(@record.errors[:field].first).to include('url_not_accessible') end it "should not perform the accessibility check if :check_host is set to 'http' and the URL scheme is not HTTP" do @validator = UrlValidator.new(:attributes => [ :field ], :check_host => 'http') @validator.validate_each(@record, :field, "https://www.invalid.tld") - @record.errors.should be_empty + expect(@record.errors).to be_empty end it "should only validate if the host is accessible when :check_host is set to 'http' and the URL scheme is HTTP" do @validator = UrlValidator.new(:attributes => [ :field ], :check_host => 'http') @validator.validate_each(@record, :field, "http://www.invalid.tld") - @record.errors[:field].first.should include('url_not_accessible') + expect(@record.errors[:field].first).to include('url_not_accessible') end 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 @validator = UrlValidator.new(:attributes => [ :field ], :check_host => %w( http https ), :scheme => %w( ftp http https )) @validator.validate_each(@record, :field, "ftp://www.invalid.tld") - @record.errors.should be_empty + expect(@record.errors).to be_empty end 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 @validator = UrlValidator.new(:attributes => [ :field ], :check_host => %w( http https )) @validator.validate_each(@record, :field, "http://www.invalid.tld") - @record.errors[:field].first.should include('url_not_accessible') + expect(@record.errors[:field].first).to include('url_not_accessible') @validator = UrlValidator.new(:attributes => [ :field ], :check_host => %w( http https )) @validator.validate_each(@record, :field, "https://www.invalid.tld") - @record.errors[:field].first.should include('url_not_accessible') + expect(@record.errors[:field].first).to include('url_not_accessible') end it "should only validate the host" do @validator = UrlValidator.new(:attributes => [ :field ], :check_host => true) @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") - @record.errors.should be_empty + expect(@record.errors).to be_empty end end @@ -123,98 +123,98 @@ class Record it "should not validate if the response code is equal to the Fixnum value of this option" do @validator = UrlValidator.new(:attributes => [ :field ], :check_path => 404) @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") - @record.errors[:field].first.should include('url_invalid_response') + expect(@record.errors[:field].first).to include('url_invalid_response') @record.errors.clear @validator = UrlValidator.new(:attributes => [ :field ], :check_path => 405) @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") - @record.errors[:field].should be_empty + expect(@record.errors[:field]).to be_empty end it "should not validate if the response code is equal to the Symbol value of this option" do @validator = UrlValidator.new(:attributes => [ :field ], :check_path => :not_found) @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") - @record.errors[:field].first.should include('url_invalid_response') + expect(@record.errors[:field].first).to include('url_invalid_response') @record.errors.clear @validator = UrlValidator.new(:attributes => [ :field ], :check_path => :unauthorized) @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") - @record.errors[:field].should be_empty + expect(@record.errors[:field]).to be_empty end it "should not validate if the response code is within the Range value of this option" do @validator = UrlValidator.new(:attributes => [ :field ], :check_path => 400..499) @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") - @record.errors[:field].first.should include('url_invalid_response') + expect(@record.errors[:field].first).to include('url_invalid_response') @record.errors.clear @validator = UrlValidator.new(:attributes => [ :field ], :check_path => 500..599) @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") - @record.errors[:field].should be_empty + expect(@record.errors[:field]).to be_empty end it "should not validate if the response code is equal to the Fixnum value contained in the Array value of this option" do @validator = UrlValidator.new(:attributes => [ :field ], :check_path => [ 404, 405 ]) @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") - @record.errors[:field].first.should include('url_invalid_response') + expect(@record.errors[:field].first).to include('url_invalid_response') @record.errors.clear @validator = UrlValidator.new(:attributes => [ :field ], :check_path => [ 405, 406 ]) @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") - @record.errors[:field].should be_empty + expect(@record.errors[:field]).to be_empty end it "should not validate if the response code is equal to the Symbol value contained in the Array value of this option" do @validator = UrlValidator.new(:attributes => [ :field ], :check_path => [ :not_found, :unauthorized ]) @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") - @record.errors[:field].first.should include('url_invalid_response') + expect(@record.errors[:field].first).to include('url_invalid_response') @record.errors.clear @validator = UrlValidator.new(:attributes => [ :field ], :check_path => [ :unauthorized, :moved_permanently ]) @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") - @record.errors[:field].should be_empty + expect(@record.errors[:field]).to be_empty end it "should not validate if the response code is equal to the Range value contained in the Array value of this option" do @validator = UrlValidator.new(:attributes => [ :field ], :check_path => [ 400..499, 500..599 ]) @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") - @record.errors[:field].first.should include('url_invalid_response') + expect(@record.errors[:field].first).to include('url_invalid_response') @record.errors.clear @validator = UrlValidator.new(:attributes => [ :field ], :check_path => [ 500..599, 300..399 ]) @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") - @record.errors[:field].should be_empty + expect(@record.errors[:field]).to be_empty end it "should skip validation by default" do @validator = UrlValidator.new(:attributes => [ :field ], :check_path => nil) @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") - @record.errors[:field].should be_empty + expect(@record.errors[:field]).to be_empty end it "should not validate 4xx and 5xx response codes if the value is true" do @validator = UrlValidator.new(:attributes => [ :field ], :check_path => true) @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") - @record.errors[:field].first.should include('url_invalid_response') + expect(@record.errors[:field].first).to include('url_invalid_response') end it "should skip validation for non-HTTP URLs" do @validator = UrlValidator.new(:attributes => [ :field ], :check_path => true, :scheme => %w( ftp http https )) @validator.validate_each(@record, :field, "ftp://ftp.sdgasdgohaodgh.com/sdgjsdg") - @record.errors[:field].should be_empty + expect(@record.errors[:field]).to be_empty end end context "[:httpi_adapter]" do it "should use the specified HTTPI adapter" do @validator = UrlValidator.new(:attributes => [ :field ], :httpi_adapter => :curl, :check_host => true) - HTTPI.should_receive(:get).once.with(an_instance_of(HTTPI::Request), :curl).and_return(false) + expect(HTTPI).to receive(:get).once.with(an_instance_of(HTTPI::Request), :curl).and_return(false) @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") end end @@ -222,18 +222,9 @@ class Record context "[:request_callback]" do it "should be yielded the HTTPI request" do called = false - @validator = UrlValidator.new(:attributes => [ :field ], :check_host => true, :request_callback => lambda { |request| called = true; request.should be_kind_of(HTTPI::Request) }) + @validator = UrlValidator.new(:attributes => [ :field ], :check_host => true, :request_callback => lambda { |request| called = true; expect(request).to be_kind_of(HTTPI::Request) }) @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") - called.should be_true - end - end - - context "[:response_callback]" do - it "should be yielded the HTTPI response" do - called = false - @validator = UrlValidator.new(:attributes => [ :field ], :check_path => true, :response_callback => lambda { |response, record, attribute, value| called = true; response.should be_kind_of(HTTPI::Response) }) - @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") - called.should be_true + expect(called).to eql(true) end end end From d2cf23e904a742f3628332cbbfc351bbb6530c9d Mon Sep 17 00:00:00 2001 From: Tim Morgan Date: Fri, 7 Nov 2014 17:32:58 -0800 Subject: [PATCH 07/14] Version 1.1.0 --- VERSION | 2 +- url_validation.gemspec | 25 ++++++++++++++----------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/VERSION b/VERSION index afaf360..1cc5f65 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.0 \ No newline at end of file +1.1.0 \ No newline at end of file diff --git a/url_validation.gemspec b/url_validation.gemspec index 3ad181b..992c4c9 100644 --- a/url_validation.gemspec +++ b/url_validation.gemspec @@ -2,16 +2,18 @@ # DO NOT EDIT THIS FILE DIRECTLY # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec' # -*- encoding: utf-8 -*- +# stub: url_validation 1.1.0 ruby lib Gem::Specification.new do |s| - s.name = %q{url_validation} - s.version = "1.0.0" + s.name = "url_validation" + s.version = "1.1.0" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= - s.authors = [%q{Tim Morgan}] - s.date = %q{2011-05-27} - s.description = %q{A simple, localizable EachValidator for URL fields in ActiveRecord 3.0.} - s.email = %q{git@timothymorgan.info} + s.require_paths = ["lib"] + s.authors = ["Tim Morgan"] + s.date = "2014-11-08" + s.description = "A simple, localizable EachValidator for URL fields in ActiveRecord 3.0." + s.email = "git@timothymorgan.info" s.extra_rdoc_files = [ "LICENSE", "README.textile" @@ -19,6 +21,8 @@ Gem::Specification.new do |s| s.files = [ ".document", ".rspec", + ".ruby-gemset", + ".ruby-version", "Gemfile", "Gemfile.lock", "LICENSE", @@ -30,14 +34,13 @@ Gem::Specification.new do |s| "spec/url_validator_spec.rb", "url_validation.gemspec" ] - s.homepage = %q{http://github.com/riscfuture/url_validation} - s.require_paths = [%q{lib}] + s.homepage = "http://github.com/riscfuture/url_validation" s.required_ruby_version = Gem::Requirement.new(">= 1.8.7") - s.rubygems_version = %q{1.8.3} - s.summary = %q{Simple URL validation in Rails 3} + s.rubygems_version = "2.4.2" + s.summary = "Simple URL validation in Rails 3" if s.respond_to? :specification_version then - s.specification_version = 3 + s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_runtime_dependency(%q, [">= 0"]) From 0f64b87aaba1eaedf596a6bc3831235bb2dac643 Mon Sep 17 00:00:00 2001 From: Tim Morgan Date: Wed, 31 May 2017 15:02:00 -0700 Subject: [PATCH 08/14] Update to Ruby 2.4.1, bump gems, update syntax & style, textile->markdown --- .ruby-version | 2 +- Gemfile | 13 ++- Gemfile.lock | 132 ++++++++++++---------- README.md | 40 +++++++ README.textile | 36 ------ Rakefile | 34 +++--- lib/url_validation.rb | 209 ++++++++++++++++++---------------- spec/url_validator_spec.rb | 223 ++++++++++++++++++------------------- url_validation.gemspec | 4 +- 9 files changed, 361 insertions(+), 332 deletions(-) create mode 100644 README.md delete mode 100644 README.textile diff --git a/.ruby-version b/.ruby-version index 7d2ed7c..005119b 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.1.4 +2.4.1 diff --git a/Gemfile b/Gemfile index f35b878..dbf5df6 100644 --- a/Gemfile +++ b/Gemfile @@ -1,13 +1,18 @@ source 'https://rubygems.org' -gem 'addressable', :require => 'addressable/uri' # for unicode URIs +gem 'addressable', require: 'addressable/uri' # for unicode URIs gem 'activesupport' gem 'activerecord' gem 'httpi' group :development do - gem 'jeweler' - gem 'yard' - gem 'RedCloth', require: 'redcloth' + # PUBLISHING + gem 'juwelier' + + # DOCS + gem 'yard', require: nil + gem 'redcarpet', require: nil + + # SPECS gem 'rspec' end diff --git a/Gemfile.lock b/Gemfile.lock index e66d772..9d1da3a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,96 +1,106 @@ GEM remote: https://rubygems.org/ specs: - RedCloth (4.2.9) - activemodel (4.1.7) - activesupport (= 4.1.7) - builder (~> 3.1) - activerecord (4.1.7) - activemodel (= 4.1.7) - activesupport (= 4.1.7) - arel (~> 5.0.0) - activesupport (4.1.7) - i18n (~> 0.6, >= 0.6.9) - json (~> 1.7, >= 1.7.7) + activemodel (5.1.1) + activesupport (= 5.1.1) + activerecord (5.1.1) + activemodel (= 5.1.1) + activesupport (= 5.1.1) + arel (~> 8.0) + activesupport (5.1.1) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (~> 0.7) minitest (~> 5.1) - thread_safe (~> 0.1) tzinfo (~> 1.1) - addressable (2.3.6) - arel (5.0.1.20140414130214) - builder (3.2.2) + addressable (2.4.0) + arel (8.0.0) + builder (3.2.3) + concurrent-ruby (1.0.5) descendants_tracker (0.0.4) thread_safe (~> 0.3, >= 0.3.1) - diff-lcs (1.2.5) - faraday (0.9.0) + diff-lcs (1.3) + faraday (0.9.2) multipart-post (>= 1.2, < 3) - git (1.2.8) - github_api (0.12.2) - addressable (~> 2.3) + git (1.3.0) + github_api (0.17.0) + addressable (~> 2.4.0) descendants_tracker (~> 0.0.4) faraday (~> 0.8, < 0.10) - hashie (>= 3.3) - multi_json (>= 1.7.5, < 2.0) - nokogiri (~> 1.6.3) - oauth2 - hashie (3.3.1) - highline (1.6.21) - httpi (2.2.7) + hashie (>= 3.4) + mime-types (>= 1.16, < 3.0) + oauth2 (~> 1.0) + hashie (3.5.5) + highline (1.7.8) + httpi (2.4.2) rack - i18n (0.6.11) - jeweler (2.0.1) + socksify + i18n (0.8.4) + juwelier (2.4.5) builder - bundler (>= 1.0) + bundler (>= 1.13) git (>= 1.2.5) github_api highline (>= 1.6.15) + kamelcase (~> 0) nokogiri (>= 1.5.10) + psych (~> 2.2) rake rdoc - json (1.8.1) - jwt (1.0.0) - mini_portile (0.6.1) - minitest (5.4.2) - multi_json (1.10.1) - multi_xml (0.5.5) + semver2 + jwt (1.5.6) + kamelcase (0.0.0) + semver2 (~> 3) + mime-types (2.99.3) + mini_portile2 (2.1.0) + minitest (5.10.2) + multi_json (1.12.1) + multi_xml (0.6.0) multipart-post (2.0.0) - nokogiri (1.6.4.1) - mini_portile (~> 0.6.0) - oauth2 (1.0.0) - faraday (>= 0.8, < 0.10) + nokogiri (1.7.2) + mini_portile2 (~> 2.1.0) + oauth2 (1.3.1) + faraday (>= 0.8, < 0.12) jwt (~> 1.0) multi_json (~> 1.3) multi_xml (~> 0.5) - rack (~> 1.2) - rack (1.5.2) - rake (10.3.2) - rdoc (4.1.2) - json (~> 1.4) - rspec (3.1.0) - rspec-core (~> 3.1.0) - rspec-expectations (~> 3.1.0) - rspec-mocks (~> 3.1.0) - rspec-core (3.1.7) - rspec-support (~> 3.1.0) - rspec-expectations (3.1.2) + rack (>= 1.2, < 3) + psych (2.2.4) + rack (2.0.3) + rake (12.0.0) + rdoc (5.1.0) + redcarpet (3.4.0) + rspec (3.6.0) + rspec-core (~> 3.6.0) + rspec-expectations (~> 3.6.0) + rspec-mocks (~> 3.6.0) + rspec-core (3.6.0) + rspec-support (~> 3.6.0) + rspec-expectations (3.6.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.6.0) + rspec-mocks (3.6.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.1.0) - rspec-mocks (3.1.3) - rspec-support (~> 3.1.0) - rspec-support (3.1.2) - thread_safe (0.3.4) - tzinfo (1.2.2) + rspec-support (~> 3.6.0) + rspec-support (3.6.0) + semver2 (3.4.2) + socksify (1.7.1) + thread_safe (0.3.6) + tzinfo (1.2.3) thread_safe (~> 0.1) - yard (0.8.7.6) + yard (0.9.9) PLATFORMS ruby DEPENDENCIES - RedCloth activerecord activesupport addressable httpi - jeweler + juwelier + redcarpet rspec yard + +BUNDLED WITH + 1.15.0 diff --git a/README.md b/README.md new file mode 100644 index 0000000..5896c84 --- /dev/null +++ b/README.md @@ -0,0 +1,40 @@ +# url_validation + +Simple URL validator for Rails 3. + +| | | +|:------------|:--------------------------------| +| **Author** | Tim Morgan | +| **Version** | 1.0 (May 9, 2011) | +| **License** | Released under the MIT license. | + +## About + +This gem adds a very simple URL format validator to be used with Active Record +models in Rails 3.0. It supports localized error messages. It can validate many +different kinds of URLs, including HTTP and HTTPS. It supports advanced +validation features like sending `HEAD` requests to URLS to verify that they are +valid endpoints. + +## Installation + +Add the gem to your project's Gemfile: + +``` ruby +gem 'url_validation' +``` + +## Usage + +This gem is an `EachValidator`, and thus is used with the `validates` method: + +``` ruby +class User < ActiveRecord::Base + validates :terms_of_service_link, + presence: true, + url: true +end +``` + +There are other options to fine-tune your validation; see the {UrlValidator} +class for more, and for a list of error message localization keys. diff --git a/README.textile b/README.textile deleted file mode 100644 index 713ebcb..0000000 --- a/README.textile +++ /dev/null @@ -1,36 +0,0 @@ -h1. url_validation -- Simple URL validator for Rails 3 - -| *Author* | Tim Morgan | -| *Version* | 1.0 (May 9, 2011) | -| *License* | Released under the MIT license. | - -h2. About - -This gem adds a very simple URL format validator to be used with ActiveRecord -models in Rails 3.0. It supports localized error messages. It can validate many -different kinds of URLs, including HTTP and HTTPS. It supports advanced -validation features like sending @HEAD@ requests to URLS to verify that they are -valid endpoints. - -h2. Installation - -Add the gem to your project's @Gemfile@: - -

-gem 'url_validation'
-
- -h2. Usage - -This gem is an @EachValidator@, and thus is used with the @validates@ method: - -

-class User < ActiveRecord::Base
-  validates :terms_of_service_link,
-            :presence => true,
-            :url => true
-end
-
- -There are other options to fine-tune your validation; see the {UrlValidator} -class for more, and for a list of error message localization keys. diff --git a/Rakefile b/Rakefile index 61308f6..7902e2a 100644 --- a/Rakefile +++ b/Rakefile @@ -9,30 +9,30 @@ rescue Bundler::BundlerError => e end require 'rake' -require 'jeweler' -Jeweler::Tasks.new do |gem| - gem.name = "url_validation" - gem.summary = %Q{Simple URL validation in Rails 3} +require 'juwelier' +Juwelier::Tasks.new do |gem| + gem.name = 'url_validation' + gem.summary = %Q{Simple URL validation in Rails 3+} gem.description = %Q{A simple, localizable EachValidator for URL fields in ActiveRecord 3.0.} - gem.email = "git@timothymorgan.info" - gem.homepage = "http://github.com/riscfuture/url_validation" - gem.authors = [ "Tim Morgan" ] - gem.required_ruby_version = '>= 1.8.7' + gem.email = 'git@timothymorgan.info' + gem.homepage = 'http://github.com/riscfuture/url_validation' + gem.authors = ['Tim Morgan'] + gem.required_ruby_version = '>= 2.0.0' end -Jeweler::RubygemsDotOrgTasks.new +Juwelier::RubygemsDotOrgTasks.new require 'yard' YARD::Rake::YardocTask.new('doc') do |doc| - doc.options << "-m" << "textile" - doc.options << "--protected" << "--no-private" - doc.options << "-r" << "README.textile" - doc.options << "-o" << "doc" - doc.options << "--title" << "url_validation Documentation".inspect - - doc.files = [ 'lib/*_validator.rb', 'README.textile' ] + doc.options << '-m' << 'markdown' << '-M' << 'redcarpet' + doc.options << '--protected' << '--no-private' + doc.options << '-r' << 'README.md' + doc.options << '-o' << 'doc' + doc.options << '--title' << 'url_validation Documentation'.inspect + + doc.files = %w(lib/**/*.rb README.md) end require 'rspec/core/rake_task' RSpec::Core::RakeTask.new -task :default => :spec +task default: :spec diff --git a/lib/url_validation.rb b/lib/url_validation.rb index bcb710b..14509e2 100644 --- a/lib/url_validation.rb +++ b/lib/url_validation.rb @@ -6,142 +6,153 @@ # Validates URLs. Uses the following I18n error message keys: # -# | @invalid_url@ | URL is improperly formatted. | -# | @url_not_accessible@ | Couldn't connect to the URL. | -# | @url_invalid_response@ | Got a bad HTTP response (not of an acceptable type, e.g., 2xx). | +# | | | +# |:-----------------------|:----------------------------------------------------------------| +# | `invalid_url` | URL is improperly formatted. | +# | `url_not_accessible` | Couldn't connect to the URL. | +# | `url_invalid_response` | Got a bad HTTP response (not of an acceptable type, e.g., 2xx). | # # @example Checks the syntax only -# validates :link, :url => true +# validates :link, url: true # # @example Ensures the host is available but does not check the path -# validates :link, :url => { :check_host => true } +# validates :link, url: {check_host: true} # # @example Ensures that the host is available and that a request for the path does not return a 4xx or 5xx response -# validates :link, :url => { :check_path => true } +# validates :link, url: {check_path: true} # # @example Ensures that the host is available and that a request for the path does not return a 3xx, 4xx, or 5xx response -# validates :link, :url => { :check_path => [ 300..399, 400..499, 500..599 ] } +# validates :link, url: {check_path: [300..399, 400..499, 500..599]} # # @example Checks for host accessibility with a custom timeout -# validates :link, :url => { -# :check_host => true, -# :request_callback => lambda { |request| request.timeout = 30 } +# validates :link, url: { +# check_host: true, +# request_callback: ->(request) { request.timeout = 30 } # } # -# h2. Options +# ## Options # -# h3. Basic options +# ### Basic options # -# | @:allow_nil@ | If @true@, @nil@ values are allowed. | -# | @:allow_blank@ | If @true@, @nil@ or empty values are allowed. | +# | | | +# |:---------------|:----------------------------------------------| +# | `:allow_nil` | If `true`, `nil` values are allowed. | +# | `:allow_blank` | If `true`, `nil` or empty values are allowed. | # -# h3. Error messages +# ### Error messages # -# | @:invalid_url_message@ | A custom message to use in place of @:invalid_url@. | -# | @:incorrect_url_type_message@ | A custom message to use in place of @:incorrect_url_type@. | -# | @:url_not_accessible_message@ | A custom message to use in place of @:url_not_accessible@. | -# | @:url_invalid_response_message@ | A custom message to use in place of @:url_invalid_response@. | +# | | | +# |:--------------------------------|:-------------------------------------------------------------| +# | `:invalid_url_message` | A custom message to use in place of `:invalid_url`. | +# | `:incorrect_url_type_message` | A custom message to use in place of `:incorrect_url_type`. | +# | `:url_not_accessible_message` | A custom message to use in place of `:url_not_accessible`. | +# | `:url_invalid_response_message` | A custom message to use in place of `:url_invalid_response`. | # -# h3. Networkless URL validation +# ### Networkless URL validation # -# | @: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. | -# | @: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. | +# | | | +# |:------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +# | `: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. | +# | `: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. | # -# h3. Over-the-network URL validation +# ### Over-the-network URL validation # # The HTTPI gem is used to provide a generic interface to whatever HTTP client # you wish to use. This allows you to drop in, e.g., a Curl client if you want. -# You can set the HTTPI adapter with the @:httpi_adapter@ option. +# You can set the HTTPI adapter with the `:httpi_adapter` option. # -# | @: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. | -# | @: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. | -# | @:httpi_adapter@ | The HTTPI adapter to use for checking HTTP and HTTPS URLs (default set by the HTTPI gem). | +# | | | +# |:-----------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +# | `: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. | +# | `: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. | +# | `:httpi_adapter` | The HTTPI adapter to use for checking HTTP and HTTPS URLs (default set by the HTTPI gem). | # -# h3. Other options +# ### Other options # -# | @: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. | +# | | | +# |:--------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +# | `: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. | class UrlValidator < ActiveModel::EachValidator # @private CODES = { - :continue => 100, - :switching_protocols => 101, - :processing => 102, - :ok => 200, - :created => 201, - :accepted => 202, - :non_authoritative_information => 203, - :no_content => 204, - :reset_content => 205, - :partial_content => 206, - :multi_status => 207, - :im_used => 226, - :multiple_choices => 300, - :moved_permanently => 301, - :found => 302, - :see_other => 303, - :not_modified => 304, - :use_proxy => 305, - :reserved => 306, - :temporary_redirect => 307, - :bad_request => 400, - :unauthorized => 401, - :payment_required => 402, - :forbidden => 403, - :not_found => 404, - :method_not_allowed => 405, - :not_acceptable => 406, - :proxy_authentication_required => 407, - :request_timeout => 408, - :conflict => 409, - :gone => 410, - :length_required => 411, - :precondition_failed => 412, - :request_entity_too_large => 413, - :request_uri_too_long => 414, - :unsupported_media_type => 415, - :requested_range_not_satisfiable => 416, - :expectation_failed => 417, - :unprocessable_entity => 422, - :locked => 423, - :failed_dependency => 424, - :upgrade_required => 426, - :internal_server_error => 500, - :not_implemented => 501, - :bad_gateway => 502, - :service_unavailable => 503, - :gateway_timeout => 504, - :http_version_not_supported => 505, - :variant_also_negotiates => 506, - :insufficient_storage => 507, - :not_extended => 510 + continue: 100, + switching_protocols: 101, + processing: 102, + ok: 200, + created: 201, + accepted: 202, + non_authoritative_information: 203, + no_content: 204, + reset_content: 205, + partial_content: 206, + multi_status: 207, + im_used: 226, + multiple_choices: 300, + moved_permanently: 301, + found: 302, + see_other: 303, + not_modified: 304, + use_proxy: 305, + reserved: 306, + temporary_redirect: 307, + bad_request: 400, + unauthorized: 401, + payment_required: 402, + forbidden: 403, + not_found: 404, + method_not_allowed: 405, + not_acceptable: 406, + proxy_authentication_required: 407, + request_timeout: 408, + conflict: 409, + gone: 410, + length_required: 411, + precondition_failed: 412, + request_entity_too_large: 413, + request_uri_too_long: 414, + unsupported_media_type: 415, + requested_range_not_satisfiable: 416, + expectation_failed: 417, + unprocessable_entity: 422, + locked: 423, + failed_dependency: 424, + upgrade_required: 426, + internal_server_error: 500, + not_implemented: 501, + bad_gateway: 502, + service_unavailable: 503, + gateway_timeout: 504, + http_version_not_supported: 505, + variant_also_negotiates: 506, + insufficient_storage: 507, + not_extended: 510 } - - + # @private def validate_each(record, attribute, value) return if value.blank? begin uri = Addressable::URI.parse(value) - if uri.scheme.nil? and options[:default_scheme] then + if uri.scheme.nil? and options[:default_scheme] uri = Addressable::URI.parse("#{options[:default_scheme]}://#{value}") end rescue Addressable::URI::InvalidURIError - record.errors.add(attribute, options[:invalid_url_message] || :invalid_url) unless url_format_valid?(uri, options) + record.errors.add(attribute, options[:invalid_url_message] || :invalid_url) unless url_format_valid?(uri, options) return end - - record.errors.add(attribute, options[:invalid_url_message] || :invalid_url) unless url_format_valid?(uri, options) - record.errors.add(attribute, options[:url_not_accessible_message] || :url_not_accessible) unless response = url_accessible?(uri, options) + + record.errors.add(attribute, options[:invalid_url_message] || :invalid_url) unless url_format_valid?(uri, options) + record.errors.add(attribute, options[:url_not_accessible_message] || :url_not_accessible) unless response = url_accessible?(uri, options) record.errors.add(attribute, options[:url_invalid_response_message] || :url_invalid_response) unless url_response_valid?(response, options) end - + private - + def url_format_valid?(uri, options) - return false unless Array.wrap(options[:scheme] || %w( http https )).include?(uri.scheme) - + return false unless Array.wrap(options[:scheme] || %w(http https)).include?(uri.scheme) + case uri.scheme when 'http', 'https' return http_url_format_valid?(uri) @@ -149,20 +160,20 @@ def url_format_valid?(uri, options) return true end end - + def http_url_format_valid?(uri) uri.host.present? and not uri.path.nil? end - + def url_accessible?(uri, options) return true unless options[:check_host] or options[:check_path] - + check_host = options[:check_host] - check_host ||= %w( http https ) if options[:check_path] - if (schemes = Array.wrap(check_host)) and schemes.all? { |scheme| scheme.kind_of?(String) } then + check_host ||= %w(http https) if options[:check_path] + if (schemes = Array.wrap(check_host)) and schemes.all? { |scheme| scheme.kind_of?(String) } return true unless schemes.include?(uri.scheme) end - + case uri.scheme when 'http', 'https' return http_url_accessible?(uri, options) @@ -178,7 +189,7 @@ def http_url_accessible?(uri, options) rescue return false end - + def url_response_valid?(response, options) return true unless response.kind_of?(HTTPI::Response) and options[:check_path] response_codes = options[:check_path] == true ? [400..499, 500..599] : Array.wrap(options[:check_path]).flatten @@ -186,7 +197,7 @@ def url_response_valid?(response, options) case code # and it's a bad response if... when Range code.include? response.code - when Fixnum + when Integer code == response.code when Symbol CODES.include?(code) && CODES[code] == response.code diff --git a/spec/url_validator_spec.rb b/spec/url_validator_spec.rb index 6b2d6d5..14d74a3 100644 --- a/spec/url_validator_spec.rb +++ b/spec/url_validator_spec.rb @@ -11,219 +11,218 @@ class Record @record = Record.new end - context "[basic]" do + context '[basic]' do it "should allow nil if :allow_nil is set" do - @validator = UrlValidator.new(:attributes => [ :field ], :allow_nil => true) + @validator = UrlValidator.new(attributes: %i(field), allow_nil: true) @validator.validate_each(@record, :field, nil) expect(@record.errors).to be_empty end it "should allow \"\" if :allow_blank is set" do - @validator = UrlValidator.new(:attributes => [ :field ], :allow_blank => true) + @validator = UrlValidator.new(attributes: %i(field), allow_blank: true) @validator.validate_each(@record, :field, "") expect(@record.errors).to be_empty end end - - context "[format]" do + + context '[format]' do it "should only allow HTTP URLs if :scheme is set to 'http'" do - @validator = UrlValidator.new(:attributes => [ :field ], :scheme => 'http') - @validator.validate_each(@record, :field, "http://www.apple.com") + @validator = UrlValidator.new(attributes: %i(field), scheme: 'http') + @validator.validate_each(@record, :field, 'http://www.apple.com') expect(@record.errors).to be_empty - @validator.validate_each(@record, :field, "https://www.apple.com") + @validator.validate_each(@record, :field, 'https://www.apple.com') expect(@record.errors[:field].first).to include('invalid_url') end - it "should only allow HTTP and HTTPS URLs if :scheme is set to %w( http https )" do - @validator = UrlValidator.new(:attributes => [ :field ], :scheme => %w( http https )) - @validator.validate_each(@record, :field, "http://www.apple.com") + it "should only allow HTTP and HTTPS URLs if :scheme is set to %w(http https)" do + @validator = UrlValidator.new(attributes: %i(field), scheme: %w(http https)) + @validator.validate_each(@record, :field, 'http://www.apple.com') expect(@record.errors).to be_empty - @validator.validate_each(@record, :field, "https://www.apple.com") + @validator.validate_each(@record, :field, 'https://www.apple.com') expect(@record.errors).to be_empty - @validator.validate_each(@record, :field, "ftp://www.apple.com") + @validator.validate_each(@record, :field, 'ftp://www.apple.com') expect(@record.errors[:field].first).to include('invalid_url') end it "should try a default scheme if :default_scheme is set" do - @validator = UrlValidator.new(:attributes => [ :field ], :scheme => 'http', :default_scheme => 'http') - @validator.validate_each(@record, :field, "www.apple.com") + @validator = UrlValidator.new(attributes: %i(field), scheme: 'http', default_scheme: 'http') + @validator.validate_each(@record, :field, 'www.apple.com') expect(@record.errors).to be_empty end - - context "[HTTP(S)]" do + + context '[HTTP(S)]' do it "should not allow garbage URLs that still somehow pass the ridiculously open-ended RFC" do - @validator = UrlValidator.new(:attributes => [ :field ]) - - [ - 'http:sdg.sdfg/', - 'http/sdg.d', - 'http:://dsfg.dsfg/', - 'http//sdg..g', - 'http://://sdfg.f', - 'http://dsaf.com://sdg.com' - ].each do |uri| + @validator = UrlValidator.new(attributes: %i(field)) + + %w( + http:sdg.sdfg/ + http/sdg.d + http:://dsfg.dsfg/ + http//sdg..g + http://://sdfg.f + http://dsaf.com://sdg.com).each do |uri| @record.errors.clear - @validator.validate_each(@record, :field, "www.apple.com") + @validator.validate_each(@record, :field, 'www.apple.com') expect(@record.errors[:field].first).to include('invalid_url') end end end end - - context "[accessibility]" do - context "[:check_host]" do + + context '[accessibility]' do + context '[:check_host]' do it "should only validate if the host is accessible when :check_host is set" do - @validator = UrlValidator.new(:attributes => [ :field ]) - @validator.validate_each(@record, :field, "http://www.invalid.tld") + @validator = UrlValidator.new(attributes: %i(field)) + @validator.validate_each(@record, :field, 'http://www.invalid.tld') expect(@record.errors).to be_empty - @validator = UrlValidator.new(:attributes => [ :field ], :check_host => true) - @validator.validate_each(@record, :field, "http://www.invalid.tld") + @validator = UrlValidator.new(attributes: %i(field), check_host: true) + @validator.validate_each(@record, :field, 'http://www.invalid.tld') expect(@record.errors[:field].first).to include('url_not_accessible') end it "should not perform the accessibility check if :check_host is set to 'http' and the URL scheme is not HTTP" do - @validator = UrlValidator.new(:attributes => [ :field ], :check_host => 'http') - @validator.validate_each(@record, :field, "https://www.invalid.tld") + @validator = UrlValidator.new(attributes: %i(field), check_host: 'http') + @validator.validate_each(@record, :field, 'https://www.invalid.tld') expect(@record.errors).to be_empty end it "should only validate if the host is accessible when :check_host is set to 'http' and the URL scheme is HTTP" do - @validator = UrlValidator.new(:attributes => [ :field ], :check_host => 'http') - @validator.validate_each(@record, :field, "http://www.invalid.tld") + @validator = UrlValidator.new(attributes: %i(field), check_host: 'http') + @validator.validate_each(@record, :field, 'http://www.invalid.tld') expect(@record.errors[:field].first).to include('url_not_accessible') end - 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 - @validator = UrlValidator.new(:attributes => [ :field ], :check_host => %w( http https ), :scheme => %w( ftp http https )) - @validator.validate_each(@record, :field, "ftp://www.invalid.tld") + 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 + @validator = UrlValidator.new(attributes: %i(field), check_host: %w(http https), scheme: %w(ftp http https)) + @validator.validate_each(@record, :field, 'ftp://www.invalid.tld') expect(@record.errors).to be_empty end - - 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 - @validator = UrlValidator.new(:attributes => [ :field ], :check_host => %w( http https )) - @validator.validate_each(@record, :field, "http://www.invalid.tld") + + 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 + @validator = UrlValidator.new(attributes: %i(field), check_host: %w(http https)) + @validator.validate_each(@record, :field, 'http://www.invalid.tld') expect(@record.errors[:field].first).to include('url_not_accessible') - @validator = UrlValidator.new(:attributes => [ :field ], :check_host => %w( http https )) - @validator.validate_each(@record, :field, "https://www.invalid.tld") + @validator = UrlValidator.new(attributes: %i(field), check_host: %w(http https)) + @validator.validate_each(@record, :field, 'https://www.invalid.tld') expect(@record.errors[:field].first).to include('url_not_accessible') end it "should only validate the host" do - @validator = UrlValidator.new(:attributes => [ :field ], :check_host => true) - @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") + @validator = UrlValidator.new(attributes: %i(field), check_host: true) + @validator.validate_each(@record, :field, 'http://www.google.com/sdgsdgf') expect(@record.errors).to be_empty end end - - context "[:check_path]" do - it "should not validate if the response code is equal to the Fixnum value of this option" do - @validator = UrlValidator.new(:attributes => [ :field ], :check_path => 404) - @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") + + context '[:check_path]' do + it "should not validate if the response code is equal to the Integer value of this option" do + @validator = UrlValidator.new(attributes: %i(field), check_path: 404) + @validator.validate_each(@record, :field, 'http://www.google.com/sdgsdgf') expect(@record.errors[:field].first).to include('url_invalid_response') - + @record.errors.clear - - @validator = UrlValidator.new(:attributes => [ :field ], :check_path => 405) - @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") + + @validator = UrlValidator.new(attributes: %i(field), check_path: 405) + @validator.validate_each(@record, :field, 'http://www.google.com/sdgsdgf') expect(@record.errors[:field]).to be_empty end - + it "should not validate if the response code is equal to the Symbol value of this option" do - @validator = UrlValidator.new(:attributes => [ :field ], :check_path => :not_found) - @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") + @validator = UrlValidator.new(attributes: %i(field), check_path: :not_found) + @validator.validate_each(@record, :field, 'http://www.google.com/sdgsdgf') expect(@record.errors[:field].first).to include('url_invalid_response') - + @record.errors.clear - - @validator = UrlValidator.new(:attributes => [ :field ], :check_path => :unauthorized) - @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") + + @validator = UrlValidator.new(attributes: %i(field), check_path: :unauthorized) + @validator.validate_each(@record, :field, 'http://www.google.com/sdgsdgf') expect(@record.errors[:field]).to be_empty end - + it "should not validate if the response code is within the Range value of this option" do - @validator = UrlValidator.new(:attributes => [ :field ], :check_path => 400..499) - @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") + @validator = UrlValidator.new(attributes: %i(field), check_path: 400..499) + @validator.validate_each(@record, :field, 'http://www.google.com/sdgsdgf') expect(@record.errors[:field].first).to include('url_invalid_response') - + @record.errors.clear - - @validator = UrlValidator.new(:attributes => [ :field ], :check_path => 500..599) - @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") + + @validator = UrlValidator.new(attributes: %i(field), check_path: 500..599) + @validator.validate_each(@record, :field, 'http://www.google.com/sdgsdgf') expect(@record.errors[:field]).to be_empty end - - it "should not validate if the response code is equal to the Fixnum value contained in the Array value of this option" do - @validator = UrlValidator.new(:attributes => [ :field ], :check_path => [ 404, 405 ]) - @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") + + it "should not validate if the response code is equal to the Integer value contained in the Array value of this option" do + @validator = UrlValidator.new(attributes: %i(field), check_path: [404, 405]) + @validator.validate_each(@record, :field, 'http://www.google.com/sdgsdgf') expect(@record.errors[:field].first).to include('url_invalid_response') - + @record.errors.clear - - @validator = UrlValidator.new(:attributes => [ :field ], :check_path => [ 405, 406 ]) - @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") + + @validator = UrlValidator.new(attributes: %i(field), check_path: [405, 406]) + @validator.validate_each(@record, :field, 'http://www.google.com/sdgsdgf') expect(@record.errors[:field]).to be_empty end - + it "should not validate if the response code is equal to the Symbol value contained in the Array value of this option" do - @validator = UrlValidator.new(:attributes => [ :field ], :check_path => [ :not_found, :unauthorized ]) - @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") + @validator = UrlValidator.new(attributes: %i(field), check_path: %i(not_found unauthorized)) + @validator.validate_each(@record, :field, 'http://www.google.com/sdgsdgf') expect(@record.errors[:field].first).to include('url_invalid_response') - + @record.errors.clear - - @validator = UrlValidator.new(:attributes => [ :field ], :check_path => [ :unauthorized, :moved_permanently ]) - @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") + + @validator = UrlValidator.new(attributes: %i(field), check_path: %i(unauthorized moved_permanently)) + @validator.validate_each(@record, :field, 'http://www.google.com/sdgsdgf') expect(@record.errors[:field]).to be_empty end - + it "should not validate if the response code is equal to the Range value contained in the Array value of this option" do - @validator = UrlValidator.new(:attributes => [ :field ], :check_path => [ 400..499, 500..599 ]) - @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") + @validator = UrlValidator.new(attributes: %i(field), check_path: [400..499, 500..599]) + @validator.validate_each(@record, :field, 'http://www.google.com/sdgsdgf') expect(@record.errors[:field].first).to include('url_invalid_response') - + @record.errors.clear - - @validator = UrlValidator.new(:attributes => [ :field ], :check_path => [ 500..599, 300..399 ]) - @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") + + @validator = UrlValidator.new(attributes: %i(field), check_path: [500..599, 300..399]) + @validator.validate_each(@record, :field, 'http://www.google.com/sdgsdgf') expect(@record.errors[:field]).to be_empty end - + it "should skip validation by default" do - @validator = UrlValidator.new(:attributes => [ :field ], :check_path => nil) - @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") + @validator = UrlValidator.new(attributes: %i(field), check_path: nil) + @validator.validate_each(@record, :field, 'http://www.google.com/sdgsdgf') expect(@record.errors[:field]).to be_empty end - + it "should not validate 4xx and 5xx response codes if the value is true" do - @validator = UrlValidator.new(:attributes => [ :field ], :check_path => true) - @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") + @validator = UrlValidator.new(attributes: %i(field), check_path: true) + @validator.validate_each(@record, :field, 'http://www.google.com/sdgsdgf') expect(@record.errors[:field].first).to include('url_invalid_response') end - + it "should skip validation for non-HTTP URLs" do - @validator = UrlValidator.new(:attributes => [ :field ], :check_path => true, :scheme => %w( ftp http https )) - @validator.validate_each(@record, :field, "ftp://ftp.sdgasdgohaodgh.com/sdgjsdg") + @validator = UrlValidator.new(attributes: %i(field), check_path: true, scheme: %w(ftp http https)) + @validator.validate_each(@record, :field, 'ftp://ftp.sdgasdgohaodgh.com/sdgjsdg') expect(@record.errors[:field]).to be_empty end end - - context "[:httpi_adapter]" do + + context '[:httpi_adapter]' do it "should use the specified HTTPI adapter" do - @validator = UrlValidator.new(:attributes => [ :field ], :httpi_adapter => :curl, :check_host => true) + @validator = UrlValidator.new(attributes: %i(field), httpi_adapter: :curl, check_host: true) expect(HTTPI).to receive(:get).once.with(an_instance_of(HTTPI::Request), :curl).and_return(false) - @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") + @validator.validate_each(@record, :field, 'http://www.google.com/sdgsdgf') end end - - context "[:request_callback]" do + + context '[:request_callback]' do it "should be yielded the HTTPI request" do called = false - @validator = UrlValidator.new(:attributes => [ :field ], :check_host => true, :request_callback => lambda { |request| called = true; expect(request).to be_kind_of(HTTPI::Request) }) - @validator.validate_each(@record, :field, "http://www.google.com/sdgsdgf") + @validator = UrlValidator.new(attributes: %i(field), check_host: true, request_callback: ->(request) { called = true; expect(request).to be_kind_of(HTTPI::Request) }) + @validator.validate_each(@record, :field, 'http://www.google.com/sdgsdgf') expect(called).to eql(true) end end diff --git a/url_validation.gemspec b/url_validation.gemspec index 992c4c9..173a209 100644 --- a/url_validation.gemspec +++ b/url_validation.gemspec @@ -39,10 +39,10 @@ Gem::Specification.new do |s| s.rubygems_version = "2.4.2" s.summary = "Simple URL validation in Rails 3" - if s.respond_to? :specification_version then + if s.respond_to? :specification_version s.specification_version = 4 - if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') s.add_runtime_dependency(%q, [">= 0"]) s.add_runtime_dependency(%q, [">= 0"]) s.add_runtime_dependency(%q, [">= 0"]) From 9c602ffc0da742f1a41ccb5a80b2dbe83470267e Mon Sep 17 00:00:00 2001 From: Tim Morgan Date: Wed, 31 May 2017 15:18:59 -0700 Subject: [PATCH 09/14] Spec fix --- spec/url_validator_spec.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/spec/url_validator_spec.rb b/spec/url_validator_spec.rb index 14d74a3..3139bce 100644 --- a/spec/url_validator_spec.rb +++ b/spec/url_validator_spec.rb @@ -61,10 +61,9 @@ class Record http/sdg.d http:://dsfg.dsfg/ http//sdg..g - http://://sdfg.f - http://dsaf.com://sdg.com).each do |uri| + http://://sdfg.f).each do |uri| @record.errors.clear - @validator.validate_each(@record, :field, 'www.apple.com') + @validator.validate_each(@record, :field, uri) expect(@record.errors[:field].first).to include('invalid_url') end end @@ -220,7 +219,7 @@ class Record context '[:request_callback]' do it "should be yielded the HTTPI request" do - called = false + called = false @validator = UrlValidator.new(attributes: %i(field), check_host: true, request_callback: ->(request) { called = true; expect(request).to be_kind_of(HTTPI::Request) }) @validator.validate_each(@record, :field, 'http://www.google.com/sdgsdgf') expect(called).to eql(true) From 4d3bcfcf6052b45a038d70414dfd9430bab82c19 Mon Sep 17 00:00:00 2001 From: Tim Morgan Date: Wed, 31 May 2017 15:23:25 -0700 Subject: [PATCH 10/14] Properly handle invalid scheme formats --- lib/url_validation.rb | 3 ++- spec/url_validator_spec.rb | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/url_validation.rb b/lib/url_validation.rb index 14509e2..6f031aa 100644 --- a/lib/url_validation.rb +++ b/lib/url_validation.rb @@ -135,11 +135,12 @@ def validate_each(record, attribute, value) begin uri = Addressable::URI.parse(value) + if uri.scheme.nil? and options[:default_scheme] uri = Addressable::URI.parse("#{options[:default_scheme]}://#{value}") end rescue Addressable::URI::InvalidURIError - record.errors.add(attribute, options[:invalid_url_message] || :invalid_url) unless url_format_valid?(uri, options) + record.errors.add(attribute, options[:invalid_url_message] || :invalid_url) if uri.nil? || !url_format_valid?(uri, options) return end diff --git a/spec/url_validator_spec.rb b/spec/url_validator_spec.rb index 3139bce..d2c33da 100644 --- a/spec/url_validator_spec.rb +++ b/spec/url_validator_spec.rb @@ -67,6 +67,12 @@ class Record expect(@record.errors[:field].first).to include('invalid_url') end end + + it "should not allow invalid scheme formats" do + @validator = UrlValidator.new(attributes: %i(field)) + @validator.validate_each(@record, :field, ' https://www.apple.com') + expect(@record.errors[:field].first).to include('invalid_url') + end end end From 43ec6c113261db5794f00d4689efca5b06782542 Mon Sep 17 00:00:00 2001 From: Tim Morgan Date: Wed, 31 May 2017 15:24:46 -0700 Subject: [PATCH 11/14] Version bump to 1.2.0 --- VERSION | 2 +- url_validation.gemspec | 86 +++++++++++++++++++++--------------------- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/VERSION b/VERSION index 1cc5f65..867e524 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.0 \ No newline at end of file +1.2.0 \ No newline at end of file diff --git a/url_validation.gemspec b/url_validation.gemspec index 173a209..af643e0 100644 --- a/url_validation.gemspec +++ b/url_validation.gemspec @@ -1,22 +1,22 @@ -# Generated by jeweler +# Generated by juwelier # DO NOT EDIT THIS FILE DIRECTLY -# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec' +# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec' # -*- encoding: utf-8 -*- -# stub: url_validation 1.1.0 ruby lib +# stub: url_validation 1.2.0 ruby lib Gem::Specification.new do |s| - s.name = "url_validation" - s.version = "1.1.0" + s.name = "url_validation".freeze + s.version = "1.2.0" - s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= - s.require_paths = ["lib"] - s.authors = ["Tim Morgan"] - s.date = "2014-11-08" - s.description = "A simple, localizable EachValidator for URL fields in ActiveRecord 3.0." - s.email = "git@timothymorgan.info" + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib".freeze] + s.authors = ["Tim Morgan".freeze] + s.date = "2017-05-31" + s.description = "A simple, localizable EachValidator for URL fields in ActiveRecord 3.0.".freeze + s.email = "git@timothymorgan.info".freeze s.extra_rdoc_files = [ "LICENSE", - "README.textile" + "README.md" ] s.files = [ ".document", @@ -26,7 +26,7 @@ Gem::Specification.new do |s| "Gemfile", "Gemfile.lock", "LICENSE", - "README.textile", + "README.md", "Rakefile", "VERSION", "lib/url_validation.rb", @@ -34,42 +34,42 @@ Gem::Specification.new do |s| "spec/url_validator_spec.rb", "url_validation.gemspec" ] - s.homepage = "http://github.com/riscfuture/url_validation" - s.required_ruby_version = Gem::Requirement.new(">= 1.8.7") - s.rubygems_version = "2.4.2" - s.summary = "Simple URL validation in Rails 3" + s.homepage = "http://github.com/riscfuture/url_validation".freeze + s.required_ruby_version = Gem::Requirement.new(">= 2.0.0".freeze) + s.rubygems_version = "2.6.12".freeze + s.summary = "Simple URL validation in Rails 3+".freeze - if s.respond_to? :specification_version + if s.respond_to? :specification_version then s.specification_version = 4 - if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') - s.add_runtime_dependency(%q, [">= 0"]) - s.add_runtime_dependency(%q, [">= 0"]) - s.add_runtime_dependency(%q, [">= 0"]) - s.add_runtime_dependency(%q, [">= 0"]) - s.add_development_dependency(%q, [">= 0"]) - s.add_development_dependency(%q, [">= 0"]) - s.add_development_dependency(%q, [">= 0"]) - s.add_development_dependency(%q, [">= 0"]) + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_runtime_dependency(%q.freeze, [">= 0"]) + s.add_runtime_dependency(%q.freeze, [">= 0"]) + s.add_runtime_dependency(%q.freeze, [">= 0"]) + s.add_runtime_dependency(%q.freeze, [">= 0"]) + s.add_development_dependency(%q.freeze, [">= 0"]) + s.add_development_dependency(%q.freeze, [">= 0"]) + s.add_development_dependency(%q.freeze, [">= 0"]) + s.add_development_dependency(%q.freeze, [">= 0"]) else - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) end else - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) + s.add_dependency(%q.freeze, [">= 0"]) end end From b418b417bdf2afa2f247238ee3c991cf626f3599 Mon Sep 17 00:00:00 2001 From: Tim Morgan Date: Tue, 12 Dec 2017 00:22:41 -0800 Subject: [PATCH 12/14] Update gems --- .ruby-version | 2 +- Gemfile.lock | 97 ++++++++++++++++++++++++++------------------------- 2 files changed, 50 insertions(+), 49 deletions(-) diff --git a/.ruby-version b/.ruby-version index 005119b..8e8299d 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.4.1 +2.4.2 diff --git a/Gemfile.lock b/Gemfile.lock index 9d1da3a..38a789e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,93 +1,94 @@ GEM remote: https://rubygems.org/ specs: - activemodel (5.1.1) - activesupport (= 5.1.1) - activerecord (5.1.1) - activemodel (= 5.1.1) - activesupport (= 5.1.1) + activemodel (5.1.4) + activesupport (= 5.1.4) + activerecord (5.1.4) + activemodel (= 5.1.4) + activesupport (= 5.1.4) arel (~> 8.0) - activesupport (5.1.1) + activesupport (5.1.4) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (~> 0.7) minitest (~> 5.1) tzinfo (~> 1.1) - addressable (2.4.0) + addressable (2.5.2) + public_suffix (>= 2.0.2, < 4.0) arel (8.0.0) builder (3.2.3) concurrent-ruby (1.0.5) descendants_tracker (0.0.4) thread_safe (~> 0.3, >= 0.3.1) diff-lcs (1.3) - faraday (0.9.2) + faraday (0.12.2) multipart-post (>= 1.2, < 3) git (1.3.0) - github_api (0.17.0) - addressable (~> 2.4.0) + github_api (0.18.2) + addressable (~> 2.4) descendants_tracker (~> 0.0.4) - faraday (~> 0.8, < 0.10) - hashie (>= 3.4) - mime-types (>= 1.16, < 3.0) + faraday (~> 0.8) + hashie (~> 3.5, >= 3.5.2) oauth2 (~> 1.0) - hashie (3.5.5) - highline (1.7.8) + hashie (3.5.6) + highline (1.7.10) httpi (2.4.2) rack socksify - i18n (0.8.4) - juwelier (2.4.5) + i18n (0.9.1) + concurrent-ruby (~> 1.0) + juwelier (2.4.7) builder - bundler (>= 1.13) - git (>= 1.2.5) + bundler + git github_api - highline (>= 1.6.15) + highline kamelcase (~> 0) - nokogiri (>= 1.5.10) - psych (~> 2.2) + nokogiri + psych rake rdoc semver2 jwt (1.5.6) - kamelcase (0.0.0) + kamelcase (0.0.1) semver2 (~> 3) - mime-types (2.99.3) - mini_portile2 (2.1.0) - minitest (5.10.2) - multi_json (1.12.1) + mini_portile2 (2.3.0) + minitest (5.10.3) + multi_json (1.12.2) multi_xml (0.6.0) multipart-post (2.0.0) - nokogiri (1.7.2) - mini_portile2 (~> 2.1.0) - oauth2 (1.3.1) - faraday (>= 0.8, < 0.12) + nokogiri (1.8.1) + mini_portile2 (~> 2.3.0) + oauth2 (1.4.0) + faraday (>= 0.8, < 0.13) jwt (~> 1.0) multi_json (~> 1.3) multi_xml (~> 0.5) rack (>= 1.2, < 3) - psych (2.2.4) + psych (3.0.1) + public_suffix (3.0.1) rack (2.0.3) - rake (12.0.0) - rdoc (5.1.0) + rake (12.3.0) + rdoc (6.0.0) redcarpet (3.4.0) - rspec (3.6.0) - rspec-core (~> 3.6.0) - rspec-expectations (~> 3.6.0) - rspec-mocks (~> 3.6.0) - rspec-core (3.6.0) - rspec-support (~> 3.6.0) - rspec-expectations (3.6.0) + rspec (3.7.0) + rspec-core (~> 3.7.0) + rspec-expectations (~> 3.7.0) + rspec-mocks (~> 3.7.0) + rspec-core (3.7.0) + rspec-support (~> 3.7.0) + rspec-expectations (3.7.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.6.0) - rspec-mocks (3.6.0) + rspec-support (~> 3.7.0) + rspec-mocks (3.7.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.6.0) - rspec-support (3.6.0) + rspec-support (~> 3.7.0) + rspec-support (3.7.0) semver2 (3.4.2) socksify (1.7.1) thread_safe (0.3.6) - tzinfo (1.2.3) + tzinfo (1.2.4) thread_safe (~> 0.1) - yard (0.9.9) + yard (0.9.12) PLATFORMS ruby @@ -103,4 +104,4 @@ DEPENDENCIES yard BUNDLED WITH - 1.15.0 + 1.16.0 From 2fc974a53a4b43a51a6a313a98fb30d3860f9f3b Mon Sep 17 00:00:00 2001 From: Andrew Meier Date: Thu, 22 Mar 2018 16:50:03 -0700 Subject: [PATCH 13/14] added a new require_domain option to force URLs to have a domain to be considered valid --- lib/url_validation.rb | 18 +++++++++++------- spec/url_validator_spec.rb | 9 +++++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/lib/url_validation.rb b/lib/url_validation.rb index 6f031aa..2f97a88 100644 --- a/lib/url_validation.rb +++ b/lib/url_validation.rb @@ -34,10 +34,11 @@ # # ### Basic options # -# | | | -# |:---------------|:----------------------------------------------| -# | `:allow_nil` | If `true`, `nil` values are allowed. | -# | `:allow_blank` | If `true`, `nil` or empty values are allowed. | +# | | | +# |:------------------|:------------------------------------------------------------| +# | `:allow_nil` | If `true`, `nil` values are allowed. | +# | `:allow_blank` | If `true`, `nil` or empty values are allowed. | +# | `:require_domain` | If `true`, A domain must be present to be considered valid. | # # ### Error messages # @@ -156,14 +157,17 @@ def url_format_valid?(uri, options) case uri.scheme when 'http', 'https' - return http_url_format_valid?(uri) + return http_url_format_valid?(uri, options) else return true end end - def http_url_format_valid?(uri) - uri.host.present? and not uri.path.nil? + def http_url_format_valid?(uri, options) + valid_format = uri.host.present? and not uri.path.nil? + return valid_format unless options[:require_domain] + + valid_format and uri.domain.present? end def url_accessible?(uri, options) diff --git a/spec/url_validator_spec.rb b/spec/url_validator_spec.rb index d2c33da..6676443 100644 --- a/spec/url_validator_spec.rb +++ b/spec/url_validator_spec.rb @@ -52,6 +52,15 @@ class Record expect(@record.errors).to be_empty end + it "should only allow URLs with a domain if :require_domain is set" do + @validator = UrlValidator.new(attributes: %i(field), require_domain: true) + @validator.validate_each(@record, :field, 'http://apple.com') + expect(@record.errors).to be_empty + + @validator.validate_each(@record, :field, 'http://apple') + expect(@record.errors[:field].first).to include('invalid_url') + end + context '[HTTP(S)]' do it "should not allow garbage URLs that still somehow pass the ridiculously open-ended RFC" do @validator = UrlValidator.new(attributes: %i(field)) From 0b900d312304d87aa790b345559d7e636a5123ed Mon Sep 17 00:00:00 2001 From: Andrew Meier Date: Thu, 22 Mar 2018 16:50:20 -0700 Subject: [PATCH 14/14] updating gems --- Gemfile.lock | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 38a789e..5809ee1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,13 +1,13 @@ GEM remote: https://rubygems.org/ specs: - activemodel (5.1.4) - activesupport (= 5.1.4) - activerecord (5.1.4) - activemodel (= 5.1.4) - activesupport (= 5.1.4) + activemodel (5.1.5) + activesupport (= 5.1.5) + activerecord (5.1.5) + activemodel (= 5.1.5) + activesupport (= 5.1.5) arel (~> 8.0) - activesupport (5.1.4) + activesupport (5.1.5) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (~> 0.7) minitest (~> 5.1) @@ -29,14 +29,14 @@ GEM faraday (~> 0.8) hashie (~> 3.5, >= 3.5.2) oauth2 (~> 1.0) - hashie (3.5.6) + hashie (3.5.7) highline (1.7.10) - httpi (2.4.2) + httpi (2.4.3) rack socksify - i18n (0.9.1) + i18n (0.9.5) concurrent-ruby (~> 1.0) - juwelier (2.4.7) + juwelier (2.4.9) builder bundler git @@ -49,14 +49,14 @@ GEM rdoc semver2 jwt (1.5.6) - kamelcase (0.0.1) + kamelcase (0.0.2) semver2 (~> 3) mini_portile2 (2.3.0) - minitest (5.10.3) - multi_json (1.12.2) + minitest (5.11.3) + multi_json (1.13.1) multi_xml (0.6.0) multipart-post (2.0.0) - nokogiri (1.8.1) + nokogiri (1.8.2) mini_portile2 (~> 2.3.0) oauth2 (1.4.0) faraday (>= 0.8, < 0.13) @@ -64,17 +64,17 @@ GEM multi_json (~> 1.3) multi_xml (~> 0.5) rack (>= 1.2, < 3) - psych (3.0.1) - public_suffix (3.0.1) - rack (2.0.3) - rake (12.3.0) - rdoc (6.0.0) + psych (3.0.2) + public_suffix (3.0.2) + rack (2.0.4) + rake (12.3.1) + rdoc (6.0.2) redcarpet (3.4.0) rspec (3.7.0) rspec-core (~> 3.7.0) rspec-expectations (~> 3.7.0) rspec-mocks (~> 3.7.0) - rspec-core (3.7.0) + rspec-core (3.7.1) rspec-support (~> 3.7.0) rspec-expectations (3.7.0) diff-lcs (>= 1.2.0, < 2.0) @@ -82,11 +82,11 @@ GEM rspec-mocks (3.7.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.7.0) - rspec-support (3.7.0) + rspec-support (3.7.1) semver2 (3.4.2) socksify (1.7.1) thread_safe (0.3.6) - tzinfo (1.2.4) + tzinfo (1.2.5) thread_safe (~> 0.1) yard (0.9.12) @@ -104,4 +104,4 @@ DEPENDENCIES yard BUNDLED WITH - 1.16.0 + 1.16.1