CommentTestBase.php 12.6 KB
Newer Older
1 2 3 4
<?php

/**
 * @file
5
 * Contains \Drupal\comment\Tests\CommentTestBase.
6 7 8 9
 */

namespace Drupal\comment\Tests;

10
use Drupal\comment\Entity\CommentType;
11
use Drupal\comment\Entity\Comment;
12
use Drupal\comment\CommentInterface;
13
use Drupal\field\Entity\FieldConfig;
14
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
15 16
use Drupal\simpletest\WebTestBase;

17 18 19
/**
 * Provides setup and helper methods for comment tests.
 */
20
abstract class CommentTestBase extends WebTestBase {
21 22

  /**
23
   * Modules to install.
24 25 26
   *
   * @var array
   */
27
  public static $modules = array('comment', 'node', 'history', 'field_ui', 'datetime');
28

29 30 31
  /**
   * An administrative user with permission to configure comment settings.
   *
32
   * @var \Drupal\user\UserInterface
33
   */
34
  protected $adminUser;
35 36 37 38

  /**
   * A normal user with permission to post comments.
   *
39
   * @var \Drupal\user\UserInterface
40
   */
41
  protected $webUser;
42 43 44 45

  /**
   * A test node to which comments will be posted.
   *
46
   * @var \Drupal\node\NodeInterface
47
   */
48 49
  protected $node;

50
  protected function setUp() {
51 52
    parent::setUp();

53 54 55 56 57 58 59 60
    // Create an article content type only if it does not yet exist, so that
    // child classes may specify the standard profile.
    $types = node_type_get_types();
    if (empty($types['article'])) {
      $this->drupalCreateContentType(array('type' => 'article', 'name' => t('Article')));
    }

    // Create two test users.
61
    $this->adminUser = $this->drupalCreateUser(array(
62 63
      'administer content types',
      'administer comments',
64
      'administer comment types',
65
      'administer comment fields',
66
      'administer comment display',
67 68 69 70 71
      'skip comment approval',
      'post comments',
      'access comments',
      'access content',
     ));
72
    $this->webUser = $this->drupalCreateUser(array(
73 74 75 76 77 78 79 80
      'access comments',
      'post comments',
      'create article content',
      'edit own comments',
      'skip comment approval',
      'access content',
    ));

81 82 83
    // Create comment field on article.
    $this->container->get('comment.manager')->addDefaultField('node', 'article');

84
    // Create a test node authored by the web user.
85
    $this->node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1, 'uid' => $this->webUser->id()));
86 87 88 89 90
  }

  /**
   * Posts a comment.
   *
91 92
   * @param \Drupal\Core\Entity\EntityInterface|null $entity
   *   Node to post comment on or NULL to post to the previously loaded page.
93
   * @param string $comment
94
   *   Comment body.
95
   * @param string $subject
96
   *   Comment subject.
97
   * @param string $contact
98 99
   *   Set to NULL for no contact info, TRUE to ignore success checking, and
   *   array of values to set contact info.
100 101 102
   * @param string $field_name
   *   (optional) Field name through which the comment should be posted.
   *   Defaults to 'comment'.
103 104 105
   *
   * @return \Drupal\comment\CommentInterface|null
   *   The posted comment or NULL when posted comment was not found.
106
   */
107
  public function postComment($entity, $comment, $subject = '', $contact = NULL, $field_name = 'comment') {
108
    $edit = array();
109
    $edit['comment_body[0][value]'] = $comment;
110

111
    if ($entity !== NULL) {
112
      $field = FieldConfig::loadByName('node', $entity->bundle(), $field_name);
113 114
    }
    else {
115
      $field = FieldConfig::loadByName('node', 'article', $field_name);
116
    }
117
    $preview_mode = $field->settings['preview'];
118 119

    // Must get the page before we test for fields.
120
    if ($entity !== NULL) {
121
      $this->drupalGet('comment/reply/node/' . $entity->id() . '/' . $field_name);
122 123
    }

124 125 126 127
    // Determine the visibility of subject form field.
    if (entity_get_form_display('comment', 'comment', 'default')->getComponent('subject')) {
      // Subject input allowed.
      $edit['subject[0][value]'] = $subject;
128 129
    }
    else {
130
      $this->assertNoFieldByName('subject[0][value]', '', 'Subject field not found.');
131 132 133 134 135 136 137 138
    }

    if ($contact !== NULL && is_array($contact)) {
      $edit += $contact;
    }
    switch ($preview_mode) {
      case DRUPAL_REQUIRED:
        // Preview required so no save button should be found.
139
        $this->assertNoFieldByName('op', t('Save'), 'Save button not found.');
140
        $this->drupalPostForm(NULL, $edit, t('Preview'));
141 142 143
        // Don't break here so that we can test post-preview field presence and
        // function below.
      case DRUPAL_OPTIONAL:
144 145
        $this->assertFieldByName('op', t('Preview'), 'Preview button found.');
        $this->assertFieldByName('op', t('Save'), 'Save button found.');
146
        $this->drupalPostForm(NULL, $edit, t('Save'));
147 148 149
        break;

      case DRUPAL_DISABLED:
150 151
        $this->assertNoFieldByName('op', t('Preview'), 'Preview button not found.');
        $this->assertFieldByName('op', t('Save'), 'Save button found.');
152
        $this->drupalPostForm(NULL, $edit, t('Save'));
153 154 155 156 157 158 159 160 161 162 163 164
        break;
    }
    $match = array();
    // Get comment ID
    preg_match('/#comment-([0-9]+)/', $this->getURL(), $match);

    // Get comment.
    if ($contact !== TRUE) { // If true then attempting to find error message.
      if ($subject) {
        $this->assertText($subject, 'Comment subject posted.');
      }
      $this->assertText($comment, 'Comment body posted.');
165
      $this->assertTrue((!empty($match) && !empty($match[1])), 'Comment id found.');
166 167 168
    }

    if (isset($match[1])) {
169 170
      \Drupal::entityManager()->getStorage('comment')->resetCache(array($match[1]));
      return Comment::load($match[1]);
171 172 173 174 175 176
    }
  }

  /**
   * Checks current page for specified comment.
   *
177
   * @param \Drupal\comment\CommentInterface $comment
178 179 180 181 182 183 184
   *   The comment object.
   * @param boolean $reply
   *   Boolean indicating whether the comment is a reply to another comment.
   *
   * @return boolean
   *   Boolean indicating whether the comment was found.
   */
185
  function commentExists(CommentInterface $comment = NULL, $reply = FALSE) {
186
    if ($comment) {
187
      $regex = '!' . ($reply ? '<div class="indented">(.*?)' : '');
188 189 190
      $regex .= '<a id="comment-' . $comment->id() . '"(.*?)';
      $regex .= $comment->getSubject() . '(.*?)';
      $regex .= $comment->comment_body->value . '(.*?)';
191 192
      $regex .= ($reply ? '</article>\s</div>(.*?)' : '');
      $regex .= '!s';
193

194
      return (boolean) preg_match($regex, $this->drupalGetContent());
195 196 197 198 199 200 201 202 203
    }
    else {
      return FALSE;
    }
  }

  /**
   * Deletes a comment.
   *
204
   * @param \Drupal\comment\CommentInterface $comment
205 206
   *   Comment to delete.
   */
207
  function deleteComment(CommentInterface $comment) {
208
    $this->drupalPostForm('comment/' . $comment->id() . '/delete', array(), t('Delete'));
209
    $this->assertText(t('The comment and all its replies have been deleted.'), 'Comment deleted.');
210 211 212 213 214
  }

  /**
   * Sets the value governing whether the subject field should be enabled.
   *
215
   * @param bool $enabled
216 217
   *   Boolean specifying whether the subject field should be enabled.
   */
218 219 220 221
  public function setCommentSubject($enabled) {
    $form_display = entity_get_form_display('comment', 'comment', 'default');
    if ($enabled) {
      $form_display->setComponent('subject', array(
222
        'type' => 'string_textfield',
223 224 225 226 227 228 229 230
      ));
    }
    else {
      $form_display->removeComponent('subject');
    }
    $form_display->save();
    // Display status message.
    $this->pass('Comment subject ' . ($enabled ? 'enabled' : 'disabled') . '.');
231 232 233 234 235 236 237
  }

  /**
   * Sets the value governing the previewing mode for the comment form.
   *
   * @param int $mode
   *   The preview mode: DRUPAL_DISABLED, DRUPAL_OPTIONAL or DRUPAL_REQUIRED.
238 239 240
   * @param string $field_name
   *   (optional) Field name through which the comment should be posted.
   *   Defaults to 'comment'.
241
   */
242
  public function setCommentPreview($mode, $field_name = 'comment') {
243 244 245 246 247 248 249 250 251 252 253 254 255
    switch ($mode) {
      case DRUPAL_DISABLED:
        $mode_text = 'disabled';
        break;

      case DRUPAL_OPTIONAL:
        $mode_text = 'optional';
        break;

      case DRUPAL_REQUIRED:
        $mode_text = 'required';
        break;
    }
256
    $this->setCommentSettings('preview', $mode, format_string('Comment preview @mode_text.', array('@mode_text' => $mode_text)), $field_name);
257 258 259 260 261
  }

  /**
   * Sets the value governing whether the comment form is on its own page.
   *
262
   * @param bool $enabled
263 264
   *   TRUE if the comment form should be displayed on the same page as the
   *   comments; FALSE if it should be displayed on its own page.
265 266 267
   * @param string $field_name
   *   (optional) Field name through which the comment should be posted.
   *   Defaults to 'comment'.
268
   */
269
  public function setCommentForm($enabled, $field_name = 'comment') {
270
    $this->setCommentSettings('form_location', ($enabled ? CommentItemInterface::FORM_BELOW : CommentItemInterface::FORM_SEPARATE_PAGE), 'Comment controls ' . ($enabled ? 'enabled' : 'disabled') . '.', $field_name);
271 272 273 274 275 276 277 278 279 280 281 282
  }

  /**
   * Sets the value governing restrictions on anonymous comments.
   *
   * @param integer $level
   *   The level of the contact information allowed for anonymous comments:
   *   - 0: No contact information allowed.
   *   - 1: Contact information allowed but not required.
   *   - 2: Contact information required.
   */
  function setCommentAnonymous($level) {
283
    $this->setCommentSettings('anonymous', $level, format_string('Anonymous commenting set to level @level.', array('@level' => $level)));
284 285 286 287 288
  }

  /**
   * Sets the value specifying the default number of comments per page.
   *
289
   * @param int $number
290
   *   Comments per page value.
291 292 293
   * @param string $field_name
   *   (optional) Field name through which the comment should be posted.
   *   Defaults to 'comment'.
294
   */
295 296
  public function setCommentsPerPage($number, $field_name = 'comment') {
    $this->setCommentSettings('per_page', $number, format_string('Number of comments per page set to @number.', array('@number' => $number)), $field_name);
297 298 299 300 301 302 303 304 305 306 307
  }

  /**
   * Sets a comment settings variable for the article content type.
   *
   * @param string $name
   *   Name of variable.
   * @param string $value
   *   Value of variable.
   * @param string $message
   *   Status message to display.
308 309 310
   * @param string $field_name
   *   (optional) Field name through which the comment should be posted.
   *   Defaults to 'comment'.
311
   */
312
  public function setCommentSettings($name, $value, $message, $field_name = 'comment') {
313 314 315
    $field = FieldConfig::loadByName('node', 'article', $field_name);
    $field->settings[$name] = $value;
    $field->save();
316
    // Display status message.
317
    $this->pass($message);
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
  }

  /**
   * Checks whether the commenter's contact information is displayed.
   *
   * @return boolean
   *   Contact info is available.
   */
  function commentContactInfoAvailable() {
    return preg_match('/(input).*?(name="name").*?(input).*?(name="mail").*?(input).*?(name="homepage")/s', $this->drupalGetContent());
  }

  /**
   * Performs the specified operation on the specified comment.
   *
333
   * @param \Drupal\comment\CommentInterface $comment
334 335 336 337 338 339
   *   Comment to perform operation on.
   * @param string $operation
   *   Operation to perform.
   * @param boolean $aproval
   *   Operation is found on approval page.
   */
340
  function performCommentOperation(CommentInterface $comment, $operation, $approval = FALSE) {
341 342
    $edit = array();
    $edit['operation'] = $operation;
343
    $edit['comments[' . $comment->id() . ']'] = TRUE;
344
    $this->drupalPostForm('admin/content/comment' . ($approval ? '/approval' : ''), $edit, t('Update'));
345 346

    if ($operation == 'delete') {
347
      $this->drupalPostForm(NULL, array(), t('Delete comments'));
348
      $this->assertRaw(\Drupal::translation()->formatPlural(1, 'Deleted 1 comment.', 'Deleted @count comments.'), format_string('Operation "@operation" was performed on comment.', array('@operation' => $operation)));
349 350
    }
    else {
351
      $this->assertText(t('The update has been performed.'), format_string('Operation "@operation" was performed on comment.', array('@operation' => $operation)));
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
    }
  }

  /**
   * Gets the comment ID for an unapproved comment.
   *
   * @param string $subject
   *   Comment subject to find.
   *
   * @return integer
   *   Comment id.
   */
  function getUnapprovedComment($subject) {
    $this->drupalGet('admin/content/comment/approval');
    preg_match('/href="(.*?)#comment-([^"]+)"(.*?)>(' . $subject . ')/', $this->drupalGetContent(), $match);

    return $match[2];
  }
370

371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390
  /**
   * Creates a comment comment type (bundle).
   *
   * @param string $label
   *   The comment type label.
   *
   * @return \Drupal\comment\Entity\CommentType
   *   Created comment type.
   */
  protected function createCommentType($label) {
    $bundle = CommentType::create(array(
      'id' => $label,
      'label' => $label,
      'description' => '',
      'target_entity_type_id' => 'node',
    ));
    $bundle->save();
    return $bundle;
  }

391
}