FIX: Correctly place moderator post for full topic move with freeze_original (#30324)

When freeze_original option is passed to PostMover, and we are moving all posts there is an issue. We attempt to put the small_action right after the last moved post. The issue is when there is an existing small action after the last moved "real" post. We then try to put the moderator post at the same location of the existing small action, which causes an index conflict and the move fails.

This makes sure that we place the moderator post at the verrrrrry end of the topic :)
This commit is contained in:
Mark VanLandingham 2024-12-17 10:31:34 -06:00 committed by GitHub
parent 37f032752e
commit 415abe6491
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 38 additions and 11 deletions

View File

@ -97,11 +97,15 @@ class PostMover
@first_post_number_moved =
posts.first.is_first_post? ? posts[1]&.post_number : posts.first.post_number
if @options[:freeze_original] # in this case we need to add the moderator post after the last copied post
from_posts = @original_topic.ordered_posts.where("post_number > ?", posts.last.post_number)
shift_post_numbers(from_posts) if !@full_move
@first_post_number_moved = posts.last.post_number + 1
if @options[:freeze_original]
# in this case we need to add the moderator post after the last copied post
if @full_move
@first_post_number_moved = @original_topic.ordered_posts.last.post_number + 1
else
from_posts = @original_topic.ordered_posts.where("post_number > ?", posts.last.post_number)
shift_post_numbers(from_posts)
@first_post_number_moved = posts.last.post_number + 1
end
end
move_each_post

View File

@ -2898,7 +2898,7 @@ RSpec.describe PostMover do
).to eq(true)
end
it "creates the moderator message in the correct position" do
it "creates the moderator message in the correct position for partial move" do
PostMover.new(
original_topic,
Discourse.system_user,
@ -2908,11 +2908,34 @@ RSpec.describe PostMover do
},
).to_topic(destination_topic.id)
moderator_post =
original_topic.reload.ordered_posts.find_by(post_number: second_post.post_number + 1) # the next post
expect(moderator_post).to be_present
expect(moderator_post.post_type).to eq(Post.types[:small_action])
expect(moderator_post.action_code).to eq("split_topic")
# Moderator post is right after the second_post since it was the last post moved
expect(
original_topic.ordered_posts.find_by(
post_number: second_post.post_number + 1,
post_type: Post.types[:small_action],
action_code: "split_topic",
),
).to be_present
end
it "creates the moderator message in the correct position for full move" do
small_action = Fabricate(:small_action, topic: original_topic)
PostMover.new(
original_topic,
Discourse.system_user,
[op.id, first_post.id, second_post.id, third_post.id],
options: {
freeze_original: true,
},
).to_topic(destination_topic.id)
expect(
original_topic.ordered_posts.find_by(
post_number: small_action.post_number + 1,
post_type: Post.types[:small_action],
action_code: "split_topic",
),
).to be_present
end
context "with `post_mover_create_moderator_post` modifier" do