FIX: prevent 💥 when selecting replies to posts quoting themselves

This commit is contained in:
Régis Hanol 2017-12-15 00:23:51 +01:00
parent 32d881399f
commit 092c976d7c
2 changed files with 8 additions and 1 deletions

View File

@ -654,6 +654,8 @@ class Post < ActiveRecord::Base
Post.secured(guardian).where(id: post_ids).includes(:user, :topic).order(:id).to_a Post.secured(guardian).where(id: post_ids).includes(:user, :topic).order(:id).to_a
end end
MAX_REPLY_LEVEL ||= 1000
def reply_ids(guardian = nil) def reply_ids(guardian = nil)
replies = Post.exec_sql(" replies = Post.exec_sql("
WITH RECURSIVE breadcrumb(id, level) AS ( WITH RECURSIVE breadcrumb(id, level) AS (
@ -662,6 +664,8 @@ class Post < ActiveRecord::Base
SELECT reply_id, level + 1 SELECT reply_id, level + 1
FROM post_replies, breadcrumb FROM post_replies, breadcrumb
WHERE post_id = id WHERE post_id = id
AND post_id <> reply_id
AND level < #{MAX_REPLY_LEVEL}
), breadcrumb_with_count AS ( ), breadcrumb_with_count AS (
SELECT id, level, COUNT(*) SELECT id, level, COUNT(*)
FROM post_replies, breadcrumb FROM post_replies, breadcrumb

View File

@ -786,6 +786,7 @@ describe Post do
let!(:p4) { Fabricate(:post, topic: topic, post_number: 4, reply_to_post_number: 2) } let!(:p4) { Fabricate(:post, topic: topic, post_number: 4, reply_to_post_number: 2) }
let!(:p5) { Fabricate(:post, topic: topic, post_number: 5, reply_to_post_number: 4) } let!(:p5) { Fabricate(:post, topic: topic, post_number: 5, reply_to_post_number: 4) }
let!(:p6) { Fabricate(:post, topic: topic, post_number: 6) } let!(:p6) { Fabricate(:post, topic: topic, post_number: 6) }
let!(:p7) { Fabricate(:post, topic: topic, post_number: 7) }
before { before {
PostReply.create!(post: p1, reply: p2) PostReply.create!(post: p1, reply: p2)
@ -793,6 +794,7 @@ describe Post do
PostReply.create!(post: p2, reply: p6) # simulates p6 quoting p2 PostReply.create!(post: p2, reply: p6) # simulates p6 quoting p2
PostReply.create!(post: p3, reply: p5) # simulates p5 quoting p3 PostReply.create!(post: p3, reply: p5) # simulates p5 quoting p3
PostReply.create!(post: p4, reply: p5) PostReply.create!(post: p4, reply: p5)
PostReply.create!(post: p7, reply: p7) # https://meta.discourse.org/t/topic-quoting-itself-displays-reply-indicator/76085
} }
it "returns the reply ids and their level" do it "returns the reply ids and their level" do
@ -801,7 +803,8 @@ describe Post do
expect(p3.reply_ids).to be_empty # has no replies expect(p3.reply_ids).to be_empty # has no replies
expect(p4.reply_ids).to be_empty # p5 replies to 2 posts (p4 and p3) expect(p4.reply_ids).to be_empty # p5 replies to 2 posts (p4 and p3)
expect(p5.reply_ids).to be_empty # has no replies expect(p5.reply_ids).to be_empty # has no replies
expect(p6.reply_ids).to be_empty # last post expect(p6.reply_ids).to be_empty # has no replies
expect(p7.reply_ids).to be_empty # quotes itself
end end
end end