From adc757f5a504e514100ab54cde4110ec07cb1518 Mon Sep 17 00:00:00 2001 From: yheuhtozr <84892012+yheuhtozr@users.noreply.github.com> Date: Wed, 19 Jan 2022 19:25:39 +0900 Subject: [PATCH] app/validators i18n (#16166) --- app/validators/bytesize_validator.rb | 6 +++--- app/validators/color_contrast_validator.rb | 5 ++--- app/validators/emoji_only_validator.rb | 5 ++--- .../existing_published_article_id_validator.rb | 5 ++--- app/validators/profile_validator.rb | 14 ++++++++------ .../unique_cross_model_slug_validator.rb | 4 +--- app/validators/valid_domain_csv_validator.rb | 4 ++-- config/locales/validators/en.yml | 17 +++++++++++++++++ config/locales/validators/fr.yml | 17 +++++++++++++++++ 9 files changed, 54 insertions(+), 23 deletions(-) create mode 100644 config/locales/validators/en.yml create mode 100644 config/locales/validators/fr.yml diff --git a/app/validators/bytesize_validator.rb b/app/validators/bytesize_validator.rb index 533ac83ff..0be8cccac 100644 --- a/app/validators/bytesize_validator.rb +++ b/app/validators/bytesize_validator.rb @@ -7,14 +7,14 @@ class BytesizeValidator < ActiveModel::EachValidator CHECKS = { maximum: :<= }.freeze RESERVED_OPTIONS = %i[maximum too_long].freeze - ERROR_MISSING_OPTIONS_MESSAGE = "Specify the :maximum option.".freeze - ERROR_NON_NEGATIVE_MESSAGE = ":maximum must be a non-negative Integer".freeze def check_validity! raise ArgumentError, ERROR_MESSAGE unless options.key?(:maximum) maximum = options[:maximum] - raise ArgumentError, ERROR_NON_NEGATIVE_MESSAGE unless maximum.is_a?(Integer) && maximum >= 0 + return if maximum.is_a?(Integer) && maximum >= 0 + + raise ArgumentError, I18n.t("validators.bytesize_validator.non_negative") end def validate_each(record, attribute, value) diff --git a/app/validators/color_contrast_validator.rb b/app/validators/color_contrast_validator.rb index 47e96f2d5..e47b436c2 100644 --- a/app/validators/color_contrast_validator.rb +++ b/app/validators/color_contrast_validator.rb @@ -1,10 +1,9 @@ class ColorContrastValidator < ActiveModel::EachValidator - DEFAULT_MESSAGE = "must be darker for accessibility".freeze - def validate_each(record, attribute, value) return unless Color::Accessibility.new(value).low_contrast? - record.errors.add(attribute, (options[:message] || DEFAULT_MESSAGE)) + record.errors.add(attribute, + (options[:message] || I18n.t("validators.color_contrast_validator.must_be_darker"))) rescue WCAGColorContrast::InvalidColorError # nothing to do here, this should be picked up by the format validation end diff --git a/app/validators/emoji_only_validator.rb b/app/validators/emoji_only_validator.rb index 83158cb61..47383c5b5 100644 --- a/app/validators/emoji_only_validator.rb +++ b/app/validators/emoji_only_validator.rb @@ -1,10 +1,9 @@ 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) + record.errors.add(attribute, + options[:message] || I18n.t("validators.emoji_only_validator.invalid_emoji")) end end diff --git a/app/validators/existing_published_article_id_validator.rb b/app/validators/existing_published_article_id_validator.rb index 72e7a2531..a65977293 100644 --- a/app/validators/existing_published_article_id_validator.rb +++ b/app/validators/existing_published_article_id_validator.rb @@ -1,9 +1,8 @@ class ExistingPublishedArticleIdValidator < ActiveModel::EachValidator - DEFAULT_MESSAGE = "must be a valid published Article identifier".freeze - def validate_each(record, attribute, value) return if Article.published.exists?(id: value) - record.errors.add(attribute, (options[:message] || DEFAULT_MESSAGE)) + record.errors.add(attribute, + (options[:message] || I18n.t("validators.existing_published_article_id_validator.default"))) end end diff --git a/app/validators/profile_validator.rb b/app/validators/profile_validator.rb index 064edcb01..390179db2 100644 --- a/app/validators/profile_validator.rb +++ b/app/validators/profile_validator.rb @@ -5,16 +5,18 @@ class ProfileValidator < ActiveModel::Validator MAX_TEXT_AREA_LENGTH = 200 MAX_TEXT_FIELD_LENGTH = 100 - ERRORS = { - text_area: "is too long (maximum is #{MAX_TEXT_AREA_LENGTH} characters)", - text_field: "is too long (maximum is #{MAX_TEXT_FIELD_LENGTH} characters)" - }.with_indifferent_access.freeze + def errors + { + text_area: I18n.t("errors.messages.too_long", count: MAX_TEXT_AREA_LENGTH), + text_field: I18n.t("errors.messages.too_long", count: MAX_TEXT_FIELD_LENGTH) + }.with_indifferent_access + end def validate(record) # NOTE: The summary is a base profile field, which we add to all new Forem # instances, so it should be safe to validate. The method itself also guards # against the field's absence. - record.errors.add(:summary, "is too long") if summary_too_long?(record) + record.errors.add(:summary, I18n.t("validators.profile_validator.too_long")) if summary_too_long?(record) ProfileField.all.each do |field| attribute = field.attribute_name @@ -22,7 +24,7 @@ class ProfileValidator < ActiveModel::Validator next unless record.respond_to?(attribute) # avoid caching issues next if __send__("#{field.input_type}_valid?", record, attribute) - record.errors.add(attribute, ERRORS[field.input_type]) + record.errors.add(attribute, errors[field.input_type]) end end diff --git a/app/validators/unique_cross_model_slug_validator.rb b/app/validators/unique_cross_model_slug_validator.rb index a0637dfb2..10f5eeb7c 100644 --- a/app/validators/unique_cross_model_slug_validator.rb +++ b/app/validators/unique_cross_model_slug_validator.rb @@ -12,12 +12,10 @@ class UniqueCrossModelSlugValidator < ActiveModel::EachValidator User => :username } - DEFAULT_MESSAGE = "is taken".freeze - def validate_each(record, attribute, value) return unless already_exists?(value: value, record: record) - record.errors.add(attribute, options[:message] || DEFAULT_MESSAGE) + record.errors.add(attribute, options[:message] || I18n.t("validators.unique_cross_model_slug_validator.is_taken")) end private diff --git a/app/validators/valid_domain_csv_validator.rb b/app/validators/valid_domain_csv_validator.rb index 43f3144ef..95c586e27 100644 --- a/app/validators/valid_domain_csv_validator.rb +++ b/app/validators/valid_domain_csv_validator.rb @@ -3,7 +3,6 @@ # and coerce it into an array. See Authentication::Base for an # example of coercing the CSV into an array. class ValidDomainCsvValidator < ActiveModel::EachValidator - DEFAULT_MESSAGE = "must be a comma-separated list of valid domains".freeze VALID_DOMAIN = /^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$/ def validate_each(record, attribute, value) @@ -11,6 +10,7 @@ class ValidDomainCsvValidator < ActiveModel::EachValidator return if value.all? { |domain| domain.match?(VALID_DOMAIN) } - record.errors.add(attribute, options[:message] || DEFAULT_MESSAGE) + record.errors.add(attribute, + options[:message] || I18n.t("validators.valid_domain_csv_validator.invalid_list_format")) end end diff --git a/config/locales/validators/en.yml b/config/locales/validators/en.yml new file mode 100644 index 000000000..a75030797 --- /dev/null +++ b/config/locales/validators/en.yml @@ -0,0 +1,17 @@ +--- +en: + validators: + bytesize_validator: + non_negative: ":maximum must be a non-negative Integer" + color_contrast_validator: + must_be_darker: must be darker for accessibility + emoji_only_validator: + invalid_emoji: contains non-emoji characters or invalid emoji + existing_published_article_id_validator: + default: must be a valid published Article identifier + profile_validator: + too_long: is too long + unique_cross_model_slug_validator: + is_taken: is taken + valid_domain_csv_validator: + invalid_list_format: must be a comma-separated list of valid domains diff --git a/config/locales/validators/fr.yml b/config/locales/validators/fr.yml new file mode 100644 index 000000000..14b48383a --- /dev/null +++ b/config/locales/validators/fr.yml @@ -0,0 +1,17 @@ +--- +fr: + validators: + bytesize_validator: + non_negative: ":maximum must be a non-negative Integer" + color_contrast_validator: + must_be_darker: must be darker for accessibility + emoji_only_validator: + invalid_emoji: contains non-emoji characters or invalid emoji + existing_published_article_id_validator: + default: must be a valid published Article identifier + profile_validator: + too_long: is too long + unique_cross_model_slug_validator: + is_taken: is taken + valid_domain_csv_validator: + invalid_list_format: must be a comma-separated list of valid domains