2019-04-29 20:27:42 -04:00
# frozen_string_literal: true
2022-07-27 22:27:38 -04:00
RSpec . describe WordWatcher do
2021-05-20 21:43:47 -04:00
let ( :raw ) { " Do you like liquorice? \n \n I really like them. One could even say that I am *addicted* to liquorice. And if \n you can mix it up with some anise, then I'm in heaven ;) " }
2017-06-28 16:56:44 -04:00
after do
2020-05-23 00:56:13 -04:00
Discourse . redis . flushdb
2017-06-28 16:56:44 -04:00
end
2019-07-22 07:59:56 -04:00
describe '.word_matcher_regexp' do
let! ( :word1 ) { Fabricate ( :watched_word , action : WatchedWord . actions [ :block ] ) . word }
let! ( :word2 ) { Fabricate ( :watched_word , action : WatchedWord . actions [ :block ] ) . word }
context 'format of the result regexp' do
it " is correct when watched_words_regular_expressions = true " do
SiteSetting . watched_words_regular_expressions = true
2022-07-26 11:15:42 -04:00
regexp = described_class . word_matcher_regexp ( :block )
2019-07-22 07:59:56 -04:00
expect ( regexp . inspect ) . to eq ( " /( #{ word1 } )|( #{ word2 } )/i " )
end
it " is correct when watched_words_regular_expressions = false " do
SiteSetting . watched_words_regular_expressions = false
2022-07-26 11:15:42 -04:00
regexp = described_class . word_matcher_regexp ( :block )
2019-07-31 13:33:49 -04:00
expect ( regexp . inspect ) . to eq ( " /(?: \\ W|^)( #{ word1 } | #{ word2 } )(?= \\ W|$)/i " )
2019-07-22 07:59:56 -04:00
end
end
end
2022-07-26 11:15:42 -04:00
describe " # word_matches_for_action? " do
2017-06-28 16:56:44 -04:00
it " is falsey when there are no watched words " do
2022-07-26 11:15:42 -04:00
expect ( described_class . new ( raw ) . word_matches_for_action? ( :require_approval ) ) . to be_falsey
2017-06-28 16:56:44 -04:00
end
context " with watched words " do
2019-05-06 23:12:20 -04:00
fab! ( :anise ) { Fabricate ( :watched_word , word : " anise " , action : WatchedWord . actions [ :require_approval ] ) }
2017-06-28 16:56:44 -04:00
it " is falsey without a match " do
2022-07-26 11:15:42 -04:00
expect ( described_class . new ( " No liquorice for me, thanks... " ) . word_matches_for_action? ( :require_approval ) ) . to be_falsey
2017-06-28 16:56:44 -04:00
end
it " is returns matched words if there's a match " do
2022-07-26 11:15:42 -04:00
matches = described_class . new ( raw ) . word_matches_for_action? ( :require_approval )
expect ( matches ) . to be_truthy
expect ( matches [ 1 ] ) . to eq ( anise . word )
2017-06-28 16:56:44 -04:00
end
it " finds at start of string " do
2022-07-26 11:15:42 -04:00
matches = described_class . new ( " #{ anise . word } is garbage " ) . word_matches_for_action? ( :require_approval )
expect ( matches [ 1 ] ) . to eq ( anise . word )
2017-06-28 16:56:44 -04:00
end
it " finds at end of string " do
2022-07-26 11:15:42 -04:00
matches = described_class . new ( " who likes #{ anise . word } " ) . word_matches_for_action? ( :require_approval )
expect ( matches [ 1 ] ) . to eq ( anise . word )
2017-06-28 16:56:44 -04:00
end
it " finds non-letters in place of letters " do
Fabricate ( :watched_word , word : " co(onut " , action : WatchedWord . actions [ :require_approval ] )
2022-07-26 11:15:42 -04:00
matches = described_class . new ( " This co(onut is delicious. " ) . word_matches_for_action? ( :require_approval )
expect ( matches [ 1 ] ) . to eq ( " co(onut " )
2017-06-28 16:56:44 -04:00
end
it " handles * for wildcards " do
Fabricate ( :watched_word , word : " a**le* " , action : WatchedWord . actions [ :require_approval ] )
2022-07-26 11:15:42 -04:00
matches = described_class . new ( " I acknowledge you. " ) . word_matches_for_action? ( :require_approval )
expect ( matches [ 1 ] ) . to eq ( " acknowledge " )
2017-06-28 16:56:44 -04:00
end
2017-09-27 15:48:57 -04:00
2019-02-17 23:24:27 -05:00
context " word boundary " do
it " handles word boundary " do
Fabricate ( :watched_word , word : " love " , action : WatchedWord . actions [ :require_approval ] )
2022-07-26 11:15:42 -04:00
expect ( described_class . new ( " I Love, bananas. " ) . word_matches_for_action? ( :require_approval ) [ 1 ] ) . to eq ( " Love " )
expect ( described_class . new ( " I LOVE; apples. " ) . word_matches_for_action? ( :require_approval ) [ 1 ] ) . to eq ( " LOVE " )
expect ( described_class . new ( " love: is a thing. " ) . word_matches_for_action? ( :require_approval ) [ 1 ] ) . to eq ( " love " )
expect ( described_class . new ( " I love. oranges " ) . word_matches_for_action? ( :require_approval ) [ 1 ] ) . to eq ( " love " )
expect ( described_class . new ( " I :love. pineapples " ) . word_matches_for_action? ( :require_approval ) [ 1 ] ) . to eq ( " love " )
expect ( described_class . new ( " peace ,love and understanding. " ) . word_matches_for_action? ( :require_approval ) [ 1 ] ) . to eq ( " love " )
2019-02-17 23:24:27 -05:00
end
end
2019-07-22 07:59:56 -04:00
context 'multiple matches' do
context 'non regexp words' do
it 'lists all matching words' do
%w{ bananas hate hates } . each do | word |
Fabricate ( :watched_word , word : word , action : WatchedWord . actions [ :block ] )
end
2022-07-26 11:15:42 -04:00
matches = described_class . new ( " I hate bananas " ) . word_matches_for_action? ( :block , all_matches : true )
2019-07-22 07:59:56 -04:00
expect ( matches ) . to contain_exactly ( 'hate' , 'bananas' )
2022-07-26 11:15:42 -04:00
matches = described_class . new ( " She hates bananas too " ) . word_matches_for_action? ( :block , all_matches : true )
2019-07-22 07:59:56 -04:00
expect ( matches ) . to contain_exactly ( 'hates' , 'bananas' )
end
end
context 'regexp words' do
before do
SiteSetting . watched_words_regular_expressions = true
end
it 'lists all matching patterns' do
Fabricate ( :watched_word , word : " (pine)?apples " , action : WatchedWord . actions [ :block ] )
Fabricate ( :watched_word , word : " ((move|store)(d)?)|((watch|listen)(ed|ing)?) " , action : WatchedWord . actions [ :block ] )
2022-07-26 11:15:42 -04:00
matches = described_class . new ( " pine pineapples apples " ) . word_matches_for_action? ( :block , all_matches : true )
2019-07-22 07:59:56 -04:00
expect ( matches ) . to contain_exactly ( 'pineapples' , 'apples' )
2022-07-26 11:15:42 -04:00
matches = described_class . new ( " go watched watch ed ing move d moveed moved moving " ) . word_matches_for_action? ( :block , all_matches : true )
2019-07-22 07:59:56 -04:00
expect ( matches ) . to contain_exactly ( * %w{ watched watch move moved } )
end
end
end
2019-02-15 10:25:48 -05:00
context " emojis " do
it " handles emoji " do
Fabricate ( :watched_word , word : " :joy: " , action : WatchedWord . actions [ :require_approval ] )
2022-07-26 11:15:42 -04:00
matches = described_class . new ( " Lots of emojis here :joy: " ) . word_matches_for_action? ( :require_approval )
expect ( matches [ 1 ] ) . to eq ( " :joy: " )
2019-02-15 10:25:48 -05:00
end
it " handles unicode emoji " do
Fabricate ( :watched_word , word : " 🎃 " , action : WatchedWord . actions [ :require_approval ] )
2022-07-26 11:15:42 -04:00
matches = described_class . new ( " Halloween party! 🎃 " ) . word_matches_for_action? ( :require_approval )
expect ( matches [ 1 ] ) . to eq ( " 🎃 " )
2019-02-15 10:25:48 -05:00
end
it " handles emoji skin tone " do
Fabricate ( :watched_word , word : " :woman:t5: " , action : WatchedWord . actions [ :require_approval ] )
2022-07-26 11:15:42 -04:00
matches = described_class . new ( " To Infinity and beyond! 🚀 :woman:t5: " ) . word_matches_for_action? ( :require_approval )
expect ( matches [ 1 ] ) . to eq ( " :woman:t5: " )
2019-02-15 10:25:48 -05:00
end
end
2017-11-17 14:10:38 -05:00
context " regular expressions " do
before do
SiteSetting . watched_words_regular_expressions = true
end
it " supports regular expressions on word boundaries " do
Fabricate (
:watched_word ,
word : / \ btest \ b / ,
action : WatchedWord . actions [ :block ]
)
2022-07-26 11:15:42 -04:00
matches = described_class . new ( " this is not a test. " ) . word_matches_for_action? ( :block )
expect ( matches [ 0 ] ) . to eq ( " test " )
2017-11-17 14:10:38 -05:00
end
it " supports regular expressions as a site setting " do
Fabricate (
:watched_word ,
word : / tro[uo]+t / ,
action : WatchedWord . actions [ :require_approval ]
)
2022-07-26 11:15:42 -04:00
matches = described_class . new ( " Evil Trout is cool " ) . word_matches_for_action? ( :require_approval )
expect ( matches [ 0 ] ) . to eq ( " Trout " )
matches = described_class . new ( " Evil Troot is cool " ) . word_matches_for_action? ( :require_approval )
expect ( matches [ 0 ] ) . to eq ( " Troot " )
matches = described_class . new ( " trooooooooot " ) . word_matches_for_action? ( :require_approval )
expect ( matches [ 0 ] ) . to eq ( " trooooooooot " )
2017-11-17 14:10:38 -05:00
end
2018-01-09 16:51:45 -05:00
it " support uppercase " do
Fabricate (
:watched_word ,
word : / a \ S+ce / ,
action : WatchedWord . actions [ :require_approval ]
)
2022-07-26 11:15:42 -04:00
matches = described_class . new ( 'Amazing place' ) . word_matches_for_action? ( :require_approval )
expect ( matches ) . to be_nil
matches = described_class . new ( 'Amazing applesauce' ) . word_matches_for_action? ( :require_approval )
expect ( matches [ 0 ] ) . to eq ( 'applesauce' )
matches = described_class . new ( 'Amazing AppleSauce' ) . word_matches_for_action? ( :require_approval )
expect ( matches [ 0 ] ) . to eq ( 'AppleSauce' )
2018-01-09 16:51:45 -05:00
end
2017-09-27 15:48:57 -04:00
end
2017-11-17 14:10:38 -05:00
2017-06-28 16:56:44 -04:00
end
end
2022-07-26 11:15:42 -04:00
describe " .apply_to_text " do
fab! ( :censored_word ) { Fabricate ( :watched_word , word : " censored " , action : WatchedWord . actions [ :censor ] ) }
fab! ( :replaced_word ) { Fabricate ( :watched_word , word : " to replace " , replacement : " replaced " , action : WatchedWord . actions [ :replace ] ) }
fab! ( :link_word ) { Fabricate ( :watched_word , word : " https://notdiscourse.org " , replacement : " https://discourse.org " , action : WatchedWord . actions [ :link ] ) }
it " replaces all types of words " do
text = " hello censored world to replace https://notdiscourse.org "
expected = " hello #{ described_class :: REPLACEMENT_LETTER * 8 } world replaced https://discourse.org "
expect ( described_class . apply_to_text ( text ) ) . to eq ( expected )
end
end
2017-06-28 16:56:44 -04:00
end