discourse/spec/integration/watched_words_spec.rb
Sam Saffron 4ea21fa2d0 DEV: use #frozen_string_literal: true on all spec
This change both speeds up specs (less strings to allocate) and helps catch
cases where methods in Discourse are mutating inputs.

Overall we will be migrating everything to use #frozen_string_literal: true
it will take a while, but this is the first and safest move in this direction
2019-04-30 10:27:42 +10:00

206 lines
8.0 KiB
Ruby

# frozen_string_literal: true
require 'rails_helper'
describe WatchedWord do
let(:tl2_user) { Fabricate(:user, trust_level: TrustLevel[2]) }
let(:admin) { Fabricate(:admin) }
let(:moderator) { Fabricate(:moderator) }
let(:topic) { Fabricate(:topic) }
let(:first_post) { Fabricate(:post, topic: topic) }
let(:require_approval_word) { Fabricate(:watched_word, action: WatchedWord.actions[:require_approval]) }
let(:flag_word) { Fabricate(:watched_word, action: WatchedWord.actions[:flag]) }
let(:block_word) { Fabricate(:watched_word, action: WatchedWord.actions[:block]) }
after do
$redis.flushall
end
context "block" do
def should_block_post(manager)
expect {
result = manager.perform
expect(result).to_not be_success
expect(result.errors[:base]&.first).to eq(I18n.t('contains_blocked_words', word: block_word.word))
}.to_not change { Post.count }
end
it "should prevent the post from being created" do
manager = NewPostManager.new(tl2_user, raw: "Want some #{block_word.word} for cheap?", topic_id: topic.id)
should_block_post(manager)
end
it "look at title too" do
manager = NewPostManager.new(tl2_user, title: "We sell #{block_word.word} online", raw: "Want some poutine for cheap?", topic_id: topic.id)
should_block_post(manager)
end
it "should not block the post from admin" do
manager = NewPostManager.new(admin, raw: "Want some #{block_word.word} for cheap?", topic_id: topic.id)
result = manager.perform
expect(result).to be_success
expect(result.action).to eq(:create_post)
end
it "should not block the post from moderator" do
manager = NewPostManager.new(moderator, raw: "Want some #{block_word.word} for cheap?", topic_id: topic.id)
result = manager.perform
expect(result).to be_success
expect(result.action).to eq(:create_post)
end
it "should block in a private message too" do
manager = NewPostManager.new(
tl2_user,
raw: "Want some #{block_word.word} for cheap?",
title: 'this is a new title',
archetype: Archetype.private_message,
target_usernames: Fabricate(:user, trust_level: TrustLevel[2]).username
)
should_block_post(manager)
end
it "blocks on revisions" do
post = Fabricate(:post, topic: Fabricate(:topic, user: tl2_user), user: tl2_user)
expect {
PostRevisor.new(post).revise!(post.user, { raw: "Want some #{block_word.word} for cheap?" }, revised_at: post.updated_at + 10.seconds)
expect(post.errors).to be_present
post.reload
}.to_not change { post.raw }
end
end
context "require_approval" do
it "should queue the post for approval" do
manager = NewPostManager.new(tl2_user, raw: "My dog's name is #{require_approval_word.word}.", topic_id: topic.id)
result = manager.perform
expect(result.action).to eq(:enqueued)
expect(result.reason).to eq(:watched_word)
end
it "looks at title too" do
manager = NewPostManager.new(tl2_user, title: "You won't believe these #{require_approval_word.word} dog names!", raw: "My dog's name is Porkins.", topic_id: topic.id)
result = manager.perform
expect(result.action).to eq(:enqueued)
end
it "should not queue posts from admin" do
manager = NewPostManager.new(admin, raw: "My dog's name is #{require_approval_word.word}.", topic_id: topic.id)
result = manager.perform
expect(result).to be_success
expect(result.action).to eq(:create_post)
end
it "should not queue posts from moderator" do
manager = NewPostManager.new(moderator, raw: "My dog's name is #{require_approval_word.word}.", topic_id: topic.id)
result = manager.perform
expect(result).to be_success
expect(result.action).to eq(:create_post)
end
it "doesn't need approval in a private message" do
manager = NewPostManager.new(
tl2_user,
raw: "Want some #{require_approval_word.word} for cheap?",
title: 'this is a new title',
archetype: Archetype.private_message,
target_usernames: Fabricate(:user, trust_level: TrustLevel[2]).username
)
result = manager.perform
expect(result).to be_success
expect(result.action).to eq(:create_post)
end
end
context "flag" do
def should_flag_post(author, raw, topic)
post = Fabricate(:post, raw: raw, topic: topic, user: author)
expect {
Jobs::ProcessPost.new.execute(post_id: post.id)
}.to change { PostAction.count }.by(1)
expect(PostAction.where(post_id: post.id, post_action_type_id: PostActionType.types[:inappropriate]).exists?).to eq(true)
end
def should_not_flag_post(author, raw, topic)
post = Fabricate(:post, raw: raw, topic: topic, user: author)
expect {
Jobs::ProcessPost.new.execute(post_id: post.id)
}.to_not change { PostAction.count }
end
it "should flag the post as inappropriate" do
should_flag_post(tl2_user, "I thought the #{flag_word.word} was bad.", Fabricate(:topic, user: tl2_user))
end
it "should look at the title too" do
should_flag_post(tl2_user, "I thought the movie was not bad actually.", Fabricate(:topic, user: tl2_user, title: "Read my #{flag_word.word} review!"))
end
it "shouldn't flag posts by admin" do
should_not_flag_post(admin, "I thought the #{flag_word.word} was bad.", Fabricate(:topic, user: admin))
end
it "shouldn't flag posts by moderator" do
should_not_flag_post(moderator, "I thought the #{flag_word.word} was bad.", Fabricate(:topic, user: moderator))
end
it "is compatible with flag_sockpuppets" do
SiteSetting.flag_sockpuppets = true
ip_address = '182.189.119.174'
user1 = Fabricate(:user, ip_address: ip_address, created_at: 2.days.ago)
user2 = Fabricate(:user, ip_address: ip_address)
first = create_post(user: user1, created_at: 2.days.ago)
sockpuppet_post = create_post(user: user2, topic: first.topic, raw: "I thought the #{flag_word.word} was bad.")
expect(PostAction.where(post_id: sockpuppet_post.id).count).to eq(1)
end
it "flags in private message too" do
post = Fabricate(:private_message_post, raw: "Want some #{flag_word.word} for cheap?", user: tl2_user)
expect {
Jobs::ProcessPost.new.execute(post_id: post.id)
}.to change { PostAction.count }.by(1)
expect(PostAction.where(post_id: post.id, post_action_type_id: PostActionType.types[:inappropriate]).exists?).to eq(true)
end
it "flags on revisions" do
Jobs.run_immediately!
post = Fabricate(:post, topic: Fabricate(:topic, user: tl2_user), user: tl2_user)
expect {
PostRevisor.new(post).revise!(post.user, { raw: "Want some #{flag_word.word} for cheap?" }, revised_at: post.updated_at + 10.seconds)
}.to change { PostAction.count }.by(1)
expect(PostAction.where(post_id: post.id, post_action_type_id: PostActionType.types[:inappropriate]).exists?).to eq(true)
end
it "should not flag on rebake" do
post = Fabricate(:post, topic: Fabricate(:topic, user: tl2_user), user: tl2_user, raw: "I have coupon codes. Message me.")
Fabricate(:watched_word, action: WatchedWord.actions[:flag], word: "coupon")
expect {
post.rebake!
}.to_not change { PostAction.count }
end
end
describe 'upload' do
context 'logged in as admin' do
before do
sign_in(admin)
end
it 'creates the words from the file' do
post '/admin/logs/watched_words/upload.json', params: {
action_key: 'flag',
file: Rack::Test::UploadedFile.new(file_from_fixtures("words.csv", "csv"))
}
expect(response.status).to eq(200)
expect(WatchedWord.count).to eq(6)
expect(WatchedWord.pluck(:word)).to contain_exactly(
'thread', '线', 'धागा', '실', 'tråd', 'нить'
)
expect(WatchedWord.pluck(:action).uniq).to eq([WatchedWord.actions[:flag]])
end
end
end
end