FIX: Update topic_count when updating visibility (#11946)

Updating a topic's visibility did not increase or decrease the
topic_count of a category, but Category.update_stats does ignore
unlisted topics which resulted in inconsistencies when deleting
such topics.
This commit is contained in:
Bianca Nenciu 2021-02-16 17:45:12 +02:00 committed by GitHub
parent f283bde25a
commit fad1fac196
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 4 deletions

View File

@ -132,7 +132,7 @@ class Topic < ActiveRecord::Base
def trash!(trashed_by = nil) def trash!(trashed_by = nil)
if deleted_at.nil? if deleted_at.nil?
update_category_topic_count_by(-1) update_category_topic_count_by(-1) if visible?
CategoryTagStat.topic_deleted(self) if self.tags.present? CategoryTagStat.topic_deleted(self) if self.tags.present?
DiscourseEvent.trigger(:topic_trashed, self) DiscourseEvent.trigger(:topic_trashed, self)
end end
@ -142,7 +142,7 @@ class Topic < ActiveRecord::Base
def recover!(recovered_by = nil) def recover!(recovered_by = nil)
unless deleted_at.nil? unless deleted_at.nil?
update_category_topic_count_by(1) update_category_topic_count_by(1) if visible?
CategoryTagStat.topic_recovered(self) if self.tags.present? CategoryTagStat.topic_recovered(self) if self.tags.present?
DiscourseEvent.trigger(:topic_recovered, self) DiscourseEvent.trigger(:topic_recovered, self)
end end
@ -1648,8 +1648,9 @@ class Topic < ActiveRecord::Base
def update_category_topic_count_by(num) def update_category_topic_count_by(num)
if category_id.present? if category_id.present?
Category Category
.where(['id = ?', category_id]) .where('id = ?', category_id)
.update_all("topic_count = topic_count " + (num > 0 ? '+' : '') + "#{num}") .where('topic_id != ? OR topic_id IS NULL', self.id)
.update_all("topic_count = topic_count + #{num.to_i}")
end end
end end

View File

@ -46,6 +46,10 @@ TopicStatusUpdater = Struct.new(:topic, :user) do
UserProfile.remove_featured_topic_from_all_profiles(topic) UserProfile.remove_featured_topic_from_all_profiles(topic)
end end
if status.visible?
topic.update_category_topic_count_by(status.enabled? ? 1 : -1)
end
if @topic_timer if @topic_timer
if status.manually_closing_topic? || status.closing_topic? if status.manually_closing_topic? || status.closing_topic?
topic.delete_topic_timer(TopicTimer.types[:close]) topic.delete_topic_timer(TopicTimer.types[:close])

View File

@ -1112,6 +1112,8 @@ describe Topic do
end end
context 'visibility' do context 'visibility' do
let(:category) { Fabricate(:category_with_definition) }
context 'disable' do context 'disable' do
it 'should not be visible and have correct counts' do it 'should not be visible and have correct counts' do
topic.update_status('visible', false, @user) topic.update_status('visible', false, @user)
@ -1121,6 +1123,14 @@ describe Topic do
expect(topic.bumped_at).to eq_time(@original_bumped_at) expect(topic.bumped_at).to eq_time(@original_bumped_at)
end end
it 'decreases topic_count of topic category' do
topic.update!(category: category)
Category.update_stats
expect { topic.update_status('visible', false, @user) }
.to change { category.reload.topic_count }.by(-1)
end
it 'removes itself as featured topic on user profiles' do it 'removes itself as featured topic on user profiles' do
user.user_profile.update(featured_topic_id: topic.id) user.user_profile.update(featured_topic_id: topic.id)
expect(user.user_profile.featured_topic).to eq(topic) expect(user.user_profile.featured_topic).to eq(topic)
@ -1142,6 +1152,13 @@ describe Topic do
expect(topic.moderator_posts_count).to eq(1) expect(topic.moderator_posts_count).to eq(1)
expect(topic.bumped_at).to eq_time(@original_bumped_at) expect(topic.bumped_at).to eq_time(@original_bumped_at)
end end
it 'increases topic_count of topic category' do
topic.update!(category: category, visible: false)
expect { topic.update_status('visible', true, @user) }
.to change { category.reload.topic_count }.by(1)
end
end end
end end
@ -2144,6 +2161,11 @@ describe Topic do
topic = Fabricate(:topic, category: category, deleted_at: 1.day.ago) topic = Fabricate(:topic, category: category, deleted_at: 1.day.ago)
expect { topic.trash!(moderator) }.to_not change { category.reload.topic_count } expect { topic.trash!(moderator) }.to_not change { category.reload.topic_count }
end end
it "doesn't subtract 1 if topic is unlisted" do
topic = Fabricate(:topic, category: category, visible: false)
expect { topic.trash!(moderator) }.to_not change { category.reload.topic_count }
end
end end
it "trashes topic embed record" do it "trashes topic embed record" do
@ -2169,6 +2191,11 @@ describe Topic do
topic = Fabricate(:topic, category: category) topic = Fabricate(:topic, category: category)
expect { topic.recover! }.to_not change { category.reload.topic_count } expect { topic.recover! }.to_not change { category.reload.topic_count }
end end
it "doesn't add 1 if topic is not visible" do
topic = Fabricate(:topic, category: category, visible: false)
expect { topic.recover! }.to_not change { category.reload.topic_count }
end
end end
it "recovers topic embed record" do it "recovers topic embed record" do