app/validators i18n (#16166)

This commit is contained in:
yheuhtozr 2022-01-19 19:25:39 +09:00 committed by GitHub
parent d5348995c1
commit adc757f5a5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 54 additions and 23 deletions

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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