FIX: Unread topics not clearing when whisper is last post (#8271)

Meta thread: https://meta.discourse.org/t/cant-dismiss-unread-if-last-post-is-an-assign-or-whisper/131823/7

* when sending a whisper, the highest_staff_post_number is set
in the next_post_number method for a Topic, but the
highest_post_number is left alone. this leaves a situation
where highest_staff_post_number is > highest_post_number
* when TopicsBulkAction#dismiss_posts was run, it was only setting the topic_user
highest_seen_post_number using the highest_post_number from the topic, so if
the user was staff and the last post in a topic was a whisper
their highest seen number was not set, and the topic stayed unread

Found through testing that the bug wasn't to do with Assign/Unassign as they do not affect the post numbers, only whispering does.
This commit is contained in:
Martin Brennan 2019-11-01 09:19:43 +10:00 committed by GitHub
parent b93f253486
commit f753643cb1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 1 deletions

View File

@ -68,9 +68,10 @@ class TopicsBulkAction
end end
def dismiss_posts def dismiss_posts
highest_number_source_column = @user.staff? ? 'highest_staff_post_number' : 'highest_post_number'
sql = <<~SQL sql = <<~SQL
UPDATE topic_users tu UPDATE topic_users tu
SET highest_seen_post_number = t.highest_post_number , last_read_post_number = highest_post_number SET highest_seen_post_number = t.#{highest_number_source_column} , last_read_post_number = t.#{highest_number_source_column}
FROM topics t FROM topics t
WHERE t.id = tu.topic_id AND tu.user_id = :user_id AND t.id IN (:topic_ids) WHERE t.id = tu.topic_id AND tu.user_id = :user_id AND t.id IN (:topic_ids)
SQL SQL

View File

@ -20,6 +20,32 @@ describe TopicsBulkAction do
expect(tu.last_read_post_number).to eq(3) expect(tu.last_read_post_number).to eq(3)
expect(tu.highest_seen_post_number).to eq(3) expect(tu.highest_seen_post_number).to eq(3)
end end
context "when the user is staff" do
fab!(:user) { Fabricate(:admin) }
context "when the highest_staff_post_number is > highest_post_number for a topic (e.g. whisper is last post)" do
it "dismisses posts" do
post1 = create_post(user: user)
p = create_post(topic_id: post1.topic_id)
create_post(topic_id: post1.topic_id)
whisper = PostCreator.new(
user,
topic_id: post1.topic.id,
post_type: Post.types[:whisper],
raw: 'this is a whispered reply'
).create
TopicsBulkAction.new(user, [post1.topic_id], type: 'dismiss_posts').perform!
tu = TopicUser.find_by(user_id: user.id, topic_id: post1.topic_id)
expect(tu.last_read_post_number).to eq(4)
expect(tu.highest_seen_post_number).to eq(4)
end
end
end
end end
describe "invalid operation" do describe "invalid operation" do