mirror of
https://github.com/discourse/discourse.git
synced 2024-11-27 11:53:44 +08:00
2d686191b5
Because bookmarks have both topic and post ID, when the post was moved into another topic the bookmark was still attached to the post but did not show in the UI. This PR makes it so the all topic IDs for bookmarks attached to a post are updated when a post is moved. Also included is a migration to fix affected records (e.g. on Meta there are 20 affected records). See: https://meta.discourse.org/t/improved-bookmarks-with-reminders/144542/203
1268 lines
52 KiB
Ruby
1268 lines
52 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'rails_helper'
|
|
|
|
describe PostMover do
|
|
fab!(:admin) { Fabricate(:admin) }
|
|
fab!(:evil_trout) { Fabricate(:evil_trout) }
|
|
|
|
describe '#move_types' do
|
|
context "verify enum sequence" do
|
|
before do
|
|
@move_types = PostMover.move_types
|
|
end
|
|
|
|
it "'new_topic' should be at 1st position" do
|
|
expect(@move_types[:new_topic]).to eq(1)
|
|
end
|
|
|
|
it "'existing_topic' should be at 2nd position" do
|
|
expect(@move_types[:existing_topic]).to eq(2)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'move_posts' do
|
|
context 'topics' do
|
|
before { freeze_time }
|
|
|
|
fab!(:user) { Fabricate(:user, admin: true) }
|
|
fab!(:another_user) { evil_trout }
|
|
fab!(:category) { Fabricate(:category, user: user) }
|
|
fab!(:topic) { Fabricate(:topic, user: user, created_at: 4.hours.ago) }
|
|
fab!(:p1) { Fabricate(:post, topic: topic, user: user, created_at: 3.hours.ago, reply_count: 2) }
|
|
|
|
fab!(:p2) do
|
|
Fabricate(
|
|
:post,
|
|
topic: topic,
|
|
user: another_user,
|
|
raw: "Has a link to [evil trout](http://eviltrout.com) which is a cool site.",
|
|
reply_to_post_number: p1.post_number,
|
|
reply_count: 1,
|
|
created_at: 2.hours.ago
|
|
)
|
|
end
|
|
|
|
fab!(:p3) { Fabricate(:post, topic: topic, reply_to_post_number: p1.post_number, user: user, created_at: 1.hour.ago) }
|
|
fab!(:p4) { Fabricate(:post, topic: topic, reply_to_post_number: p2.post_number, user: user, created_at: 45.minutes.ago) }
|
|
fab!(:p5) { Fabricate(:post, created_at: 30.minutes.ago) }
|
|
let(:p6) { Fabricate(:post, topic: topic, created_at: 15.minutes.ago) }
|
|
|
|
before do
|
|
SiteSetting.tagging_enabled = true
|
|
Jobs.run_immediately!
|
|
p1.replies.push(p2, p3)
|
|
p2.replies.push(p4)
|
|
UserActionManager.enable
|
|
@like = PostActionCreator.like(another_user, p4)
|
|
end
|
|
|
|
context 'success' do
|
|
|
|
it "correctly handles notifications and bread crumbs" do
|
|
old_topic = p2.topic
|
|
|
|
old_topic_id = p2.topic_id
|
|
|
|
topic.move_posts(user, [p2.id, p4.id, p6.id], title: "new testing topic name")
|
|
|
|
p2.reload
|
|
expect(p2.topic_id).not_to eq(old_topic_id)
|
|
expect(p2.reply_to_post_number).to eq(nil)
|
|
expect(p2.reply_to_user_id).to eq(nil)
|
|
|
|
notification = p2.user.notifications.where(notification_type: Notification.types[:moved_post]).first
|
|
|
|
expect(notification.topic_id).to eq(p2.topic_id)
|
|
expect(notification.topic_id).not_to eq(old_topic_id)
|
|
expect(notification.post_number).to eq(1)
|
|
|
|
# no message for person who made the move
|
|
expect(p4.user.notifications.where(notification_type: Notification.types[:moved_post]).length).to eq(0)
|
|
|
|
# notify at the right spot in the stream
|
|
notification = p6.user.notifications.where(notification_type: Notification.types[:moved_post]).first
|
|
|
|
expect(notification.topic_id).to eq(p2.topic_id)
|
|
expect(notification.topic_id).not_to eq(old_topic_id)
|
|
|
|
# this is the 3rd post we moved
|
|
expect(notification.post_number).to eq(3)
|
|
|
|
old_topic.reload
|
|
move_message = old_topic.posts.find_by(post_number: 2)
|
|
expect(move_message.post_type).to eq(Post.types[:small_action])
|
|
expect(move_message.raw).to include("3 posts were split")
|
|
end
|
|
|
|
it "correctly remaps quotes" do
|
|
raw = <<~RAW
|
|
[quote="dan, post:#{p2.post_number}, topic:#{p2.topic_id}, full:true"]
|
|
some quote from the other post
|
|
[/quote]
|
|
|
|
the quote above should be updated with new post number and topic id
|
|
RAW
|
|
|
|
p3.update!(raw: raw)
|
|
p3.rebake!
|
|
|
|
expect { topic.move_posts(user, [p2.id], title: "new testing topic name") }
|
|
.to change { p2.reload.topic_id }
|
|
.and change { p2.post_number }
|
|
.and change { p3.reload.raw }
|
|
.and change { p3.baked_version }.to nil
|
|
|
|
expect(p3.raw).to include("post:#{p2.post_number}, topic:#{p2.topic_id}")
|
|
end
|
|
end
|
|
|
|
context "errors" do
|
|
|
|
it "raises an error when one of the posts doesn't exist" do
|
|
non_existent_post_id = Post.maximum(:id)&.next || 1
|
|
expect { topic.move_posts(user, [non_existent_post_id], title: "new testing topic name") }.to raise_error(Discourse::InvalidParameters)
|
|
end
|
|
|
|
it "raises an error and does not create a topic if no posts were moved" do
|
|
Topic.count.tap do |original_topic_count|
|
|
expect {
|
|
topic.move_posts(user, [], title: "new testing topic name")
|
|
}.to raise_error(Discourse::InvalidParameters)
|
|
|
|
expect(Topic.count).to eq original_topic_count
|
|
end
|
|
end
|
|
end
|
|
|
|
context "successfully moved" do
|
|
before do
|
|
TopicUser.update_last_read(user, topic.id, p4.post_number, p4.post_number, 0)
|
|
TopicLink.extract_from(p2)
|
|
end
|
|
|
|
def create_post_timing(post, user, msecs)
|
|
PostTiming.create!(
|
|
topic_id: post.topic_id,
|
|
user_id: user.id,
|
|
post_number: post.post_number,
|
|
msecs: msecs
|
|
)
|
|
end
|
|
|
|
context "post replies" do
|
|
describe "when a post with replies is moved" do
|
|
it "should update post replies correctly" do
|
|
topic.move_posts(
|
|
user,
|
|
[p2.id],
|
|
title: 'GOT is a very addictive show', category_id: category.id
|
|
)
|
|
|
|
expect(p2.reload.replies).to eq([])
|
|
end
|
|
|
|
it "doesn't raise errors with deleted replies" do
|
|
p4.trash!
|
|
topic.move_posts(
|
|
user,
|
|
[p2.id],
|
|
title: 'GOT is a very addictive show', category_id: category.id
|
|
)
|
|
|
|
expect(p2.reload.replies).to eq([])
|
|
end
|
|
end
|
|
|
|
describe "when replies of a post have been moved" do
|
|
it "should update post replies correctly" do
|
|
p5 = Fabricate(
|
|
:post,
|
|
topic: topic,
|
|
reply_to_post_number: p2.post_number,
|
|
user: another_user
|
|
)
|
|
|
|
p2.replies << p5
|
|
|
|
topic.move_posts(
|
|
user,
|
|
[p4.id],
|
|
title: 'GOT is a very addictive show', category_id: category.id
|
|
)
|
|
|
|
expect(p2.reload.replies).to eq([p5])
|
|
end
|
|
end
|
|
|
|
describe "when only one reply is left behind" do
|
|
it "should update post replies correctly" do
|
|
p5 = Fabricate(
|
|
:post,
|
|
topic: topic,
|
|
reply_to_post_number: p2.post_number,
|
|
user: another_user
|
|
)
|
|
|
|
p2.replies << p5
|
|
|
|
topic.move_posts(
|
|
user,
|
|
[p2.id, p4.id],
|
|
title: 'GOT is a very addictive show', category_id: category.id
|
|
)
|
|
|
|
expect(p2.reload.replies).to eq([p4])
|
|
end
|
|
end
|
|
end
|
|
|
|
context "to a new topic" do
|
|
it "works correctly" do
|
|
topic.expects(:add_moderator_post).once
|
|
new_topic = topic.move_posts(user, [p2.id, p4.id], title: "new testing topic name", category_id: category.id, tags: ["tag1", "tag2"])
|
|
|
|
expect(TopicUser.find_by(user_id: user.id, topic_id: topic.id).last_read_post_number).to eq(p3.post_number)
|
|
|
|
expect(new_topic).to be_present
|
|
expect(new_topic.featured_user1_id).to eq(p4.user_id)
|
|
expect(new_topic.like_count).to eq(1)
|
|
|
|
expect(new_topic.category).to eq(category)
|
|
expect(new_topic.tags.pluck(:name)).to contain_exactly("tag1", "tag2")
|
|
expect(topic.featured_user1_id).to be_blank
|
|
expect(new_topic.posts.by_post_number).to match_array([p2, p4])
|
|
|
|
new_topic.reload
|
|
expect(new_topic.posts_count).to eq(2)
|
|
expect(new_topic.highest_post_number).to eq(2)
|
|
|
|
p4.reload
|
|
expect(new_topic.last_post_user_id).to eq(p4.user_id)
|
|
expect(new_topic.last_posted_at).to eq_time(p4.created_at)
|
|
expect(new_topic.bumped_at).to eq_time(Time.zone.now)
|
|
|
|
p2.reload
|
|
expect(p2.sort_order).to eq(1)
|
|
expect(p2.post_number).to eq(1)
|
|
expect(p2.topic_links.first.topic_id).to eq(new_topic.id)
|
|
|
|
expect(p4.post_number).to eq(2)
|
|
expect(p4.sort_order).to eq(2)
|
|
|
|
topic.reload
|
|
expect(topic.featured_user1_id).to be_blank
|
|
expect(topic.like_count).to eq(0)
|
|
expect(topic.posts_count).to eq(2)
|
|
expect(topic.posts.by_post_number).to match_array([p1, p3])
|
|
expect(topic.highest_post_number).to eq(p3.post_number)
|
|
|
|
# both the like and was_liked user actions should be correct
|
|
action = UserAction.find_by(user_id: another_user.id)
|
|
expect(action.target_topic_id).to eq(new_topic.id)
|
|
|
|
expect(TopicUser.exists?(
|
|
user_id: another_user,
|
|
topic_id: new_topic.id,
|
|
notification_level: TopicUser.notification_levels[:watching],
|
|
notifications_reason_id: TopicUser.notification_reasons[:created_topic]
|
|
)).to eq(true)
|
|
expect(TopicUser.exists?(user_id: user, topic_id: new_topic.id)).to eq(true)
|
|
end
|
|
|
|
it "moving all posts will close the topic" do
|
|
topic.expects(:add_moderator_post).twice
|
|
new_topic = topic.move_posts(user, [p1.id, p2.id, p3.id, p4.id], title: "new testing topic name", category_id: category.id)
|
|
expect(new_topic).to be_present
|
|
|
|
topic.reload
|
|
expect(topic.closed).to eq(true)
|
|
end
|
|
|
|
it 'does not move posts that do not belong to the existing topic' do
|
|
new_topic = topic.move_posts(
|
|
user, [p2.id, p3.id, p5.id], title: 'Logan is a pretty good movie'
|
|
)
|
|
|
|
expect(new_topic.posts.pluck(:id).sort).to eq([p2.id, p3.id].sort)
|
|
end
|
|
|
|
it "uses default locale for moderator post" do
|
|
I18n.locale = 'de'
|
|
|
|
new_topic = topic.move_posts(user, [p2.id, p4.id], title: "new testing topic name", category_id: category.id)
|
|
post = Post.find_by(topic_id: topic.id, post_type: Post.types[:small_action])
|
|
|
|
expected_text = I18n.with_locale(:en) do
|
|
I18n.t("move_posts.new_topic_moderator_post",
|
|
count: 2,
|
|
topic_link: "[#{new_topic.title}](#{new_topic.relative_url})")
|
|
end
|
|
|
|
expect(post.raw).to eq(expected_text)
|
|
end
|
|
|
|
it "does not try to move small action posts" do
|
|
small_action = Fabricate(:post, topic: topic, raw: "A small action", post_type: Post.types[:small_action])
|
|
hidden_small_action = Fabricate(:post, topic: topic, post_type: Post.types[:whisper])
|
|
hidden_small_action.update_attribute(:raw, "")
|
|
new_topic = topic.move_posts(user, [p2.id, p4.id, small_action.id, hidden_small_action.id], title: "new testing topic name", category_id: category.id)
|
|
|
|
expect(new_topic.posts_count).to eq(2)
|
|
expect(small_action.topic_id).to eq(topic.id)
|
|
expect(hidden_small_action.topic_id).to eq(topic.id)
|
|
|
|
moderator_post = topic.posts.last
|
|
expect(moderator_post.raw).to include("2 posts were split")
|
|
end
|
|
|
|
it "forces resulting topic owner to watch the new topic" do
|
|
new_topic = topic.move_posts(user, [p2.id, p4.id], title: "new testing topic name", category_id: category.id)
|
|
|
|
expect(new_topic.posts_count).to eq(2)
|
|
|
|
expect(TopicUser.exists?(
|
|
user_id: another_user,
|
|
topic_id: new_topic.id,
|
|
notification_level: TopicUser.notification_levels[:watching],
|
|
notifications_reason_id: TopicUser.notification_reasons[:created_topic]
|
|
)).to eq(true)
|
|
end
|
|
|
|
it "updates existing notifications" do
|
|
n3 = Fabricate(:mentioned_notification, post: p3, user: another_user)
|
|
n4 = Fabricate(:mentioned_notification, post: p4, user: another_user)
|
|
|
|
new_topic = topic.move_posts(user, [p3.id], title: "new testing topic name")
|
|
|
|
n3 = Notification.find(n3.id)
|
|
expect(n3.topic_id).to eq(new_topic.id)
|
|
expect(n3.post_number).to eq(1)
|
|
expect(n3.data_hash[:topic_title]).to eq(new_topic.title)
|
|
|
|
n4 = Notification.find(n4.id)
|
|
expect(n4.topic_id).to eq(topic.id)
|
|
expect(n4.post_number).to eq(4)
|
|
end
|
|
|
|
it "doesn't update notifications of type 'watching_first_post'" do
|
|
n1 = Fabricate(:watching_first_post_notification, post: p1, user: another_user)
|
|
|
|
topic.move_posts(user, [p1.id], title: "new testing topic name")
|
|
|
|
n1 = Notification.find(n1.id)
|
|
expect(n1.topic_id).to eq(topic.id)
|
|
expect(n1.data_hash[:topic_title]).to eq(topic.title)
|
|
expect(n1.post_number).to eq(1)
|
|
end
|
|
|
|
it "deletes notifications for users not allowed to see the topic" do
|
|
another_admin = Fabricate(:admin)
|
|
staff_category = Fabricate(:private_category, group: Group[:staff])
|
|
user_notification = Fabricate(:mentioned_notification, post: p3, user: another_user)
|
|
admin_notification = Fabricate(:mentioned_notification, post: p3, user: another_admin)
|
|
|
|
topic.move_posts(user, [p3.id], title: "new testing topic name", category_id: staff_category.id)
|
|
|
|
expect(Notification.exists?(user_notification.id)).to eq(false)
|
|
expect(Notification.exists?(admin_notification.id)).to eq(true)
|
|
end
|
|
|
|
it "moves post timings" do
|
|
some_user = Fabricate(:user)
|
|
create_post_timing(p1, some_user, 500)
|
|
create_post_timing(p2, some_user, 1000)
|
|
create_post_timing(p3, some_user, 1500)
|
|
create_post_timing(p4, some_user, 750)
|
|
|
|
new_topic = topic.move_posts(user, [p1.id, p4.id], title: "new testing topic name")
|
|
|
|
expect(PostTiming.where(topic_id: topic.id, user_id: some_user.id).pluck(:post_number, :msecs))
|
|
.to contain_exactly([1, 500], [2, 1000], [3, 1500])
|
|
|
|
expect(PostTiming.where(topic_id: new_topic.id, user_id: some_user.id).pluck(:post_number, :msecs))
|
|
.to contain_exactly([1, 500], [2, 750])
|
|
end
|
|
|
|
it "updates bookmark topic_ids to the new topic id and does not affect bookmarks for posts not moving" do
|
|
some_user = Fabricate(:user)
|
|
new_post = Fabricate(:post, topic: p1.topic)
|
|
bookmark1 = Fabricate(:bookmark, topic: p1.topic, post: p1, user: some_user)
|
|
bookmark2 = Fabricate(:bookmark, topic: p4.topic, post: p4)
|
|
bookmark3 = Fabricate(:bookmark, topic: p4.topic, post: p4)
|
|
bookmark4 = Fabricate(:bookmark, topic: new_post.topic, post: new_post)
|
|
new_topic = topic.move_posts(user, [p1.id, p4.id], title: "new testing topic name")
|
|
expect(bookmark1.reload.topic_id).to eq(new_topic.id)
|
|
expect(bookmark2.reload.topic_id).to eq(new_topic.id)
|
|
expect(bookmark3.reload.topic_id).to eq(new_topic.id)
|
|
expect(bookmark4.reload.topic_id).to eq(new_post.topic_id)
|
|
end
|
|
|
|
context "read state and other stats per user" do
|
|
def create_topic_user(user, opts = {})
|
|
notification_level = opts.delete(:notification_level) || :regular
|
|
|
|
Fabricate(:topic_user, opts.merge(
|
|
notification_level: TopicUser.notification_levels[notification_level],
|
|
topic: topic,
|
|
user: user
|
|
))
|
|
end
|
|
|
|
fab!(:user1) { Fabricate(:user) }
|
|
fab!(:user2) { Fabricate(:user) }
|
|
fab!(:user3) { Fabricate(:user) }
|
|
fab!(:admin1) { Fabricate(:admin) }
|
|
fab!(:admin2) { Fabricate(:admin) }
|
|
|
|
it "correctly moves topic_user records" do
|
|
create_topic_user(
|
|
user1,
|
|
last_read_post_number: 4,
|
|
highest_seen_post_number: 4,
|
|
last_emailed_post_number: 3,
|
|
notification_level: :tracking
|
|
)
|
|
create_topic_user(
|
|
user2,
|
|
last_read_post_number: 2,
|
|
highest_seen_post_number: 2,
|
|
last_emailed_post_number: 2,
|
|
notification_level: :tracking
|
|
)
|
|
create_topic_user(
|
|
user3,
|
|
last_read_post_number: 1,
|
|
highest_seen_post_number: 2,
|
|
last_emailed_post_number: 4,
|
|
notification_level: :watching
|
|
)
|
|
|
|
p2.update!(user_id: user2.id)
|
|
new_topic = topic.move_posts(user, [p1.id, p2.id], title: "new testing topic name")
|
|
|
|
expect(TopicUser.where(topic_id: topic.id).count).to eq(4)
|
|
expect(TopicUser.find_by(topic: topic, user: user))
|
|
.to have_attributes(
|
|
last_read_post_number: 4,
|
|
highest_seen_post_number: 4,
|
|
last_emailed_post_number: nil,
|
|
notification_level: TopicUser.notification_levels[:tracking]
|
|
)
|
|
expect(TopicUser.find_by(topic: topic, user: user1))
|
|
.to have_attributes(
|
|
last_read_post_number: 4,
|
|
highest_seen_post_number: 4,
|
|
last_emailed_post_number: 3,
|
|
notification_level: TopicUser.notification_levels[:tracking]
|
|
)
|
|
expect(TopicUser.find_by(topic: topic, user: user2))
|
|
.to have_attributes(
|
|
last_read_post_number: 2,
|
|
highest_seen_post_number: 2,
|
|
last_emailed_post_number: 2,
|
|
notification_level: TopicUser.notification_levels[:tracking]
|
|
)
|
|
expect(TopicUser.find_by(topic: topic, user: user3))
|
|
.to have_attributes(
|
|
last_read_post_number: 1,
|
|
highest_seen_post_number: 2,
|
|
last_emailed_post_number: 4,
|
|
notification_level: TopicUser.notification_levels[:watching]
|
|
)
|
|
|
|
expect(TopicUser.where(topic_id: new_topic.id).count).to eq(4)
|
|
expect(TopicUser.find_by(topic: new_topic, user: user))
|
|
.to have_attributes(
|
|
last_read_post_number: 1,
|
|
highest_seen_post_number: 1,
|
|
last_emailed_post_number: nil,
|
|
notification_level: TopicUser.notification_levels[:watching],
|
|
posted: true
|
|
)
|
|
expect(TopicUser.find_by(topic: new_topic, user: user1))
|
|
.to have_attributes(
|
|
last_read_post_number: 2,
|
|
highest_seen_post_number: 2,
|
|
last_emailed_post_number: 2,
|
|
notification_level: TopicUser.notification_levels[:tracking],
|
|
posted: false
|
|
)
|
|
expect(TopicUser.find_by(topic: new_topic, user: user2))
|
|
.to have_attributes(
|
|
last_read_post_number: 2,
|
|
highest_seen_post_number: 2,
|
|
last_emailed_post_number: 2,
|
|
notification_level: TopicUser.notification_levels[:tracking],
|
|
posted: true
|
|
)
|
|
expect(TopicUser.find_by(topic: new_topic, user: user3))
|
|
.to have_attributes(
|
|
last_read_post_number: 1,
|
|
highest_seen_post_number: 2,
|
|
last_emailed_post_number: 2,
|
|
notification_level: TopicUser.notification_levels[:watching],
|
|
posted: false
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
context "to an existing topic" do
|
|
fab!(:destination_topic) { Fabricate(:topic, user: another_user) }
|
|
fab!(:destination_op) { Fabricate(:post, topic: destination_topic, user: another_user, created_at: 1.day.ago) }
|
|
|
|
it "works correctly" do
|
|
topic.expects(:add_moderator_post).once
|
|
moved_to = topic.move_posts(user, [p2.id, p4.id], destination_topic_id: destination_topic.id)
|
|
expect(moved_to).to eq(destination_topic)
|
|
|
|
# Check out new topic
|
|
moved_to.reload
|
|
expect(moved_to.posts_count).to eq(3)
|
|
expect(moved_to.highest_post_number).to eq(3)
|
|
expect(moved_to.user_id).to eq(destination_op.user_id)
|
|
expect(moved_to.like_count).to eq(1)
|
|
expect(moved_to.category_id).to eq(SiteSetting.uncategorized_category_id)
|
|
p4.reload
|
|
expect(moved_to.last_post_user_id).to eq(p4.user_id)
|
|
expect(moved_to.last_posted_at).to eq_time(p4.created_at)
|
|
expect(moved_to.bumped_at).to eq_time(Time.zone.now)
|
|
|
|
# Posts should be re-ordered
|
|
p2.reload
|
|
expect(p2.sort_order).to eq(2)
|
|
expect(p2.post_number).to eq(2)
|
|
expect(p2.topic_id).to eq(moved_to.id)
|
|
expect(p2.reply_count).to eq(1)
|
|
expect(p2.reply_to_post_number).to eq(nil)
|
|
|
|
expect(p4.post_number).to eq(3)
|
|
expect(p4.sort_order).to eq(3)
|
|
expect(p4.topic_id).to eq(moved_to.id)
|
|
expect(p4.reply_count).to eq(0)
|
|
expect(p4.reply_to_post_number).to eq(2)
|
|
|
|
# Check out the original topic
|
|
topic.reload
|
|
expect(topic.posts_count).to eq(2)
|
|
expect(topic.highest_post_number).to eq(3)
|
|
expect(topic.featured_user1_id).to be_blank
|
|
expect(topic.like_count).to eq(0)
|
|
expect(topic.posts_count).to eq(2)
|
|
expect(topic.posts.by_post_number).to match_array([p1, p3])
|
|
expect(topic.highest_post_number).to eq(p3.post_number)
|
|
|
|
# Should notify correctly
|
|
notification = p2.user.notifications.where(notification_type: Notification.types[:moved_post]).first
|
|
|
|
expect(notification.topic_id).to eq(destination_topic.id)
|
|
expect(notification.post_number).to eq(p2.post_number)
|
|
|
|
# Should update last reads
|
|
expect(TopicUser.find_by(user_id: user.id, topic_id: topic.id).last_read_post_number).to eq(p3.post_number)
|
|
end
|
|
|
|
it "moving all posts will close the topic" do
|
|
topic.expects(:add_moderator_post).twice
|
|
moved_to = topic.move_posts(user, [p1.id, p2.id, p3.id, p4.id], destination_topic_id: destination_topic.id)
|
|
expect(moved_to).to be_present
|
|
|
|
topic.reload
|
|
expect(topic.closed).to eq(true)
|
|
end
|
|
|
|
it "does not try to move small action posts" do
|
|
small_action = Fabricate(:post, topic: topic, raw: "A small action", post_type: Post.types[:small_action])
|
|
moved_to = topic.move_posts(user, [p1.id, p2.id, p3.id, p4.id, small_action.id], destination_topic_id: destination_topic.id)
|
|
|
|
moved_to.reload
|
|
expect(moved_to.posts_count).to eq(5)
|
|
expect(small_action.topic_id).to eq(topic.id)
|
|
|
|
moderator_post = topic.posts.find_by(post_number: 2)
|
|
expect(moderator_post.raw).to include("4 posts were merged")
|
|
end
|
|
|
|
it "updates existing notifications" do
|
|
n3 = Fabricate(:mentioned_notification, post: p3, user: another_user)
|
|
n4 = Fabricate(:mentioned_notification, post: p4, user: another_user)
|
|
|
|
moved_to = topic.move_posts(user, [p3.id], destination_topic_id: destination_topic.id)
|
|
|
|
n3 = Notification.find(n3.id)
|
|
expect(n3.topic_id).to eq(moved_to.id)
|
|
expect(n3.post_number).to eq(2)
|
|
expect(n3.data_hash[:topic_title]).to eq(moved_to.title)
|
|
|
|
n4 = Notification.find(n4.id)
|
|
expect(n4.topic_id).to eq(topic.id)
|
|
expect(n4.post_number).to eq(4)
|
|
end
|
|
|
|
it "deletes notifications for users not allowed to see the topic" do
|
|
another_admin = Fabricate(:admin)
|
|
staff_category = Fabricate(:private_category, group: Group[:staff])
|
|
user_notification = Fabricate(:mentioned_notification, post: p3, user: another_user)
|
|
admin_notification = Fabricate(:mentioned_notification, post: p3, user: another_admin)
|
|
|
|
destination_topic.update!(category_id: staff_category.id)
|
|
topic.move_posts(user, [p3.id], destination_topic_id: destination_topic.id)
|
|
|
|
expect(Notification.exists?(user_notification.id)).to eq(false)
|
|
expect(Notification.exists?(admin_notification.id)).to eq(true)
|
|
end
|
|
|
|
it "updates bookmark topic_ids to the new topic id and does not affect bookmarks for posts not moving" do
|
|
some_user = Fabricate(:user)
|
|
new_post = Fabricate(:post, topic: p3.topic)
|
|
bookmark1 = Fabricate(:bookmark, topic: p3.topic, post: p3, user: some_user)
|
|
bookmark2 = Fabricate(:bookmark, topic: p3.topic, post: p3)
|
|
bookmark3 = Fabricate(:bookmark, topic: p3.topic, post: p3)
|
|
bookmark4 = Fabricate(:bookmark, topic: new_post.topic, post: new_post)
|
|
topic.move_posts(user, [p3.id], destination_topic_id: destination_topic.id)
|
|
expect(bookmark1.reload.topic_id).to eq(destination_topic.id)
|
|
expect(bookmark2.reload.topic_id).to eq(destination_topic.id)
|
|
expect(bookmark3.reload.topic_id).to eq(destination_topic.id)
|
|
expect(bookmark4.reload.topic_id).to eq(new_post.topic_id)
|
|
end
|
|
|
|
context "post timings" do
|
|
fab!(:some_user) { Fabricate(:user) }
|
|
|
|
it "successfully moves timings" do
|
|
create_post_timing(p1, some_user, 500)
|
|
create_post_timing(p2, some_user, 1000)
|
|
create_post_timing(p3, some_user, 1500)
|
|
create_post_timing(p4, some_user, 750)
|
|
|
|
moved_to = topic.move_posts(user, [p1.id, p4.id], destination_topic_id: destination_topic.id)
|
|
|
|
expect(PostTiming.where(topic_id: topic.id, user_id: some_user.id).pluck(:post_number, :msecs))
|
|
.to contain_exactly([1, 500], [2, 1000], [3, 1500])
|
|
|
|
expect(PostTiming.where(topic_id: moved_to.id, user_id: some_user.id).pluck(:post_number, :msecs))
|
|
.to contain_exactly([2, 500], [3, 750])
|
|
end
|
|
|
|
it "moves timings when post timing exists in destination topic" do
|
|
PostTiming.create!(
|
|
topic_id: destination_topic.id,
|
|
user_id: some_user.id,
|
|
post_number: 2,
|
|
msecs: 800
|
|
)
|
|
create_post_timing(p1, some_user, 500)
|
|
|
|
moved_to = topic.move_posts(user, [p1.id], destination_topic_id: destination_topic.id)
|
|
|
|
expect(PostTiming.where(topic_id: moved_to.id, user_id: some_user.id).pluck(:post_number, :msecs))
|
|
.to contain_exactly([2, 500])
|
|
end
|
|
end
|
|
|
|
context "read state and other stats per user" do
|
|
def create_topic_user(user, topic, opts = {})
|
|
notification_level = opts.delete(:notification_level) || :regular
|
|
|
|
Fabricate(:topic_user, opts.merge(
|
|
notification_level: TopicUser.notification_levels[notification_level],
|
|
topic: topic,
|
|
user: user
|
|
))
|
|
end
|
|
|
|
fab!(:user1) { Fabricate(:user) }
|
|
fab!(:user2) { Fabricate(:user) }
|
|
fab!(:user3) { Fabricate(:user) }
|
|
fab!(:admin1) { Fabricate(:admin) }
|
|
fab!(:admin2) { Fabricate(:admin) }
|
|
|
|
it "leaves post numbers unchanged when they were lower then the topic's highest post number" do
|
|
Fabricate(:post, topic: destination_topic)
|
|
Fabricate(:whisper, topic: destination_topic)
|
|
|
|
destination_topic.reload
|
|
expect(destination_topic.highest_post_number).to eq(2)
|
|
expect(destination_topic.highest_staff_post_number).to eq(3)
|
|
|
|
create_topic_user(
|
|
user1, topic,
|
|
last_read_post_number: 3,
|
|
highest_seen_post_number: 3,
|
|
last_emailed_post_number: 3
|
|
)
|
|
create_topic_user(
|
|
user1, destination_topic,
|
|
last_read_post_number: 1,
|
|
highest_seen_post_number: 2,
|
|
last_emailed_post_number: 1
|
|
)
|
|
|
|
create_topic_user(
|
|
user2, topic,
|
|
last_read_post_number: 3,
|
|
highest_seen_post_number: 3,
|
|
last_emailed_post_number: 3
|
|
)
|
|
create_topic_user(
|
|
user2, destination_topic,
|
|
last_read_post_number: 2,
|
|
highest_seen_post_number: 1,
|
|
last_emailed_post_number: 2
|
|
)
|
|
|
|
create_topic_user(
|
|
admin1, topic,
|
|
last_read_post_number: 3,
|
|
highest_seen_post_number: 3,
|
|
last_emailed_post_number: 3
|
|
)
|
|
create_topic_user(
|
|
admin1, destination_topic,
|
|
last_read_post_number: 2,
|
|
highest_seen_post_number: 3,
|
|
last_emailed_post_number: 1
|
|
)
|
|
|
|
create_topic_user(
|
|
admin2, topic,
|
|
last_read_post_number: 3,
|
|
highest_seen_post_number: 3,
|
|
last_emailed_post_number: 3
|
|
)
|
|
create_topic_user(
|
|
admin2, destination_topic,
|
|
last_read_post_number: 3,
|
|
highest_seen_post_number: 2,
|
|
last_emailed_post_number: 3
|
|
)
|
|
|
|
moved_to_topic = topic.move_posts(user, [p1.id, p2.id], destination_topic_id: destination_topic.id)
|
|
|
|
expect(TopicUser.find_by(topic: moved_to_topic, user: user1))
|
|
.to have_attributes(
|
|
last_read_post_number: 1,
|
|
highest_seen_post_number: 5,
|
|
last_emailed_post_number: 1
|
|
)
|
|
|
|
expect(TopicUser.find_by(topic: moved_to_topic, user: user2))
|
|
.to have_attributes(
|
|
last_read_post_number: 5,
|
|
highest_seen_post_number: 1,
|
|
last_emailed_post_number: 5
|
|
)
|
|
|
|
expect(TopicUser.find_by(topic: moved_to_topic, user: admin1))
|
|
.to have_attributes(
|
|
last_read_post_number: 2,
|
|
highest_seen_post_number: 5,
|
|
last_emailed_post_number: 1
|
|
)
|
|
|
|
expect(TopicUser.find_by(topic: moved_to_topic, user: admin2))
|
|
.to have_attributes(
|
|
last_read_post_number: 5,
|
|
highest_seen_post_number: 2,
|
|
last_emailed_post_number: 5
|
|
)
|
|
end
|
|
|
|
it "correctly updates existing topic_user records" do
|
|
destination_topic.update!(created_at: 1.day.ago)
|
|
|
|
original_topic_user1 = create_topic_user(
|
|
user1, topic,
|
|
highest_seen_post_number: 5,
|
|
first_visited_at: 5.hours.ago,
|
|
last_visited_at: 30.minutes.ago,
|
|
notification_level: :tracking
|
|
).reload
|
|
destination_topic_user1 = create_topic_user(
|
|
user1, destination_topic,
|
|
highest_seen_post_number: 5,
|
|
first_visited_at: 7.hours.ago,
|
|
last_visited_at: 2.hours.ago,
|
|
notification_level: :watching
|
|
).reload
|
|
|
|
original_topic_user2 = create_topic_user(
|
|
user2, topic,
|
|
highest_seen_post_number: 5,
|
|
first_visited_at: 3.hours.ago,
|
|
last_visited_at: 1.hour.ago,
|
|
notification_level: :watching
|
|
).reload
|
|
destination_topic_user2 = create_topic_user(
|
|
user2, destination_topic,
|
|
highest_seen_post_number: 5,
|
|
first_visited_at: 2.hours.ago,
|
|
last_visited_at: 1.hour.ago,
|
|
notification_level: :tracking
|
|
).reload
|
|
|
|
new_topic = topic.move_posts(user, [p1.id, p2.id], destination_topic_id: destination_topic.id)
|
|
|
|
expect(TopicUser.find_by(topic: new_topic, user: user))
|
|
.to have_attributes(
|
|
notification_level: TopicUser.notification_levels[:tracking],
|
|
posted: true
|
|
)
|
|
|
|
expect(TopicUser.find_by(topic: new_topic, user: user1))
|
|
.to have_attributes(
|
|
first_visited_at: destination_topic_user1.first_visited_at,
|
|
last_visited_at: original_topic_user1.last_visited_at,
|
|
notification_level: destination_topic_user1.notification_level,
|
|
posted: false
|
|
)
|
|
|
|
expect(TopicUser.find_by(topic: new_topic, user: user2))
|
|
.to have_attributes(
|
|
first_visited_at: original_topic_user2.first_visited_at,
|
|
last_visited_at: destination_topic_user2.last_visited_at,
|
|
notification_level: destination_topic_user2.notification_level,
|
|
posted: false
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
context "to a message" do
|
|
|
|
it "works correctly" do
|
|
topic.expects(:add_moderator_post).once
|
|
new_topic = topic.move_posts(user, [p2.id, p4.id], title: "new testing topic name", archetype: "private_message")
|
|
|
|
expect(TopicUser.find_by(user_id: user.id, topic_id: topic.id).last_read_post_number).to eq(p3.post_number)
|
|
|
|
expect(new_topic).to be_present
|
|
expect(new_topic.featured_user1_id).to eq(p4.user_id)
|
|
expect(new_topic.like_count).to eq(1)
|
|
|
|
expect(new_topic.archetype).to eq(Archetype.private_message)
|
|
expect(topic.featured_user1_id).to be_blank
|
|
expect(new_topic.posts.by_post_number).to match_array([p2, p4])
|
|
|
|
new_topic.reload
|
|
expect(new_topic.posts_count).to eq(2)
|
|
expect(new_topic.highest_post_number).to eq(2)
|
|
|
|
p4.reload
|
|
expect(new_topic.last_post_user_id).to eq(p4.user_id)
|
|
expect(new_topic.last_posted_at).to eq_time(p4.created_at)
|
|
expect(new_topic.bumped_at).to eq_time(Time.zone.now)
|
|
|
|
p2.reload
|
|
expect(p2.sort_order).to eq(1)
|
|
expect(p2.post_number).to eq(1)
|
|
expect(p2.topic_links.first.topic_id).to eq(new_topic.id)
|
|
|
|
expect(p4.post_number).to eq(2)
|
|
expect(p4.sort_order).to eq(2)
|
|
|
|
topic.reload
|
|
expect(topic.featured_user1_id).to be_blank
|
|
expect(topic.like_count).to eq(0)
|
|
expect(topic.posts_count).to eq(2)
|
|
expect(topic.posts.by_post_number).to match_array([p1, p3])
|
|
expect(topic.highest_post_number).to eq(p3.post_number)
|
|
|
|
# both the like and was_liked user actions should be correct
|
|
action = UserAction.find_by(user_id: another_user.id)
|
|
expect(action.target_topic_id).to eq(new_topic.id)
|
|
|
|
expect(TopicUser.exists?(
|
|
user_id: another_user,
|
|
topic_id: new_topic.id,
|
|
notification_level: TopicUser.notification_levels[:watching],
|
|
notifications_reason_id: TopicUser.notification_reasons[:created_topic]
|
|
)).to eq(true)
|
|
expect(TopicUser.exists?(
|
|
user_id: user,
|
|
topic_id: new_topic.id,
|
|
notification_level: TopicUser.notification_levels[:watching],
|
|
notifications_reason_id: TopicUser.notification_reasons[:created_post]
|
|
)).to eq(true)
|
|
end
|
|
|
|
end
|
|
|
|
shared_examples "moves email related stuff" do
|
|
it "moves incoming email" do
|
|
Fabricate(:incoming_email, user: old_post.user, topic: old_post.topic, post: old_post)
|
|
|
|
new_topic = topic.move_posts(user, [old_post.id], title: "new testing topic name")
|
|
new_post = new_topic.first_post
|
|
email = new_post.incoming_email
|
|
|
|
expect(email).to be_present
|
|
expect(email.topic_id).to eq(new_topic.id)
|
|
expect(email.post_id).to eq(new_post.id)
|
|
|
|
expect(old_post.reload.incoming_email).to_not be_present unless old_post.id == new_post.id
|
|
end
|
|
|
|
it "moves email log entries" do
|
|
old_topic = old_post.topic
|
|
|
|
2.times do
|
|
Fabricate(:email_log,
|
|
user: old_post.user,
|
|
post: old_post,
|
|
email_type: :mailing_list
|
|
)
|
|
end
|
|
|
|
some_post = Fabricate(:post)
|
|
|
|
Fabricate(:email_log,
|
|
user: some_post.user,
|
|
post: some_post,
|
|
email_type: :mailing_list
|
|
)
|
|
|
|
expect(EmailLog.where(post_id: old_post.id).count).to eq(2)
|
|
|
|
new_topic = old_topic.move_posts(
|
|
user,
|
|
[old_post.id],
|
|
title: "new testing topic name"
|
|
)
|
|
|
|
new_post = new_topic.first_post
|
|
|
|
expect(EmailLog.where(post_id: new_post.id).count).to eq(2)
|
|
end
|
|
|
|
it "preserves post attributes" do
|
|
old_post.update_columns(cook_method: Post.cook_methods[:email], via_email: true, raw_email: "raw email content")
|
|
|
|
new_topic = old_post.topic.move_posts(user, [old_post.id], title: "new testing topic name")
|
|
new_post = new_topic.first_post
|
|
|
|
expect(new_post.cook_method).to eq(Post.cook_methods[:email])
|
|
expect(new_post.via_email).to eq(true)
|
|
expect(new_post.raw_email).to eq("raw email content")
|
|
end
|
|
end
|
|
|
|
context "moving the first post" do
|
|
it "copies the OP, doesn't delete it" do
|
|
topic.expects(:add_moderator_post).once
|
|
new_topic = topic.move_posts(user, [p1.id, p2.id], title: "new testing topic name")
|
|
|
|
expect(new_topic).to be_present
|
|
expect(new_topic.posts.by_post_number.first.raw).to eq(p1.raw)
|
|
expect(new_topic.posts_count).to eq(2)
|
|
expect(new_topic.highest_post_number).to eq(2)
|
|
|
|
# First post didn't move
|
|
p1.reload
|
|
expect(p1.sort_order).to eq(1)
|
|
expect(p1.post_number).to eq(1)
|
|
expect(p1.topic_id).to eq(topic.id)
|
|
expect(p1.reply_count).to eq(1)
|
|
|
|
# New first post
|
|
new_first = new_topic.posts.where(post_number: 1).first
|
|
expect(new_first.reply_count).to eq(1)
|
|
expect(new_first.created_at).to eq_time(p1.created_at)
|
|
|
|
# Second post is in a new topic
|
|
p2.reload
|
|
expect(p2.post_number).to eq(2)
|
|
expect(p2.sort_order).to eq(2)
|
|
expect(p2.topic_id).to eq(new_topic.id)
|
|
expect(p2.reply_to_post_number).to eq(1)
|
|
expect(p2.reply_count).to eq(0)
|
|
|
|
topic.reload
|
|
expect(topic.posts.by_post_number).to match_array([p1, p3, p4])
|
|
expect(topic.highest_post_number).to eq(p4.post_number)
|
|
|
|
# updates replies for posts moved to same topic
|
|
expect(PostReply.where(reply_post_id: p2.id).pluck(:post_id)).to contain_exactly(new_first.id)
|
|
|
|
# leaves replies to the first post of the original topic unchanged
|
|
expect(PostReply.where(reply_post_id: p3.id).pluck(:post_id)).to contain_exactly(p1.id)
|
|
end
|
|
|
|
it "preserves post actions in the new post" do
|
|
PostActionCreator.like(another_user, p1)
|
|
|
|
new_topic = topic.move_posts(user, [p1.id], title: "new testing topic name")
|
|
new_post = new_topic.posts.where(post_number: 1).first
|
|
|
|
expect(new_topic.like_count).to eq(1)
|
|
expect(new_post.like_count).to eq(1)
|
|
expect(new_post.post_actions.size).to eq(1)
|
|
end
|
|
|
|
it "preserves the custom_fields in the new post" do
|
|
custom_fields = { "some_field" => 'payload' }
|
|
p1.custom_fields = custom_fields
|
|
p1.save_custom_fields
|
|
|
|
new_topic = topic.move_posts(user, [p1.id], title: "new testing topic name")
|
|
|
|
expect(new_topic.first_post.custom_fields).to eq(custom_fields)
|
|
end
|
|
|
|
include_examples "moves email related stuff" do
|
|
let!(:old_post) { p1 }
|
|
end
|
|
end
|
|
|
|
context "moving replies" do
|
|
include_examples "moves email related stuff" do
|
|
let!(:old_post) { p3 }
|
|
end
|
|
end
|
|
|
|
context "to an existing topic with a deleted post" do
|
|
|
|
before do
|
|
topic.expects(:add_moderator_post)
|
|
end
|
|
|
|
fab!(:destination_topic) { Fabricate(:topic, user: user) }
|
|
fab!(:destination_op) { Fabricate(:post, topic: destination_topic, user: user) }
|
|
fab!(:destination_deleted_reply) { Fabricate(:post, topic: destination_topic, user: another_user) }
|
|
let(:moved_to) { topic.move_posts(user, [p2.id, p4.id], destination_topic_id: destination_topic.id) }
|
|
|
|
it "works correctly" do
|
|
destination_deleted_reply.trash!
|
|
|
|
expect(moved_to).to eq(destination_topic)
|
|
|
|
# Check out new topic
|
|
moved_to.reload
|
|
expect(moved_to.posts_count).to eq(3)
|
|
expect(moved_to.highest_post_number).to eq(4)
|
|
|
|
# Posts should be re-ordered
|
|
p2.reload
|
|
expect(p2.sort_order).to eq(3)
|
|
expect(p2.post_number).to eq(3)
|
|
expect(p2.topic_id).to eq(moved_to.id)
|
|
expect(p2.reply_count).to eq(1)
|
|
expect(p2.reply_to_post_number).to eq(nil)
|
|
|
|
p4.reload
|
|
expect(p4.post_number).to eq(4)
|
|
expect(p4.sort_order).to eq(4)
|
|
expect(p4.topic_id).to eq(moved_to.id)
|
|
expect(p4.reply_to_post_number).to eq(p2.post_number)
|
|
end
|
|
end
|
|
|
|
context "to an existing closed topic" do
|
|
fab!(:destination_topic) { Fabricate(:topic, closed: true) }
|
|
|
|
it "works correctly for admin" do
|
|
moved_to = topic.move_posts(admin, [p1.id, p2.id], destination_topic_id: destination_topic.id)
|
|
expect(moved_to).to be_present
|
|
|
|
moved_to.reload
|
|
expect(moved_to.posts_count).to eq(2)
|
|
expect(moved_to.highest_post_number).to eq(2)
|
|
end
|
|
end
|
|
|
|
it "skips validations when moving posts" do
|
|
p1.update_attribute(:raw, "foo")
|
|
p2.update_attribute(:raw, "bar")
|
|
|
|
new_topic = topic.move_posts(user, [p1.id, p2.id], title: "new testing topic name")
|
|
|
|
expect(new_topic).to be_present
|
|
expect(new_topic.posts.by_post_number.first.raw).to eq(p1.raw)
|
|
expect(new_topic.posts.by_post_number.last.raw).to eq(p2.raw)
|
|
expect(new_topic.posts_count).to eq(2)
|
|
end
|
|
|
|
it "corrects reply_counts within original topic" do
|
|
expect do
|
|
topic.move_posts(user, [p4.id], title: "new testing topic name 1")
|
|
end.to change { PostReply.count }.by(-1)
|
|
expect(p1.reload.reply_count).to eq(2)
|
|
expect(p2.reload.reply_count).to eq(0)
|
|
|
|
expect do
|
|
topic.move_posts(user, [p2.id, p3.id], title: "new testing topic name 2")
|
|
end.to change { PostReply.count }.by(-2)
|
|
expect(p1.reload.reply_count).to eq(0)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'messages' do
|
|
fab!(:user) { Fabricate(:user) }
|
|
fab!(:another_user) { Fabricate(:user) }
|
|
fab!(:regular_user) { Fabricate(:trust_level_4) }
|
|
fab!(:personal_message) { Fabricate(:private_message_topic, user: evil_trout) }
|
|
fab!(:p1) { Fabricate(:post, topic: personal_message, user: user, created_at: 4.hours.ago) }
|
|
fab!(:p2) { Fabricate(:post, topic: personal_message, reply_to_post_number: p1.post_number, user: another_user, created_at: 3.hours.ago) }
|
|
fab!(:p3) { Fabricate(:post, topic: personal_message, reply_to_post_number: p1.post_number, user: user, created_at: 2.hours.ago) }
|
|
fab!(:p4) { Fabricate(:post, topic: personal_message, reply_to_post_number: p2.post_number, user: user, created_at: 1.hour.ago) }
|
|
fab!(:p5) { Fabricate(:post, topic: personal_message, user: evil_trout, created_at: 30.minutes.ago) }
|
|
let(:another_personal_message) do
|
|
Fabricate(:private_message_topic, user: user, topic_allowed_users: [
|
|
Fabricate.build(:topic_allowed_user, user: admin)
|
|
])
|
|
end
|
|
let!(:p6) { Fabricate(:post, topic: another_personal_message, user: evil_trout) }
|
|
|
|
before do
|
|
SiteSetting.tagging_enabled = true
|
|
Jobs.run_immediately!
|
|
p1.replies << p3
|
|
p2.replies << p4
|
|
UserActionManager.enable
|
|
@like = PostActionCreator.like(another_user, p4)
|
|
end
|
|
|
|
context 'move to new message' do
|
|
it "adds post users as topic allowed users" do
|
|
TopicUser.change(user, personal_message, notification_level: TopicUser.notification_levels[:muted])
|
|
TopicUser.change(another_user, personal_message, notification_level: TopicUser.notification_levels[:tracking])
|
|
|
|
personal_message.move_posts(admin, [p2.id, p3.id, p4.id, p5.id], title: "new testing message name", tags: ["tag1", "tag2"], archetype: "private_message")
|
|
|
|
p2.reload
|
|
destination_topic = p2.topic
|
|
expect(destination_topic.archetype).to eq(Archetype.private_message)
|
|
expect(destination_topic.topic_allowed_users.where(user_id: user.id).count).to eq(1)
|
|
expect(destination_topic.topic_allowed_users.where(user_id: another_user.id).count).to eq(1)
|
|
expect(destination_topic.topic_allowed_users.where(user_id: evil_trout.id).count).to eq(1)
|
|
expect(destination_topic.tags.pluck(:name)).to eq([])
|
|
expect(TopicUser.exists?(
|
|
user_id: another_user,
|
|
topic_id: destination_topic.id,
|
|
notification_level: TopicUser.notification_levels[:tracking],
|
|
notifications_reason_id: TopicUser.notification_reasons[:created_topic]
|
|
)).to eq(true)
|
|
expect(TopicUser.exists?(
|
|
user_id: user,
|
|
topic_id: destination_topic.id,
|
|
notification_level: TopicUser.notification_levels[:muted],
|
|
notifications_reason_id: TopicUser.notification_reasons[:created_post]
|
|
)).to eq(true)
|
|
end
|
|
|
|
it "can add tags to new message when allow_staff_to_tag_pms is enabled" do
|
|
SiteSetting.allow_staff_to_tag_pms = true
|
|
personal_message.move_posts(admin, [p2.id, p5.id], title: "new testing message name", tags: ["tag1", "tag2"], archetype: "private_message")
|
|
|
|
p2.reload
|
|
expect(p2.topic.tags.pluck(:name)).to contain_exactly("tag1", "tag2")
|
|
end
|
|
|
|
it "correctly handles notifications" do
|
|
old_message = p2.topic
|
|
old_message_id = p2.topic_id
|
|
|
|
personal_message.move_posts(admin, [p2.id, p4.id], title: "new testing message name", archetype: "private_message")
|
|
|
|
p2.reload
|
|
expect(p2.topic_id).not_to eq(old_message_id)
|
|
expect(p2.reply_to_post_number).to eq(nil)
|
|
expect(p2.reply_to_user_id).to eq(nil)
|
|
|
|
notification = p2.user.notifications.where(notification_type: Notification.types[:moved_post]).first
|
|
|
|
expect(notification.topic_id).to eq(p2.topic_id)
|
|
expect(notification.topic_id).not_to eq(old_message_id)
|
|
expect(notification.post_number).to eq(1)
|
|
|
|
# no message for person who made the move
|
|
expect(admin.notifications.where(notification_type: Notification.types[:moved_post]).length).to eq(0)
|
|
|
|
old_message.reload
|
|
move_message = old_message.posts.find_by(post_number: 2)
|
|
expect(move_message.post_type).to eq(Post.types[:whisper])
|
|
expect(move_message.raw).to include("2 posts were split")
|
|
end
|
|
end
|
|
|
|
context 'move to existing message' do
|
|
it "adds post users as topic allowed users" do
|
|
personal_message.move_posts(admin, [p2.id, p5.id], destination_topic_id: another_personal_message.id, archetype: "private_message")
|
|
|
|
p2.reload
|
|
expect(p2.topic_id).to eq(another_personal_message.id)
|
|
|
|
another_personal_message.reload
|
|
expect(another_personal_message.topic_allowed_users.where(user_id: another_user.id).count).to eq(1)
|
|
expect(another_personal_message.topic_allowed_users.where(user_id: evil_trout.id).count).to eq(1)
|
|
end
|
|
|
|
it "can add additional participants" do
|
|
personal_message.move_posts(admin, [p2.id, p5.id], destination_topic_id: another_personal_message.id, participants: [regular_user.username], archetype: "private_message")
|
|
|
|
another_personal_message.reload
|
|
expect(another_personal_message.topic_allowed_users.where(user_id: another_user.id).count).to eq(1)
|
|
expect(another_personal_message.topic_allowed_users.where(user_id: evil_trout.id).count).to eq(1)
|
|
expect(another_personal_message.topic_allowed_users.where(user_id: regular_user.id).count).to eq(1)
|
|
end
|
|
|
|
it "does not allow moving regular topic posts in personal message" do
|
|
topic = Fabricate(:topic, created_at: 4.hours.ago)
|
|
|
|
expect {
|
|
personal_message.move_posts(admin, [p2.id, p5.id], destination_topic_id: topic.id)
|
|
}.to raise_error(Discourse::InvalidParameters)
|
|
end
|
|
|
|
it "moving all posts will close the message" do
|
|
moved_to = personal_message.move_posts(admin, [p1.id, p2.id, p3.id, p4.id, p5.id], destination_topic_id: another_personal_message.id, archetype: "private_message")
|
|
expect(moved_to).to be_present
|
|
|
|
personal_message.reload
|
|
expect(personal_message.closed).to eq(true)
|
|
expect(moved_to.posts_count).to eq(6)
|
|
end
|
|
|
|
it "uses the correct small action post" do
|
|
moved_to = personal_message.move_posts(admin, [p2.id], destination_topic_id: another_personal_message.id, archetype: "private_message")
|
|
post = Post.find_by(topic_id: personal_message.id, post_type: Post.types[:whisper])
|
|
|
|
expected_text = I18n.t(
|
|
"move_posts.existing_message_moderator_post",
|
|
count: 1,
|
|
topic_link: "[#{moved_to.title}](#{p2.reload.url})",
|
|
locale: :en
|
|
)
|
|
|
|
expect(post.raw).to eq(expected_text)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'banner topic' do
|
|
fab!(:regular_user) { Fabricate(:trust_level_4) }
|
|
fab!(:topic) { Fabricate(:topic) }
|
|
fab!(:personal_message) { Fabricate(:private_message_topic, user: regular_user) }
|
|
fab!(:banner_topic) { Fabricate(:banner_topic, user: evil_trout) }
|
|
fab!(:p1) { Fabricate(:post, topic: banner_topic, user: evil_trout) }
|
|
fab!(:p2) { Fabricate(:post, topic: banner_topic, reply_to_post_number: p1.post_number, user: regular_user) }
|
|
|
|
context 'move to existing topic' do
|
|
it "allows moving banner topic posts in regular topic" do
|
|
banner_topic.move_posts(admin, [p2.id], destination_topic_id: topic.id)
|
|
expect(p2.reload.topic_id).to eq(topic.id)
|
|
end
|
|
|
|
it "does not allow moving banner topic posts in personal message" do
|
|
expect {
|
|
banner_topic.move_posts(admin, [p2.id], destination_topic_id: personal_message.id)
|
|
}.to raise_error(Discourse::InvalidParameters)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|