From ddf591963e2f1f3e8d10a230683ee180720469f2 Mon Sep 17 00:00:00 2001
From: Angie Byron <webchick@24967.no-reply.drupal.org>
Date: Tue, 8 Dec 2009 06:33:11 +0000
Subject: [PATCH] #520740 by marcingy, catch, and Damien Tournoud: Fixed
 Comment threading (with test).

---
 includes/entity.inc          |  20 +++----
 modules/comment/comment.test | 100 +++++++++++++++++++++++++++++++++++
 2 files changed, 110 insertions(+), 10 deletions(-)

diff --git a/includes/entity.inc b/includes/entity.inc
index 06334cceedcf..5808bc6623dc 100644
--- a/includes/entity.inc
+++ b/includes/entity.inc
@@ -100,7 +100,6 @@ public function load($ids = array(), $conditions = array()) {
       $this->revisionId = FALSE;
     }
 
-
     // Create a new variable which is either a prepared version of the $ids
     // array for later comparison with the entity cache, or FALSE if no $ids
     // were passed. The $ids array is reduced as items are loaded from cache,
@@ -141,16 +140,17 @@ public function load($ids = array(), $conditions = array()) {
       if (!empty($queried_entities) && !$this->revisionId) {
         $this->cacheSet($queried_entities);
       }
-      // Ensure that the returned array is ordered the same as the original
-      // $ids array if this was passed in and remove any invalid ids.
-      if ($passed_ids) {
-        // Remove any invalid ids from the array.
-        $passed_ids = array_intersect_key($passed_ids, $entities);
-        foreach ($entities as $entity) {
-          $passed_ids[$entity->{$this->idKey}] = $entity;
-        }
-        $entities = $passed_ids;
+    }
+
+    // Ensure that the returned array is ordered the same as the original
+    // $ids array if this was passed in and remove any invalid ids.
+    if ($passed_ids) {
+      // Remove any invalid ids from the array.
+      $passed_ids = array_intersect_key($passed_ids, $entities);
+      foreach ($entities as $entity) {
+        $passed_ids[$entity->{$this->idKey}] = $entity;
       }
+      $entities = $passed_ids;
     }
 
     return $entities;
diff --git a/modules/comment/comment.test b/modules/comment/comment.test
index 3d2db380799e..047cb91b390f 100644
--- a/modules/comment/comment.test
+++ b/modules/comment/comment.test
@@ -660,6 +660,106 @@ class CommentPagerTest extends CommentHelperCase {
 
     $this->drupalLogout();
   }
+
+  /**
+   * Test comment ordering and threading.
+   */
+  function testCommentOrderingThreading() {
+    $this->drupalLogin($this->admin_user);
+
+    // Set comment variables.
+    $this->setCommentForm(TRUE);
+    $this->setCommentSubject(TRUE);
+    $this->setCommentPreview(FALSE);
+
+    // Display all the comments on the same page.
+    $this->setCommentsPerPage(1000);
+
+    // Create a node and three comments.
+    $node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1));
+    $comments = array();
+    $comments[] = $this->postComment($node, $this->randomName(), $this->randomName(), TRUE);
+    $comments[] = $this->postComment($node, $this->randomName(), $this->randomName(), TRUE);
+    $comments[] = $this->postComment($node, $this->randomName(), $this->randomName(), TRUE);
+
+    // Post a reply to the second comment.
+    $this->drupalGet('comment/reply/' . $node->nid . '/' . $comments[1]->id);
+    $comments[] = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE);
+
+    // Post a reply to the first comment.
+    $this->drupalGet('comment/reply/' . $node->nid . '/' . $comments[0]->id);
+    $comments[] = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE);
+
+    // Post a reply to the last comment.
+    $this->drupalGet('comment/reply/' . $node->nid . '/' . $comments[2]->id);
+    $comments[] = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE);
+
+    // Post a reply to the second comment.
+    $this->drupalGet('comment/reply/' . $node->nid . '/' . $comments[3]->id);
+    $comments[] = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE);
+
+    // At this point, the comment tree is:
+    // - 0
+    //   - 4
+    // - 1
+    //   - 3
+    //     - 6
+    // - 2
+    //   - 5
+
+    $this->setCommentSettings('comment_default_mode', COMMENT_MODE_FLAT, t('Comment paging changed.'));
+
+    $expected_order = array(
+      0,
+      1,
+      2,
+      3,
+      4,
+      5,
+      6,
+    );
+    $this->drupalGet('node/' . $node->nid);
+    $this->assertCommentOrder($comments, $expected_order);
+
+    $this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, t('Switched to threaded mode.'));
+
+    $expected_order = array(
+      0,
+      4,
+      1,
+      3,
+      6,
+      2,
+      5,
+    );
+    $this->drupalGet('node/' . $node->nid);
+    $this->assertCommentOrder($comments, $expected_order);
+  }
+
+  /**
+   * Helper function: assert that the comments are displayed in the correct order.
+   *
+   * @param $comments
+   *   And array of comments.
+   * @param $expected_order
+   *   An array of keys from $comments describing the expected order.
+   */
+  function assertCommentOrder(array $comments, array $expected_order) {
+    $expected_cids = array();
+
+    // First, rekey the expected order by cid.
+    foreach ($expected_order as $key) {
+      $expected_cids[] = $comments[$key]->id;
+    }
+
+    $comment_anchors = $this->xpath("//a[starts-with(@id,'comment-')]");
+    $result_order = array();
+    foreach ($comment_anchors as $anchor) {
+      $result_order[] = substr($anchor['id'], 8);
+    }
+
+    return $this->assertIdentical($expected_cids, $result_order, t('Comment order: expected @expected, returned @returned.', array('@expected' => implode(',', $expected_cids), '@returned' => implode(',', $result_order))));
+  }
 }
 
 class CommentApprovalTest extends CommentHelperCase {
-- 
GitLab