Add Slack messengers: part 2 (#6916)

* Add Slack::Messengers::ArticlePublished

* Add Slack::Messengers::ReactionVomit

* Add Slack::Messengers::CommentUserWarned

* Add missing URL helpers

* Add Slack::Messengers::ArticleFetchedFeed

* Remove callback condition

* Build, don't create
This commit is contained in:
rhymes 2020-04-03 17:00:06 +02:00 committed by GitHub
parent d6e5808dec
commit f2b0be2043
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 516 additions and 159 deletions

View file

@ -182,14 +182,22 @@ module ApplicationHelper
URL.url(uri)
end
def tag_url(tag, page)
URL.tag(tag, page)
end
def article_url(article)
URL.article(article)
end
def comment_url(comment)
URL.comment(comment)
end
def reaction_url(reaction)
URL.reaction(reaction)
end
def tag_url(tag, page)
URL.tag(tag, page)
end
def user_url(user)
URL.user(user)
end

View file

@ -30,7 +30,23 @@ module URL
url(article.path)
end
# Creates an article URL
# Creates a comment URL
#
# @param comment [Comment] the comment to create the URL for
def self.comment(comment)
url(comment.path)
end
# Creates a reaction URL
#
# A reaction URL is the URL of its reactable.
#
# @param reactable [Reaction] the reaction to create the URL for
def self.reaction(reaction)
url(reaction.reactable.path)
end
# Creates a tag URL
#
# @param tag [Tag] the tag to create the URL for
def self.tag(tag, page = 1)

View file

@ -72,7 +72,7 @@ class Article < ApplicationRecord
before_save :update_cached_user
after_save :bust_cache, :detect_human_language
after_save :notify_slack_channel_about_publication, if: -> { published && published_at > 30.seconds.ago }
after_save :notify_slack_channel_about_publication
after_update_commit :update_notifications, if: proc { |article| article.notifications.any? && !article.saved_changes.empty? }
after_update_commit :update_reading_list_reactions, if: proc { |article|
@ -718,18 +718,6 @@ class Article < ApplicationRecord
end
def notify_slack_channel_about_publication
url = "#{ApplicationConfig['APP_PROTOCOL']}#{ApplicationConfig['APP_DOMAIN']}"
message = <<~MESSAGE.chomp
New Article Published: #{title}
#{url}#{path}
MESSAGE
SlackBotPingWorker.perform_async(
message: message,
channel: "activity",
username: "article_bot",
icon_emoji: ":writing_hand:",
)
Slack::Messengers::ArticlePublished.call(article: self)
end
end

View file

@ -27,7 +27,7 @@ class Comment < ApplicationRecord
validates :commentable_type, inclusion: { in: %w[Article PodcastEpisode] }
validates :user_id, presence: true
after_create :notify_slack_channel_about_warned_users, if: -> { user.warned }
after_create :notify_slack_channel_about_warned_users
after_create :after_create_checks
after_create_commit :record_field_test_event
after_commit :calculate_score
@ -248,20 +248,6 @@ class Comment < ApplicationRecord
end
def notify_slack_channel_about_warned_users
url = "#{ApplicationConfig['APP_PROTOCOL']}#{ApplicationConfig['APP_DOMAIN']}"
message = <<~MESSAGE.chomp
Activity: #{url}#{path}
Comment text: #{body_markdown.truncate(300)}
---
Manage commenter - @#{user.username}: #{url}/internal/users/#{user.id}
MESSAGE
SlackBotPingWorker.perform_async(
message: message,
channel: "warned-user-comments",
username: "sloan_watch_bot",
icon_emoji: ":sloan:",
)
Slack::Messengers::CommentUserWarned.call(comment: self)
end
end

View file

@ -216,19 +216,6 @@ class Reaction < ApplicationRecord
end
def notify_slack_channel_about_vomit_reaction
url = "#{ApplicationConfig['APP_PROTOCOL']}#{ApplicationConfig['APP_DOMAIN']}"
message = <<~MESSAGE.chomp
#{user.name} (#{url}#{user.path})
reacted with a #{category} on
#{url}#{reactable.path}
MESSAGE
SlackBotPingWorker.perform_async(
message: message,
channel: "abuse-reports",
username: "abuse_bot",
icon_emoji: ":cry:",
)
Slack::Messengers::ReactionVomit.call(reaction: self)
end
end

View file

@ -79,7 +79,7 @@ class RssReader
organization_id: nil,
)
send_slack_notification(article)
Slack::Messengers::ArticleFetchedFeed.call(article: article)
end
def get_host_without_www(url)
@ -108,17 +108,6 @@ class RssReader
relation.where(title: title).or(relation.where(feed_source_url: feed_source_url)).exists?
end
def send_slack_notification(article)
return unless Rails.env.production?
SlackBotPingWorker.perform_async(
message: "New Article Retrieved via RSS: #{article.title}\nhttps://dev.to#{article.path}",
channel: "activity",
username: "article_bot",
icon_emoji: ":robot_face:",
)
end
def log_error(error_msg, metadata)
Rails.logger.error(error_msg, metadata)
end

View file

@ -0,0 +1,39 @@
module Slack
module Messengers
class ArticleFetchedFeed
MESSAGE_TEMPLATE = <<~TEXT.chomp.freeze
New Article Retrieved via RSS: %<title>s
%<url>s
TEXT
def initialize(article:)
@article = article
end
def self.call(*args)
new(*args).call
end
def call
return unless article.published_from_feed?
message = format(
MESSAGE_TEMPLATE,
title: article.title,
url: URL.article(article),
)
SlackBotPingWorker.perform_async(
message: message,
channel: "activity",
username: "article_bot",
icon_emoji: ":robot_face:",
)
end
private
attr_reader :article
end
end
end

View file

@ -0,0 +1,39 @@
module Slack
module Messengers
class ArticlePublished
MESSAGE_TEMPLATE = <<~TEXT.chomp.freeze
New Article Published: %<title>s
%<url>s
TEXT
def initialize(article:)
@article = article
end
def self.call(*args)
new(*args).call
end
def call
return unless article.published && article.published_at > 30.seconds.ago
message = format(
MESSAGE_TEMPLATE,
title: article.title,
url: URL.article(article),
)
SlackBotPingWorker.perform_async(
message: message,
channel: "activity",
username: "article_bot",
icon_emoji: ":writing_hand:",
)
end
private
attr_reader :article
end
end
end

View file

@ -0,0 +1,48 @@
module Slack
module Messengers
class CommentUserWarned
MESSAGE_TEMPLATE = <<~TEXT.chomp.freeze
Activity: %<url>s
Comment text: %<text>s
---
Manage commenter - @%<username>s: %<internal_user_url>s
TEXT
def initialize(comment:)
@comment = comment
@user = comment.user
end
def self.call(*args)
new(*args).call
end
def call
return unless user.warned
internal_user_url = URL.url(
Rails.application.routes.url_helpers.internal_user_path(user),
)
message = format(
MESSAGE_TEMPLATE,
url: URL.comment(comment),
text: comment.body_markdown.truncate(300),
username: user.username,
internal_user_url: internal_user_url,
)
SlackBotPingWorker.perform_async(
message: message,
channel: "warned-user-comments",
username: "sloan_watch_bot",
icon_emoji: ":sloan:",
)
end
private
attr_reader :comment, :user
end
end
end

View file

@ -0,0 +1,43 @@
module Slack
module Messengers
class ReactionVomit
MESSAGE_TEMPLATE = <<~TEXT.chomp.freeze
%<name>s (%<user_url>s)
reacted with a vomit on
%<reactable_url>s
TEXT
def initialize(reaction:)
@reaction = reaction
end
def self.call(*args)
new(*args).call
end
def call
return unless reaction.category == "vomit"
user = reaction.user
message = format(
MESSAGE_TEMPLATE,
name: user.name,
user_url: URL.user(user),
reactable_url: URL.reaction(reaction),
)
SlackBotPingWorker.perform_async(
message: message,
channel: "abuse-reports",
username: "abuse_bot",
icon_emoji: ":cry:",
)
end
private
attr_reader :reaction
end
end
end

View file

@ -45,6 +45,28 @@ RSpec.describe URL, type: :lib do
end
end
describe ".comment" do
let(:comment) { build(:comment) }
it "returns the correct URL for a comment" do
expect(described_class.comment(comment)).to eq("https://dev.to#{comment.path}")
end
end
describe ".reaction" do
it "returns the correct URL for an article's reaction" do
article = build(:article, path: "/username1/slug")
reaction = build(:reaction, reactable: article)
expect(described_class.reaction(reaction)).to eq("https://dev.to#{article.path}")
end
it "returns the correct URL for a comment's reaction" do
comment = build(:comment)
reaction = build(:reaction, reactable: comment)
expect(described_class.reaction(reaction)).to eq("https://dev.to#{comment.path}")
end
end
describe ".user" do
let(:user) { build(:user) }

View file

@ -793,46 +793,33 @@ RSpec.describe Article, type: :model do
end
end
describe "slack notifications" do
describe "slack messages" do
before do
# making sure there are no other enqueued jobs from other tests
sidekiq_perform_enqueued_jobs(only: SlackBotPingWorker)
end
it "notifies the proper slack channel about a recently published new article" do
Timecop.freeze(Time.current) do
article = create(:article, published: true)
url = "#{ApplicationConfig['APP_PROTOCOL']}#{ApplicationConfig['APP_DOMAIN']}"
message = "New Article Published: #{article.title}\n#{url}#{article.path}"
args = {
message: message,
channel: "activity",
username: "article_bot",
icon_emoji: ":writing_hand:"
}.stringify_keys
sidekiq_assert_enqueued_jobs(1, only: SlackBotPingWorker)
job = sidekiq_enqueued_jobs(worker: SlackBotPingWorker).last
expect(job["args"]).to eq([args])
it "queues a slack message to be sent" do
sidekiq_assert_enqueued_jobs(1, only: SlackBotPingWorker) do
article.update(published: true, published_at: Time.current)
end
end
it "does not send a notification for a new article published more than 30 seconds ago" do
it "does not queue a message for an article published more than 30 seconds ago" do
Timecop.freeze(Time.current) do
sidekiq_assert_no_enqueued_jobs(only: SlackBotPingWorker) do
create(:article, published: true, published_at: 31.seconds.ago)
article.update(published: true, published_at: 31.seconds.ago)
end
end
end
it "does not send a notification for a non published article" do
it "does not queue a message for a draft article" do
sidekiq_assert_no_enqueued_jobs(only: SlackBotPingWorker) do
create(:article, published: false)
article.update(body_markdown: "foobar", published: false)
end
end
it "sends a notification for a draft article that gets published" do
it "queues a message for a draft article that gets published" do
Timecop.freeze(Time.current) do
sidekiq_assert_enqueued_with(job: SlackBotPingWorker) do
article.update_columns(published: false)

View file

@ -312,35 +312,20 @@ RSpec.describe Comment, type: :model do
expect { comment.save }.to change(user, :last_comment_at)
end
describe "slack notifications" do
describe "slack messages" do
let!(:user) { create(:user) }
before do
# making sure there are no other enqueued jobs from other tests
sidekiq_perform_enqueued_jobs(only: SlackBotPingWorker)
end
it "notifies proper slack channel when a warned user leaves a comment" do
user = create(:user)
it "queues a slack message when a warned user leaves a comment" do
user.add_role(:warned)
comment = create(:comment, user: user, commentable: article)
url = "#{ApplicationConfig['APP_PROTOCOL']}#{ApplicationConfig['APP_DOMAIN']}"
message = <<~MESSAGE.chomp
Activity: #{url}#{comment.path}
Comment text: #{comment.body_markdown.truncate(300)}
---
Manage commenter - @#{user.username}: #{url}/internal/users/#{user.id}
MESSAGE
args = {
message: message,
channel: "warned-user-comments",
username: "sloan_watch_bot",
icon_emoji: ":sloan:"
}.stringify_keys
sidekiq_assert_enqueued_jobs(1, only: SlackBotPingWorker)
job = sidekiq_enqueued_jobs(worker: SlackBotPingWorker).last
expect(job["args"]).to eq([args])
sidekiq_assert_enqueued_jobs(1, only: SlackBotPingWorker) do
create(:comment, user: user, commentable: article)
end
end
it "does not send notification if a regular user leaves a comment" do

View file

@ -181,7 +181,7 @@ RSpec.describe Reaction, type: :model do
end
context "when callbacks are called after create" do
describe "slack notifications" do
describe "slack messages" do
let_it_be_changeable(:user) { create(:user, :trusted) }
let_it_be_readonly(:article) { create(:article, user: user) }
@ -190,28 +190,19 @@ RSpec.describe Reaction, type: :model do
sidekiq_perform_enqueued_jobs(only: SlackBotPingWorker)
end
it "notifies proper slack channel about vomit reaction" do
url = "#{ApplicationConfig['APP_PROTOCOL']}#{ApplicationConfig['APP_DOMAIN']}"
message = "#{user.name} (#{url}#{user.path})\nreacted with a vomit on\n#{url}#{article.path}"
args = {
message: message,
channel: "abuse-reports",
username: "abuse_bot",
icon_emoji: ":cry:"
}.stringify_keys
sidekiq_assert_enqueued_with(job: SlackBotPingWorker, args: [args]) do
it "queues a slack message to be sent for a vomit reaction" do
sidekiq_assert_enqueued_jobs(1, only: SlackBotPingWorker) do
create(:reaction, reactable: article, user: user, category: "vomit")
end
end
it "does not send notification for like reaction" do
it "does not queue a message for a like reaction" do
sidekiq_assert_no_enqueued_jobs(only: SlackBotPingWorker) do
create(:reaction, reactable: article, user: user, category: "like")
end
end
it "does not send notification for thumbsdown reaction" do
it "does not queue a message for a thumbsdown reaction" do
sidekiq_assert_no_enqueued_jobs(only: SlackBotPingWorker) do
create(:reaction, reactable: article, user: user, category: "thumbsdown")
end

View file

@ -1,18 +1,14 @@
require "rails_helper"
require "rss"
vcr_option = {
cassette_name: "rss_feeds",
allow_playback_repeats: "true"
}
default_logger = Rails.logger
RSpec.describe RssReader, type: :service, vcr: vcr_option do
RSpec.describe RssReader, type: :service, vcr: VCR_OPTIONS[:rss_feeds] do
let(:link) { "https://medium.com/feed/@vaidehijoshi" }
let(:nonmedium_link) { "https://circleci.com/blog/feed.xml" }
let(:nonpermanent_link) { "https://medium.com/feed/@macsiri/" }
let(:rss_data) { RSS::Parser.parse(HTTParty.get(link).body, false) }
let!(:rss_reader) { described_class.new }
# Override the default Rails logger as these tests require the Timber logger.
before do
@ -30,66 +26,91 @@ RSpec.describe RssReader, type: :service, vcr: vcr_option do
end
it "fetch only articles from an feed_url" do
described_class.get_all_articles
rss_reader.get_all_articles
# the result within the approval file depends on the feed
# not fetching comments is baked into this
verify(format: :txt) { Article.count }
end
it "does not re-create article if it already exist" do
described_class.new.get_all_articles
expect { described_class.new.get_all_articles }.not_to change(Article, :count)
rss_reader.get_all_articles
expect { rss_reader.get_all_articles }.not_to change(Article, :count)
end
it "parses correctly" do
described_class.new.get_all_articles
rss_reader.get_all_articles
verify format: :txt do
User.find_by(feed_url: nonpermanent_link).articles.first.body_markdown
end
end
it "sets time current" do
described_class.new.get_all_articles
expect(User.find_by(feed_url: nonpermanent_link).feed_fetched_at).to be > 2.minutes.ago
it "sets feed_fetched_at to the current time" do
Timecop.freeze(Time.current) do
rss_reader.get_all_articles
user = User.find_by(feed_url: nonpermanent_link)
feed_fetched_at = user.feed_fetched_at
expect(feed_fetched_at.to_i).to eq(Time.current.to_i)
end
end
it "does refetch same user over and over by default" do
user = User.find_by(feed_url: nonpermanent_link)
Timecop.freeze(Time.current) do
user.update_column(:feed_fetched_at, Time.current)
user.update_columns(feed_fetched_at: Time.current)
fetched_at_time = user.reload.feed_fetched_at
# travel a few seconds in the future to simulate a new time
3.times do |i|
Timecop.travel((i + 5).seconds.from_now) { described_class.new.get_all_articles }
Timecop.travel((i + 5).seconds.from_now) do
rss_reader.get_all_articles
end
end
expect(user.reload.feed_fetched_at > fetched_at_time).to be(true)
end
end
it "logs an article creation error" do
reader = described_class.new
allow(reader).to receive(:make_from_rss_item).and_raise(StandardError)
allow(rss_reader).to receive(:make_from_rss_item).and_raise(StandardError)
allow(Rails.logger).to receive(:error)
reader.get_all_articles
rss_reader.get_all_articles
expect(Rails.logger).to have_received(:error).at_least(:once)
end
it "logs a fetching error" do
reader = described_class.new
allow(reader).to receive(:fetch_rss).and_raise(StandardError)
allow(rss_reader).to receive(:fetch_rss).and_raise(StandardError)
allow(Rails.logger).to receive(:error)
reader.get_all_articles
rss_reader.get_all_articles
expect(Rails.logger).to have_received(:error).at_least(:once)
end
it "queues as many slack messages as there are articles" do
expect do
rss_reader.get_all_articles
end.to change(SlackBotPingWorker.jobs, :count).by(12)
end
end
context "when feed_referential_link is false" do
it "does not self-reference links for user" do
# Article.find_by is used by find_and_replace_possible_links!
# checking it's invocation s a shortcut to testing the functionality.
# checking its invocation is a shortcut to testing the functionality.
allow(Article).to receive(:find_by).and_call_original
create(:user, feed_url: nonpermanent_link, feed_referential_link: false)
described_class.get_all_articles
rss_reader.get_all_articles
expect(Article).not_to have_received(:find_by)
end
end
@ -102,41 +123,52 @@ RSpec.describe RssReader, type: :service, vcr: vcr_option do
end
it "gets articles for user" do
rss_reader.fetch_user(User.find_by(feed_url: link))
# the result within the approval file depends on the feed
described_class.new.fetch_user(User.first)
verify(format: :txt) { Article.count }
end
it "does not set featured_number" do
described_class.new.fetch_user(User.first)
expect(Article.all.map(&:featured_number).uniq).to eq([nil])
user = User.find_by(feed_url: link)
rss_reader.fetch_user(user)
expect(user.articles.select(&:featured_number)).to be_empty
end
it "logs an article creation error on the standard logger" do
reader = described_class.new
allow(reader).to receive(:make_from_rss_item).and_raise(StandardError)
allow(rss_reader).to receive(:make_from_rss_item).and_raise(StandardError)
allow(Rails.logger).to receive(:error)
reader.fetch_user(User.first)
rss_reader.fetch_user(User.find_by(feed_url: link))
expect(Rails.logger).to have_received(:error).at_least(:once)
end
it "logs a fetching error on the standard logger" do
reader = described_class.new
allow(reader).to receive(:fetch_rss).and_raise(StandardError)
allow(rss_reader).to receive(:fetch_rss).and_raise(StandardError)
allow(Rails.logger).to receive(:error)
reader.fetch_user(User.first)
rss_reader.fetch_user(User.find_by(feed_url: link))
expect(Rails.logger).to have_received(:error).at_least(:once)
end
it "queues as many slack messages as there are user articles" do
expect do
rss_reader.fetch_user(User.find_by(feed_url: link))
end.to change(SlackBotPingWorker.jobs, :count).by(1)
end
end
describe "#valid_feed_url?" do
it "returns true on valid feed url" do
expect(described_class.new.valid_feed_url?(link)).to be true
expect(rss_reader.valid_feed_url?(link)).to be(true)
end
it "returns false on invalid feed url" do
bad_link = "www.google.com"
expect(described_class.new.valid_feed_url?(bad_link)).to be false
expect(rss_reader.valid_feed_url?(bad_link)).to be(false)
end
end
end

View file

@ -0,0 +1,45 @@
require "rails_helper"
RSpec.describe Slack::Messengers::ArticleFetchedFeed, type: :service do
let!(:article) do
build(:article).tap do |article|
article.title = "Awesome article"
article.published_from_feed = true
end
end
let(:default_params) { { article: article } }
it "does not message slack for a new article not coming from the feed" do
sidekiq_assert_no_enqueued_jobs(only: SlackBotPingWorker) do
article.published_from_feed = false
described_class.call(article: article)
end
end
it "contains the correct info", :aggregate_failures do
sidekiq_assert_enqueued_jobs(1, only: SlackBotPingWorker) do
described_class.call(default_params)
end
job = sidekiq_enqueued_jobs(worker: SlackBotPingWorker).last
message = job["args"].first["message"]
expect(message).to include(article.title)
expect(message).to include(URL.article(article))
end
it "messages the proper channel with the proper username and emoji", :aggregate_failures do
sidekiq_assert_enqueued_jobs(1, only: SlackBotPingWorker) do
described_class.call(default_params)
end
job = sidekiq_enqueued_jobs(worker: SlackBotPingWorker).last
job_args = job["args"].first
expect(job_args["channel"]).to eq("activity")
expect(job_args["username"]).to eq("article_bot")
expect(job_args["icon_emoji"]).to eq(":robot_face:")
end
end

View file

@ -0,0 +1,55 @@
require "rails_helper"
RSpec.describe Slack::Messengers::ArticlePublished, type: :service do
let(:article) do
build(:article).tap do |article|
article.title = "Awesome article"
article.published = true
article.published_at = Time.current
end
end
let(:default_params) { { article: article } }
it "does not message slack for a draft article" do
sidekiq_assert_no_enqueued_jobs(only: SlackBotPingWorker) do
article = build(:article, published: false)
described_class.call(article: article)
end
end
it "does not message slack for an article that was published long ago" do
sidekiq_assert_no_enqueued_jobs(only: SlackBotPingWorker) do
article = build(:article).tap do |art|
art.published = true
art.published_at = 1.minute.ago
end
described_class.call(article: article)
end
end
it "contains the correct info", :aggregate_failures do
sidekiq_assert_enqueued_jobs(1, only: SlackBotPingWorker) do
described_class.call(default_params)
end
job = sidekiq_enqueued_jobs(worker: SlackBotPingWorker).last
message = job["args"].first["message"]
expect(message).to include(article.title)
expect(message).to include(URL.article(article))
end
it "messages the proper channel with the proper username and emoji", :aggregate_failures do
sidekiq_assert_enqueued_jobs(1, only: SlackBotPingWorker) do
described_class.call(default_params)
end
job = sidekiq_enqueued_jobs(worker: SlackBotPingWorker).last
job_args = job["args"].first
expect(job_args["channel"]).to eq("activity")
expect(job_args["username"]).to eq("article_bot")
expect(job_args["icon_emoji"]).to eq(":writing_hand:")
end
end

View file

@ -0,0 +1,51 @@
require "rails_helper"
RSpec.describe Slack::Messengers::CommentUserWarned, type: :service do
let(:comment) { create(:comment) }
let(:user) { comment.user }
let(:default_params) { { comment: comment } }
it "does not message slack for a comment with a regular user" do
sidekiq_assert_no_enqueued_jobs(only: SlackBotPingWorker) do
described_class.call(comment: build(:comment, user: build(:user)))
end
end
context "when the uesr has been warned" do
before do
user.add_role(:warned)
end
it "contains the correct info", :aggregate_failures do
sidekiq_assert_enqueued_jobs(1, only: SlackBotPingWorker) do
described_class.call(default_params)
end
job = sidekiq_enqueued_jobs(worker: SlackBotPingWorker).last
message = job["args"].first["message"]
internal_user_url = URL.url(
Rails.application.routes.url_helpers.internal_user_path(user),
)
expect(message).to include(URL.comment(comment))
expect(message).to include(comment.body_markdown.truncate(300))
expect(message).to include(user.username)
expect(message).to include(internal_user_url)
end
it "messages the proper channel with the proper username and emoji", :aggregate_failures do
sidekiq_assert_enqueued_jobs(1, only: SlackBotPingWorker) do
described_class.call(default_params)
end
job = sidekiq_enqueued_jobs(worker: SlackBotPingWorker).last
job_args = job["args"].first
expect(job_args["channel"]).to eq("warned-user-comments")
expect(job_args["username"]).to eq("sloan_watch_bot")
expect(job_args["icon_emoji"]).to eq(":sloan:")
end
end
end

View file

@ -1,7 +1,7 @@
require "rails_helper"
RSpec.describe Slack::Messengers::Feedback, type: :service do
let_it_be_readonly(:user) { create(:user) }
let(:user) { build(:user) }
let(:default_params) do
{
type: "abuse-reports",

View file

@ -1,7 +1,7 @@
require "rails_helper"
RSpec.describe Slack::Messengers::PotentialSpammer, type: :service do
let_it_be_readonly(:user) { create(:user) }
let(:user) { build(:user) }
let(:default_params) { { user: user } }

View file

@ -1,7 +1,7 @@
require "rails_helper"
RSpec.describe Slack::Messengers::RateLimit, type: :service do
let_it_be_readonly(:user) { create(:user) }
let(:user) { build(:user) }
let(:default_params) do
{

View file

@ -0,0 +1,42 @@
require "rails_helper"
RSpec.describe Slack::Messengers::ReactionVomit, type: :service do
let(:reaction) { build(:reaction, category: :vomit, user: build(:user)) }
let(:user) { reaction.user }
let(:default_params) { { reaction: reaction } }
it "does not message slack for a like reaction" do
sidekiq_assert_no_enqueued_jobs(only: SlackBotPingWorker) do
reaction = build(:reaction, category: :like)
described_class.call(reaction: reaction)
end
end
it "contains the correct info", :aggregate_failures do
sidekiq_assert_enqueued_jobs(1, only: SlackBotPingWorker) do
described_class.call(default_params)
end
job = sidekiq_enqueued_jobs(worker: SlackBotPingWorker).last
message = job["args"].first["message"]
expect(message).to include(user.name)
expect(message).to include(URL.user(user))
expect(message).to include(reaction.category)
expect(message).to include(URL.reaction(reaction))
end
it "messages the proper channel with the proper username and emoji", :aggregate_failures do
sidekiq_assert_enqueued_jobs(1, only: SlackBotPingWorker) do
described_class.call(default_params)
end
job = sidekiq_enqueued_jobs(worker: SlackBotPingWorker).last
job_args = job["args"].first
expect(job_args["channel"]).to eq("abuse-reports")
expect(job_args["username"]).to eq("abuse_bot")
expect(job_args["icon_emoji"]).to eq(":cry:")
end
end

View file

@ -1,9 +1,9 @@
require "rails_helper"
RSpec.describe Slack::Messengers::Sponsorship, type: :service do
let_it_be_readonly(:user) { create(:user) }
let_it_be_readonly(:organization) { create(:organization) }
let(:tag) { create(:tag) }
let(:user) { build(:user) }
let(:organization) { build(:organization) }
let(:tag) { build(:tag) }
let(:default_params) do
{

View file

@ -29,5 +29,9 @@ VCR_OPTIONS = {
twitter_fetch_status: {
cassette_name: "twitter_fetch_status",
allow_playback_repeats: true
},
rss_feeds: {
cassette_name: "rss_feeds",
allow_playback_repeats: true
}
}.freeze