app/validators i18n (#16166)
This commit is contained in:
parent
d5348995c1
commit
adc757f5a5
9 changed files with 54 additions and 23 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
17
config/locales/validators/en.yml
Normal file
17
config/locales/validators/en.yml
Normal 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
|
||||
17
config/locales/validators/fr.yml
Normal file
17
config/locales/validators/fr.yml
Normal 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
|
||||
Loading…
Add table
Reference in a new issue