'Comment links', 'description' => 'Tests comment links based on environment configurations.', 'group' => 'Comment', ); } /** * Tests comment links. * * The output of comment links depends on various environment conditions: * - Various Comment module configuration settings, user registration * settings, and user access permissions. * - Whether the user is authenticated or not, and whether any comments exist. * * To account for all possible cases, this test creates permutations of all * possible conditions and tests the expected appearance of comment links in * each environment. */ function testCommentLinks() { // Bartik theme alters comment links, so use a different theme. theme_enable(array('stark')); variable_set('theme_default', 'stark'); // Remove additional user permissions from $this->web_user added by setUp(), // since this test is limited to anonymous and authenticated roles only. entity_delete_multiple('user_role', array(key($this->web_user->roles))); // Matrix of possible environmental conditions and configuration settings. // See setEnvironment() for details. $conditions = array( 'authenticated' => array(FALSE, TRUE), 'comment count' => array(FALSE, TRUE), 'access comments' => array(0, 1), 'post comments' => array(0, 1), 'form' => array(COMMENT_FORM_BELOW, COMMENT_FORM_SEPARATE_PAGE), // USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL is irrelevant for this // test; there is only a difference between open and closed registration. 'user_register' => array(USER_REGISTER_VISITORS, USER_REGISTER_ADMINISTRATORS_ONLY), // @todo Complete test coverage for: //'comments' => array(COMMENT_NODE_OPEN, COMMENT_NODE_CLOSED, COMMENT_NODE_HIDDEN), //// COMMENT_ANONYMOUS_MUST_CONTACT is irrelevant for this test. //'contact ' => array(COMMENT_ANONYMOUS_MAY_CONTACT, COMMENT_ANONYMOUS_MAYNOT_CONTACT), ); $environments = $this->generatePermutations($conditions); foreach ($environments as $info) { $this->assertCommentLinks($info); } } /** * Re-configures the environment, module settings, and user permissions. * * @param $info * An associative array describing the environment to setup: * - Environment conditions: * - authenticated: Boolean whether to test with $this->web_user or * anonymous. * - comment count: Boolean whether to test with a new/unread comment on * $this->node or no comments. * - Configuration settings: * - form: COMMENT_FORM_BELOW or COMMENT_FORM_SEPARATE_PAGE. * - user_register: USER_REGISTER_ADMINISTRATORS_ONLY or * USER_REGISTER_VISITORS. * - contact: COMMENT_ANONYMOUS_MAY_CONTACT or * COMMENT_ANONYMOUS_MAYNOT_CONTACT. * - comments: COMMENT_NODE_OPEN, COMMENT_NODE_CLOSED, or * COMMENT_NODE_HIDDEN. * - User permissions: * These are granted or revoked for the user, according to the * 'authenticated' flag above. Pass 0 or 1 as parameter values. See * user_role_change_permissions(). * - access comments * - post comments * - skip comment approval * - edit own comments */ function setEnvironment(array $info) { static $current; // Apply defaults to initial environment. if (!isset($current)) { $current = array( 'authenticated' => FALSE, 'comment count' => FALSE, 'form' => COMMENT_FORM_BELOW, 'user_register' => USER_REGISTER_VISITORS, 'contact' => COMMENT_ANONYMOUS_MAY_CONTACT, 'comments' => COMMENT_NODE_OPEN, 'access comments' => 0, 'post comments' => 0, // 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']) { // Create a comment via CRUD API functionality, since // $this->postComment() relies on actual user permissions. $comment = entity_create('comment', array( 'cid' => NULL, 'nid' => $this->node->nid, 'node_type' => $this->node->type, 'pid' => 0, 'uid' => 0, 'status' => COMMENT_PUBLISHED, 'subject' => $this->randomName(), 'hostname' => ip_address(), 'langcode' => LANGUAGE_NOT_SPECIFIED, 'comment_body' => array(LANGUAGE_NOT_SPECIFIED => array($this->randomName())), )); comment_save($comment); $this->comment = $comment; // comment_num_new() relies on history_read(), so ensure that no one has // seen the node of this comment. db_delete('history')->condition('nid', $this->node->nid)->execute(); } else { $cids = db_query("SELECT cid FROM {comment}")->fetchCol(); comment_delete_multiple($cids); unset($this->comment); } } // 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 settings. config('user.settings')->set('register', $info['user_register'])->save(); // 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 Drupal\simpletest\TestBase::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:
@verbose
', array( '@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. * * @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', "node/$nid") as $path) { $this->drupalGet($path); // User is allowed to view comments. if ($info['access comments']) { if ($path == '') { // In teaser view, a link containing the comment count is always // expected. if ($info['comment count']) { $this->assertLink(t('1 comment')); // For logged in users, a link containing the amount of new/unread // comments is expected. // See important note about comment_num_new() below. if ($this->loggedInUser && isset($this->comment) && !isset($this->comment->seen)) { $this->assertLink(t('1 new comment')); $this->comment->seen = TRUE; } } } } else { $this->assertNoLink(t('1 comment')); $this->assertNoLink(t('1 new comment')); } // comment_num_new() is based on node views, so comments are marked as // read when a node is viewed, regardless of whether we have access to // comments. if ($path == "node/$nid" && $this->loggedInUser && isset($this->comment)) { $this->comment->seen = TRUE; } // User is not allowed to post comments. 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. // @see theme_comment_post_forbidden() if (!$this->loggedInUser) { if (user_access('post comments', $this->web_user)) { // The note depends on whether users are actually able to register. if ($info['user_register'] != USER_REGISTER_ADMINISTRATORS_ONLY) { $this->assertText('Log in or register to post comments'); } else { $this->assertText('Log in to post comments'); } } else { $this->assertNoText('Log in or register to post comments'); $this->assertNoText('Log in to post comments'); } } } // User is allowed to post comments. else { $this->assertNoText('Log in or register to post comments'); // "Add new comment" is always expected, except when there are no // comments or if the user cannot see them. if ($path == "node/$nid" && $info['form'] == COMMENT_FORM_BELOW && (!$info['comment count'] || !$info['access comments'])) { $this->assertNoLink('Add new comment'); } else { $this->assertLink('Add new comment'); // Verify that the "Add new comment" link points to the correct URL // based on the comment form location configuration. if ($info['form'] == COMMENT_FORM_SEPARATE_PAGE) { $this->assertLinkByHref("comment/reply/$nid#comment-form", 0, 'Comment form link destination is on a separate page.'); $this->assertNoLinkByHref("node/$nid#comment-form"); } else { $this->assertLinkByHref("node/$nid#comment-form", 0, 'Comment form link destination is on node.'); $this->assertNoLinkByHref("comment/reply/$nid#comment-form"); } } // Also verify that the comment form appears according to the configured // location. if ($path == "node/$nid") { $elements = $this->xpath('//form[@id=:id]', array(':id' => 'comment-form')); if ($info['form'] == COMMENT_FORM_BELOW) { $this->assertTrue(count($elements), 'Comment form found below.'); } else { $this->assertFalse(count($elements), 'Comment form not found below.'); } } } } } }