Index: modules/comment/comment.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.test,v
retrieving revision 1.92
diff -u -p -r1.92 comment.test
--- modules/comment/comment.test	8 Nov 2010 21:36:45 -0000	1.92
+++ modules/comment/comment.test	27 Nov 2010 22:16:49 -0000
@@ -261,7 +261,7 @@ class CommentInterfaceTest extends Comme
   /**
    * Test comment interface.
    */
-  function testCommentInterface() {
+  function xtestCommentInterface() {
     $langcode = LANGUAGE_NONE;
     // Set comments to have subject and preview disabled.
     $this->drupalLogin($this->admin_user);
@@ -394,7 +394,7 @@ class CommentInterfaceTest extends Comme
   /**
    * Tests the node comment statistics.
    */
-  function testCommentNodeCommentStatistics() {
+  function xtestCommentNodeCommentStatistics() {
     $langcode = LANGUAGE_NONE;
     // Set comments to have subject and preview disabled.
     $this->drupalLogin($this->admin_user);
@@ -473,6 +473,241 @@ class CommentInterfaceTest extends Comme
     $this->assertEqual($node->last_comment_uid, 0, t('The value of node last_comment_uid is zero.'));
     $this->assertEqual($node->comment_count, 2, t('The value of node comment_count is 2.'));
   }
+
+  /**
+   * Tests comment links.
+   *
+   * This test verifies whether the expected comment links are output.
+   *
+   * The output of those links depends on two fundamentally different categories
+   * of environment conditions:
+   * - Internal conditions: Various Comment module configuration settings and
+   *   user access permissions.
+   * - External conditions: Whether the user is authenticated or not, and
+   *   whether any comments exist.
+   *
+   * To account for all possible cases, this test implements two matrixes, one
+   * for configuration conditions, and another one for environmental conditions.
+   * Since the expected behavior of comment links is different for each
+   * environment, each set of configuration settings needs to be checked against
+   * each set of environmental conditions.
+   *
+   * The matrixes leverage the fact that most environment/configuration settings
+   * can be expressed in 0 or 1.
+   */
+  function testCommentLinks() {
+    // Bartik theme alters comment links, so use a different.
+    theme_enable(array('garland'));
+    variable_set('theme_default', 'garland');
+
+    // Remove additional user permissions from $this->web_user added by setUp(),
+    // since this test is limited to anonymous and authenticated roles only.
+    // @todo Standard installation profile grants authenticated users
+    //   permissions to view and post comments by default, which should have an
+    //   impact on "log in or register to post" links for anonymous users.
+    user_role_delete(key($this->web_user->roles));
+
+    // Matrix of possible configuration settings.
+    $configuration = array(
+      'access comments' => array(0, 1, 0, 0, 1, 0, 1),
+      'post comments'   => array(0, 0, 1, 0, 1, 1, 1),
+      'form'            => array(0, 0, 0, 1, 0, 1, 1),
+      // @todo 0, 1, 2 -- ugh. Later... ;)
+     #'comments'        => array(),
+    );
+
+    // Matrix of possible environment conditions.
+    $conditions = array(
+      'authenticated' => array(0, 1, 0, 1),
+      'comment count' => array(0, 0, 1, 1),
+    );
+
+    // Iterate through conditions matrix.
+    while (current($conditions['authenticated']) !== FALSE) {
+      // For each new environment condition column, start from scratch.
+      $condition_info = array();
+
+      // Use the next column of environment conditions.
+      foreach ($conditions as $condition => $condition_values) {
+        $condition_info[$condition] = current($conditions[$condition]);
+        next($conditions[$condition]);
+      }
+
+      // Iterate through configuration matrix.
+      while (current($configuration['access comments']) !== FALSE) {
+        // Use current environment conditions as base for each column of the
+        // configuration settings.
+        $info = $condition_info;
+
+        // Use the next column of configuration settings.
+        foreach ($configuration as $setting => $setting_values) {
+          $info[$setting] = current($configuration[$setting]);
+          next($configuration[$setting]);
+        }
+
+        // Lastly, perform the comment link assertions.
+        $this->assertCommentLinks($info);
+      }
+
+      // Reset configuration matrix array pointers, so we can iterate over it
+      // again for the next column of environment conditions.
+      foreach ($configuration as $setting => $setting_values) {
+        reset($configuration[$setting]);
+      }
+    }
+  }
+
+  /**
+   * Re-configures comment settings and user permissions.
+   *
+   * @param $info
+   *   An associative array describing the environment to setup.
+   *   Environment conditions:
+   *   - authenticated: 0 or 1. A change to a previously passed value triggers
+   *     a login or logout of $this->web_user accordingly.
+   *   - comment count: 0 or 1. A change to a previously passed value triggers
+   *     the creation or deletion of a comment on $this->node accordingly.
+   *   Configuration settings:
+   *   - form: COMMENT_FORM_BELOW or COMMENT_FORM_SEPARATE_PAGE.
+   *   - contact: COMMENT_ANONYMOUS_MAY_CONTACT,
+   *     COMMENT_ANONYMOUS_MAYNOT_CONTACT, or COMMENT_ANONYMOUS_MUST_CONTACT.
+   *   - comments: COMMENT_NODE_OPEN, COMMENT_NODE_CLOSED, or
+   *     COMMENT_NODE_HIDDEN.
+   *   User permissions:
+   *   - access comments: 0 or 1. Grants or revokes access for the currently
+   *     logged in user.
+   *   - post comments: 0 or 1. Grants or revokes access for the currently
+   *     logged in user.
+   *   - skip comment approval: 0 or 1. Grants or revokes access for the
+   *     currently logged in user.
+   *   - edit own comments: 0 or 1. Grants or revokes access for the currently
+   *     logged in user.
+   */
+  function setEnvironment(array $info) {
+    static $current;
+
+    // Apply defaults to initial environment.
+    if (!isset($current)) {
+      $current = array(
+        'authenticated' => 0,
+        'comment count' => 0,
+        'access comments' => 0,
+        'post comments' => 0,
+        'form' => COMMENT_FORM_BELOW,
+        'contact' => COMMENT_ANONYMOUS_MAY_CONTACT,
+        'comments' => COMMENT_NODE_OPEN,
+        // Enabled by default, because it's irrelevant for this test.
+        'skip comment approval' => 1,
+        'edit own comments' => 0,
+      );
+    }
+    // Complete new environment with current environment.
+    $info = array_merge($current, $info);
+
+    // Change environment conditions.
+    if ($current['authenticated'] != $info['authenticated']) {
+      if ($this->loggedInUser) {
+        $this->drupalLogout();
+      }
+      else {
+        $this->drupalLogin($this->web_user);
+      }
+    }
+    if ($current['comment count'] != $info['comment count']) {
+      if ($info['comment count']) {
+        $this->postComment($this->node, $this->randomString(), $this->randomName());
+      }
+      else {
+        $cids = db_query("SELECT cid FROM {comment}")->fetchCol();
+        comment_delete_multiple($cids);
+      }
+    }
+
+    // Change comment settings.
+    variable_set('comment_form_location_' . $this->node->type, $info['form']);
+    variable_set('comment_anonymous_' . $this->node->type, $info['contact']);
+    if ($this->node->comment != $info['comments']) {
+      $this->node->comment = $info['comments'];
+      node_save($this->node);
+    }
+
+    // Change user permissions.
+    $rid = ($this->loggedInUser ? DRUPAL_AUTHENTICATED_RID : DRUPAL_ANONYMOUS_RID);
+    $perms = array_intersect_key($info, array('access comments' => 1, 'post comments' => 1, 'skip comment approval' => 1, 'edit own comments' => 1));
+    user_role_change_permissions($rid, $perms);
+
+    // Output verbose debugging information.
+    // @see DrupalTestCase::error()
+    $t_form = array(
+      COMMENT_FORM_BELOW => 'below',
+      COMMENT_FORM_SEPARATE_PAGE => 'separate page',
+    );
+    $t_contact = array(
+      COMMENT_ANONYMOUS_MAY_CONTACT => 'optional',
+      COMMENT_ANONYMOUS_MAYNOT_CONTACT => 'disabled',
+      COMMENT_ANONYMOUS_MUST_CONTACT => 'required',
+    );
+    $t_comments = array(
+      COMMENT_NODE_OPEN => 'open',
+      COMMENT_NODE_CLOSED => 'closed',
+      COMMENT_NODE_HIDDEN => 'hidden',
+    );
+    $verbose = $info;
+    $verbose['form'] = $t_form[$info['form']];
+    $verbose['contact'] = $t_contact[$info['contact']];
+    $verbose['comments'] = $t_comments[$info['comments']];
+    $message = t('Changed environment for role @rid:<pre>@verbose</pre>', array(
+      '@rid' => $rid,
+      '@verbose' => var_export($verbose, TRUE),
+    ));
+    $this->assert('debug', $message, 'Debug');
+
+    // Update current environment.
+    $current = $info;
+
+    return $info;
+  }
+
+  /**
+   * Asserts that comment links appear according to the passed environment setup.
+   *
+   * @param $info
+   *   An associative array describing the environment to pass to
+   *   setEnvironment().
+   */
+  function assertCommentLinks(array $info) {
+    $info = $this->setEnvironment($info);
+
+    $nid = $this->node->nid;
+
+    foreach (array('', "node/$nid") as $path) {
+      $this->drupalGet($path);
+
+      // Posting comments is not allowed.
+      if (!$info['post comments']) {
+        $this->assertNoLink('Add new comment');
+        // Anonymous users should see a note to log in or register in case
+        // authenticated users are allowed to post comments.
+        if (!$this->loggedInUser) {
+          if (user_access('post comments', $this->web_user)) {
+            $this->assertText('Log in or register to post comments');
+          }
+          else {
+            $this->assertNoText('Log in or register to post comments');
+          }
+        }
+      }
+      // Posting comments is allowed.
+      else {
+        $this->assertLink('Add new comment');
+        $this->assertNoText('Log in or register to post comments');
+        if ($path == "node/$nid" && $info['form'] == COMMENT_FORM_BELOW) {
+          $elements = $this->xpath('//form[@id=:id]', array(':id' => 'comment-form'));
+          $this->assertTrue(count($elements), t('Comment form found.'));
+        }
+      }
+    }
+  }
 }
 
 /**
