UX: Skip applying link-type watched words to user custom fields (#20465)

We currently apply type: :link watched words to custom user fields. This makes the user card pretty ugly because we don't allow html / links there. Additionally, the admin UI also does not say that we apply this to custom user fields, but only words in posts.

So this PR is to remove the replacement of link-type watch words for custom user fields.
This commit is contained in:
Natalie Tay 2023-03-01 10:43:34 +08:00 committed by GitHub
parent d3a1b09361
commit 44b7706a2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 79 additions and 31 deletions

View File

@ -1523,7 +1523,9 @@ class User < ActiveRecord::Base
def apply_watched_words def apply_watched_words
validatable_user_fields.each do |id, value| validatable_user_fields.each do |id, value|
set_user_field(id, WordWatcher.apply_to_text(value)) field = WordWatcher.censor_text(value)
field = WordWatcher.replace_text(field)
set_user_field(id, field)
end end
end end

View File

@ -132,18 +132,18 @@ class WordWatcher
def self.replace_text(text) def self.replace_text(text)
return text if text.blank? return text if text.blank?
replace(text, :replace)
%i[replace link]
.flat_map { |type| word_matcher_regexps(type).to_a }
.reduce(text) do |t, (word_regexp, attrs)|
case_flag = attrs[:case_sensitive] ? nil : Regexp::IGNORECASE
replace_text_with_regexp(t, Regexp.new(word_regexp, case_flag), attrs[:replacement])
end end
def self.replace_link(text)
return text if text.blank?
replace(text, :link)
end end
def self.apply_to_text(text) def self.apply_to_text(text)
text = censor_text(text) text = censor_text(text)
text = replace_text(text) text = replace_text(text)
text = replace_link(text)
text text
end end
@ -246,4 +246,15 @@ class WordWatcher
end end
private_class_method :censor_text_with_regexp private_class_method :censor_text_with_regexp
private
def self.replace(text, watch_word_type)
word_matcher_regexps(watch_word_type)
.to_a
.reduce(text) do |t, (word_regexp, attrs)|
case_flag = attrs[:case_sensitive] ? nil : Regexp::IGNORECASE
replace_text_with_regexp(t, Regexp.new(word_regexp, case_flag), attrs[:replacement])
end
end
end end

View File

@ -362,6 +362,23 @@ RSpec.describe User do
end end
end end
end end
context "when watched words are of type 'link'" do
let(:value) { "don't replace me" }
let!(:replace_word) do
Fabricate(
:watched_word,
word: "replace",
replacement: "touch",
action: WatchedWord.actions[:link],
)
end
it "does not replace anything" do
user.save!
expect(user_field_value).to eq value
end
end
end end
context "when user fields do not contain watched words" do context "when user fields do not contain watched words" do

View File

@ -361,7 +361,7 @@ RSpec.describe WordWatcher do
end end
end end
describe ".apply_to_text" do describe "word replacement" do
fab!(:censored_word) do fab!(:censored_word) do
Fabricate(:watched_word, word: "censored", action: WatchedWord.actions[:censor]) Fabricate(:watched_word, word: "censored", action: WatchedWord.actions[:censor])
end end
@ -382,6 +382,23 @@ RSpec.describe WordWatcher do
) )
end end
it "censors text" do
expect(described_class.censor_text("a censored word")).to eq(
"a #{described_class::REPLACEMENT_LETTER * 8} word",
)
end
it "replaces text" do
expect(described_class.replace_text("a word to replace meow")).to eq("a word replaced meow")
end
it "replaces links" do
expect(described_class.replace_link("please visit https://notdiscourse.org meow")).to eq(
"please visit https://discourse.org meow",
)
end
describe ".apply_to_text" do
it "replaces all types of words" do it "replaces all types of words" do
text = "hello censored world to replace https://notdiscourse.org" text = "hello censored world to replace https://notdiscourse.org"
expected = expected =
@ -416,3 +433,4 @@ RSpec.describe WordWatcher do
end end
end end
end end
end