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
2 changed files with 38 additions and 11 deletions

View File

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

View File

@ -2898,7 +2898,7 @@ RSpec.describe PostMover do
).to eq(true) ).to eq(true)
end 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( PostMover.new(
original_topic, original_topic,
Discourse.system_user, Discourse.system_user,
@ -2908,11 +2908,34 @@ RSpec.describe PostMover do
}, },
).to_topic(destination_topic.id) ).to_topic(destination_topic.id)
moderator_post = # Moderator post is right after the second_post since it was the last post moved
original_topic.reload.ordered_posts.find_by(post_number: second_post.post_number + 1) # the next post expect(
expect(moderator_post).to be_present original_topic.ordered_posts.find_by(
expect(moderator_post.post_type).to eq(Post.types[:small_action]) post_number: second_post.post_number + 1,
expect(moderator_post.action_code).to eq("split_topic") 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 end
context "with `post_mover_create_moderator_post` modifier" do context "with `post_mover_create_moderator_post` modifier" do