Duplicate notifications, when replying to and mentioning the same user (#8156)

* Refactor Mentions::CreateAll

* Update app/services/mentions/create_all.rb

Co-authored-by: Vaidehi Joshi <vaidehi.sj@gmail.com>

* Refactor for readability

* Try writing tests for duplicate notifications

* Skip Bullet warning, essentially for #current_user

* Fix duplicate notification, when mentioning comment author

* Improve spec readability

* Refactor specs and fix duplicate notificaation for moderator comments

* Refactor spec

* Remove obsolete code and refactor specs

* Remove obsolete spec

* Update spec/requests/comments_create_spec.rb

Co-authored-by: Vaidehi Joshi <vaidehi.sj@gmail.com>

* Get rid of #json_response

* Remove Bullet skipping

* Change #where -> #exists?

Co-authored-by: Vaidehi Joshi <vaidehi.sj@gmail.com>
This commit is contained in:
Dmitry Maksyoma 2020-06-18 00:47:31 +12:00 committed by GitHub
parent e6abadff6c
commit 17a9335680
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 79 additions and 2 deletions

View file

@ -63,11 +63,11 @@ class CommentsController < ApplicationController
checked_code_of_conduct = params[:checked_code_of_conduct].present? && !current_user.checked_code_of_conduct
current_user.update(checked_code_of_conduct: true) if checked_code_of_conduct
Mention.create_all(@comment)
NotificationSubscription.create(
user: current_user, notifiable_id: @comment.id, notifiable_type: "Comment", config: "all_comments",
)
Notification.send_new_comment_notifications_without_delay(@comment)
Mention.create_all(@comment)
if @comment.invalid?
@comment.destroy
@ -132,8 +132,8 @@ class CommentsController < ApplicationController
authorize @comment
if @comment.save
Mention.create_all(@comment)
Notification.send_new_comment_notifications_without_delay(@comment)
Mention.create_all(@comment)
render json: { status: "created", path: @comment.path }
elsif (@comment = Comment.where(body_markdown: @comment.body_markdown,

View file

@ -56,7 +56,13 @@ module Mentions
Notification.remove_all(notifiable_ids: mentions.pluck(:id), notifiable_type: "Mention") if mentions.present?
end
def user_has_comment_notifications?(user)
user.notifications.exists?(notifiable_id: @notifiable.id)
end
def create_mention_for(user)
return if user_has_comment_notifications?(user)
mention = Mention.create(user_id: user.id, mentionable_id: @notifiable.id, mentionable_type: @notifiable.class.name)
# mentionable_type = model that created the mention, user = user to be mentioned
Notification.send_mention_notification(mention)

View file

@ -93,4 +93,75 @@ RSpec.describe "CommentsCreate", type: :request do
expect(response.parsed_body["error"]).to be_present
end
end
context "when there's already a notification for comment" do
around do |example|
Sidekiq::Testing.inline!(&example)
end
let(:comment_author) { create(:user) }
let(:user_replier) { create(:user) }
let(:moderator_replier) { create(:user, :admin) }
let(:response_template) do
create(:response_template, type_of: "mod_comment",
content: text_mentioning_comment_author, user_id: nil)
end
let(:text_mentioning_comment_author) do
"Hello, @#{comment_author.username}"
end
it "doesn't create mention notification, when replying as regular user" do
comment = comment_on_article
reply_and_mention_comment_author(comment)
expect_no_duplicate_notifications_for_comment_author
end
it "doesn't create mention notification, when replying as moderator" do
comment = comment_on_article
reply_and_mention_comment_author_as_moderator(comment)
expect_no_duplicate_notifications_for_comment_author
end
private
def comment_on_article
sign_in comment_author
post comments_path, params: comment_params
expect_request_to_be_successful
Comment.first
end
def reply_and_mention_comment_author(comment)
sign_in user_replier
post comments_path, params: comment_params(
parent_id: comment.id,
body_markdown: text_mentioning_comment_author,
)
expect_request_to_be_successful
end
def reply_and_mention_comment_author_as_moderator(comment)
allow(SiteConfig).to receive(:mascot_user_id).
and_return(moderator_replier.id)
sign_in moderator_replier
post moderator_create_comments_path, params: comment_params(
parent_id: comment.id,
).merge(response_template: { id: response_template.id })
expect(response).to be_successful
end
def expect_no_duplicate_notifications_for_comment_author
expect(Mention.count).to eq 0
expect(Notification.where(user: comment_author).count).to eq 1
end
def expect_request_to_be_successful
expect(response.parsed_body["error"]).to be_nil
expect(response).to be_successful
end
end
end