FEATURE: topic title is validated for blocked words (#8127)

Currently, the topic is only validated for censored words and should be validated for blocked words as well.

Blocked word validation is now used by both Post and Topic. To avoid code duplication, I extracted blocked words validation code into separate Validator, and use it in both places.

The only downside is that even if the topic contains blocked words validation message is saying "Your post contains a word that's not allowed: tomato" but I think this is descriptive enough.
This commit is contained in:
Krzysztof Kotlarek
2019-10-02 10:38:34 +10:00
committed by Sam
parent 0b93f1239b
commit f331b5eab2
4 changed files with 34 additions and 14 deletions

View File

@ -36,7 +36,7 @@ class Validators::PostValidator < ActiveModel::Validator
return if options[:skip_post_body] || post.topic&.pm_with_non_human_user?
stripped_length(post)
raw_quality(post)
watched_words(post)
WatchedWordsValidator.new(attributes: [:raw]).validate(post) if !post.acting_user&.staged
end
def stripped_length(post)
@ -59,19 +59,6 @@ class Validators::PostValidator < ActiveModel::Validator
post.errors.add(:raw, I18n.t(:is_invalid)) unless sentinel.valid?
end
def watched_words(post)
if !post.acting_user&.staged && matches = WordWatcher.new(post.raw).should_block?.presence
if matches.size == 1
key = 'contains_blocked_word'
translation_args = { word: matches[0] }
else
key = 'contains_blocked_words'
translation_args = { words: matches.join(', ') }
end
post.errors.add(:base, I18n.t(key, translation_args))
end
end
# Ensure maximum amount of mentions in a post
def max_mention_validator(post)
return if post.acting_user.try(:staff?)

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
class WatchedWordsValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
if matches = WordWatcher.new(value).should_block?.presence
if matches.size == 1
key = 'contains_blocked_word'
translation_args = { word: matches[0] }
else
key = 'contains_blocked_words'
translation_args = { words: matches.join(', ') }
end
record.errors.add(:base, I18n.t(key, translation_args))
end
end
end