mirror of
https://github.com/discourse/discourse.git
synced 2025-01-19 16:02:45 +08:00
b876ff6281
Breakdown of fixes in this commit: * `UserStat#topic_count` was not updated when visibility of the topic changed. * `UserStat#post_count` was not updated when post was hidden or unhidden. * `TopicConverter` was only incrementing or decrementing the counts by 1 even if a user has multiple posts in the topic. * The commit turns off the verbose logging by default as it is just noise to normal users who are not debugging this problem.
245 lines
9.8 KiB
Ruby
245 lines
9.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'rails_helper'
|
|
|
|
describe TopicConverter do
|
|
|
|
context 'convert_to_public_topic' do
|
|
fab!(:admin) { Fabricate(:admin) }
|
|
fab!(:author) { Fabricate(:user) }
|
|
fab!(:category) { Fabricate(:category, topic_count: 1) }
|
|
fab!(:private_message) { Fabricate(:private_message_topic, user: author) } # creates a topic without a first post
|
|
let(:first_post) { create_post(user: author, topic: private_message) }
|
|
let(:other_user) { private_message.topic_allowed_users.find { |u| u.user != author }.user }
|
|
|
|
let(:uncategorized_category) do
|
|
Category.find(SiteSetting.uncategorized_category_id)
|
|
end
|
|
|
|
context 'success' do
|
|
it "converts private message to regular topic" do
|
|
SiteSetting.allow_uncategorized_topics = true
|
|
topic = nil
|
|
|
|
_pm_post_2 = Fabricate(:post, topic: private_message, user: author)
|
|
_pm_post_3 = Fabricate(:post, topic: private_message, user: author)
|
|
|
|
other_pm = Fabricate(:private_message_post).topic
|
|
other_pm_post = Fabricate(:private_message_post, topic: other_pm)
|
|
other_pm_post_2 = Fabricate(:private_message_post, topic: other_pm, user: other_pm_post.user)
|
|
|
|
expect do
|
|
topic = TopicConverter.new(first_post.topic, admin).convert_to_public_topic
|
|
topic.reload
|
|
end.to change { uncategorized_category.reload.topic_count }.by(1)
|
|
.and change { author.reload.topic_count }.from(0).to(1)
|
|
.and change { author.reload.post_count }.from(0).to(2)
|
|
|
|
# Ensure query does not affect users from other topics or posts as DB query to update count is quite complex.
|
|
expect(other_pm.user.topic_count).to eq(0)
|
|
expect(other_pm.user.post_count).to eq(0)
|
|
expect(other_pm_post.user.topic_count).to eq(0)
|
|
expect(other_pm_post.user.post_count).to eq(0)
|
|
|
|
expect(topic).to be_valid
|
|
expect(topic.archetype).to eq("regular")
|
|
expect(topic.category_id).to eq(SiteSetting.uncategorized_category_id)
|
|
end
|
|
|
|
describe 'when uncategorized category is not allowed' do
|
|
before do
|
|
SiteSetting.allow_uncategorized_topics = false
|
|
category.update!(read_restricted: false)
|
|
end
|
|
|
|
it 'should convert private message into the right category' do
|
|
topic = TopicConverter.new(first_post.topic, admin).convert_to_public_topic
|
|
topic.reload
|
|
|
|
expect(topic).to be_valid
|
|
expect(topic.archetype).to eq("regular")
|
|
|
|
first_category = Category.where.not(id: SiteSetting.uncategorized_category_id)
|
|
.where(read_restricted: false).order('id asc').first
|
|
|
|
expect(topic.category_id).to eq(first_category.id)
|
|
expect(topic.category.topic_count).to eq(2)
|
|
end
|
|
end
|
|
|
|
describe 'when a custom category_id is given' do
|
|
it 'should convert private message into the right category' do
|
|
topic = TopicConverter.new(first_post.topic, admin).convert_to_public_topic(category.id)
|
|
|
|
expect(topic.reload.category).to eq(category)
|
|
expect(topic.category.topic_count).to eq(2)
|
|
end
|
|
end
|
|
|
|
it "updates user stats" do
|
|
first_post
|
|
topic_user = TopicUser.find_by(user_id: author.id, topic_id: private_message.id)
|
|
expect(private_message.user.user_stat.topic_count).to eq(0)
|
|
expect(private_message.user.user_stat.post_count).to eq(0)
|
|
private_message.convert_to_public_topic(admin)
|
|
expect(private_message.reload.user.user_stat.topic_count).to eq(1)
|
|
expect(private_message.user.user_stat.post_count).to eq(0)
|
|
expect(topic_user.reload.notification_level).to eq(TopicUser.notification_levels[:watching])
|
|
end
|
|
|
|
context "with a reply" do
|
|
before do
|
|
Jobs.run_immediately!
|
|
UserActionManager.enable
|
|
first_post
|
|
create_post(topic: private_message, user: other_user)
|
|
private_message.reload
|
|
end
|
|
|
|
it "updates UserActions" do
|
|
TopicConverter.new(private_message, admin).convert_to_public_topic
|
|
expect(author.user_actions.where(action_type: UserAction::NEW_PRIVATE_MESSAGE).count).to eq(0)
|
|
expect(author.user_actions.where(action_type: UserAction::NEW_TOPIC).count).to eq(1)
|
|
expect(other_user.user_actions.where(action_type: UserAction::NEW_PRIVATE_MESSAGE).count).to eq(0)
|
|
expect(other_user.user_actions.where(action_type: UserAction::GOT_PRIVATE_MESSAGE).count).to eq(0)
|
|
expect(other_user.user_actions.where(action_type: UserAction::REPLY).count).to eq(1)
|
|
end
|
|
end
|
|
|
|
it "deletes notifications for users not allowed to see the topic" do
|
|
staff_category = Fabricate(:private_category, group: Group[:staff])
|
|
user_notification = Fabricate(:mentioned_notification, post: first_post, user: Fabricate(:user))
|
|
admin_notification = Fabricate(:mentioned_notification, post: first_post, user: Fabricate(:admin))
|
|
|
|
Jobs.run_immediately!
|
|
TopicConverter.new(first_post.topic, admin).convert_to_public_topic(staff_category.id)
|
|
|
|
expect(Notification.exists?(user_notification.id)).to eq(false)
|
|
expect(Notification.exists?(admin_notification.id)).to eq(true)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'convert_to_private_message' do
|
|
fab!(:admin) { Fabricate(:admin) }
|
|
fab!(:author) { Fabricate(:user) }
|
|
fab!(:category) { Fabricate(:category) }
|
|
fab!(:topic) { Fabricate(:topic, user: author, category_id: category.id) }
|
|
fab!(:post) { Fabricate(:post, topic: topic, user: topic.user) }
|
|
|
|
context 'success' do
|
|
it "converts regular topic to private message" do
|
|
private_message = topic.convert_to_private_message(post.user)
|
|
expect(private_message).to be_valid
|
|
expect(topic.archetype).to eq("private_message")
|
|
expect(topic.category_id).to eq(nil)
|
|
expect(category.reload.topic_count).to eq(0)
|
|
end
|
|
|
|
it "converts unlisted topic to private message" do
|
|
topic.update_status('visible', false, admin)
|
|
private_message = topic.convert_to_private_message(post.user)
|
|
|
|
expect(private_message).to be_valid
|
|
expect(topic.archetype).to eq("private_message")
|
|
expect(topic.category_id).to eq(nil)
|
|
expect(topic.user.post_count).to eq(0)
|
|
expect(topic.user.topic_count).to eq(0)
|
|
expect(category.reload.topic_count).to eq(0)
|
|
end
|
|
|
|
it "updates user stats when converting topic to private message" do
|
|
_post_2 = Fabricate(:post, topic: topic, user: author)
|
|
_post_3 = Fabricate(:post, topic: topic, user: author)
|
|
|
|
other_topic = Fabricate(:post).topic
|
|
other_post = Fabricate(:post, topic: other_topic)
|
|
|
|
topic_user = TopicUser.create!(user_id: author.id, topic_id: topic.id, posted: true)
|
|
|
|
expect do
|
|
topic.convert_to_private_message(admin)
|
|
end.to change { author.reload.post_count }.from(2).to(0)
|
|
.and change { author.reload.topic_count }.from(1).to(0)
|
|
|
|
# Ensure query does not affect users from other topics or posts as DB query to update count is quite complex.
|
|
expect(other_topic.user.post_count).to eq(0)
|
|
expect(other_topic.user.topic_count).to eq(1)
|
|
expect(other_post.user.post_count).to eq(1)
|
|
expect(other_post.user.topic_count).to eq(0)
|
|
|
|
expect(topic.reload.topic_allowed_users.where(user_id: author.id).count).to eq(1)
|
|
expect(topic_user.reload.notification_level).to eq(TopicUser.notification_levels[:watching])
|
|
end
|
|
|
|
it "changes user_action type" do
|
|
Jobs.run_immediately!
|
|
UserActionManager.enable
|
|
topic.convert_to_private_message(admin)
|
|
expect(author.user_actions.where(action_type: UserAction::NEW_TOPIC).count).to eq(0)
|
|
expect(author.user_actions.where(action_type: UserAction::NEW_PRIVATE_MESSAGE).count).to eq(1)
|
|
end
|
|
|
|
it "deletes notifications for users not allowed to see the message" do
|
|
user_notification = Fabricate(:mentioned_notification, post: post, user: Fabricate(:user))
|
|
admin_notification = Fabricate(:mentioned_notification, post: post, user: Fabricate(:admin))
|
|
|
|
Jobs.run_immediately!
|
|
topic.convert_to_private_message(admin)
|
|
|
|
expect(Notification.exists?(user_notification.id)).to eq(false)
|
|
expect(Notification.exists?(admin_notification.id)).to eq(true)
|
|
end
|
|
|
|
it "limits PM participants" do
|
|
SiteSetting.max_allowed_message_recipients = 2
|
|
Fabricate(:post, topic: topic)
|
|
Fabricate(:post, topic: topic)
|
|
|
|
private_message = topic.convert_to_private_message(post.user)
|
|
|
|
# Skips posters and just adds the acting user
|
|
expect(private_message.topic_allowed_users.count).to eq(1)
|
|
end
|
|
|
|
end
|
|
|
|
context 'topic has replies' do
|
|
before do
|
|
@replied_user = Fabricate(:coding_horror)
|
|
create_post(topic: topic, user: @replied_user)
|
|
topic.reload
|
|
end
|
|
|
|
it 'adds users who replied to topic in Private Message' do
|
|
topic.convert_to_private_message(admin)
|
|
|
|
expect(topic.reload.topic_allowed_users.where(user_id: @replied_user.id).count).to eq(1)
|
|
expect(topic.reload.user.user_stat.post_count).to eq(0)
|
|
end
|
|
end
|
|
|
|
context 'when user already exists in topic_allowed_users table' do
|
|
before do
|
|
topic.topic_allowed_users.create!(user_id: admin.id)
|
|
end
|
|
|
|
it "works" do
|
|
topic.convert_to_private_message(admin)
|
|
|
|
expect(topic.reload.archetype).to eq("private_message")
|
|
end
|
|
end
|
|
|
|
context 'user_profiles with newly converted PM as featured topic' do
|
|
it "sets all matching user_profile featured topic ids to nil" do
|
|
author.user_profile.update(featured_topic: topic)
|
|
topic.convert_to_private_message(admin)
|
|
|
|
expect(author.user_profile.reload.featured_topic).to eq(nil)
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|