docbrown/spec/services/spam/article_handler_spec.rb
Jeremy Friesen 91b951eb05
Refactoring and extending article spam behavior (#15399)
* Refactoring and extending article spam behavior

Prior to this refactor, we were checking an Article's title for
spaminess.  This change now checks the Article's title and
body_markdown.

In addition, the encapsulates the regular expression implementations in
favor of asking the Settings::RateLimit class to determine if the passed
in text is "spammy".

Furthermore, instead of having lots of inline logic within the article,
this refactor introduces a `Spam::ArticleHandler` class.  This helps
tidy up the already busy Article specs by delegating the business logic
of Spam handling to it's own class.

There are further refactors for Comments and Users that would follow
this pattern, but this change is more important to get out the door.

Closes #15396

* Adding comments to clarify behavior of spam handling

* Adding missing expectation to spec
2021-11-17 17:09:17 -05:00

52 lines
2.2 KiB
Ruby

require "rails_helper"
RSpec.describe Spam::ArticleHandler, type: :service do
describe ".handle!" do
subject(:handler) { described_class.handle!(article: article) }
let!(:article) { create(:article) }
let(:mascot_user) { create(:user) }
before do
allow(Settings::General).to receive(:mascot_user_id).and_return(mascot_user.id)
end
context "when non-spammy content" do
before do
allow(Settings::RateLimit).to receive(:trigger_spam_for?).with(text: article.title).and_return(false)
allow(Settings::RateLimit).to receive(:trigger_spam_for?).with(text: article.body_markdown).and_return(false)
end
it { is_expected.to eq(:not_spam) }
end
context "when first time spammy content" do
before do
allow(Settings::RateLimit).to receive(:trigger_spam_for?).with(text: article.title).and_return(true)
allow(Settings::RateLimit).to receive(:trigger_spam_for?).with(text: article.body_markdown).and_return(false)
allow(Reaction).to receive(:user_has_been_given_too_many_spammy_reactions?)
.with(user: article.user).and_return(false)
end
it "creates a reaction but does not suspend the user" do
expect { handler }.to change { Reaction.where(reactable: article, category: "vomit").count }.by(1)
expect(article.user.reload).not_to be_suspended
end
end
context "when multiple offender of spammy" do
before do
allow(Settings::RateLimit).to receive(:trigger_spam_for?).with(text: article.title).and_return(true)
allow(Settings::RateLimit).to receive(:trigger_spam_for?).with(text: article.body_markdown).and_return(false)
allow(Reaction).to receive(:user_has_been_given_too_many_spammy_reactions?)
.with(user: article.user).and_return(true)
end
it "creates a reaction, suspends the user, and creates a note for the user" do
expect { handler }.to change { Reaction.where(reactable: article, category: "vomit").count }.by(1)
expect(article.user.reload).to be_suspended
expect(Note.where(noteable: article.user, reason: "automatic_suspend").count).to eq(1)
end
end
end
end