From 4d4c3fe1e421e91eb9aa1dd30da88f0715f0bd53 Mon Sep 17 00:00:00 2001 From: Penar Musaraj Date: Tue, 1 Jun 2021 14:02:53 -0400 Subject: [PATCH] FIX: Delete internal links when moderator deletes a post (#13233) --- app/models/topic_link.rb | 2 +- lib/post_destroyer.rb | 1 + spec/components/post_destroyer_spec.rb | 37 ++++++++++++++++++++++++++ spec/models/topic_link_spec.rb | 16 +++++++++++ 4 files changed, 55 insertions(+), 1 deletion(-) diff --git a/app/models/topic_link.rb b/app/models/topic_link.rb index 516c5f32bc3..1770ea7ed48 100644 --- a/app/models/topic_link.rb +++ b/app/models/topic_link.rb @@ -108,7 +108,7 @@ class TopicLink < ActiveRecord::Base end def self.extract_from(post) - return if post.blank? || post.whisper? || post.user_id.blank? + return if post.blank? || post.whisper? || post.user_id.blank? || post.deleted_at.present? current_urls = [] reflected_ids = [] diff --git a/lib/post_destroyer.rb b/lib/post_destroyer.rb index 750fa55a6e5..60662b85cc1 100644 --- a/lib/post_destroyer.rb +++ b/lib/post_destroyer.rb @@ -168,6 +168,7 @@ class PostDestroyer permanent? ? @post.topic.destroy! : @post.topic.trash!(@user) PublishedPage.unpublish!(@user, @post.topic) if @post.topic.published_page end + TopicLink.where(link_post_id: @post.id).destroy_all update_associated_category_latest_topic update_user_counts TopicUser.update_post_action_cache(post_id: @post.id) diff --git a/spec/components/post_destroyer_spec.rb b/spec/components/post_destroyer_spec.rb index 18297c020b1..a5ae57d487a 100644 --- a/spec/components/post_destroyer_spec.rb +++ b/spec/components/post_destroyer_spec.rb @@ -938,6 +938,43 @@ describe PostDestroyer do end end + describe 'internal links' do + fab!(:topic) { Fabricate(:topic) } + let!(:second_post) { Fabricate(:post, topic: topic) } + fab!(:other_topic) { Fabricate(:topic) } + let!(:other_post) { Fabricate(:post, topic: other_topic) } + fab!(:user) { Fabricate(:user) } + let!(:base_url) { URI.parse(Discourse.base_url) } + let!(:guardian) { Guardian.new } + let!(:url) { "http://#{base_url.host}/t/#{other_topic.slug}/#{other_topic.id}/#{other_post.post_number}" } + + it 'should destroy internal links when user deletes own post' do + new_post = Post.create!(user: user, topic: topic, raw: "Link to other topic:\n\n#{url}\n") + TopicLink.extract_from(new_post) + + link_counts = TopicLink.counts_for(guardian, other_topic.reload, [other_post]) + expect(link_counts.count).to eq(1) + + PostDestroyer.new(user, new_post).destroy + + updated_link_counts = TopicLink.counts_for(guardian, other_topic.reload, [other_post]) + expect(updated_link_counts.count).to eq(0) + end + + it 'should destroy internal links when moderator deletes post' do + new_post = Post.create!(user: user, topic: topic, raw: "Link to other topic:\n\n#{url}\n") + TopicLink.extract_from(new_post) + link_counts = TopicLink.counts_for(guardian, other_topic.reload, [other_post]) + expect(link_counts.count).to eq(1) + + PostDestroyer.new(moderator, new_post).destroy + TopicLink.extract_from(new_post) + updated_link_counts = TopicLink.counts_for(guardian, other_topic, [other_post]) + + expect(updated_link_counts.count).to eq(0) + end + end + describe '#delete_with_replies' do let(:reporter) { Discourse.system_user } fab!(:post) { Fabricate(:post) } diff --git a/spec/models/topic_link_spec.rb b/spec/models/topic_link_spec.rb index c1a11711a7e..b6f6f1c9790 100644 --- a/spec/models/topic_link_spec.rb +++ b/spec/models/topic_link_spec.rb @@ -107,6 +107,7 @@ describe TopicLink do fab!(:other_topic) do Fabricate(:topic, user: user) end + fab!(:moderator) { Fabricate(:moderator) } let(:post) do other_topic.posts.create(user: user, raw: "some content") @@ -185,6 +186,21 @@ describe TopicLink do expect(reflection.link_post_id).to eq(linked_post.id) expect(reflection.user_id).to eq(link.user_id) end + + it "doesn't work for a deleted post" do + post + url = "http://#{test_uri.host}/t/#{other_topic.slug}/#{other_topic.id}" + + topic.posts.create(user: user, raw: 'initial post') + linked_post = topic.posts.create(user: user, raw: "Link to another topic: #{url}") + TopicLink.extract_from(linked_post) + expect(other_topic.reload.topic_links.where(link_post_id: linked_post.id).count).to eq(1) + + PostDestroyer.new(moderator, linked_post).destroy + TopicLink.extract_from(linked_post) + expect(other_topic.reload.topic_links.where(link_post_id: linked_post.id)).to be_blank + + end end context "link to a user on discourse" do