rename topic_status_update to topic_timer

This commit is contained in:
Neil Lalonde 2017-05-11 18:23:18 -04:00
parent 92d63b59a7
commit 55b61e9bea
39 changed files with 297 additions and 287 deletions

View File

@ -1,6 +1,6 @@
import { default as computed, observes } from "ember-addons/ember-computed-decorators"; import { default as computed, observes } from "ember-addons/ember-computed-decorators";
import Combobox from 'discourse-common/components/combo-box'; import Combobox from 'discourse-common/components/combo-box';
import { CLOSE_STATUS_TYPE } from 'discourse/controllers/edit-topic-status-update'; import { CLOSE_STATUS_TYPE } from 'discourse/controllers/edit-topic-timer';
const LATER_TODAY = 'later_today'; const LATER_TODAY = 'later_today';
const TOMORROW = 'tomorrow'; const TOMORROW = 'tomorrow';

View File

@ -1,6 +1,6 @@
import { default as computed, observes } from "ember-addons/ember-computed-decorators"; import { default as computed, observes } from "ember-addons/ember-computed-decorators";
import ModalFunctionality from 'discourse/mixins/modal-functionality'; import ModalFunctionality from 'discourse/mixins/modal-functionality';
import TopicStatusUpdate from 'discourse/models/topic-status-update'; import TopicTimer from 'discourse/models/topic-timer';
import { popupAjaxError } from 'discourse/lib/ajax-error'; import { popupAjaxError } from 'discourse/lib/ajax-error';
export const CLOSE_STATUS_TYPE = 'close'; export const CLOSE_STATUS_TYPE = 'close';
@ -11,8 +11,8 @@ const DELETE_STATUS_TYPE = 'delete';
export default Ember.Controller.extend(ModalFunctionality, { export default Ember.Controller.extend(ModalFunctionality, {
loading: false, loading: false,
updateTime: null, updateTime: null,
topicStatusUpdate: Ember.computed.alias("model.topic_status_update"), topicTimer: Ember.computed.alias("model.topic_timer"),
selection: Ember.computed.alias('model.topic_status_update.status_type'), selection: Ember.computed.alias('model.topic_timer.status_type'),
autoOpen: Ember.computed.equal('selection', OPEN_STATUS_TYPE), autoOpen: Ember.computed.equal('selection', OPEN_STATUS_TYPE),
autoClose: Ember.computed.equal('selection', CLOSE_STATUS_TYPE), autoClose: Ember.computed.equal('selection', CLOSE_STATUS_TYPE),
autoDelete: Ember.computed.equal('selection', DELETE_STATUS_TYPE), autoDelete: Ember.computed.equal('selection', DELETE_STATUS_TYPE),
@ -21,7 +21,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
showTimeOnly: Ember.computed.or('autoOpen', 'autoDelete'), showTimeOnly: Ember.computed.or('autoOpen', 'autoDelete'),
@computed("model.closed") @computed("model.closed")
statusUpdates(closed) { timerTypes(closed) {
return [ return [
{ id: CLOSE_STATUS_TYPE, name: I18n.t(closed ? 'topic.temp_open.title' : 'topic.auto_close.title'), }, { id: CLOSE_STATUS_TYPE, name: I18n.t(closed ? 'topic.temp_open.title' : 'topic.auto_close.title'), },
{ id: OPEN_STATUS_TYPE, name: I18n.t(closed ? 'topic.auto_reopen.title' : 'topic.temp_close.title') }, { id: OPEN_STATUS_TYPE, name: I18n.t(closed ? 'topic.auto_reopen.title' : 'topic.temp_close.title') },
@ -40,16 +40,16 @@ export default Ember.Controller.extend(ModalFunctionality, {
if (visible) return this.get('model.category_id'); if (visible) return this.get('model.category_id');
}, },
@observes("topicStatusUpdate.execute_at", "topicStatusUpdate.duration") @observes("topicTimer.execute_at", "topicTimer.duration")
_setUpdateTime() { _setUpdateTime() {
if (!this.get('topicStatusUpdate.execute_at')) return; if (!this.get('topicTimer.execute_at')) return;
let time = null; let time = null;
if (this.get("topicStatusUpdate.based_on_last_post")) { if (this.get("topicTimer.based_on_last_post")) {
time = this.get("topicStatusUpdate.duration"); time = this.get("topicTimer.duration");
} else if (this.get("topicStatusUpdate.execute_at")) { } else if (this.get("topicTimer.execute_at")) {
const closeTime = moment(this.get('topicStatusUpdate.execute_at')); const closeTime = moment(this.get('topicTimer.execute_at'));
if (closeTime > moment()) { if (closeTime > moment()) {
time = closeTime.format("YYYY-MM-DD HH:mm"); time = closeTime.format("YYYY-MM-DD HH:mm");
@ -59,20 +59,20 @@ export default Ember.Controller.extend(ModalFunctionality, {
this.set("updateTime", time); this.set("updateTime", time);
}, },
_setStatusUpdate(time, statusType) { _setTimer(time, statusType) {
this.set('loading', true); this.set('loading', true);
TopicStatusUpdate.updateStatus( TopicTimer.updateStatus(
this.get('model.id'), this.get('model.id'),
time, time,
this.get('topicStatusUpdate.based_on_last_post'), this.get('topicTimer.based_on_last_post'),
statusType, statusType,
this.get('categoryId') this.get('categoryId')
).then(result => { ).then(result => {
if (time) { if (time) {
this.send('closeModal'); this.send('closeModal');
this.get("topicStatusUpdate").setProperties({ this.get("topicTimer").setProperties({
execute_at: result.execute_at, execute_at: result.execute_at,
duration: result.duration, duration: result.duration,
category_id: result.category_id category_id: result.category_id
@ -81,7 +81,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
this.set('model.closed', result.closed); this.set('model.closed', result.closed);
} else { } else {
this.setProperties({ this.setProperties({
topicStatusUpdate: Ember.Object.create({}), topicTimer: Ember.Object.create({}),
selection: null, selection: null,
updateTime: null updateTime: null
}); });
@ -92,12 +92,12 @@ export default Ember.Controller.extend(ModalFunctionality, {
}, },
actions: { actions: {
saveStatusUpdate() { saveTimer() {
this._setStatusUpdate(this.get("updateTime"), this.get('selection')); this._setTimer(this.get("updateTime"), this.get('selection'));
}, },
removeStatusUpdate() { removeTimer() {
this._setStatusUpdate(null, this.get('selection')); this._setTimer(null, this.get('selection'));
} }
} }
}); });

View File

@ -1,9 +1,9 @@
import { ajax } from 'discourse/lib/ajax'; import { ajax } from 'discourse/lib/ajax';
import RestModel from 'discourse/models/rest'; import RestModel from 'discourse/models/rest';
const TopicStatusUpdate = RestModel.extend({}); const TopicTimer = RestModel.extend({});
TopicStatusUpdate.reopenClass({ TopicTimer.reopenClass({
updateStatus(topicId, time, basedOnLastPost, statusType, categoryId) { updateStatus(topicId, time, basedOnLastPost, statusType, categoryId) {
let data = { let data = {
time: time, time: time,
@ -15,11 +15,11 @@ TopicStatusUpdate.reopenClass({
if (categoryId) data.category_id = categoryId; if (categoryId) data.category_id = categoryId;
return ajax({ return ajax({
url: `/t/${topicId}/status_update`, url: `/t/${topicId}/timer`,
type: 'POST', type: 'POST',
data data
}); });
} }
}); });
export default TopicStatusUpdate; export default TopicTimer;

View File

@ -52,9 +52,9 @@ const TopicRoute = Discourse.Route.extend({
showTopicStatusUpdate() { showTopicStatusUpdate() {
const model = this.modelFor('topic'); const model = this.modelFor('topic');
model.set('topic_status_update', Ember.Object.create(model.get('topic_status_update'))); model.set('topic_timer', Ember.Object.create(model.get('topic_timer')));
showModal('edit-topic-status-update', { model }); showModal('edit-topic-timer', { model });
this.controllerFor('modal').set('modalClass', 'edit-topic-status-update-modal'); this.controllerFor('modal').set('modalClass', 'edit-topic-timer-modal');
}, },
showChangeTimestamp() { showChangeTimestamp() {

View File

@ -41,7 +41,7 @@
{{#if showTopicStatusInfo}} {{#if showTopicStatusInfo}}
<div class="alert alert-info"> <div class="alert alert-info">
{{topic-status-info {{topic-timer-info
statusType=statusType statusType=statusType
executeAt=executeAt executeAt=executeAt
basedOnLastPost=basedOnLastPost basedOnLastPost=basedOnLastPost

View File

@ -1,7 +1,7 @@
<form> <form>
{{#d-modal-body title="topic.topic_status_update.title" autoFocus="false"}} {{#d-modal-body title="topic.topic_status_update.title" autoFocus="false"}}
<div class="control-group"> <div class="control-group">
{{combo-box content=statusUpdates value=selection width="50%"}} {{combo-box content=timerTypes value=selection width="50%"}}
</div> </div>
<div> <div>
@ -25,7 +25,7 @@
{{auto-update-input {{auto-update-input
input=updateTime input=updateTime
statusType=selection statusType=selection
basedOnLastPost=topicStatusUpdate.based_on_last_post basedOnLastPost=topicTimer.based_on_last_post
lastPostedAt=model.last_posted_at}} lastPostedAt=model.last_posted_at}}
{{/if}} {{/if}}
</div> </div>
@ -35,14 +35,14 @@
{{d-button class="btn-primary" {{d-button class="btn-primary"
disabled=saveDisabled disabled=saveDisabled
label="topic.topic_status_update.save" label="topic.topic_status_update.save"
action="saveStatusUpdate"}} action="saveTimer"}}
<a {{action "closeModal"}}>{{i18n 'cancel'}}</a> <a {{action "closeModal"}}>{{i18n 'cancel'}}</a>
{{conditional-loading-spinner size="small" condition=loading}} {{conditional-loading-spinner size="small" condition=loading}}
{{#if topicStatusUpdate.execute_at}} {{#if topicTimer.execute_at}}
{{d-button class="pull-right btn-danger" {{d-button class="pull-right btn-danger"
action="removeStatusUpdate" action="removeTimer"
label='topic.topic_status_update.remove'}} label='topic.topic_status_update.remove'}}
{{/if}} {{/if}}
</div> </div>

View File

@ -174,12 +174,12 @@
{{#conditional-loading-spinner condition=model.postStream.loadingFilter}} {{#conditional-loading-spinner condition=model.postStream.loadingFilter}}
{{#if loadedAllPosts}} {{#if loadedAllPosts}}
{{topic-status-info {{topic-timer-info
statusType=model.topic_status_update.status_type statusType=model.topic_timer.status_type
executeAt=model.topic_status_update.execute_at executeAt=model.topic_timer.execute_at
basedOnLastPost=model.topic_status_update.based_on_last_post basedOnLastPost=model.topic_timer.based_on_last_post
duration=model.topic_status_update.duration duration=model.topic_timer.duration
categoryId=model.topic_status_update.category_id}} categoryId=model.topic_timer.category_id}}
{{#if session.showSignupCta}} {{#if session.showSignupCta}}
{{! replace "Log In to Reply" with the infobox }} {{! replace "Log In to Reply" with the infobox }}

View File

@ -1,4 +1,4 @@
.edit-topic-status-update-modal { .edit-topic-timer-modal {
.modal-body { .modal-body {
max-height: none; max-height: none;
} }

View File

@ -22,6 +22,7 @@ class TopicsController < ApplicationController
:clear_pin, :clear_pin,
:re_pin, :re_pin,
:status_update, :status_update,
:timer,
:bulk, :bulk,
:reset_new, :reset_new,
:change_post_owners, :change_post_owners,
@ -275,8 +276,8 @@ class TopicsController < ApplicationController
@topic.update_status(status, enabled, current_user, until: params[:until]) @topic.update_status(status, enabled, current_user, until: params[:until])
render json: success_json.merge!( render json: success_json.merge!(
topic_status_update: TopicStatusUpdateSerializer.new( topic_status_update: TopicTimerSerializer.new(
TopicStatusUpdate.find_by(topic: @topic), root: false TopicTimer.find_by(topic: @topic), root: false
) )
) )
end end
@ -289,13 +290,13 @@ class TopicsController < ApplicationController
toggle_mute toggle_mute
end end
def status_update def timer
params.permit(:time, :timezone_offset, :based_on_last_post, :category_id) params.permit(:time, :timezone_offset, :based_on_last_post, :category_id)
params.require(:status_type) params.require(:status_type)
status_type = status_type =
begin begin
TopicStatusUpdate.types.fetch(params[:status_type].to_sym) TopicTimer.types.fetch(params[:status_type].to_sym)
rescue rescue
invalid_param(:status_type) invalid_param(:status_type)
end end
@ -311,7 +312,7 @@ class TopicsController < ApplicationController
options.merge!(category_id: params[:category_id]) if !params[:category_id].blank? options.merge!(category_id: params[:category_id]) if !params[:category_id].blank?
topic_status_update = topic.set_or_create_status_update( topic_status_update = topic.set_or_create_timer(
status_type, status_type,
params[:time], params[:time],
options options

View File

@ -2,18 +2,17 @@ module Jobs
class DeleteTopic < Jobs::Base class DeleteTopic < Jobs::Base
def execute(args) def execute(args)
topic_status_update = TopicStatusUpdate.find_by(id: args[:topic_status_update_id]) topic_timer = TopicTimer.find_by(id: args[:topic_timer_id] || args[:topic_status_update_id])
topic = topic_status_update&.topic topic = topic_timer&.topic
if topic_status_update.blank? || topic.blank? || if topic_timer.blank? || topic.blank? || topic_timer.execute_at > Time.zone.now
topic_status_update.execute_at > Time.zone.now
return return
end end
if Guardian.new(topic_status_update.user).can_delete?(topic) if Guardian.new(topic_timer.user).can_delete?(topic)
first_post = topic.ordered_posts.first first_post = topic.ordered_posts.first
PostDestroyer.new(topic_status_update.user, first_post, { context: I18n.t("topic_statuses.auto_deleted_by_timer") }).destroy PostDestroyer.new(topic_timer.user, first_post, { context: I18n.t("topic_statuses.auto_deleted_by_timer") }).destroy
end end
end end

View File

@ -1,22 +1,22 @@
module Jobs module Jobs
class PublishTopicToCategory < Jobs::Base class PublishTopicToCategory < Jobs::Base
def execute(args) def execute(args)
topic_status_update = TopicStatusUpdate.find_by(id: args[:topic_status_update_id]) topic_timer = TopicTimer.find_by(id: args[:topic_timer_id] || args[:topic_status_update_id])
raise Discourse::InvalidParameters.new(:topic_status_update_id) if topic_status_update.blank? raise Discourse::InvalidParameters.new(:topic_timer_id) if topic_timer.blank?
topic = topic_status_update.topic topic = topic_timer.topic
return if topic.blank? return if topic.blank?
PostTimestampChanger.new(timestamp: Time.zone.now, topic: topic).change! do PostTimestampChanger.new(timestamp: Time.zone.now, topic: topic).change! do
if topic.private_message? if topic.private_message?
topic = TopicConverter.new(topic, Discourse.system_user) topic = TopicConverter.new(topic, Discourse.system_user)
.convert_to_public_topic(topic_status_update.category_id) .convert_to_public_topic(topic_timer.category_id)
else else
topic.change_category_to_id(topic_status_update.category_id) topic.change_category_to_id(topic_timer.category_id)
end end
topic.update_columns(visible: true) topic.update_columns(visible: true)
topic_status_update.trash!(Discourse.system_user) topic_timer.trash!(Discourse.system_user)
end end
MessageBus.publish("/topic/#{topic.id}", reload_topic: true, refresh_stream: true) MessageBus.publish("/topic/#{topic.id}", reload_topic: true, refresh_stream: true)

View File

@ -1,18 +1,18 @@
module Jobs module Jobs
class ToggleTopicClosed < Jobs::Base class ToggleTopicClosed < Jobs::Base
def execute(args) def execute(args)
topic_status_update = TopicStatusUpdate.find_by(id: args[:topic_status_update_id]) topic_timer = TopicTimer.find_by(id: args[:topic_timer_id] || args[:topic_status_update_id])
state = !!args[:state] state = !!args[:state]
if topic_status_update.blank? || if topic_timer.blank? ||
topic_status_update.execute_at > Time.zone.now || topic_timer.execute_at > Time.zone.now ||
(topic = topic_status_update.topic).blank? || (topic = topic_timer.topic).blank? ||
topic.closed == state topic.closed == state
return return
end end
user = topic_status_update.user user = topic_timer.user
if Guardian.new(user).can_close?(topic) if Guardian.new(user).can_close?(topic)
topic.update_status('autoclosed', state, user) topic.update_status('autoclosed', state, user)

View File

@ -25,7 +25,7 @@ module Jobs
ScoreCalculator.new.calculate(args) ScoreCalculator.new.calculate(args)
# Re-run stuff that we missed # Re-run stuff that we missed
TopicStatusUpdate.ensure_consistency! TopicTimer.ensure_consistency!
# Forces rebake of old posts where needed, as long as no system avatars need updating # Forces rebake of old posts where needed, as long as no system avatars need updating
unless UserAvatar.where("last_gravatar_download_attempt IS NULL").limit(1).first unless UserAvatar.where("last_gravatar_download_attempt IS NULL").limit(1).first

View File

@ -202,7 +202,7 @@ SQL
t = Topic.new(title: I18n.t("category.topic_prefix", category: name), user: user, pinned_at: Time.now, category_id: id) t = Topic.new(title: I18n.t("category.topic_prefix", category: name), user: user, pinned_at: Time.now, category_id: id)
t.skip_callbacks = true t.skip_callbacks = true
t.ignore_category_auto_close = true t.ignore_category_auto_close = true
t.set_or_create_status_update(TopicStatusUpdate.types[:close], nil) t.set_or_create_timer(TopicTimer.types[:close], nil)
t.save!(validate: false) t.save!(validate: false)
update_column(:topic_id, t.id) update_column(:topic_id, t.id)
t.posts.create(raw: post_template, user: user) t.posts.create(raw: post_template, user: user)

View File

@ -521,8 +521,8 @@ SQL
) )
) )
topic.set_or_create_status_update( topic.set_or_create_timer(
TopicStatusUpdate.types[:open], TopicTimer.types[:open],
SiteSetting.num_hours_to_close_topic, SiteSetting.num_hours_to_close_topic,
by_user: Discourse.system_user by_user: Discourse.system_user
) )

View File

@ -121,7 +121,7 @@ class Topic < ActiveRecord::Base
has_many :topic_links has_many :topic_links
has_many :topic_invites has_many :topic_invites
has_many :invites, through: :topic_invites, source: :invite has_many :invites, through: :topic_invites, source: :invite
has_many :topic_status_updates, dependent: :destroy has_many :topic_timers, dependent: :destroy
has_one :user_warning has_one :user_warning
has_one :first_post, -> {where post_number: 1}, class_name: Post has_one :first_post, -> {where post_number: 1}, class_name: Post
@ -215,10 +215,10 @@ class Topic < ActiveRecord::Base
if !@ignore_category_auto_close && if !@ignore_category_auto_close &&
self.category && self.category &&
self.category.auto_close_hours && self.category.auto_close_hours &&
!topic_status_update&.execute_at !topic_timer&.execute_at
self.set_or_create_status_update( self.set_or_create_timer(
TopicStatusUpdate.types[:close], TopicTimer.types[:close],
self.category.auto_close_hours, self.category.auto_close_hours,
based_on_last_post: self.category.auto_close_based_on_last_post based_on_last_post: self.category.auto_close_based_on_last_post
) )
@ -952,8 +952,12 @@ SQL
Topic.where("pinned_until < now()").update_all(pinned_at: nil, pinned_globally: false, pinned_until: nil) Topic.where("pinned_until < now()").update_all(pinned_at: nil, pinned_globally: false, pinned_until: nil)
end end
def topic_timer
@topic_timer ||= topic_timers.where('deleted_at IS NULL').first
end
def topic_status_update def topic_status_update
@topic_status_update ||= topic_status_updates.where('deleted_at IS NULL').first topic_timer # will be used to filter timers unrelated to topic status
end end
# Valid arguments for the time: # Valid arguments for the time:
@ -968,31 +972,31 @@ SQL
# * timezone_offset: (Integer) offset from UTC in minutes of the given argument. # * timezone_offset: (Integer) offset from UTC in minutes of the given argument.
# * based_on_last_post: True if time should be based on timestamp of the last post. # * based_on_last_post: True if time should be based on timestamp of the last post.
# * category_id: Category that the update will apply to. # * category_id: Category that the update will apply to.
def set_or_create_status_update(status_type, time, by_user: nil, timezone_offset: 0, based_on_last_post: false, category_id: SiteSetting.uncategorized_category_id) def set_or_create_timer(status_type, time, by_user: nil, timezone_offset: 0, based_on_last_post: false, category_id: SiteSetting.uncategorized_category_id)
topic_status_update = TopicStatusUpdate.find_or_initialize_by( topic_timer = TopicTimer.find_or_initialize_by(
status_type: status_type, status_type: status_type,
topic: self topic: self
) )
if time.blank? if time.blank?
topic_status_update.trash!(trashed_by: by_user || Discourse.system_user) topic_timer.trash!(trashed_by: by_user || Discourse.system_user)
return return
end end
time_now = Time.zone.now time_now = Time.zone.now
topic_status_update.based_on_last_post = !based_on_last_post.blank? topic_timer.based_on_last_post = !based_on_last_post.blank?
if status_type == TopicStatusUpdate.types[:publish_to_category] if status_type == TopicTimer.types[:publish_to_category]
topic_status_update.category = Category.find_by(id: category_id) topic_timer.category = Category.find_by(id: category_id)
end end
if topic_status_update.based_on_last_post if topic_timer.based_on_last_post
num_hours = time.to_f num_hours = time.to_f
if num_hours > 0 if num_hours > 0
last_post_created_at = self.ordered_posts.last.present? ? self.ordered_posts.last.created_at : time_now last_post_created_at = self.ordered_posts.last.present? ? self.ordered_posts.last.created_at : time_now
topic_status_update.execute_at = last_post_created_at + num_hours.hours topic_timer.execute_at = last_post_created_at + num_hours.hours
topic_status_update.created_at = last_post_created_at topic_timer.created_at = last_post_created_at
end end
else else
utc = Time.find_zone("UTC") utc = Time.find_zone("UTC")
@ -1001,37 +1005,37 @@ SQL
if is_timestamp && m = /^(\d{1,2}):(\d{2})(?:\s*[AP]M)?$/i.match(time.strip) if is_timestamp && m = /^(\d{1,2}):(\d{2})(?:\s*[AP]M)?$/i.match(time.strip)
# a time of day in client's time zone, like "15:00" # a time of day in client's time zone, like "15:00"
topic_status_update.execute_at = utc.local(now.year, now.month, now.day, m[1].to_i, m[2].to_i) topic_timer.execute_at = utc.local(now.year, now.month, now.day, m[1].to_i, m[2].to_i)
topic_status_update.execute_at += timezone_offset * 60 if timezone_offset topic_timer.execute_at += timezone_offset * 60 if timezone_offset
topic_status_update.execute_at += 1.day if topic_status_update.execute_at < now topic_timer.execute_at += 1.day if topic_timer.execute_at < now
elsif is_timestamp && time.include?("-") && timestamp = utc.parse(time) elsif is_timestamp && time.include?("-") && timestamp = utc.parse(time)
# a timestamp in client's time zone, like "2015-5-27 12:00" # a timestamp in client's time zone, like "2015-5-27 12:00"
topic_status_update.execute_at = timestamp topic_timer.execute_at = timestamp
topic_status_update.execute_at += timezone_offset * 60 if timezone_offset topic_timer.execute_at += timezone_offset * 60 if timezone_offset
topic_status_update.errors.add(:execute_at, :invalid) if timestamp < now topic_timer.errors.add(:execute_at, :invalid) if timestamp < now
else else
num_hours = time.to_f num_hours = time.to_f
if num_hours > 0 if num_hours > 0
topic_status_update.execute_at = num_hours.hours.from_now topic_timer.execute_at = num_hours.hours.from_now
end end
end end
end end
if topic_status_update.execute_at if topic_timer.execute_at
if by_user&.staff? || by_user&.trust_level == TrustLevel[4] if by_user&.staff? || by_user&.trust_level == TrustLevel[4]
topic_status_update.user = by_user topic_timer.user = by_user
else else
topic_status_update.user ||= (self.user.staff? || self.user.trust_level == TrustLevel[4] ? self.user : Discourse.system_user) topic_timer.user ||= (self.user.staff? || self.user.trust_level == TrustLevel[4] ? self.user : Discourse.system_user)
end end
if self.persisted? if self.persisted?
topic_status_update.save! topic_timer.save!
else else
self.topic_status_updates << topic_status_update self.topic_timers << topic_timer
end end
topic_status_update topic_timer
end end
end end

View File

@ -1,4 +1,4 @@
class TopicStatusUpdate < ActiveRecord::Base class TopicTimer < ActiveRecord::Base
include Trashable include Trashable
belongs_to :user belongs_to :user
@ -41,12 +41,12 @@ class TopicStatusUpdate < ActiveRecord::Base
end end
def self.ensure_consistency! def self.ensure_consistency!
TopicStatusUpdate.where("topic_status_updates.execute_at < ?", Time.zone.now) TopicTimer.where("topic_timers.execute_at < ?", Time.zone.now)
.find_each do |topic_status_update| .find_each do |topic_timer|
topic_status_update.send( topic_timer.send(
"schedule_auto_#{self.types[topic_status_update.status_type]}_job", "schedule_auto_#{self.types[topic_timer.status_type]}_job",
topic_status_update.execute_at topic_timer.execute_at
) )
end end
end end
@ -64,22 +64,22 @@ class TopicStatusUpdate < ActiveRecord::Base
def ensure_update_will_happen def ensure_update_will_happen
if created_at && (execute_at < created_at) if created_at && (execute_at < created_at)
errors.add(:execute_at, I18n.t( errors.add(:execute_at, I18n.t(
'activerecord.errors.models.topic_status_update.attributes.execute_at.in_the_past' 'activerecord.errors.models.topic_timer.attributes.execute_at.in_the_past'
)) ))
end end
end end
def cancel_auto_close_job def cancel_auto_close_job
Jobs.cancel_scheduled_job(:toggle_topic_closed, topic_status_update_id: id) Jobs.cancel_scheduled_job(:toggle_topic_closed, topic_timer_id: id)
end end
alias_method :cancel_auto_open_job, :cancel_auto_close_job alias_method :cancel_auto_open_job, :cancel_auto_close_job
def cancel_auto_publish_to_category_job def cancel_auto_publish_to_category_job
Jobs.cancel_scheduled_job(:publish_topic_to_category, topic_status_update_id: id) Jobs.cancel_scheduled_job(:publish_topic_to_category, topic_timer_id: id)
end end
def cancel_auto_delete_job def cancel_auto_delete_job
Jobs.cancel_scheduled_job(:delete_topic, topic_status_update_id: id) Jobs.cancel_scheduled_job(:delete_topic, topic_timer_id: id)
end end
def schedule_auto_open_job(time) def schedule_auto_open_job(time)
@ -87,7 +87,7 @@ class TopicStatusUpdate < ActiveRecord::Base
topic.update_status('closed', true, user) if !topic.closed topic.update_status('closed', true, user) if !topic.closed
Jobs.enqueue_at(time, :toggle_topic_closed, Jobs.enqueue_at(time, :toggle_topic_closed,
topic_status_update_id: id, topic_timer_id: id,
state: false state: false
) )
end end
@ -97,27 +97,27 @@ class TopicStatusUpdate < ActiveRecord::Base
topic.update_status('closed', false, user) if topic.closed topic.update_status('closed', false, user) if topic.closed
Jobs.enqueue_at(time, :toggle_topic_closed, Jobs.enqueue_at(time, :toggle_topic_closed,
topic_status_update_id: id, topic_timer_id: id,
state: true state: true
) )
end end
def schedule_auto_publish_to_category_job(time) def schedule_auto_publish_to_category_job(time)
Jobs.enqueue_at(time, :publish_topic_to_category, topic_status_update_id: id) Jobs.enqueue_at(time, :publish_topic_to_category, topic_timer_id: id)
end end
def publishing_to_category? def publishing_to_category?
self.status_type.to_i == TopicStatusUpdate.types[:publish_to_category] self.status_type.to_i == TopicTimer.types[:publish_to_category]
end end
def schedule_auto_delete_job(time) def schedule_auto_delete_job(time)
Jobs.enqueue_at(time, :delete_topic, topic_status_update_id: id) Jobs.enqueue_at(time, :delete_topic, topic_timer_id: id)
end end
end end
# == Schema Information # == Schema Information
# #
# Table name: topic_status_updates # Table name: topic_timers
# #
# id :integer not null, primary key # id :integer not null, primary key
# execute_at :datetime not null # execute_at :datetime not null

View File

@ -1,4 +1,4 @@
class TopicStatusUpdateSerializer < ApplicationSerializer class TopicTimerSerializer < ApplicationSerializer
attributes :id, attributes :id,
:execute_at, :execute_at,
:duration, :duration,
@ -7,6 +7,6 @@ class TopicStatusUpdateSerializer < ApplicationSerializer
:category_id :category_id
def status_type def status_type
TopicStatusUpdate.types[object.status_type] TopicTimer.types[object.status_type]
end end
end end

View File

@ -60,7 +60,7 @@ class TopicViewSerializer < ApplicationSerializer
:message_archived, :message_archived,
:tags, :tags,
:featured_link, :featured_link,
:topic_status_update, :topic_timer,
:unicode_title :unicode_title
# TODO: Split off into proper object / serializer # TODO: Split off into proper object / serializer
@ -249,9 +249,9 @@ class TopicViewSerializer < ApplicationSerializer
SiteSetting.tagging_enabled SiteSetting.tagging_enabled
end end
def topic_status_update def topic_timer
TopicStatusUpdateSerializer.new( TopicTimerSerializer.new(
object.topic.topic_status_update, root: false object.topic.topic_timer, root: false
) )
end end

View File

@ -38,9 +38,9 @@ TopicStatusUpdater = Struct.new(:topic, :user) do
if @topic_status_update if @topic_status_update
if status.manually_closing_topic? || status.closing_topic? if status.manually_closing_topic? || status.closing_topic?
topic.set_or_create_status_update(TopicStatusUpdate.types[:close], nil) topic.set_or_create_timer(TopicTimer.types[:close], nil)
elsif status.manually_opening_topic? || status.opening_topic? elsif status.manually_opening_topic? || status.opening_topic?
topic.set_or_create_status_update(TopicStatusUpdate.types[:open], nil) topic.set_or_create_timer(TopicTimer.types[:open], nil)
end end
end end

View File

@ -401,7 +401,7 @@ en:
attributes: attributes:
name: name:
taken: is already in use by another emoji taken: is already in use by another emoji
topic_status_update: topic_timer:
attributes: attributes:
execute_at: execute_at:
in_the_past: "must be in the future." in_the_past: "must be in the future."

View File

@ -605,7 +605,7 @@ Discourse::Application.routes.draw do
put "t/:topic_id/re-pin" => "topics#re_pin", constraints: {topic_id: /\d+/} put "t/:topic_id/re-pin" => "topics#re_pin", constraints: {topic_id: /\d+/}
put "t/:topic_id/mute" => "topics#mute", constraints: {topic_id: /\d+/} put "t/:topic_id/mute" => "topics#mute", constraints: {topic_id: /\d+/}
put "t/:topic_id/unmute" => "topics#unmute", constraints: {topic_id: /\d+/} put "t/:topic_id/unmute" => "topics#unmute", constraints: {topic_id: /\d+/}
post "t/:topic_id/status_update" => "topics#status_update", constraints: {topic_id: /\d+/} post "t/:topic_id/timer" => "topics#timer", constraints: {topic_id: /\d+/}
put "t/:topic_id/make-banner" => "topics#make_banner", constraints: {topic_id: /\d+/} put "t/:topic_id/make-banner" => "topics#make_banner", constraints: {topic_id: /\d+/}
put "t/:topic_id/remove-banner" => "topics#remove_banner", constraints: {topic_id: /\d+/} put "t/:topic_id/remove-banner" => "topics#remove_banner", constraints: {topic_id: /\d+/}
put "t/:topic_id/remove-allowed-user" => "topics#remove_allowed_user", constraints: {topic_id: /\d+/} put "t/:topic_id/remove-allowed-user" => "topics#remove_allowed_user", constraints: {topic_id: /\d+/}

View File

@ -1,12 +1,13 @@
class MoveAutoCloseColumnsToTopicStatusUpdate < ActiveRecord::Migration class MoveAutoCloseColumnsToTopicStatusUpdate < ActiveRecord::Migration
def up def up
# The 1 in the fourth column is TopicStatusUpdate.types[:close], an enum with value 1.
execute <<~SQL execute <<~SQL
INSERT INTO topic_status_updates(topic_id, user_id, execute_at, status_type, based_on_last_post, created_at, updated_at) INSERT INTO topic_status_updates(topic_id, user_id, execute_at, status_type, based_on_last_post, created_at, updated_at)
SELECT SELECT
t.id, t.id,
t.auto_close_user_id, t.auto_close_user_id,
t.auto_close_at, t.auto_close_at,
#{TopicStatusUpdate.types[:close]}, 1,
t.auto_close_based_on_last_post, t.auto_close_based_on_last_post,
t.auto_close_started_at, t.auto_close_started_at,
t.auto_close_started_at t.auto_close_started_at

View File

@ -0,0 +1,5 @@
class RenameTopicStatusUpdatesToTopicTimers < ActiveRecord::Migration
def change
rename_table :topic_status_updates, :topic_timers
end
end

View File

@ -390,15 +390,15 @@ class PostCreator
end end
def update_topic_auto_close def update_topic_auto_close
topic_status_update = @topic.topic_status_update topic_timer = @topic.topic_timer
if topic_status_update && if topic_timer &&
topic_status_update.based_on_last_post && topic_timer.based_on_last_post &&
topic_status_update.duration > 0 topic_timer.duration > 0
@topic.set_or_create_status_update(TopicStatusUpdate.types[:close], @topic.set_or_create_timer(TopicTimer.types[:close],
topic_status_update.duration, topic_timer.duration,
based_on_last_post: topic_status_update.based_on_last_post based_on_last_post: topic_timer.based_on_last_post
) )
end end
end end

View File

@ -269,12 +269,12 @@ describe PostCreator do
it "doesn't update topic's auto close when it's not based on last post" do it "doesn't update topic's auto close when it's not based on last post" do
Timecop.freeze do Timecop.freeze do
topic = Fabricate(:topic).set_or_create_status_update(TopicStatusUpdate.types[:close], 12) topic = Fabricate(:topic).set_or_create_timer(TopicTimer.types[:close], 12)
PostCreator.new(topic.user, topic_id: topic.id, raw: "this is a second post").create PostCreator.new(topic.user, topic_id: topic.id, raw: "this is a second post").create
topic.reload topic.reload
topic_status_update = TopicStatusUpdate.last topic_status_update = TopicTimer.last
expect(topic_status_update.execute_at).to be_within(1.second).of(Time.zone.now + 12.hours) expect(topic_status_update.execute_at).to be_within(1.second).of(Time.zone.now + 12.hours)
expect(topic_status_update.created_at).to be_within(1.second).of(Time.zone.now) expect(topic_status_update.created_at).to be_within(1.second).of(Time.zone.now)
end end
@ -283,7 +283,7 @@ describe PostCreator do
it "updates topic's auto close date when it's based on last post" do it "updates topic's auto close date when it's based on last post" do
Timecop.freeze do Timecop.freeze do
topic = Fabricate(:topic, topic = Fabricate(:topic,
topic_status_updates: [Fabricate(:topic_status_update, topic_timers: [Fabricate(:topic_timer,
based_on_last_post: true, based_on_last_post: true,
execute_at: Time.zone.now - 12.hours, execute_at: Time.zone.now - 12.hours,
created_at: Time.zone.now - 24.hours created_at: Time.zone.now - 24.hours
@ -294,7 +294,7 @@ describe PostCreator do
PostCreator.new(topic.user, topic_id: topic.id, raw: "this is a second post").create PostCreator.new(topic.user, topic_id: topic.id, raw: "this is a second post").create
topic_status_update = TopicStatusUpdate.last topic_status_update = TopicTimer.last
expect(topic_status_update.execute_at).to be_within(1.second).of(Time.zone.now + 12.hours) expect(topic_status_update.execute_at).to be_within(1.second).of(Time.zone.now + 12.hours)
expect(topic_status_update.created_at).to be_within(1.second).of(Time.zone.now) expect(topic_status_update.created_at).to be_within(1.second).of(Time.zone.now)
end end
@ -362,7 +362,7 @@ describe PostCreator do
Guardian.any_instance.stubs(:can_moderate?).returns(false) Guardian.any_instance.stubs(:can_moderate?).returns(false)
expect { expect {
PostCreator.new(user, basic_topic_params.merge(auto_close_time: 2)).create! PostCreator.new(user, basic_topic_params.merge(auto_close_time: 2)).create!
}.to_not change { TopicStatusUpdate.count } }.to_not change { TopicTimer.count }
end end
end end
end end

View File

@ -413,8 +413,8 @@ describe TopicsController do
end end
it 'should update the status of the topic correctly' do it 'should update the status of the topic correctly' do
@topic = Fabricate(:topic, user: @user, closed: true, topic_status_updates: [ @topic = Fabricate(:topic, user: @user, closed: true, topic_timers: [
Fabricate(:topic_status_update, status_type: TopicStatusUpdate.types[:open]) Fabricate(:topic_timer, status_type: TopicTimer.types[:open])
]) ])
xhr :put, :status, topic_id: @topic.id, status: 'closed', enabled: 'false' xhr :put, :status, topic_id: @topic.id, status: 'closed', enabled: 'false'

View File

@ -1,6 +0,0 @@
Fabricator(:topic_status_update) do
user
topic
execute_at Time.zone.now + 1.hour
status_type TopicStatusUpdate.types[:close]
end

View File

@ -0,0 +1,6 @@
Fabricator(:topic_timer) do
user
topic
execute_at Time.zone.now + 1.hour
status_type TopicTimer.types[:close]
end

View File

@ -7,9 +7,9 @@ RSpec.describe "Managing a topic's status update", type: :request do
context 'when a user is not logged in' do context 'when a user is not logged in' do
it 'should return the right response' do it 'should return the right response' do
expect do expect do
post "/t/#{topic.id}/status_update.json", post "/t/#{topic.id}/timer.json",
time: '24', time: '24',
status_type: TopicStatusUpdate.types[1] status_type: TopicTimer.types[1]
end.to raise_error(Discourse::NotLoggedIn) end.to raise_error(Discourse::NotLoggedIn)
end end
end end
@ -18,9 +18,9 @@ RSpec.describe "Managing a topic's status update", type: :request do
it 'should return the right response' do it 'should return the right response' do
sign_in(user) sign_in(user)
post "/t/#{topic.id}/status_update.json", post "/t/#{topic.id}/timer.json",
time: '24', time: '24',
status_type: TopicStatusUpdate.types[1] status_type: TopicTimer.types[1]
expect(response.status).to eq(403) expect(response.status).to eq(403)
expect(JSON.parse(response.body)["error_type"]).to eq('invalid_access') expect(JSON.parse(response.body)["error_type"]).to eq('invalid_access')
@ -37,13 +37,13 @@ RSpec.describe "Managing a topic's status update", type: :request do
it 'should be able to create a topic status update' do it 'should be able to create a topic status update' do
time = 24 time = 24
post "/t/#{topic.id}/status_update.json", post "/t/#{topic.id}/timer.json",
time: 24, time: 24,
status_type: TopicStatusUpdate.types[1] status_type: TopicTimer.types[1]
expect(response).to be_success expect(response).to be_success
topic_status_update = TopicStatusUpdate.last topic_status_update = TopicTimer.last
expect(topic_status_update.topic).to eq(topic) expect(topic_status_update.topic).to eq(topic)
@ -60,11 +60,11 @@ RSpec.describe "Managing a topic's status update", type: :request do
end end
it 'should be able to delete a topic status update' do it 'should be able to delete a topic status update' do
topic.update!(topic_status_updates: [Fabricate(:topic_status_update)]) topic.update!(topic_timers: [Fabricate(:topic_timer)])
post "/t/#{topic.id}/status_update.json", post "/t/#{topic.id}/timer.json",
time: nil, time: nil,
status_type: TopicStatusUpdate.types[1] status_type: TopicTimer.types[1]
expect(response).to be_success expect(response).to be_success
expect(topic.reload.topic_status_update).to eq(nil) expect(topic.reload.topic_status_update).to eq(nil)
@ -80,14 +80,14 @@ RSpec.describe "Managing a topic's status update", type: :request do
it 'should be able to create the topic status update' do it 'should be able to create the topic status update' do
SiteSetting.queue_jobs = true SiteSetting.queue_jobs = true
post "/t/#{topic.id}/status_update.json", post "/t/#{topic.id}/timer.json",
time: 24, time: 24,
status_type: TopicStatusUpdate.types[3], status_type: TopicTimer.types[3],
category_id: topic.category_id category_id: topic.category_id
expect(response).to be_success expect(response).to be_success
topic_status_update = TopicStatusUpdate.last topic_status_update = TopicTimer.last
expect(topic_status_update.topic).to eq(topic) expect(topic_status_update.topic).to eq(topic)
@ -95,7 +95,7 @@ RSpec.describe "Managing a topic's status update", type: :request do
.to be_within(1.second).of(24.hours.from_now) .to be_within(1.second).of(24.hours.from_now)
expect(topic_status_update.status_type) expect(topic_status_update.status_type)
.to eq(TopicStatusUpdate.types[:publish_to_category]) .to eq(TopicTimer.types[:publish_to_category])
json = JSON.parse(response.body) json = JSON.parse(response.body)
@ -106,7 +106,7 @@ RSpec.describe "Managing a topic's status update", type: :request do
describe 'invalid status type' do describe 'invalid status type' do
it 'should raise the right error' do it 'should raise the right error' do
expect do expect do
post "/t/#{topic.id}/status_update.json", post "/t/#{topic.id}/timer.json",
time: 10, time: 10,
status_type: 'something' status_type: 'something'
end.to raise_error(Discourse::InvalidParameters) end.to raise_error(Discourse::InvalidParameters)

View File

@ -46,14 +46,14 @@ describe Topic do
it 'should schedule the topic to auto-close' do it 'should schedule the topic to auto-close' do
topic topic
topic_status_update = TopicStatusUpdate.last topic_status_update = TopicTimer.last
expect(topic_status_update.topic).to eq(topic) expect(topic_status_update.topic).to eq(topic)
expect(topic.topic_status_update.execute_at).to be_within_one_second_of(2.hours.from_now) expect(topic.topic_status_update.execute_at).to be_within_one_second_of(2.hours.from_now)
args = job_klass.jobs.last['args'].first args = job_klass.jobs.last['args'].first
expect(args["topic_status_update_id"]).to eq(topic.topic_status_update.id) expect(args["topic_timer_id"]).to eq(topic.topic_status_update.id)
expect(args["state"]).to eq(true) expect(args["state"]).to eq(true)
end end
@ -64,7 +64,7 @@ describe Topic do
it 'should schedule the topic to auto-close' do it 'should schedule the topic to auto-close' do
staff_topic staff_topic
topic_status_update = TopicStatusUpdate.last topic_status_update = TopicTimer.last
expect(topic_status_update.topic).to eq(staff_topic) expect(topic_status_update.topic).to eq(staff_topic)
expect(topic_status_update.execute_at).to be_within_one_second_of(2.hours.from_now) expect(topic_status_update.execute_at).to be_within_one_second_of(2.hours.from_now)
@ -72,7 +72,7 @@ describe Topic do
args = job_klass.jobs.last['args'].first args = job_klass.jobs.last['args'].first
expect(args["topic_status_update_id"]).to eq(topic_status_update.id) expect(args["topic_timer_id"]).to eq(topic_status_update.id)
expect(args["state"]).to eq(true) expect(args["state"]).to eq(true)
end end
@ -95,7 +95,7 @@ describe Topic do
it 'should schedule the topic to auto-close' do it 'should schedule the topic to auto-close' do
regular_user_topic regular_user_topic
topic_status_update = TopicStatusUpdate.last topic_status_update = TopicTimer.last
expect(topic_status_update.topic).to eq(regular_user_topic) expect(topic_status_update.topic).to eq(regular_user_topic)
expect(topic_status_update.execute_at).to be_within_one_second_of(2.hours.from_now) expect(topic_status_update.execute_at).to be_within_one_second_of(2.hours.from_now)
@ -103,7 +103,7 @@ describe Topic do
args = job_klass.jobs.last['args'].first args = job_klass.jobs.last['args'].first
expect(args["topic_status_update_id"]).to eq(topic_status_update.id) expect(args["topic_timer_id"]).to eq(topic_status_update.id)
expect(args["state"]).to eq(true) expect(args["state"]).to eq(true)
end end
end end

View File

@ -5,7 +5,7 @@ describe Jobs::DeleteTopic do
let(:topic) do let(:topic) do
Fabricate(:topic, Fabricate(:topic,
topic_status_updates: [Fabricate(:topic_status_update, user: admin)] topic_timers: [Fabricate(:topic_timer, user: admin)]
) )
end end
@ -18,7 +18,7 @@ describe Jobs::DeleteTopic do
it "can close a topic" do it "can close a topic" do
first_post first_post
Timecop.freeze(2.hours.from_now) do Timecop.freeze(2.hours.from_now) do
described_class.new.execute(topic_status_update_id: topic.topic_status_update.id) described_class.new.execute(topic_timer_id: topic.topic_timer.id)
expect(topic.reload).to be_trashed expect(topic.reload).to be_trashed
expect(first_post.reload).to be_trashed expect(first_post.reload).to be_trashed
end end
@ -29,17 +29,17 @@ describe Jobs::DeleteTopic do
topic.trash! topic.trash!
Timecop.freeze(2.hours.from_now) do Timecop.freeze(2.hours.from_now) do
Topic.any_instance.expects(:trash!).never Topic.any_instance.expects(:trash!).never
described_class.new.execute(topic_status_update_id: topic.topic_status_update.id) described_class.new.execute(topic_timer_id: topic.topic_timer.id)
end end
end end
it "should do nothing if it's too early" do it "should do nothing if it's too early" do
t = Fabricate(:topic, t = Fabricate(:topic,
topic_status_updates: [Fabricate(:topic_status_update, user: admin, execute_at: 5.hours.from_now)] topic_timers: [Fabricate(:topic_timer, user: admin, execute_at: 5.hours.from_now)]
) )
create_post(topic: t) create_post(topic: t)
Timecop.freeze(4.hours.from_now) do Timecop.freeze(4.hours.from_now) do
described_class.new.execute(topic_status_update_id: t.topic_status_update.id) described_class.new.execute(topic_timer_id: t.topic_timer.id)
expect(t.reload).to_not be_trashed expect(t.reload).to_not be_trashed
end end
end end
@ -47,14 +47,14 @@ describe Jobs::DeleteTopic do
describe "user isn't authorized to delete topics" do describe "user isn't authorized to delete topics" do
let(:topic) { let(:topic) {
Fabricate(:topic, Fabricate(:topic,
topic_status_updates: [Fabricate(:topic_status_update, user: Fabricate(:user))] topic_timers: [Fabricate(:topic_timer, user: Fabricate(:user))]
) )
} }
it "shouldn't delete the topic" do it "shouldn't delete the topic" do
create_post(topic: topic) create_post(topic: topic)
Timecop.freeze(2.hours.from_now) do Timecop.freeze(2.hours.from_now) do
described_class.new.execute(topic_status_update_id: topic.topic_status_update.id) described_class.new.execute(topic_timer_id: topic.topic_timer.id)
expect(topic.reload).to_not be_trashed expect(topic.reload).to_not be_trashed
end end
end end

View File

@ -5,9 +5,9 @@ RSpec.describe Jobs::PublishTopicToCategory do
let(:another_category) { Fabricate(:category) } let(:another_category) { Fabricate(:category) }
let(:topic) do let(:topic) do
Fabricate(:topic, category: category, topic_status_updates: [ Fabricate(:topic, category: category, topic_timers: [
Fabricate(:topic_status_update, Fabricate(:topic_timer,
status_type: TopicStatusUpdate.types[:publish_to_category], status_type: TopicTimer.types[:publish_to_category],
category_id: another_category.id category_id: another_category.id
) )
]) ])
@ -17,9 +17,9 @@ RSpec.describe Jobs::PublishTopicToCategory do
SiteSetting.queue_jobs = true SiteSetting.queue_jobs = true
end end
describe 'when topic_status_update_id is invalid' do describe 'when topic_timer_id is invalid' do
it 'should raise the right error' do it 'should raise the right error' do
expect { described_class.new.execute(topic_status_update_id: -1) } expect { described_class.new.execute(topic_timer_id: -1) }
.to raise_error(Discourse::InvalidParameters) .to raise_error(Discourse::InvalidParameters)
end end
end end
@ -29,7 +29,7 @@ RSpec.describe Jobs::PublishTopicToCategory do
Timecop.travel(1.hour.ago) { topic } Timecop.travel(1.hour.ago) { topic }
topic.trash! topic.trash!
described_class.new.execute(topic_status_update_id: topic.topic_status_update.id) described_class.new.execute(topic_timer_id: topic.topic_timer.id)
topic.reload topic.reload
expect(topic.category).to eq(category) expect(topic.category).to eq(category)
@ -41,13 +41,13 @@ RSpec.describe Jobs::PublishTopicToCategory do
Timecop.travel(1.hour.ago) { topic.update!(visible: false) } Timecop.travel(1.hour.ago) { topic.update!(visible: false) }
message = MessageBus.track_publish do message = MessageBus.track_publish do
described_class.new.execute(topic_status_update_id: topic.topic_status_update.id) described_class.new.execute(topic_timer_id: topic.topic_timer.id)
end.first end.first
topic.reload topic.reload
expect(topic.category).to eq(another_category) expect(topic.category).to eq(another_category)
expect(topic.visible).to eq(true) expect(topic.visible).to eq(true)
expect(TopicStatusUpdate.find_by(id: topic.topic_status_update.id)).to eq(nil) expect(TopicTimer.find_by(id: topic.topic_timer.id)).to eq(nil)
%w{created_at bumped_at updated_at last_posted_at}.each do |attribute| %w{created_at bumped_at updated_at last_posted_at}.each do |attribute|
expect(topic.public_send(attribute)).to be_within(1.second).of(Time.zone.now) expect(topic.public_send(attribute)).to be_within(1.second).of(Time.zone.now)
@ -68,7 +68,7 @@ RSpec.describe Jobs::PublishTopicToCategory do
it 'should publish the topic to the new category' do it 'should publish the topic to the new category' do
message = MessageBus.track_publish do message = MessageBus.track_publish do
described_class.new.execute(topic_status_update_id: topic.topic_status_update.id) described_class.new.execute(topic_timer_id: topic.topic_timer.id)
end.last end.last
topic.reload topic.reload

View File

@ -5,7 +5,7 @@ describe Jobs::ToggleTopicClosed do
let(:topic) do let(:topic) do
Fabricate(:topic, Fabricate(:topic,
topic_status_updates: [Fabricate(:topic_status_update, user: admin)] topic_timers: [Fabricate(:topic_timer, user: admin)]
) )
end end
@ -18,7 +18,7 @@ describe Jobs::ToggleTopicClosed do
Timecop.travel(1.hour.from_now) do Timecop.travel(1.hour.from_now) do
described_class.new.execute( described_class.new.execute(
topic_status_update_id: topic.topic_status_update.id, topic_timer_id: topic.topic_timer.id,
state: true state: true
) )
@ -35,7 +35,7 @@ describe Jobs::ToggleTopicClosed do
Timecop.travel(1.hour.from_now) do Timecop.travel(1.hour.from_now) do
described_class.new.execute( described_class.new.execute(
topic_status_update_id: topic.topic_status_update.id, topic_timer_id: topic.topic_timer.id,
state: false state: false
) )
@ -54,7 +54,7 @@ describe Jobs::ToggleTopicClosed do
Topic.any_instance.expects(:update_status).never Topic.any_instance.expects(:update_status).never
described_class.new.execute( described_class.new.execute(
topic_status_update_id: topic.topic_status_update.id, topic_timer_id: topic.topic_timer.id,
state: true state: true
) )
end end
@ -63,13 +63,13 @@ describe Jobs::ToggleTopicClosed do
describe 'when user is not authorized to close topics' do describe 'when user is not authorized to close topics' do
let(:topic) do let(:topic) do
Fabricate(:topic, Fabricate(:topic,
topic_status_updates: [Fabricate(:topic_status_update, execute_at: 2.hours.from_now)] topic_timers: [Fabricate(:topic_timer, execute_at: 2.hours.from_now)]
) )
end end
it 'should not do anything' do it 'should not do anything' do
described_class.new.execute( described_class.new.execute(
topic_status_update_id: topic.topic_status_update.id, topic_timer_id: topic.topic_timer.id,
state: false state: false
) )

View File

@ -496,11 +496,11 @@ describe PostAction do
expect(topic.reload.closed).to eq(true) expect(topic.reload.closed).to eq(true)
topic_status_update = TopicStatusUpdate.last topic_status_update = TopicTimer.last
expect(topic_status_update.topic).to eq(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.execute_at).to be_within(1.second).of(1.hour.from_now)
expect(topic_status_update.status_type).to eq(TopicStatusUpdate.types[:open]) expect(topic_status_update.status_type).to eq(TopicTimer.types[:open])
end end
end end

View File

@ -746,7 +746,7 @@ describe Topic do
expect(@topic).to be_closed expect(@topic).to be_closed
expect(@topic.bumped_at.to_f).to eq(@original_bumped_at) expect(@topic.bumped_at.to_f).to eq(@original_bumped_at)
expect(@topic.moderator_posts_count).to eq(1) expect(@topic.moderator_posts_count).to eq(1)
expect(@topic.topic_status_updates.first).to eq(nil) expect(@topic.topic_timers.first).to eq(nil)
end end
end end
end end
@ -777,7 +777,7 @@ describe Topic do
freeze_time(2.days.ago) freeze_time(2.days.ago)
@topic.set_or_create_status_update(TopicStatusUpdate.types[:close], 48) @topic.set_or_create_timer(TopicTimer.types[:close], 48)
@topic.save! @topic.save!
freeze_time(2.days.from_now) freeze_time(2.days.from_now)
@ -1100,12 +1100,12 @@ describe Topic do
end end
end end
describe '#set_or_create_status_update' do describe '#set_or_create_timer' do
let(:topic) { Fabricate.build(:topic) } let(:topic) { Fabricate.build(:topic) }
let(:closing_topic) do let(:closing_topic) do
Fabricate(:topic, Fabricate(:topic,
topic_status_updates: [Fabricate(:topic_status_update, execute_at: 5.hours.from_now)] topic_timers: [Fabricate(:topic_timer, execute_at: 5.hours.from_now)]
) )
end end
@ -1116,146 +1116,146 @@ describe Topic do
it 'can take a number of hours as an integer' do it 'can take a number of hours as an integer' do
Timecop.freeze(now) do Timecop.freeze(now) do
topic.set_or_create_status_update(TopicStatusUpdate.types[:close], 72, by_user: admin) topic.set_or_create_timer(TopicTimer.types[:close], 72, by_user: admin)
expect(topic.topic_status_updates.first.execute_at).to eq(3.days.from_now) expect(topic.topic_timers.first.execute_at).to eq(3.days.from_now)
end end
end end
it 'can take a number of hours as an integer, with timezone offset' do it 'can take a number of hours as an integer, with timezone offset' do
Timecop.freeze(now) do Timecop.freeze(now) do
topic.set_or_create_status_update(TopicStatusUpdate.types[:close], 72, {by_user: admin, timezone_offset: 240}) topic.set_or_create_timer(TopicTimer.types[:close], 72, {by_user: admin, timezone_offset: 240})
expect(topic.topic_status_updates.first.execute_at).to eq(3.days.from_now) expect(topic.topic_timers.first.execute_at).to eq(3.days.from_now)
end end
end end
it 'can take a number of hours as a string' do it 'can take a number of hours as a string' do
Timecop.freeze(now) do Timecop.freeze(now) do
topic.set_or_create_status_update(TopicStatusUpdate.types[:close], '18', by_user: admin) topic.set_or_create_timer(TopicTimer.types[:close], '18', by_user: admin)
expect(topic.topic_status_updates.first.execute_at).to eq(18.hours.from_now) expect(topic.topic_timers.first.execute_at).to eq(18.hours.from_now)
end end
end end
it 'can take a number of hours as a string, with timezone offset' do it 'can take a number of hours as a string, with timezone offset' do
Timecop.freeze(now) do Timecop.freeze(now) do
topic.set_or_create_status_update(TopicStatusUpdate.types[:close], '18', {by_user: admin, timezone_offset: 240}) topic.set_or_create_timer(TopicTimer.types[:close], '18', {by_user: admin, timezone_offset: 240})
expect(topic.topic_status_updates.first.execute_at).to eq(18.hours.from_now) expect(topic.topic_timers.first.execute_at).to eq(18.hours.from_now)
end end
end end
it 'can take a number of hours as a string and can handle based on last post' do it 'can take a number of hours as a string and can handle based on last post' do
Timecop.freeze(now) do Timecop.freeze(now) do
topic.set_or_create_status_update(TopicStatusUpdate.types[:close], '18', {by_user: admin, based_on_last_post: true}) topic.set_or_create_timer(TopicTimer.types[:close], '18', {by_user: admin, based_on_last_post: true})
expect(topic.topic_status_updates.first.execute_at).to eq(18.hours.from_now) expect(topic.topic_timers.first.execute_at).to eq(18.hours.from_now)
end end
end end
it "can take a time later in the day" do it "can take a time later in the day" do
Timecop.freeze(now) do Timecop.freeze(now) do
topic.set_or_create_status_update(TopicStatusUpdate.types[:close], '13:00', {by_user: admin}) topic.set_or_create_timer(TopicTimer.types[:close], '13:00', {by_user: admin})
expect(topic.topic_status_updates.first.execute_at).to eq(Time.zone.local(2013,11,20,13,0)) expect(topic.topic_timers.first.execute_at).to eq(Time.zone.local(2013,11,20,13,0))
end end
end end
it "can take a time later in the day, with timezone offset" do it "can take a time later in the day, with timezone offset" do
Timecop.freeze(now) do Timecop.freeze(now) do
topic.set_or_create_status_update(TopicStatusUpdate.types[:close], '13:00', {by_user: admin, timezone_offset: 240}) topic.set_or_create_timer(TopicTimer.types[:close], '13:00', {by_user: admin, timezone_offset: 240})
expect(topic.topic_status_updates.first.execute_at).to eq(Time.zone.local(2013,11,20,17,0)) expect(topic.topic_timers.first.execute_at).to eq(Time.zone.local(2013,11,20,17,0))
end end
end end
it "can take a time for the next day" do it "can take a time for the next day" do
Timecop.freeze(now) do Timecop.freeze(now) do
topic.set_or_create_status_update(TopicStatusUpdate.types[:close], '5:00', {by_user: admin}) topic.set_or_create_timer(TopicTimer.types[:close], '5:00', {by_user: admin})
expect(topic.topic_status_updates.first.execute_at).to eq(Time.zone.local(2013,11,21,5,0)) expect(topic.topic_timers.first.execute_at).to eq(Time.zone.local(2013,11,21,5,0))
end end
end end
it "can take a time for the next day, with timezone offset" do it "can take a time for the next day, with timezone offset" do
Timecop.freeze(now) do Timecop.freeze(now) do
topic.set_or_create_status_update(TopicStatusUpdate.types[:close], '1:00', {by_user: admin, timezone_offset: 240}) topic.set_or_create_timer(TopicTimer.types[:close], '1:00', {by_user: admin, timezone_offset: 240})
expect(topic.topic_status_updates.first.execute_at).to eq(Time.zone.local(2013,11,21,5,0)) expect(topic.topic_timers.first.execute_at).to eq(Time.zone.local(2013,11,21,5,0))
end end
end end
it "can take a timestamp for a future time" do it "can take a timestamp for a future time" do
Timecop.freeze(now) do Timecop.freeze(now) do
topic.set_or_create_status_update(TopicStatusUpdate.types[:close], '2013-11-22 5:00', {by_user: admin}) topic.set_or_create_timer(TopicTimer.types[:close], '2013-11-22 5:00', {by_user: admin})
expect(topic.topic_status_updates.first.execute_at).to eq(Time.zone.local(2013,11,22,5,0)) expect(topic.topic_timers.first.execute_at).to eq(Time.zone.local(2013,11,22,5,0))
end end
end end
it "can take a timestamp for a future time, with timezone offset" do it "can take a timestamp for a future time, with timezone offset" do
Timecop.freeze(now) do Timecop.freeze(now) do
topic.set_or_create_status_update(TopicStatusUpdate.types[:close], '2013-11-22 5:00', {by_user: admin, timezone_offset: 240}) topic.set_or_create_timer(TopicTimer.types[:close], '2013-11-22 5:00', {by_user: admin, timezone_offset: 240})
expect(topic.topic_status_updates.first.execute_at).to eq(Time.zone.local(2013,11,22,9,0)) expect(topic.topic_timers.first.execute_at).to eq(Time.zone.local(2013,11,22,9,0))
end end
end end
it "sets a validation error when given a timestamp in the past" do it "sets a validation error when given a timestamp in the past" do
Timecop.freeze(now) do Timecop.freeze(now) do
topic.set_or_create_status_update(TopicStatusUpdate.types[:close], '2013-11-19 5:00', {by_user: admin}) topic.set_or_create_timer(TopicTimer.types[:close], '2013-11-19 5:00', {by_user: admin})
expect(topic.topic_status_updates.first.execute_at).to eq(Time.zone.local(2013,11,19,5,0)) expect(topic.topic_timers.first.execute_at).to eq(Time.zone.local(2013,11,19,5,0))
expect(topic.topic_status_updates.first.errors[:execute_at]).to be_present expect(topic.topic_timers.first.errors[:execute_at]).to be_present
end end
end end
it "can take a timestamp with timezone" do it "can take a timestamp with timezone" do
Timecop.freeze(now) do Timecop.freeze(now) do
topic.set_or_create_status_update(TopicStatusUpdate.types[:close], '2013-11-25T01:35:00-08:00', {by_user: admin}) topic.set_or_create_timer(TopicTimer.types[:close], '2013-11-25T01:35:00-08:00', {by_user: admin})
expect(topic.topic_status_updates.first.execute_at).to eq(Time.utc(2013,11,25,9,35)) expect(topic.topic_timers.first.execute_at).to eq(Time.utc(2013,11,25,9,35))
end end
end end
it 'sets topic status update user to given user if it is a staff or TL4 user' do it 'sets topic status update user to given user if it is a staff or TL4 user' do
topic.set_or_create_status_update(TopicStatusUpdate.types[:close], 3, {by_user: admin}) topic.set_or_create_timer(TopicTimer.types[:close], 3, {by_user: admin})
expect(topic.topic_status_updates.first.user).to eq(admin) expect(topic.topic_timers.first.user).to eq(admin)
end end
it 'sets topic status update user to given user if it is a TL4 user' do it 'sets topic status update user to given user if it is a TL4 user' do
topic.set_or_create_status_update(TopicStatusUpdate.types[:close], 3, {by_user: trust_level_4}) topic.set_or_create_timer(TopicTimer.types[:close], 3, {by_user: trust_level_4})
expect(topic.topic_status_updates.first.user).to eq(trust_level_4) expect(topic.topic_timers.first.user).to eq(trust_level_4)
end end
it 'sets topic status update user to system user if given user is not staff or a TL4 user' do it 'sets topic status update user to system user if given user is not staff or a TL4 user' do
topic.set_or_create_status_update(TopicStatusUpdate.types[:close], 3, {by_user: Fabricate.build(:user, id: 444)}) topic.set_or_create_timer(TopicTimer.types[:close], 3, {by_user: Fabricate.build(:user, id: 444)})
expect(topic.topic_status_updates.first.user).to eq(admin) expect(topic.topic_timers.first.user).to eq(admin)
end end
it 'sets topic status update user to system user if user is not given and topic creator is not staff nor TL4 user' do it 'sets topic status update user to system user if user is not given and topic creator is not staff nor TL4 user' do
topic.set_or_create_status_update(TopicStatusUpdate.types[:close], 3) topic.set_or_create_timer(TopicTimer.types[:close], 3)
expect(topic.topic_status_updates.first.user).to eq(admin) expect(topic.topic_timers.first.user).to eq(admin)
end end
it 'sets topic status update user to topic creator if it is a staff user' do it 'sets topic status update user to topic creator if it is a staff user' do
staff_topic = Fabricate.build(:topic, user: Fabricate.build(:admin, id: 999)) staff_topic = Fabricate.build(:topic, user: Fabricate.build(:admin, id: 999))
staff_topic.set_or_create_status_update(TopicStatusUpdate.types[:close], 3) staff_topic.set_or_create_timer(TopicTimer.types[:close], 3)
expect(staff_topic.topic_status_updates.first.user_id).to eq(999) expect(staff_topic.topic_timers.first.user_id).to eq(999)
end end
it 'sets topic status update user to topic creator if it is a TL4 user' do it 'sets topic status update user to topic creator if it is a TL4 user' do
tl4_topic = Fabricate.build(:topic, user: Fabricate.build(:trust_level_4, id: 998)) tl4_topic = Fabricate.build(:topic, user: Fabricate.build(:trust_level_4, id: 998))
tl4_topic.set_or_create_status_update(TopicStatusUpdate.types[:close], 3) tl4_topic.set_or_create_timer(TopicTimer.types[:close], 3)
expect(tl4_topic.topic_status_updates.first.user_id).to eq(998) expect(tl4_topic.topic_timers.first.user_id).to eq(998)
end end
it 'removes close topic status update if arg is nil' do it 'removes close topic status update if arg is nil' do
closing_topic.set_or_create_status_update(TopicStatusUpdate.types[:close], nil) closing_topic.set_or_create_timer(TopicTimer.types[:close], nil)
closing_topic.reload closing_topic.reload
expect(closing_topic.topic_status_updates.first).to be_nil expect(closing_topic.topic_timers.first).to be_nil
end end
it 'updates topic status update execute_at if it was already set to close' do it 'updates topic status update execute_at if it was already set to close' do
Timecop.freeze(now) do Timecop.freeze(now) do
closing_topic.set_or_create_status_update(TopicStatusUpdate.types[:close], 48) closing_topic.set_or_create_timer(TopicTimer.types[:close], 48)
expect(closing_topic.reload.topic_status_update.execute_at).to eq(2.days.from_now) expect(closing_topic.reload.topic_status_update.execute_at).to eq(2.days.from_now)
end end
end end
it "does not update topic's topic status created_at it was already set to close" do it "does not update topic's topic status created_at it was already set to close" do
expect{ expect{
closing_topic.set_or_create_status_update(TopicStatusUpdate.types[:close], 14) closing_topic.set_or_create_timer(TopicTimer.types[:close], 14)
}.to_not change { closing_topic.topic_status_updates.first.created_at } }.to_not change { closing_topic.topic_timers.first.created_at }
end end
describe "when category's default auto close is set" do describe "when category's default auto close is set" do
@ -1263,14 +1263,14 @@ describe Topic do
let(:topic) { Fabricate(:topic, category: category) } let(:topic) { Fabricate(:topic, category: category) }
it "should be able to override category's default auto close" do it "should be able to override category's default auto close" do
expect(topic.topic_status_updates.first.duration).to eq(4) expect(topic.topic_timers.first.duration).to eq(4)
topic.set_or_create_status_update(TopicStatusUpdate.types[:close], 2, by_user: admin) topic.set_or_create_timer(TopicTimer.types[:close], 2, by_user: admin)
expect(topic.reload.closed).to eq(false) expect(topic.reload.closed).to eq(false)
Timecop.travel(3.hours.from_now) do Timecop.travel(3.hours.from_now) do
TopicStatusUpdate.ensure_consistency! TopicTimer.ensure_consistency!
expect(topic.reload.closed).to eq(true) expect(topic.reload.closed).to eq(true)
end end
end end

View File

@ -1,7 +1,7 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe TopicStatusUpdate, type: :model do RSpec.describe TopicTimer, type: :model do
let(:topic_status_update) { Fabricate(:topic_status_update) } let(:topic_timer) { Fabricate(:topic_timer) }
let(:topic) { Fabricate(:topic) } let(:topic) { Fabricate(:topic) }
before do before do
@ -11,10 +11,10 @@ RSpec.describe TopicStatusUpdate, type: :model do
context "validations" do context "validations" do
describe '#status_type' do describe '#status_type' do
it 'should ensure that only one active topic status update exists' do it 'should ensure that only one active topic status update exists' do
topic_status_update.update!(topic: topic) topic_timer.update!(topic: topic)
Fabricate(:topic_status_update, deleted_at: Time.zone.now, topic: topic) Fabricate(:topic_timer, deleted_at: Time.zone.now, topic: topic)
expect { Fabricate(:topic_status_update, topic: topic) } expect { Fabricate(:topic_timer, topic: topic) }
.to raise_error(ActiveRecord::RecordInvalid) .to raise_error(ActiveRecord::RecordInvalid)
end end
end end
@ -22,26 +22,26 @@ RSpec.describe TopicStatusUpdate, type: :model do
describe '#execute_at' do describe '#execute_at' do
describe 'when #execute_at is greater than #created_at' do describe 'when #execute_at is greater than #created_at' do
it 'should be valid' do it 'should be valid' do
topic_status_update = Fabricate.build(:topic_status_update, topic_timer = Fabricate.build(:topic_timer,
execute_at: Time.zone.now + 1.hour, execute_at: Time.zone.now + 1.hour,
user: Fabricate(:user), user: Fabricate(:user),
topic: Fabricate(:topic) topic: Fabricate(:topic)
) )
expect(topic_status_update).to be_valid expect(topic_timer).to be_valid
end end
end end
describe 'when #execute_at is smaller than #created_at' do describe 'when #execute_at is smaller than #created_at' do
it 'should not be valid' do it 'should not be valid' do
topic_status_update = Fabricate.build(:topic_status_update, topic_timer = Fabricate.build(:topic_timer,
execute_at: Time.zone.now - 1.hour, execute_at: Time.zone.now - 1.hour,
created_at: Time.zone.now, created_at: Time.zone.now,
user: Fabricate(:user), user: Fabricate(:user),
topic: Fabricate(:topic) topic: Fabricate(:topic)
) )
expect(topic_status_update).to_not be_valid expect(topic_timer).to_not be_valid
end end
end end
end end
@ -50,25 +50,25 @@ RSpec.describe TopicStatusUpdate, type: :model do
describe 'when #status_type is publish_to_category' do describe 'when #status_type is publish_to_category' do
describe 'when #category_id is not present' do describe 'when #category_id is not present' do
it 'should not be valid' do it 'should not be valid' do
topic_status_update = Fabricate.build(:topic_status_update, topic_timer = Fabricate.build(:topic_timer,
status_type: TopicStatusUpdate.types[:publish_to_category] status_type: TopicTimer.types[:publish_to_category]
) )
expect(topic_status_update).to_not be_valid expect(topic_timer).to_not be_valid
expect(topic_status_update.errors.keys).to include(:category_id) expect(topic_timer.errors.keys).to include(:category_id)
end end
end end
describe 'when #category_id is present' do describe 'when #category_id is present' do
it 'should be valid' do it 'should be valid' do
topic_status_update = Fabricate.build(:topic_status_update, topic_timer = Fabricate.build(:topic_timer,
status_type: TopicStatusUpdate.types[:publish_to_category], status_type: TopicTimer.types[:publish_to_category],
category_id: Fabricate(:category).id, category_id: Fabricate(:category).id,
user: Fabricate(:user), user: Fabricate(:user),
topic: Fabricate(:topic) topic: Fabricate(:topic)
) )
expect(topic_status_update).to be_valid expect(topic_timer).to be_valid
end end
end end
end end
@ -79,51 +79,51 @@ RSpec.describe TopicStatusUpdate, type: :model do
describe 'when #execute_at and #user_id are not changed' do describe 'when #execute_at and #user_id are not changed' do
it 'should not schedule another to update topic' do it 'should not schedule another to update topic' do
Jobs.expects(:enqueue_at).with( Jobs.expects(:enqueue_at).with(
topic_status_update.execute_at, topic_timer.execute_at,
:toggle_topic_closed, :toggle_topic_closed,
topic_status_update_id: topic_status_update.id, topic_timer_id: topic_timer.id,
state: true state: true
).once ).once
topic_status_update topic_timer
Jobs.expects(:cancel_scheduled_job).never Jobs.expects(:cancel_scheduled_job).never
topic_status_update.update!(topic: Fabricate(:topic)) topic_timer.update!(topic: Fabricate(:topic))
end end
end end
describe 'when #execute_at value is changed' do describe 'when #execute_at value is changed' do
it 'reschedules the job' do it 'reschedules the job' do
Timecop.freeze do Timecop.freeze do
topic_status_update topic_timer
Jobs.expects(:cancel_scheduled_job).with( Jobs.expects(:cancel_scheduled_job).with(
:toggle_topic_closed, topic_status_update_id: topic_status_update.id :toggle_topic_closed, topic_timer_id: topic_timer.id
) )
Jobs.expects(:enqueue_at).with( Jobs.expects(:enqueue_at).with(
3.days.from_now, :toggle_topic_closed, 3.days.from_now, :toggle_topic_closed,
topic_status_update_id: topic_status_update.id, topic_timer_id: topic_timer.id,
state: true state: true
) )
topic_status_update.update!(execute_at: 3.days.from_now, created_at: Time.zone.now) topic_timer.update!(execute_at: 3.days.from_now, created_at: Time.zone.now)
end end
end end
describe 'when execute_at is smaller than the current time' do describe 'when execute_at is smaller than the current time' do
it 'should enqueue the job immediately' do it 'should enqueue the job immediately' do
Timecop.freeze do Timecop.freeze do
topic_status_update topic_timer
Jobs.expects(:enqueue_at).with( Jobs.expects(:enqueue_at).with(
Time.zone.now, :toggle_topic_closed, Time.zone.now, :toggle_topic_closed,
topic_status_update_id: topic_status_update.id, topic_timer_id: topic_timer.id,
state: true state: true
) )
topic_status_update.update!( topic_timer.update!(
execute_at: Time.zone.now - 1.hour, execute_at: Time.zone.now - 1.hour,
created_at: Time.zone.now - 2.hour created_at: Time.zone.now - 2.hour
) )
@ -135,22 +135,22 @@ RSpec.describe TopicStatusUpdate, type: :model do
describe 'when user is changed' do describe 'when user is changed' do
it 'should update the job' do it 'should update the job' do
Timecop.freeze do Timecop.freeze do
topic_status_update topic_timer
Jobs.expects(:cancel_scheduled_job).with( Jobs.expects(:cancel_scheduled_job).with(
:toggle_topic_closed, topic_status_update_id: topic_status_update.id :toggle_topic_closed, topic_timer_id: topic_timer.id
) )
admin = Fabricate(:admin) admin = Fabricate(:admin)
Jobs.expects(:enqueue_at).with( Jobs.expects(:enqueue_at).with(
topic_status_update.execute_at, topic_timer.execute_at,
:toggle_topic_closed, :toggle_topic_closed,
topic_status_update_id: topic_status_update.id, topic_timer_id: topic_timer.id,
state: true state: true
) )
topic_status_update.update!(user: admin) topic_timer.update!(user: admin)
end end
end end
end end
@ -158,22 +158,22 @@ RSpec.describe TopicStatusUpdate, type: :model do
describe 'when a open topic status update is created for an open topic' do describe 'when a open topic status update is created for an open topic' do
let(:topic) { Fabricate(:topic, closed: false) } let(:topic) { Fabricate(:topic, closed: false) }
let(:topic_status_update) do let(:topic_timer) do
Fabricate(:topic_status_update, Fabricate(:topic_timer,
status_type: described_class.types[:open], status_type: described_class.types[:open],
topic: topic topic: topic
) )
end end
it 'should close the topic' do it 'should close the topic' do
topic_status_update topic_timer
expect(topic.reload.closed).to eq(true) expect(topic.reload.closed).to eq(true)
end end
describe 'when topic has been deleted' do describe 'when topic has been deleted' do
it 'should not queue the job' do it 'should not queue the job' do
topic.trash! topic.trash!
topic_status_update topic_timer
expect(Jobs::ToggleTopicClosed.jobs).to eq([]) expect(Jobs::ToggleTopicClosed.jobs).to eq([])
end end
@ -183,22 +183,22 @@ RSpec.describe TopicStatusUpdate, type: :model do
describe 'when a close topic status update is created for a closed topic' do describe 'when a close topic status update is created for a closed topic' do
let(:topic) { Fabricate(:topic, closed: true) } let(:topic) { Fabricate(:topic, closed: true) }
let(:topic_status_update) do let(:topic_timer) do
Fabricate(:topic_status_update, Fabricate(:topic_timer,
status_type: described_class.types[:close], status_type: described_class.types[:close],
topic: topic topic: topic
) )
end end
it 'should open the topic' do it 'should open the topic' do
topic_status_update topic_timer
expect(topic.reload.closed).to eq(false) expect(topic.reload.closed).to eq(false)
end end
describe 'when topic has been deleted' do describe 'when topic has been deleted' do
it 'should not queue the job' do it 'should not queue the job' do
topic.trash! topic.trash!
topic_status_update topic_timer
expect(Jobs::ToggleTopicClosed.jobs).to eq([]) expect(Jobs::ToggleTopicClosed.jobs).to eq([])
end end
@ -213,20 +213,20 @@ RSpec.describe TopicStatusUpdate, type: :model do
end end
it 'should enqueue jobs that have been missed' do it 'should enqueue jobs that have been missed' do
close_topic_status_update = Fabricate(:topic_status_update, close_topic_timer = Fabricate(:topic_timer,
execute_at: Time.zone.now - 1.hour, execute_at: Time.zone.now - 1.hour,
created_at: Time.zone.now - 2.hour created_at: Time.zone.now - 2.hour
) )
open_topic_status_update = Fabricate(:topic_status_update, open_topic_timer = Fabricate(:topic_timer,
status_type: described_class.types[:open], status_type: described_class.types[:open],
execute_at: Time.zone.now - 1.hour, execute_at: Time.zone.now - 1.hour,
created_at: Time.zone.now - 2.hour created_at: Time.zone.now - 2.hour
) )
Fabricate(:topic_status_update) Fabricate(:topic_timer)
Fabricate(:topic_status_update, Fabricate(:topic_timer,
execute_at: Time.zone.now - 1.hour, execute_at: Time.zone.now - 1.hour,
created_at: Time.zone.now - 2.hour created_at: Time.zone.now - 2.hour
).topic.trash! ).topic.trash!
@ -236,12 +236,12 @@ RSpec.describe TopicStatusUpdate, type: :model do
job_args = Jobs::ToggleTopicClosed.jobs.first["args"].first job_args = Jobs::ToggleTopicClosed.jobs.first["args"].first
expect(job_args["topic_status_update_id"]).to eq(close_topic_status_update.id) expect(job_args["topic_timer_id"]).to eq(close_topic_timer.id)
expect(job_args["state"]).to eq(true) expect(job_args["state"]).to eq(true)
job_args = Jobs::ToggleTopicClosed.jobs.last["args"].first job_args = Jobs::ToggleTopicClosed.jobs.last["args"].first
expect(job_args["topic_status_update_id"]).to eq(open_topic_status_update.id) expect(job_args["topic_timer_id"]).to eq(open_topic_timer.id)
expect(job_args["state"]).to eq(false) expect(job_args["state"]).to eq(false)
end end
end end

View File

@ -17,7 +17,7 @@ describe TopicStatusUpdater do
title: "hello world title", title: "hello world title",
) )
# TODO needed so counts sync up, PostCreator really should not give back out-of-date Topic # TODO needed so counts sync up, PostCreator really should not give back out-of-date Topic
post.topic.set_or_create_status_update(TopicStatusUpdate.types[:close], '10') post.topic.set_or_create_timer(TopicTimer.types[:close], '10')
post.topic.reload post.topic.reload
TopicStatusUpdater.new(post.topic, admin).update!("autoclosed", true) TopicStatusUpdater.new(post.topic, admin).update!("autoclosed", true)
@ -30,7 +30,7 @@ describe TopicStatusUpdater do
it "adds an autoclosed message" do it "adds an autoclosed message" do
topic = create_topic topic = create_topic
topic.set_or_create_status_update(TopicStatusUpdate.types[:close], '10') topic.set_or_create_timer(TopicTimer.types[:close], '10')
TopicStatusUpdater.new(topic, admin).update!("autoclosed", true) TopicStatusUpdater.new(topic, admin).update!("autoclosed", true)
@ -44,8 +44,8 @@ describe TopicStatusUpdater do
topic = create_topic topic = create_topic
Fabricate(:post, topic: topic) Fabricate(:post, topic: topic)
topic.set_or_create_status_update( topic.set_or_create_timer(
TopicStatusUpdate.types[:close], '10', based_on_last_post: true TopicTimer.types[:close], '10', based_on_last_post: true
) )
TopicStatusUpdater.new(topic, admin).update!("autoclosed", true) TopicStatusUpdater.new(topic, admin).update!("autoclosed", true)