FIX: change **default** notification state when a topic is recategorized within 5 days of creation

This commit is contained in:
Régis Hanol 2015-08-19 22:40:20 +02:00
parent eafeec51a5
commit 9ae9aed010
3 changed files with 50 additions and 18 deletions

View file

@ -15,18 +15,19 @@ class CategoryUser < ActiveRecord::Base
TopicUser.notification_levels TopicUser.notification_levels
end end
def self.auto_track_new_topic(topic) %w{watch track}.each do |s|
apply_default_to_topic(topic, define_singleton_method("auto_#{s}_new_topic") do |topic, new_category=nil|
TopicUser.notification_levels[:tracking], category_id = topic.category_id
TopicUser.notification_reasons[:auto_track_category]
) if new_category && topic.created_at > 5.days.ago
# we want to apply default of the new category
category_id = new_category.id
# remove defaults from previous category
remove_default_from_topic(topic.id, TopicUser.notification_levels[:"#{s}ing"], TopicUser.notification_reasons[:"auto_#{s}_category"])
end end
def self.auto_watch_new_topic(topic) apply_default_to_topic(topic.id, category_id, TopicUser.notification_levels[:"#{s}ing"], TopicUser.notification_reasons[:"auto_#{s}_category"])
apply_default_to_topic(topic, end
TopicUser.notification_levels[:watching],
TopicUser.notification_reasons[:auto_watch_category]
)
end end
def self.batch_set(user, level, category_ids) def self.batch_set(user, level, category_ids)
@ -56,7 +57,7 @@ class CategoryUser < ActiveRecord::Base
end end
end end
def self.apply_default_to_topic(topic, level, reason) def self.apply_default_to_topic(topic_id, category_id, level, reason)
# Can not afford to slow down creation of topics when a pile of users are watching new topics, reverting to SQL for max perf here # Can not afford to slow down creation of topics when a pile of users are watching new topics, reverting to SQL for max perf here
sql = <<-SQL sql = <<-SQL
INSERT INTO topic_users(user_id, topic_id, notification_level, notifications_reason_id) INSERT INTO topic_users(user_id, topic_id, notification_level, notifications_reason_id)
@ -68,14 +69,30 @@ class CategoryUser < ActiveRecord::Base
SQL SQL
exec_sql(sql, exec_sql(sql,
topic_id: topic.id, topic_id: topic_id,
category_id: topic.category_id, category_id: category_id,
level: level, level: level,
reason: reason reason: reason
) )
end end
private_class_method :apply_default_to_topic def self.remove_default_from_topic(topic_id, level, reason)
sql = <<-SQL
DELETE FROM topic_users
WHERE topic_id = :topic_id
AND notifications_changed_at IS NULL
AND notification_level = :level
AND notifications_reason_id = :reason
SQL
exec_sql(sql,
topic_id: topic_id,
level: level,
reason: reason
)
end
private_class_method :apply_default_to_topic, :remove_default_from_topic
end end
# == Schema Information # == Schema Information

View file

@ -482,8 +482,8 @@ class Topic < ActiveRecord::Base
Category.where(id: new_category.id).update_all("topic_count = topic_count + 1") Category.where(id: new_category.id).update_all("topic_count = topic_count + 1")
CategoryFeaturedTopic.feature_topics_for(old_category) unless @import_mode CategoryFeaturedTopic.feature_topics_for(old_category) unless @import_mode
CategoryFeaturedTopic.feature_topics_for(new_category) unless @import_mode || old_category.id == new_category.id CategoryFeaturedTopic.feature_topics_for(new_category) unless @import_mode || old_category.id == new_category.id
CategoryUser.auto_watch_new_topic(self) CategoryUser.auto_watch_new_topic(self, new_category)
CategoryUser.auto_track_new_topic(self) CategoryUser.auto_track_new_topic(self, new_category)
end end
true true

View file

@ -52,8 +52,8 @@ describe CategoryUser do
end end
it "watches categories that have been changed" do it "watches categories that have been changed" do
watched_category = Fabricate(:category)
user = Fabricate(:user) user = Fabricate(:user)
watched_category = Fabricate(:category)
CategoryUser.create!(user: user, category: watched_category, notification_level: CategoryUser.notification_levels[:watching]) CategoryUser.create!(user: user, category: watched_category, notification_level: CategoryUser.notification_levels[:watching])
post = create_post post = create_post
@ -65,6 +65,21 @@ describe CategoryUser do
expect(tu.notification_level).to eq TopicUser.notification_levels[:watching] expect(tu.notification_level).to eq TopicUser.notification_levels[:watching]
end end
it "unwatches categories that have been changed" do
user = Fabricate(:user)
watched_category = Fabricate(:category)
CategoryUser.create!(user: user, category: watched_category, notification_level: CategoryUser.notification_levels[:watching])
post = create_post(category: watched_category)
tu = TopicUser.get(post.topic, user)
expect(tu.notification_level).to eq TopicUser.notification_levels[:watching]
# Now, change the topic's category
unwatched_category = Fabricate(:category)
post.topic.change_category_to_id(unwatched_category.id)
expect(TopicUser.get(post.topic, user)).to be_blank
end
end end
end end