discourse/spec/services/post_owner_changer_spec.rb

255 lines
8.9 KiB
Ruby

# frozen_string_literal: true
RSpec.describe PostOwnerChanger do
describe "change_owner!" do
fab!(:editor) { Fabricate(:admin) }
fab!(:user_a) { Fabricate(:user) }
let(:p1) { create_post(post_number: 1) }
let(:topic) { p1.topic }
let(:p2) { create_post(topic: topic, post_number: 2) }
let(:p3) { create_post }
it "raises an error with a parameter missing" do
expect {
PostOwnerChanger.new(post_ids: [p1.id], topic_id: topic.id, new_owner: nil, acting_user: editor)
}.to raise_error(ArgumentError, /new_owner/)
end
it "calls PostRevisor" do
PostRevisor.any_instance.expects(:revise!)
PostOwnerChanger.new(post_ids: [p1.id], topic_id: topic.id, new_owner: user_a, acting_user: editor).change_owner!
end
it "changes the user" do
bumped_at = freeze_time topic.bumped_at
now = Time.zone.now
freeze_time(now - 1.day)
old_user = p1.user
PostActionCreator.like(user_a, p1)
p1.reload
expect(p1.topic.like_count).to eq(1)
freeze_time(now)
PostOwnerChanger.new(post_ids: [p1.id], topic_id: topic.id, new_owner: user_a, acting_user: editor).change_owner!
p1.reload
expect(p1.topic.like_count).to eq(0)
expect(p1.topic.bumped_at).to eq_time(bumped_at)
expect(p1.topic.last_post_user_id).to eq(user_a.id)
expect(old_user).not_to eq(p1.user)
expect(p1.user).to eq(user_a)
end
it "changes multiple posts" do
PostOwnerChanger.new(post_ids: [p1.id, p2.id], topic_id: topic.id, new_owner: user_a, acting_user: editor).change_owner!
p1.reload; p2.reload
expect(p1.user).not_to eq(nil)
expect(p1.user).to eq(user_a)
expect(p1.user).to eq(p2.user)
end
it "ignores posts in other topics" do
PostOwnerChanger.new(post_ids: [p1.id, p3.id], topic_id: topic.id, new_owner: user_a, acting_user: editor).change_owner!
p1.reload; p3.reload
expect(p1.user).to eq(user_a)
expect(p3.topic_id).not_to eq(p1.topic_id)
expect(p2.user).not_to eq(user_a)
end
it "skips creating new post revision if skip_revision is true" do
PostOwnerChanger.new(post_ids: [p1.id, p2.id], topic_id: topic.id, new_owner: user_a, acting_user: editor, skip_revision: true).change_owner!
p1.reload; p2.reload
expect(p1.revisions.size).to eq(0)
expect(p2.revisions.size).to eq(0)
end
it "changes the user even when the post does not pass validation" do
p1.update_attribute(:raw, "foo")
PostOwnerChanger.new(post_ids: [p1.id], topic_id: topic.id, new_owner: user_a, acting_user: editor).change_owner!
expect(p1.reload.user).to eq(user_a)
end
it "changes the user even when the topic does not pass validation" do
topic.update_column(:title, "short")
PostOwnerChanger.new(post_ids: [p1.id], topic_id: topic.id, new_owner: user_a, acting_user: editor).change_owner!
expect(p1.reload.user).to eq(user_a)
end
it "changes the owner when the post is deleted" do
p4 = Fabricate(:post, topic: topic, reply_to_post_number: p2.post_number)
PostDestroyer.new(editor, p4).destroy
PostOwnerChanger.new(post_ids: [p4.id], topic_id: topic.id, new_owner: user_a, acting_user: editor).change_owner!
expect(p4.reload.user).to eq(user_a)
end
it "sets 'posted' for TopicUser to true" do
PostOwnerChanger.new(post_ids: [p1.id], topic_id: topic.id, new_owner: user_a, acting_user: editor).change_owner!
expect(TopicUser.find_by(topic_id: topic.id, user_id: user_a.id).posted).to eq(true)
end
context "sets topic notification level for the new owner" do
let(:p4) { create_post(post_number: 2, topic: topic) }
it "'watching' if the first post gets a new owner" do
PostOwnerChanger.new(post_ids: [p1.id], topic_id: topic.id, new_owner: user_a, acting_user: editor).change_owner!
tu = TopicUser.find_by(user_id: user_a.id, topic_id: topic.id)
expect(tu.notification_level).to eq(3)
end
it "'tracking' if other than the first post gets a new owner" do
PostOwnerChanger.new(post_ids: [p4.id], topic_id: topic.id, new_owner: user_a, acting_user: editor).change_owner!
tu = TopicUser.find_by(user_id: user_a.id, topic_id: topic.id)
expect(tu.notification_level).to eq(2)
end
end
context "integration tests" do
let(:p1user) { p1.user }
let(:p2user) { p2.user }
before do
topic.update!(user_id: p1user.id)
p1user.user_stat.update!(
topic_count: 1,
post_count: 0,
first_post_created_at: p1.created_at,
)
p2user.user_stat.update!(
topic_count: 0,
post_count: 1,
first_post_created_at: p2.created_at,
)
UserAction.create!(action_type: UserAction::NEW_TOPIC, user_id: p1user.id, acting_user_id: p1user.id,
target_post_id: -1, target_topic_id: p1.topic_id, created_at: p1.created_at)
UserAction.create!(action_type: UserAction::REPLY, user_id: p2user.id, acting_user_id: p2user.id,
target_post_id: p2.id, target_topic_id: p2.topic_id, created_at: p2.created_at)
UserActionManager.enable
end
subject(:change_owners) do
PostOwnerChanger.new(
post_ids: [p1.id, p2.id],
topic_id: topic.id,
new_owner: user_a,
acting_user: editor
).change_owner!
end
it "updates users' topic and post counts" do
PostActionCreator.like(p2user, p1)
expect(p1user.user_stat.reload.likes_received).to eq(1)
change_owners
p1user.reload; p2user.reload; user_a.reload
expect(p1user.topic_count).to eq(0)
expect(p1user.post_count).to eq(0)
expect(p2user.topic_count).to eq(0)
expect(p2user.post_count).to eq(0)
expect(user_a.topic_count).to eq(1)
expect(user_a.post_count).to eq(1)
p1_user_stat = p1user.user_stat
expect(p1_user_stat.first_post_created_at).to eq(nil)
expect(p1_user_stat.likes_received).to eq(0)
p2_user_stat = p2user.user_stat
expect(p2_user_stat.first_post_created_at).to eq(nil)
user_a_stat = user_a.user_stat
expect(user_a_stat.first_post_created_at).to be_present
expect(user_a_stat.likes_received).to eq(1)
end
it "handles whispers" do
whisper = PostCreator.new(
editor,
topic_id: p1.topic_id,
reply_to_post_number: 1,
post_type: Post.types[:whisper],
raw: 'this is a whispered reply'
).create
user_stat = editor.user_stat
expect {
PostOwnerChanger.new(
post_ids: [whisper.id],
topic_id: topic.id,
new_owner: Fabricate(:admin),
acting_user: editor
).change_owner!
}.to_not change { user_stat.reload.post_count }
end
context 'private message topic' do
# fab!(:topic) { Fabricate(:private_message_topic) }
let(:pm) do
create_post(
archetype: 'private_message',
target_usernames: [p2user.username]
)
end
let(:pm_poster) { pm.user }
it "should update users' counts" do
PostActionCreator.like(p2user, pm)
expect {
PostOwnerChanger.new(
post_ids: [pm.id],
topic_id: pm.topic_id,
new_owner: user_a,
acting_user: editor
).change_owner!
}.to_not change { pm_poster.user_stat.post_count }
expect(pm_poster.user_stat.likes_received).to eq(0)
user_a_stat = user_a.user_stat
expect(user_a_stat.first_post_created_at).to be_present
expect(user_a_stat.likes_received).to eq(0)
expect(user_a_stat.post_count).to eq(0)
end
end
it "updates UserAction records" do
g = Guardian.new(editor)
expect(UserAction.stats(user_a.id, g)).to eq([])
change_owners
expect(UserAction.stats(p1user.id, g)).to eq([])
expect(UserAction.stats(p2user.id, g)).to eq([])
stats = UserAction.stats(user_a.id, g)
expect(stats.size).to eq(2)
expect(stats[0].action_type).to eq(UserAction::NEW_TOPIC)
expect(stats[0].count).to eq(1)
expect(stats[1].action_type).to eq(UserAction::REPLY)
expect(stats[1].count).to eq(1)
end
it "updates reply_to_user_id" do
p4 = Fabricate(:post, topic: topic, reply_to_post_number: p1.post_number, reply_to_user_id: p1.user_id)
p5 = Fabricate(:post, topic: topic, reply_to_post_number: p2.post_number, reply_to_user_id: p2.user_id)
PostOwnerChanger.new(post_ids: [p1.id], topic_id: topic.id, new_owner: user_a, acting_user: editor).change_owner!
p4.reload; p5.reload
expect(p4.reply_to_user_id).to eq(user_a.id)
expect(p5.reply_to_user_id).to eq(p2.user_id)
end
end
end
end