FIX: Delete internal links when moderator deletes a post (#13233)

FIX: Delete internal links when moderator deletes a post (#13233)

diff --git a/app/models/topic_link.rb b/app/models/topic_link.rb
index 516c5f3..1770ea7 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 750fa55..60662b8 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 18297c0..a5ae57d 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 c1a1171..b6f6f1c 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

GitHub sha: 4d4c3fe1

This commit appears in #13233 which was approved by eviltrout. It was merged by pmusaraj.