discourse/spec/services/topic_status_updater_spec.rb
Martin Brennan 4af77f1e38
FEATURE: Allow durations < 1 hour and < 1 day for topic timers where duration is specified (auto delete replies, close based on last post) (#11961)
This PR allows entering a float value for topic timers e.g. 0.5 for 30 minutes when entering hours, 0.5 for 12 hours when entering days. This is achieved by adding a new column to store the duration of a topic timer in minutes instead of the ambiguous both hours and days that it could be before.

This PR has ommitted the post migration to delete the duration column in topic timers; it will be done in a subsequent PR to ensure that no data is lost if the UPDATE query to set duration_mintues fails.

I have to keep the old keyword of duration in set_or_create_topic_timer for backwards compat, will remove at a later date after plugins are updated.
2021-02-05 10:12:56 +10:00

130 lines
4.3 KiB
Ruby

# encoding: UTF-8
# frozen_string_literal: true
require 'rails_helper'
# TODO - test pinning, create_moderator_post
describe TopicStatusUpdater do
fab!(:user) { Fabricate(:user) }
fab!(:admin) { Fabricate(:admin) }
it "avoids notifying on automatically closed topics" do
# TODO: TopicStatusUpdater should suppress message bus updates from the users it "pretends to read"
post = PostCreator.create(user,
raw: "this is a test post 123 this is a test post",
title: "hello world title",
)
# TODO needed so counts sync up, PostCreator really should not give back out-of-date Topic
post.topic.set_or_create_timer(TopicTimer.types[:close], '10')
post.topic.reload
TopicStatusUpdater.new(post.topic, admin).update!("autoclosed", true)
expect(post.topic.posts.count).to eq(2)
tu = TopicUser.find_by(user_id: user.id)
expect(tu.last_read_post_number).to eq(2)
end
it "adds an autoclosed message" do
topic = create_topic
topic.set_or_create_timer(TopicTimer.types[:close], '10')
TopicStatusUpdater.new(topic, admin).update!("autoclosed", true)
last_post = topic.posts.last
expect(last_post.post_type).to eq(Post.types[:small_action])
expect(last_post.action_code).to eq('autoclosed.enabled')
expect(last_post.raw).to eq(I18n.t("topic_statuses.autoclosed_enabled_minutes", count: 0))
end
it "triggers a DiscourseEvent on close" do
topic = create_topic
called = false
updater = -> (_) { called = true }
DiscourseEvent.on(:topic_closed, &updater)
TopicStatusUpdater.new(topic, admin).update!("closed", true)
DiscourseEvent.off(:topic_closed, &updater)
expect(topic).to be_closed
expect(called).to eq(true)
end
it "adds an autoclosed message based on last post" do
topic = create_topic
Fabricate(:post, topic: topic)
topic.set_or_create_timer(
TopicTimer.types[:close], nil, based_on_last_post: true, duration_minutes: 600
)
TopicStatusUpdater.new(topic, admin).update!("autoclosed", true)
last_post = topic.posts.last
expect(last_post.post_type).to eq(Post.types[:small_action])
expect(last_post.action_code).to eq('autoclosed.enabled')
expect(last_post.raw).to eq(I18n.t("topic_statuses.autoclosed_enabled_lastpost_hours", count: 10))
end
describe "repeat actions" do
shared_examples "an action that doesn't repeat" do
it "does not perform the update twice" do
topic = Fabricate(:topic, status_name => false)
updated = TopicStatusUpdater.new(topic, admin).update!(status_name, true)
expect(updated).to eq(true)
expect(topic.public_send("#{status_name}?")).to eq(true)
updated = TopicStatusUpdater.new(topic, admin).update!(status_name, true)
expect(updated).to eq(false)
expect(topic.posts.where(post_type: Post.types[:small_action]).count).to eq(1)
updated = TopicStatusUpdater.new(topic, admin).update!(status_name, false)
expect(updated).to eq(true)
expect(topic.public_send("#{status_name}?")).to eq(false)
updated = TopicStatusUpdater.new(topic, admin).update!(status_name, false)
expect(updated).to eq(false)
expect(topic.posts.where(post_type: Post.types[:small_action]).count).to eq(2)
end
end
it_behaves_like "an action that doesn't repeat" do
let(:status_name) { "closed" }
end
it_behaves_like "an action that doesn't repeat" do
let(:status_name) { "visible" }
end
it_behaves_like "an action that doesn't repeat" do
let(:status_name) { "archived" }
end
it "updates autoclosed" do
topic = Fabricate(:topic)
updated = TopicStatusUpdater.new(topic, admin).update!('autoclosed', true)
expect(updated).to eq(true)
expect(topic.closed?).to eq(true)
updated = TopicStatusUpdater.new(topic, admin).update!('autoclosed', true)
expect(updated).to eq(false)
expect(topic.posts.where(post_type: Post.types[:small_action]).count).to eq(1)
updated = TopicStatusUpdater.new(topic, admin).update!('autoclosed', false)
expect(updated).to eq(true)
expect(topic.closed?).to eq(false)
updated = TopicStatusUpdater.new(topic, admin).update!('autoclosed', false)
expect(updated).to eq(false)
expect(topic.posts.where(post_type: Post.types[:small_action]).count).to eq(2)
end
end
end