mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 08:57:10 -06:00
FEATURE: keep the topic in closed status until the community flags are handled
This commit is contained in:
parent
f947e3c6cc
commit
8f602be2fe
@ -15,7 +15,16 @@ module Jobs
|
||||
user = topic_timer.user
|
||||
|
||||
if Guardian.new(user).can_close?(topic)
|
||||
topic.update_status('autoclosed', state, user)
|
||||
if state == false && PostAction.auto_close_threshold_reached?(topic)
|
||||
topic.set_or_create_timer(
|
||||
TopicTimer.types[:open],
|
||||
SiteSetting.num_hours_to_close_topic,
|
||||
by_user: Discourse.system_user
|
||||
)
|
||||
else
|
||||
topic.update_status('autoclosed', state, user)
|
||||
end
|
||||
|
||||
topic.inherit_auto_close_from_category if state == false
|
||||
end
|
||||
end
|
||||
|
@ -564,9 +564,7 @@ class PostAction < ActiveRecord::Base
|
||||
|
||||
MAXIMUM_FLAGS_PER_POST = 3
|
||||
|
||||
def self.auto_close_if_threshold_reached(topic)
|
||||
return if topic.nil? || topic.closed?
|
||||
|
||||
def self.auto_close_threshold_reached?(topic)
|
||||
flags = PostAction.active
|
||||
.flags
|
||||
.joins(:post)
|
||||
@ -580,6 +578,13 @@ class PostAction < ActiveRecord::Base
|
||||
# we need a minimum number of flags
|
||||
return if flags.sum { |f| f[1] } < SiteSetting.num_flags_to_close_topic
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def self.auto_close_if_threshold_reached(topic)
|
||||
return if topic.nil? || topic.closed?
|
||||
return unless auto_close_threshold_reached?(topic)
|
||||
|
||||
# the threshold has been reached, we will close the topic waiting for intervention
|
||||
topic.update_status("closed", true, Discourse.system_user,
|
||||
message: I18n.t(
|
||||
|
@ -589,54 +589,100 @@ describe PostAction do
|
||||
expect(post.hidden).to eq(false)
|
||||
end
|
||||
|
||||
it "will automatically pause a topic due to large community flagging" do
|
||||
SiteSetting.flags_required_to_hide_post = 0
|
||||
SiteSetting.num_flags_to_close_topic = 3
|
||||
SiteSetting.num_flaggers_to_close_topic = 2
|
||||
SiteSetting.num_hours_to_close_topic = 1
|
||||
context "topic auto closing" do
|
||||
let(:topic) { Fabricate(:topic) }
|
||||
let(:post1) { create_post(topic: topic) }
|
||||
let(:post2) { create_post(topic: topic) }
|
||||
let(:post3) { create_post(topic: topic) }
|
||||
|
||||
topic = Fabricate(:topic)
|
||||
post1 = create_post(topic: topic)
|
||||
post2 = create_post(topic: topic)
|
||||
post3 = create_post(topic: topic)
|
||||
let(:flagger1) { Fabricate(:user) }
|
||||
let(:flagger2) { Fabricate(:user) }
|
||||
|
||||
flagger1 = Fabricate(:user)
|
||||
flagger2 = Fabricate(:user)
|
||||
|
||||
# reaching `num_flaggers_to_close_topic` isn't enough
|
||||
[flagger1, flagger2].each do |flagger|
|
||||
PostAction.act(flagger, post1, PostActionType.types[:inappropriate])
|
||||
before do
|
||||
SiteSetting.flags_required_to_hide_post = 0
|
||||
SiteSetting.num_flags_to_close_topic = 3
|
||||
SiteSetting.num_flaggers_to_close_topic = 2
|
||||
SiteSetting.num_hours_to_close_topic = 1
|
||||
end
|
||||
|
||||
expect(topic.reload.closed).to eq(false)
|
||||
|
||||
# clean up
|
||||
PostAction.where(post: post1).delete_all
|
||||
|
||||
# reaching `num_flags_to_close_topic` isn't enough
|
||||
[post1, post2, post3].each do |post|
|
||||
PostAction.act(flagger1, post, PostActionType.types[:inappropriate])
|
||||
end
|
||||
|
||||
expect(topic.reload.closed).to eq(false)
|
||||
|
||||
# clean up
|
||||
PostAction.where(post: [post1, post2, post3]).delete_all
|
||||
|
||||
# reaching both should close the topic
|
||||
[flagger1, flagger2].each do |flagger|
|
||||
[post1, post2, post3].each do |post|
|
||||
PostAction.act(flagger, post, PostActionType.types[:inappropriate])
|
||||
it "will automatically pause a topic due to large community flagging" do
|
||||
# reaching `num_flaggers_to_close_topic` isn't enough
|
||||
[flagger1, flagger2].each do |flagger|
|
||||
PostAction.act(flagger, post1, PostActionType.types[:inappropriate])
|
||||
end
|
||||
|
||||
expect(topic.reload.closed).to eq(false)
|
||||
|
||||
# clean up
|
||||
PostAction.where(post: post1).delete_all
|
||||
|
||||
# reaching `num_flags_to_close_topic` isn't enough
|
||||
[post1, post2, post3].each do |post|
|
||||
PostAction.act(flagger1, post, PostActionType.types[:inappropriate])
|
||||
end
|
||||
|
||||
expect(topic.reload.closed).to eq(false)
|
||||
|
||||
# clean up
|
||||
PostAction.where(post: [post1, post2, post3]).delete_all
|
||||
|
||||
# reaching both should close the topic
|
||||
[flagger1, flagger2].each do |flagger|
|
||||
[post1, post2, post3].each do |post|
|
||||
PostAction.act(flagger, post, PostActionType.types[:inappropriate])
|
||||
end
|
||||
end
|
||||
|
||||
expect(topic.reload.closed).to eq(true)
|
||||
|
||||
topic_status_update = TopicTimer.last
|
||||
|
||||
expect(topic_status_update.topic).to eq(topic)
|
||||
expect(topic_status_update.execute_at).to be_within(1.second).of(1.hour.from_now)
|
||||
expect(topic_status_update.status_type).to eq(TopicTimer.types[:open])
|
||||
end
|
||||
|
||||
expect(topic.reload.closed).to eq(true)
|
||||
it "will keep the topic in closed status until the community flags are handled" do
|
||||
freeze_time
|
||||
|
||||
topic_status_update = TopicTimer.last
|
||||
PostAction.stubs(:auto_close_threshold_reached?).returns(true)
|
||||
PostAction.auto_close_if_threshold_reached(topic)
|
||||
|
||||
expect(topic_status_update.topic).to eq(topic)
|
||||
expect(topic_status_update.execute_at).to be_within(1.second).of(1.hour.from_now)
|
||||
expect(topic_status_update.status_type).to eq(TopicTimer.types[:open])
|
||||
expect(topic.reload.closed).to eq(true)
|
||||
|
||||
timer = TopicTimer.last
|
||||
expect(timer.execute_at).to eq(1.hour.from_now)
|
||||
|
||||
freeze_time timer.execute_at
|
||||
Jobs.expects(:enqueue_in).with(1.hour.to_i, :toggle_topic_closed, topic_timer_id: timer.id, state: false).returns(true)
|
||||
Jobs::ToggleTopicClosed.new.execute(topic_timer_id: timer.id, state: false)
|
||||
|
||||
expect(topic.reload.closed).to eq(true)
|
||||
expect(timer.reload.execute_at).to eq(1.hour.from_now)
|
||||
|
||||
freeze_time timer.execute_at
|
||||
PostAction.stubs(:auto_close_threshold_reached?).returns(false)
|
||||
Jobs::ToggleTopicClosed.new.execute(topic_timer_id: timer.id, state: false)
|
||||
|
||||
expect(topic.reload.closed).to eq(false)
|
||||
end
|
||||
|
||||
it "will reopen topic after the flags are auto handled" do
|
||||
freeze_time
|
||||
[flagger1, flagger2].each do |flagger|
|
||||
[post1, post2, post3].each do |post|
|
||||
PostAction.act(flagger, post, PostActionType.types[:inappropriate])
|
||||
end
|
||||
end
|
||||
|
||||
expect(topic.reload.closed).to eq(true)
|
||||
|
||||
freeze_time 61.days.from_now
|
||||
Jobs::AutoQueueHandler.new.execute({})
|
||||
Jobs::ToggleTopicClosed.new.execute(topic_timer_id: TopicTimer.last.id, state: false)
|
||||
|
||||
expect(topic.reload.closed).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user