mirror of
https://github.com/discourse/discourse.git
synced 2024-11-27 20:03:39 +08:00
03338f9086
The new topic timer backend code introduced six months ago
in 0034cbd
is now used instead of this legacy code. It can be safely removed
now.
211 lines
6.9 KiB
Ruby
211 lines
6.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'rails_helper'
|
|
|
|
RSpec.describe TopicTimer, type: :model do
|
|
fab!(:topic_timer) { Fabricate(:topic_timer) }
|
|
fab!(:topic) { Fabricate(:topic) }
|
|
fab!(:admin) { Fabricate(:admin) }
|
|
|
|
before { freeze_time }
|
|
|
|
context "validations" do
|
|
describe "pending_timers scope" do
|
|
it "does not return deleted timers" do
|
|
topic_timer.trash!
|
|
expect(TopicTimer.pending_timers.pluck(:id)).not_to include(topic_timer.id)
|
|
end
|
|
|
|
it "does not return timers in the future of the provided before time" do
|
|
topic_timer.update!(execute_at: 3.days.from_now)
|
|
expect(TopicTimer.pending_timers.pluck(:id)).not_to include(topic_timer.id)
|
|
expect(TopicTimer.pending_timers(2.days.from_now).pluck(:id)).not_to include(topic_timer.id)
|
|
topic_timer.update!(execute_at: 1.minute.ago, created_at: 10.minutes.ago)
|
|
expect(TopicTimer.pending_timers.pluck(:id)).to include(topic_timer.id)
|
|
end
|
|
|
|
describe "duration values" do
|
|
it "does not allow durations <= 0" do
|
|
topic_timer.duration_minutes = -1
|
|
topic_timer.save
|
|
expect(topic_timer.errors.full_messages.first).to include("Duration minutes must be greater than 0.")
|
|
end
|
|
|
|
it "does not allow crazy big durations (20 years in minutes)" do
|
|
topic_timer.duration_minutes = 21.years.to_i / 60
|
|
topic_timer.save
|
|
expect(topic_timer.errors.full_messages.first).to include("Duration minutes cannot be more than 20 years.")
|
|
end
|
|
end
|
|
end
|
|
describe '#status_type' do
|
|
it 'should ensure that only one active public topic status update exists' do
|
|
topic_timer.update!(topic: topic)
|
|
Fabricate(:topic_timer, deleted_at: Time.zone.now, topic: topic)
|
|
|
|
expect { Fabricate(:topic_timer, topic: topic) }
|
|
.to raise_error(ActiveRecord::RecordInvalid)
|
|
end
|
|
end
|
|
|
|
describe '#execute_at' do
|
|
describe 'when #execute_at is greater than #created_at' do
|
|
it 'should be valid' do
|
|
topic_timer = Fabricate.build(:topic_timer,
|
|
execute_at: Time.zone.now + 1.hour,
|
|
user: Fabricate(:user),
|
|
topic: Fabricate(:topic)
|
|
)
|
|
|
|
expect(topic_timer).to be_valid
|
|
end
|
|
end
|
|
|
|
describe 'when #execute_at is smaller than #created_at' do
|
|
it 'should not be valid' do
|
|
topic_timer = Fabricate.build(:topic_timer,
|
|
execute_at: Time.zone.now - 1.hour,
|
|
created_at: Time.zone.now,
|
|
user: Fabricate(:user),
|
|
topic: Fabricate(:topic)
|
|
)
|
|
|
|
expect(topic_timer).to_not be_valid
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#category_id' do
|
|
describe 'when #status_type is publish_to_category' do
|
|
describe 'when #category_id is not present' do
|
|
it 'should not be valid' do
|
|
topic_timer = Fabricate.build(:topic_timer,
|
|
status_type: TopicTimer.types[:publish_to_category]
|
|
)
|
|
|
|
expect(topic_timer).to_not be_valid
|
|
expect(topic_timer.errors).to include(:category_id)
|
|
end
|
|
end
|
|
|
|
describe 'when #category_id is present' do
|
|
it 'should be valid' do
|
|
topic_timer = Fabricate.build(:topic_timer,
|
|
status_type: TopicTimer.types[:publish_to_category],
|
|
category_id: Fabricate(:category).id,
|
|
user: Fabricate(:user),
|
|
topic: Fabricate(:topic)
|
|
)
|
|
|
|
expect(topic_timer).to be_valid
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'callbacks' do
|
|
describe 'when #execute_at and #user_id are not changed' do
|
|
it 'should not schedule another to update topic' do
|
|
Jobs.expects(:enqueue_at).never
|
|
|
|
topic_timer.update!(topic: Fabricate(:topic))
|
|
end
|
|
end
|
|
|
|
describe 'when a open topic status update is created for an open topic' do
|
|
fab!(:topic) { Fabricate(:topic, closed: false) }
|
|
fab!(:topic_timer) do
|
|
Fabricate(:topic_timer,
|
|
status_type: described_class.types[:open],
|
|
topic: topic
|
|
)
|
|
end
|
|
|
|
before do
|
|
Jobs.run_immediately!
|
|
end
|
|
|
|
it 'should close the topic' do
|
|
topic_timer.send(:schedule_auto_open_job)
|
|
expect(topic.reload.closed).to eq(true)
|
|
end
|
|
end
|
|
|
|
describe 'when a close topic status update is created for a closed topic' do
|
|
fab!(:topic) { Fabricate(:topic, closed: true) }
|
|
fab!(:topic_timer) do
|
|
Fabricate(:topic_timer,
|
|
status_type: described_class.types[:close],
|
|
topic: topic
|
|
)
|
|
end
|
|
|
|
before do
|
|
Jobs.run_immediately!
|
|
end
|
|
|
|
it 'should open the topic' do
|
|
topic_timer.send(:schedule_auto_close_job)
|
|
expect(topic.reload.closed).to eq(false)
|
|
end
|
|
end
|
|
|
|
describe '#public_type' do
|
|
[:close, :open, :delete].each do |public_type|
|
|
it "is true for #{public_type}" do
|
|
timer = Fabricate(:topic_timer, status_type: described_class.types[public_type])
|
|
expect(timer.public_type).to eq(true)
|
|
end
|
|
end
|
|
|
|
it "is true for publish_to_category" do
|
|
timer = Fabricate(:topic_timer, status_type: described_class.types[:publish_to_category], category: Fabricate(:category))
|
|
expect(timer.public_type).to eq(true)
|
|
end
|
|
|
|
described_class.private_types.keys.each do |private_type|
|
|
it "is false for #{private_type}" do
|
|
timer = Fabricate(:topic_timer, status_type: described_class.types[private_type])
|
|
expect(timer.public_type).to be_falsey
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "runnable?" do
|
|
it "returns false if execute_at > now" do
|
|
topic_timer = Fabricate.build(:topic_timer,
|
|
execute_at: Time.zone.now + 1.hour,
|
|
user: Fabricate(:user),
|
|
topic: Fabricate(:topic)
|
|
)
|
|
|
|
expect(topic_timer.runnable?).to eq(false)
|
|
end
|
|
|
|
it "returns false if timer is deleted" do
|
|
topic_timer = Fabricate.create(:topic_timer,
|
|
execute_at: Time.zone.now - 1.hour,
|
|
created_at: Time.zone.now - 2.hour,
|
|
user: Fabricate(:user),
|
|
topic: Fabricate(:topic)
|
|
)
|
|
topic_timer.trash!
|
|
|
|
expect(topic_timer.runnable?).to eq(false)
|
|
end
|
|
|
|
it "returns true if execute_at < now" do
|
|
topic_timer = Fabricate.build(:topic_timer,
|
|
execute_at: Time.zone.now - 1.hour,
|
|
created_at: Time.zone.now - 2.hour,
|
|
user: Fabricate(:user),
|
|
topic: Fabricate(:topic)
|
|
)
|
|
|
|
expect(topic_timer.runnable?).to eq(true)
|
|
end
|
|
end
|
|
end
|