From efc636f07bcbea656272d8f9bcebe0e658bb8a8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janosch=20Mu=CC=88ller?= Date: Tue, 22 Oct 2024 16:15:11 +0200 Subject: [PATCH] Alway use given message ... fixes #122. I could only run the specs by removing Gemfile.lock and would recommend #150 to be merged before this PR. Several examples were red with NoMethodErrors before I made any changes. I had to add the `value && ` to fix that. The example `does not allow a url with only a scheme` was also red. I had to add the `host.empty?` check to fix that one. --- lib/validate_url.rb | 15 ++++++++++----- .../user_with_accept_array_with_message.rb | 9 +++++++++ spec/spec_helper.rb | 1 + spec/validate_url_spec.rb | 18 ++++++++++++++++++ 4 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 spec/resources/user_with_accept_array_with_message.rb diff --git a/lib/validate_url.rb b/lib/validate_url.rb index 0e0e374..8006f8f 100644 --- a/lib/validate_url.rb +++ b/lib/validate_url.rb @@ -23,7 +23,7 @@ def validate_each(record, attribute, value) if value.respond_to?(:each) # Error out if we're not allowing arrays if !options.include?(:accept_array) || !options.fetch(:accept_array) - record.errors.add(attribute, :url, **filtered_options(value)) + record.errors.add(attribute, message, **filtered_options(value)) end # We have to manually handle `:allow_nil` and `:allow_blank` since it's not caught by @@ -50,20 +50,25 @@ def filtered_options(value) end def validate_url(record, attribute, value, schemes) - uri = URI.parse(URI::Parser.new.escape(value)) + uri = value && URI.parse(URI::Parser.new.escape(value)) host = uri && uri.host scheme = uri && uri.scheme + valid_host = host && !host.empty? valid_raw_url = scheme && value =~ /\A#{URI::regexp([scheme])}\z/ valid_scheme = host && scheme && schemes.include?(scheme) valid_no_local = !options.fetch(:no_local) || (host && host.include?('.')) valid_suffix = !options.fetch(:public_suffix) || (host && PublicSuffix.valid?(host, :default_rule => nil)) - unless valid_raw_url && valid_scheme && valid_no_local && valid_suffix - record.errors.add(attribute, options.fetch(:message), value: value) + unless valid_host && valid_raw_url && valid_scheme && valid_no_local && valid_suffix + record.errors.add(attribute, message, value: value) end rescue URI::InvalidURIError, URI::InvalidComponentError - record.errors.add(attribute, :url, **filtered_options(value)) + record.errors.add(attribute, message, **filtered_options(value)) + end + + def message + options.fetch(:message) end end diff --git a/spec/resources/user_with_accept_array_with_message.rb b/spec/resources/user_with_accept_array_with_message.rb new file mode 100644 index 0000000..132823e --- /dev/null +++ b/spec/resources/user_with_accept_array_with_message.rb @@ -0,0 +1,9 @@ +require 'active_model/validations' + +class UserWithAcceptArrayWithMessage + include ActiveModel::Validations + + attr_accessor :homepage + + validates :homepage, url: { accept_array: true, message: 'wrong' } +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 73889c4..b7d4943 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -30,6 +30,7 @@ autoload :UserWithNoLocal, 'resources/user_with_no_local' autoload :UserWithPublicSuffix, 'resources/user_with_public_suffix' autoload :UserWithAcceptArray, 'resources/user_with_accept_array' +autoload :UserWithAcceptArrayWithMessage, 'resources/user_with_accept_array_with_message' autoload :UserWithAcceptArrayWithNil, 'resources/user_with_accept_array_with_nil' autoload :UserWithAcceptArrayWithBlank, 'resources/user_with_accept_array_with_blank' diff --git a/spec/validate_url_spec.rb b/spec/validate_url_spec.rb index fe1eac1..fdd87bf 100644 --- a/spec/validate_url_spec.rb +++ b/spec/validate_url_spec.rb @@ -277,6 +277,17 @@ end end + context "with accept array with message" do + let!(:user) { UserWithAcceptArrayWithMessage.new } + + it "uses the custom message" do + user.homepage = ["https://foo.com", "https://foo bar.com"] + user.valid? + + expect(user.errors[:homepage]).to eq(["wrong"]) + end + end + context 'with legacy syntax' do let!(:user) { UserWithLegacySyntax.new } @@ -350,5 +361,12 @@ expect(user.errors[:homepage]).to eq(['wrong']) end + + it 'uses custom message for URIs that can not be parsed' do + user.homepage = ':::' + user.valid? + + expect(user.errors[:homepage]).to eq(['wrong']) + end end end