FEATURE: Add freeze_original option to PostMover (#29880)

* FEATURE: Add `freeze_original` option to `PostMover`

This option will allow the api user to specify if the original topic should be `frozen`(locked and posts not deleted neither moved)

With this option when moving topic posts your posts will be `copied` to the new topic and the original topic will be kept there.

* DEV: update tests to check raw instead of ids

* DEV: Implement `freeze_original` option for `PostMover`

update specs to use `*array` matcher

* DEV: add tests to `MovedPost` model in post mover

* DEV: Update `MovedPost` model rspec

* DEV: add back empty line to `post_mover.rb`
This commit is contained in:
Gabriel Grubba
2024-11-26 14:25:55 -03:00
committed by GitHub
parent cddc018959
commit b6ec07c3ef
2 changed files with 182 additions and 6 deletions

View File

@ -2637,5 +2637,158 @@ RSpec.describe PostMover do
expect(topic_1.deleted_at).not_to be_nil
end
end
context "with freeze_original option" do
fab!(:original_topic) { Fabricate(:topic) }
fab!(:destination_topic) { Fabricate(:topic) }
fab!(:op) { Fabricate(:post, topic: original_topic, raw: "op of this topic") }
fab!(:op_of_destination) do
Fabricate(:post, topic: destination_topic, raw: "op of this topic")
end
fab!(:first_post) { Fabricate(:post, topic: original_topic, raw: "first_post") }
fab!(:second_post) { Fabricate(:post, topic: original_topic, raw: "second_post") }
fab!(:third_post) { Fabricate(:post, topic: original_topic, raw: "third_post") }
it "keeps a post when moving it to a new topic" do
new_topic =
PostMover.new(
original_topic,
Discourse.system_user,
[first_post.id],
options: {
freeze_original: true,
},
).to_new_topic("Hi I'm a new topic, with a copy of the old posts")
expect(new_topic.posts.map(&:raw)).to include(first_post.raw)
expect(original_topic.posts.map(&:raw)).to include(first_post.raw)
end
it "keeps a post when moving to an existing topic" do
PostMover.new(
original_topic,
Discourse.system_user,
[first_post.id],
options: {
freeze_original: true,
},
).to_topic(destination_topic.id)
expect(destination_topic.posts.map(&:raw)).to include(first_post.raw)
expect(original_topic.posts.map(&:raw)).to include(first_post.raw)
end
it "creates a MovedPost record when moving to an existing topic" do
PostMover.new(
original_topic,
Discourse.system_user,
[first_post.id],
options: {
freeze_original: true,
},
).to_topic(destination_topic.id)
expect(
MovedPost.exists?(
old_topic_id: original_topic.id,
new_topic_id: destination_topic.id,
old_post_id: first_post.id,
),
).to eq(true)
end
it "creates the moderator message in the correct position" do
PostMover.new(
original_topic,
Discourse.system_user,
[first_post.id, second_post.id],
options: {
freeze_original: true,
},
).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")
end
it "keeps posts when moving all posts to a new topic" do
all_posts_from_original_topic = original_topic.ordered_posts.map(&:raw)
new_topic =
PostMover.new(
original_topic,
Discourse.system_user,
original_topic.posts.map(&:id),
options: {
freeze_original: true,
},
).to_new_topic("Hi I'm a new topic, with a copy of the old posts")
expect(original_topic.deleted_at).to be_nil
expect(original_topic.closed?).to eq(true)
expect(original_topic.posts.map(&:raw)).to include(*all_posts_from_original_topic)
expect(new_topic.posts.map(&:raw)).to include(*all_posts_from_original_topic)
end
it "does not get deleted when moved all posts to topic" do
SiteSetting.delete_merged_stub_topics_after_days = 0
all_posts_from_original_topic = original_topic.posts.map(&:raw)
PostMover.new(
original_topic,
Discourse.system_user,
original_topic.posts.map(&:id),
options: {
freeze_original: true,
},
).to_topic(destination_topic.id)
expect(original_topic.deleted_at).to be_nil
expect(original_topic.closed?).to eq(true)
expect(original_topic.posts.map(&:raw)).to include(*all_posts_from_original_topic)
expect(destination_topic.posts.map(&:raw)).to include(*all_posts_from_original_topic)
end
it "keeps all posts when moving to a new PM" do
moving_posts = [first_post, second_post]
pm =
PostMover.new(
original_topic,
Discourse.system_user,
moving_posts.map(&:id),
move_to_pm: true,
options: {
freeze_original: true,
},
).to_new_topic("Hi I'm a new PM, with a copy of the old posts")
expect(original_topic.posts.map(&:raw)).to include(*moving_posts.map(&:raw))
expect(pm.posts.map(&:raw)).to include(*moving_posts.map(&:raw))
end
it "keep all posts when moving to an existing PM" do
pm = Fabricate(:private_message_topic)
pm_with_posts = Fabricate(:private_message_topic)
moving_posts = [
Fabricate(:post, topic: pm_with_posts),
Fabricate(:post, topic: pm_with_posts),
]
PostMover.new(
pm_with_posts,
Discourse.system_user,
moving_posts.map(&:id),
move_to_pm: true,
options: {
freeze_original: true,
},
).to_topic(pm.id)
expect(pm_with_posts.posts.map(&:raw)).to include(*moving_posts.map(&:raw))
expect(pm.posts.map(&:raw)).to include(*moving_posts.map(&:raw))
end
end
end
end