From 4b93684dab5714a1dc1aab7987510743d0e53d2b Mon Sep 17 00:00:00 2001 From: Daniel Uber Date: Fri, 17 Dec 2021 09:29:55 -0600 Subject: [PATCH] Don't raise error when empty community emoji setting submitted (#15723) * Don't raise NoMethodError when validating emoji settings Cargo culted the unique cross model slug validator setup (which is why value is called name here in the validatable). Don't raise an error when validating a nil emoji, and assert nil and empty string are permitted values. This expects no non-emoji characters (so an empty string would be permitted), and nil should be permitted. I believe this might have been introduced by the string settings cleaner (exchanging "" for nil in form inputs). * Update app/validators/emoji_only_validator.rb guard for value, and then validate value --- app/validators/emoji_only_validator.rb | 1 + spec/validators/emoji_only_validator_spec.rb | 60 ++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 spec/validators/emoji_only_validator_spec.rb diff --git a/app/validators/emoji_only_validator.rb b/app/validators/emoji_only_validator.rb index fb4ab4d0d..8db34cdb5 100644 --- a/app/validators/emoji_only_validator.rb +++ b/app/validators/emoji_only_validator.rb @@ -2,6 +2,7 @@ class EmojiOnlyValidator < ActiveModel::EachValidator DEFAULT_MESSAGE = "contains non-emoji characters or invalid emoji".freeze def validate_each(record, attribute, value) + return unless value return if value.gsub(EmojiRegex::RGIEmoji, "").blank? record.errors.add(attribute, options[:message] || DEFAULT_MESSAGE) diff --git a/spec/validators/emoji_only_validator_spec.rb b/spec/validators/emoji_only_validator_spec.rb new file mode 100644 index 000000000..413d837cc --- /dev/null +++ b/spec/validators/emoji_only_validator_spec.rb @@ -0,0 +1,60 @@ +require "rails_helper" + +RSpec.describe EmojiOnlyValidator do + subject(:record) { validatable.new.tap { |m| m.name = name } } + + let(:validatable) do + Class.new do + def self.name + "👍" + end + include ActiveModel::Validations + attr_accessor :name + + def initialize + @enforce_validation = true + end + + attr_accessor :enforce_validation + alias_method :enforce_validation?, :enforce_validation + + validates :name, emoji_only: true, if: :enforce_validation? + end + end + + context "when if option is false" do + let(:name) { "not-an-emoji" } + + before { record.enforce_validation = false } + + it { is_expected.to be_valid } + end + + context "when name includes non-emoji" do + let(:name) { "not-an-emoji" } + + it { is_expected.not_to be_valid } + end + + context "when name is an emoji" do + let(:name) { "🍀" } + + it { is_expected.to be_valid } + end + + context "when name is nil" do + let(:name) { nil } + + it "does not raise no method error" do + expect { record.valid? }.not_to raise_error + end + + it { is_expected.to be_valid } + end + + context "when name is empty" do + let(:name) { "" } + + it { is_expected.to be_valid } + end +end