FIX: Alter "Take Action" default behaviour to hide post (#24088)
This commit fixes an issue where clicking the default "Take Action" option on a flag for a post doesn't always end up with the post hidden. This is because the "take_action" score bonus doesn’t take into account the final score required to hide the post. Especially with the `hide_post_sensitivity` site setting set to `low` sensitivity, there is a likelihood the score needed to hide the post won’t be reached. Now, the default "Take Action" button has been changed to "Hide Post" to reflect what is actually happening and the description has been improved, and if "Take Action" is clicked we _always_ hide the post regardless of score and sensitivity settings. This way the action reflects expectations of the user.
This commit is contained in:
parent
c0dff8e728
commit
0a4b1b655d
|
@ -32,7 +32,7 @@
|
||||||
</:body>
|
</:body>
|
||||||
<:footer>
|
<:footer>
|
||||||
<DButton
|
<DButton
|
||||||
class="btn-primary"
|
class="btn-primary flag-modal__create-flag"
|
||||||
@action={{this.createFlag}}
|
@action={{this.createFlag}}
|
||||||
@disabled={{not this.submitEnabled}}
|
@disabled={{not this.submitEnabled}}
|
||||||
@title="flagging.submit_tooltip"
|
@title="flagging.submit_tooltip"
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
{{#if this.canSendWarning}}
|
{{#if this.canSendWarning}}
|
||||||
<DButton
|
<DButton
|
||||||
class="btn-danger"
|
class="btn-danger flag-modal__send-warning"
|
||||||
@action={{this.createFlagAsWarning}}
|
@action={{this.createFlagAsWarning}}
|
||||||
@disabled={{not this.submitEnabled}}
|
@disabled={{not this.submitEnabled}}
|
||||||
@icon="exclamation-triangle"
|
@icon="exclamation-triangle"
|
||||||
|
@ -52,13 +52,14 @@
|
||||||
|
|
||||||
{{#if this.canTakeAction}}
|
{{#if this.canTakeAction}}
|
||||||
<ReviewableBundledAction
|
<ReviewableBundledAction
|
||||||
|
class="flag-modal__take-action"
|
||||||
@bundle={{this.flagActions}}
|
@bundle={{this.flagActions}}
|
||||||
@performAction={{this.takeAction}}
|
@performAction={{this.takeAction}}
|
||||||
@reviewableUpdating={{not this.submitEnabled}}
|
@reviewableUpdating={{not this.submitEnabled}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<DButton
|
<DButton
|
||||||
class="btn-danger"
|
class="btn-danger flag-modal__flag-for-review"
|
||||||
@action={{this.flagForReview}}
|
@action={{this.flagForReview}}
|
||||||
@disabled={{not this.submitEnabled this.notifyModeratorsFlag}}
|
@disabled={{not this.submitEnabled this.notifyModeratorsFlag}}
|
||||||
@icon="exclamation-triangle"
|
@icon="exclamation-triangle"
|
||||||
|
@ -68,7 +69,7 @@
|
||||||
|
|
||||||
{{#if this.showDeleteSpammer}}
|
{{#if this.showDeleteSpammer}}
|
||||||
<DButton
|
<DButton
|
||||||
class="btn-danger delete-spammer"
|
class="btn-danger delete-spammer flag-modal__delete-spammer"
|
||||||
@action={{this.deleteSpammer}}
|
@action={{this.deleteSpammer}}
|
||||||
@disabled={{not this.submitEnabled}}
|
@disabled={{not this.submitEnabled}}
|
||||||
@icon="exclamation-triangle"
|
@icon="exclamation-triangle"
|
||||||
|
|
|
@ -36,7 +36,7 @@ export default class Flag extends Component {
|
||||||
label: I18n.t("flagging.take_action"),
|
label: I18n.t("flagging.take_action"),
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
id: "agree_and_keep",
|
id: "agree_and_hide",
|
||||||
icon: "thumbs-up",
|
icon: "thumbs-up",
|
||||||
label: I18n.t("flagging.take_action_options.default.title"),
|
label: I18n.t("flagging.take_action_options.default.title"),
|
||||||
description: I18n.t("flagging.take_action_options.default.details"),
|
description: I18n.t("flagging.take_action_options.default.details"),
|
||||||
|
|
|
@ -109,8 +109,14 @@ acceptance("flagging", function (needs) {
|
||||||
exists("[data-value='agree_and_silence']"),
|
exists("[data-value='agree_and_silence']"),
|
||||||
"it shows the silence action option"
|
"it shows the silence action option"
|
||||||
);
|
);
|
||||||
await click("[data-value='agree_and_silence']");
|
assert.ok(
|
||||||
assert.ok(exists(".silence-user-modal"), "it shows the silence modal");
|
exists("[data-value='agree_and_suspend']"),
|
||||||
|
"it shows the suspend action option"
|
||||||
|
);
|
||||||
|
assert.ok(
|
||||||
|
exists("[data-value='agree_and_hide']"),
|
||||||
|
"it shows the hide action option"
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Can silence from take action", async function (assert) {
|
test("Can silence from take action", async function (assert) {
|
||||||
|
@ -119,6 +125,7 @@ acceptance("flagging", function (needs) {
|
||||||
await click("#radio_inappropriate");
|
await click("#radio_inappropriate");
|
||||||
await selectKit(".reviewable-action-dropdown").expand();
|
await selectKit(".reviewable-action-dropdown").expand();
|
||||||
await click("[data-value='agree_and_silence']");
|
await click("[data-value='agree_and_silence']");
|
||||||
|
assert.ok(exists(".silence-user-modal"), "it shows the silence modal");
|
||||||
|
|
||||||
const silenceUntilCombobox = selectKit(".silence-until .combobox");
|
const silenceUntilCombobox = selectKit(".silence-until .combobox");
|
||||||
await silenceUntilCombobox.expand();
|
await silenceUntilCombobox.expand();
|
||||||
|
|
|
@ -3855,8 +3855,8 @@ en:
|
||||||
take_action: "Take Action…"
|
take_action: "Take Action…"
|
||||||
take_action_options:
|
take_action_options:
|
||||||
default:
|
default:
|
||||||
title: "Take Action"
|
title: "Hide Post"
|
||||||
details: "Reach the flag threshold immediately, rather than waiting for more community flags"
|
details: "Reach the flag threshold immediately, hide the post, and agree with all pending flags"
|
||||||
suspend:
|
suspend:
|
||||||
title: "Suspend User"
|
title: "Suspend User"
|
||||||
details: "Reach the flag threshold, and suspend the user"
|
details: "Reach the flag threshold, and suspend the user"
|
||||||
|
@ -3882,7 +3882,7 @@ en:
|
||||||
ip_address_missing: "(N/A)"
|
ip_address_missing: "(N/A)"
|
||||||
hidden_email_address: "(hidden)"
|
hidden_email_address: "(hidden)"
|
||||||
submit_tooltip: "Submit the private flag"
|
submit_tooltip: "Submit the private flag"
|
||||||
take_action_tooltip: "Reach the flag threshold immediately, rather than waiting for more community flags"
|
take_action_tooltip: "Reach the flag threshold immediately, hide the post, and agree with all pending flags"
|
||||||
cant: "Sorry, you can't flag this post at this time."
|
cant: "Sorry, you can't flag this post at this time."
|
||||||
notify_staff: "Notify staff privately"
|
notify_staff: "Notify staff privately"
|
||||||
formatted_name:
|
formatted_name:
|
||||||
|
|
|
@ -250,7 +250,9 @@ class PostActionCreator
|
||||||
end
|
end
|
||||||
|
|
||||||
score = ReviewableFlaggedPost.find_by(target: @post)&.score || 0
|
score = ReviewableFlaggedPost.find_by(target: @post)&.score || 0
|
||||||
@post.hide!(@post_action_type_id) if score >= Reviewable.score_required_to_hide_post
|
if score >= Reviewable.score_required_to_hide_post || @take_action
|
||||||
|
@post.hide!(@post_action_type_id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Special case: If you have TL3 and the user is TL0, and the flag is spam,
|
# Special case: If you have TL3 and the user is TL0, and the flag is spam,
|
||||||
|
|
|
@ -271,18 +271,38 @@ RSpec.describe PostActionCreator do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "take_action" do
|
describe "take_action" do
|
||||||
before { PostActionCreator.create(Fabricate(:user), post, :inappropriate) }
|
it "will hide the post" do
|
||||||
|
PostActionCreator
|
||||||
|
.new(Fabricate(:moderator), post, PostActionType.types[:spam], take_action: true)
|
||||||
|
.perform
|
||||||
|
.reviewable
|
||||||
|
expect(post.reload).to be_hidden
|
||||||
|
end
|
||||||
|
|
||||||
it "will agree with the old reviewable" do
|
context "when there is another reviewable on the post" do
|
||||||
reviewable =
|
before { PostActionCreator.create(Fabricate(:user), post, :inappropriate) }
|
||||||
|
|
||||||
|
it "will agree with the old reviewable" do
|
||||||
|
reviewable =
|
||||||
|
PostActionCreator
|
||||||
|
.new(Fabricate(:moderator), post, PostActionType.types[:spam], take_action: true)
|
||||||
|
.perform
|
||||||
|
.reviewable
|
||||||
|
expect(reviewable.reload).to be_approved
|
||||||
|
expect(reviewable.reviewable_scores).to all(be_agreed)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when hide_post_sensitivity is low" do
|
||||||
|
before { SiteSetting.hide_post_sensitivity = Reviewable.sensitivities[:low] }
|
||||||
|
|
||||||
|
it "still hides the post without considering the score" do
|
||||||
PostActionCreator
|
PostActionCreator
|
||||||
.new(Fabricate(:moderator), post, PostActionType.types[:spam], take_action: true)
|
.new(Fabricate(:moderator), post, PostActionType.types[:spam], take_action: true)
|
||||||
.perform
|
.perform
|
||||||
.reviewable
|
.reviewable
|
||||||
scores = reviewable.reviewable_scores
|
expect(post.reload).to be_hidden
|
||||||
expect(scores[0]).to be_agreed
|
end
|
||||||
expect(scores[1]).to be_agreed
|
|
||||||
expect(reviewable.reload).to be_approved
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -307,7 +327,7 @@ RSpec.describe PostActionCreator do
|
||||||
|
|
||||||
score = result.reviewable.reviewable_scores.last
|
score = result.reviewable.reviewable_scores.last
|
||||||
expect(score.reason).to eq("queued_by_staff")
|
expect(score.reason).to eq("queued_by_staff")
|
||||||
expect(post.reload.hidden?).to eq(true)
|
expect(post.reload).to be_hidden
|
||||||
end
|
end
|
||||||
|
|
||||||
it "hides the topic even if it has replies" do
|
it "hides the topic even if it has replies" do
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
describe "Flagging post", type: :system, js: true do
|
||||||
|
fab!(:current_user) { Fabricate(:admin) }
|
||||||
|
fab!(:first_post) { Fabricate(:post) }
|
||||||
|
fab!(:post_to_flag) { Fabricate(:post, topic: first_post.topic) }
|
||||||
|
|
||||||
|
let(:topic_page) { PageObjects::Pages::Topic.new }
|
||||||
|
let(:flag_modal) { PageObjects::Modals::Flag.new }
|
||||||
|
|
||||||
|
before { sign_in(current_user) }
|
||||||
|
|
||||||
|
describe "Using Take Action" do
|
||||||
|
it "can select the default action to hide the post, agree with other flags, and reach the flag threshold" do
|
||||||
|
other_flag = Fabricate(:flag, post: post_to_flag, user: Fabricate(:moderator))
|
||||||
|
expect(other_flag.reload.agreed_at).to be_nil
|
||||||
|
topic_page.visit_topic(post_to_flag.topic)
|
||||||
|
topic_page.expand_post_actions(post_to_flag)
|
||||||
|
topic_page.click_post_action_button(post_to_flag, :flag)
|
||||||
|
flag_modal.choose_type(:off_topic)
|
||||||
|
flag_modal.take_action(:agree_and_hide)
|
||||||
|
expect(
|
||||||
|
topic_page.post_by_number(post_to_flag).ancestor(".topic-post.post-hidden"),
|
||||||
|
).to be_present
|
||||||
|
expect(other_flag.reload.agreed_at).to be_present
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -6,6 +6,16 @@ module PageObjects
|
||||||
include Capybara::DSL
|
include Capybara::DSL
|
||||||
include RSpec::Matchers
|
include RSpec::Matchers
|
||||||
|
|
||||||
|
BODY_SELECTOR = ""
|
||||||
|
|
||||||
|
def body
|
||||||
|
find(".modal-body#{BODY_SELECTOR}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def footer
|
||||||
|
find(".modal-footer")
|
||||||
|
end
|
||||||
|
|
||||||
def close
|
def close
|
||||||
find(".modal-close").click
|
find(".modal-close").click
|
||||||
end
|
end
|
||||||
|
@ -19,11 +29,11 @@ module PageObjects
|
||||||
end
|
end
|
||||||
|
|
||||||
def click_primary_button
|
def click_primary_button
|
||||||
find(".modal-footer .btn-primary").click
|
footer.find(".btn-primary").click
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_content?(content)
|
def has_content?(content)
|
||||||
find(".modal-body").has_content?(content)
|
body.has_content?(content)
|
||||||
end
|
end
|
||||||
|
|
||||||
def open?
|
def open?
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module PageObjects
|
||||||
|
module Modals
|
||||||
|
class Flag < PageObjects::Modals::Base
|
||||||
|
BODY_SELECTOR = ".flag-modal-body"
|
||||||
|
MODAL_SELECTOR = ".flag-modal"
|
||||||
|
|
||||||
|
def choose_type(type)
|
||||||
|
body.find("#radio_#{type}").click
|
||||||
|
end
|
||||||
|
|
||||||
|
def confirm_flag
|
||||||
|
click_primary_button
|
||||||
|
end
|
||||||
|
|
||||||
|
def take_action(action)
|
||||||
|
select_kit =
|
||||||
|
PageObjects::Components::SelectKit.new(".modal-footer .reviewable-action-dropdown")
|
||||||
|
select_kit.expand
|
||||||
|
select_kit.select_row_by_value(action)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -84,6 +84,8 @@ module PageObjects
|
||||||
post_by_number(post).find(".bookmark.with-reminder").click
|
post_by_number(post).find(".bookmark.with-reminder").click
|
||||||
when :reply
|
when :reply
|
||||||
post_by_number(post).find(".post-controls .reply").click
|
post_by_number(post).find(".post-controls .reply").click
|
||||||
|
when :flag
|
||||||
|
post_by_number(post).find(".post-controls .create-flag").click
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue