Feature/Fix: Flagged posts user notifications (#8041)
* FIX: User should get notified when a post is deleted * FEATURE: Notify posters when restoring flagged posts * Fix typo Co-Authored-By: Régis Hanol <regis@hanol.fr> * Improve tests
This commit is contained in:
parent
5db204f370
commit
e515324afa
|
@ -198,6 +198,7 @@ class ReviewableFlaggedPost < Reviewable
|
|||
|
||||
# Undo hide/silence if applicable
|
||||
if post&.hidden?
|
||||
notify_poster(performed_by)
|
||||
post.unhide!
|
||||
UserSilencer.unsilence(post.user) if UserSilencer.was_silenced_for?(post)
|
||||
end
|
||||
|
@ -210,30 +211,26 @@ class ReviewableFlaggedPost < Reviewable
|
|||
|
||||
def perform_delete_and_ignore(performed_by, args)
|
||||
result = perform_ignore(performed_by, args)
|
||||
PostDestroyer.new(performed_by, post).destroy
|
||||
destroyer(performed_by, post).destroy
|
||||
result
|
||||
end
|
||||
|
||||
def perform_delete_and_ignore_replies(performed_by, args)
|
||||
result = perform_ignore(performed_by, args)
|
||||
|
||||
reply_ids = post.reply_ids(Guardian.new(performed_by), only_replies_to_single_post: false)
|
||||
replies = Post.where(id: reply_ids.map { |r| r[:id] })
|
||||
PostDestroyer.new(performed_by, post).destroy
|
||||
replies.each { |reply| PostDestroyer.new(performed_by, reply).destroy }
|
||||
PostDestroyer.delete_with_replies(performed_by, post, self)
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
def perform_delete_and_agree(performed_by, args)
|
||||
result = agree(performed_by, args)
|
||||
PostDestroyer.new(performed_by, post).destroy
|
||||
destroyer(performed_by, post).destroy
|
||||
result
|
||||
end
|
||||
|
||||
def perform_delete_and_agree_replies(performed_by, args)
|
||||
result = agree(performed_by, args)
|
||||
PostDestroyer.delete_with_replies(performed_by, post)
|
||||
PostDestroyer.delete_with_replies(performed_by, post, self)
|
||||
result
|
||||
end
|
||||
|
||||
|
@ -283,6 +280,25 @@ protected
|
|||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def destroyer(performed_by, post)
|
||||
PostDestroyer.new(performed_by, post, reviewable: self)
|
||||
end
|
||||
|
||||
def notify_poster(performed_by)
|
||||
return unless performed_by.human? && performed_by.staff?
|
||||
|
||||
Jobs.enqueue(
|
||||
:send_system_message,
|
||||
user_id: post.user_id,
|
||||
message_type: :flags_disagreed,
|
||||
message_options: {
|
||||
flagged_post_raw_content: post.raw,
|
||||
url: post.url
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# == Schema Information
|
||||
|
|
|
@ -2555,7 +2555,23 @@ en:
|
|||
The community flagged this post and now it is hidden. **Because this post has been hidden more than once, your post will now remain hidden until it is handled by a staff member.**
|
||||
|
||||
For additional guidance, please refer to our [community guidelines](%{base_url}/guidelines).
|
||||
|
||||
flags_disagreed:
|
||||
title: "Flagged post restored by staff"
|
||||
subject_template: "Flagged post restored by staff"
|
||||
text_body_template: |
|
||||
Hello,
|
||||
|
||||
This is an automated message from %{site_name} to let you know that [your post](%{base_url}%{url}) was restored.
|
||||
|
||||
This post was flagged by the community and a staff member opted to restore it.
|
||||
|
||||
[details="Click to expand restored post"]
|
||||
``` markdown
|
||||
%{flagged_post_raw_content}
|
||||
```
|
||||
[/details]
|
||||
|
||||
flags_agreed_and_post_deleted:
|
||||
title: "Flagged post removed by staff"
|
||||
subject_template: "Flagged post removed by staff"
|
||||
|
|
|
@ -39,10 +39,10 @@ class PostDestroyer
|
|||
end
|
||||
end
|
||||
|
||||
def self.delete_with_replies(performed_by, post)
|
||||
def self.delete_with_replies(performed_by, post, reviewable = nil)
|
||||
reply_ids = post.reply_ids(Guardian.new(performed_by), only_replies_to_single_post: false)
|
||||
replies = Post.where(id: reply_ids.map { |r| r[:id] })
|
||||
PostDestroyer.new(performed_by, post).destroy
|
||||
PostDestroyer.new(performed_by, post, reviewable: reviewable).destroy
|
||||
replies.each { |reply| PostDestroyer.new(performed_by, reply).destroy }
|
||||
end
|
||||
|
||||
|
@ -156,12 +156,10 @@ class PostDestroyer
|
|||
TopicUser.update_post_action_cache(post_id: @post.id)
|
||||
|
||||
DB.after_commit do
|
||||
if reviewable = @post.reviewable_flag
|
||||
if @opts[:defer_flags]
|
||||
ignore(reviewable)
|
||||
else
|
||||
agree(reviewable)
|
||||
end
|
||||
if @opts[:reviewable]
|
||||
notify_deletion(@opts[:reviewable])
|
||||
elsif reviewable = @post.reviewable_flag
|
||||
@opts[:defer_flags] ? ignore(reviewable) : agree(reviewable)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -263,23 +261,7 @@ class PostDestroyer
|
|||
end
|
||||
|
||||
def agree(reviewable)
|
||||
if @user.human? && @user.staff? && rs = reviewable.reviewable_scores.order('created_at DESC').first
|
||||
Jobs.enqueue(
|
||||
:send_system_message,
|
||||
user_id: @post.user_id,
|
||||
message_type: :flags_agreed_and_post_deleted,
|
||||
message_options: {
|
||||
flagged_post_raw_content: @post.raw,
|
||||
url: @post.url,
|
||||
flag_reason: I18n.t(
|
||||
"flag_reasons.#{PostActionType.types[rs.reviewable_score_type]}",
|
||||
locale: SiteSetting.default_locale,
|
||||
base_path: Discourse.base_path
|
||||
)
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
notify_deletion(reviewable)
|
||||
result = reviewable.perform(@user, :agree_and_keep, post_was_deleted: true)
|
||||
reviewable.transition_to(result.transition_to, @user)
|
||||
end
|
||||
|
@ -289,6 +271,26 @@ class PostDestroyer
|
|||
reviewable.transition_to(:ignored, @user)
|
||||
end
|
||||
|
||||
def notify_deletion(reviewable)
|
||||
allowed_user = @user.human? && @user.staff?
|
||||
return unless allowed_user && rs = reviewable.reviewable_scores.order('created_at DESC').first
|
||||
|
||||
Jobs.enqueue(
|
||||
:send_system_message,
|
||||
user_id: @post.user_id,
|
||||
message_type: :flags_agreed_and_post_deleted,
|
||||
message_options: {
|
||||
flagged_post_raw_content: @post.raw,
|
||||
url: @post.url,
|
||||
flag_reason: I18n.t(
|
||||
"flag_reasons.#{PostActionType.types[rs.reviewable_score_type]}",
|
||||
locale: SiteSetting.default_locale,
|
||||
base_path: Discourse.base_path
|
||||
)
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
def trash_user_actions
|
||||
UserAction.where(target_post_id: @post.id).each do |ua|
|
||||
row = {
|
||||
|
|
|
@ -273,4 +273,35 @@ RSpec.describe ReviewableFlaggedPost, type: :model do
|
|||
|
||||
end
|
||||
|
||||
describe "#perform_delete_and_agree" do
|
||||
it "notifies the user about the flagged post deletion" do
|
||||
reviewable = Fabricate(:reviewable_flagged_post)
|
||||
reviewable.add_score(
|
||||
moderator, PostActionType.types[:spam],
|
||||
created_at: reviewable.created_at
|
||||
)
|
||||
|
||||
reviewable.perform(moderator, :delete_and_agree)
|
||||
|
||||
assert_pm_creation_enqueued(reviewable.post.user_id, "flags_agreed_and_post_deleted")
|
||||
end
|
||||
end
|
||||
|
||||
describe "#perform_disagree" do
|
||||
it "notifies the user about the flagged post being restored" do
|
||||
reviewable = Fabricate(:reviewable_flagged_post)
|
||||
reviewable.post.update(hidden: true, hidden_at: Time.zone.now, hidden_reason_id: PostActionType.types[:spam])
|
||||
|
||||
reviewable.perform(moderator, :disagree)
|
||||
|
||||
assert_pm_creation_enqueued(reviewable.post.user_id, "flags_disagreed")
|
||||
end
|
||||
end
|
||||
|
||||
def assert_pm_creation_enqueued(user_id, pm_type)
|
||||
expect(Jobs::SendSystemMessage.jobs.length).to eq(1)
|
||||
job = Jobs::SendSystemMessage.jobs[0]
|
||||
expect(job["args"][0]["user_id"]).to eq(user_id)
|
||||
expect(job["args"][0]["message_type"]).to eq(pm_type)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue