PageRenderTime 51ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/core/modules/comment/src/Tests/CommentTestBase.php

http://github.com/drupal/drupal
PHP | 418 lines | 204 code | 42 blank | 172 comment | 26 complexity | c05ca5e762a0dd6f8c0720e2d72e4814 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. namespace Drupal\comment\Tests;
  3. @trigger_error(__NAMESPACE__ . '\CommentTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Use \Drupal\Tests\comment\Functional\CommentTestBase instead. See http://www.drupal.org/node/2908490', E_USER_DEPRECATED);
  4. use Drupal\Component\Render\FormattableMarkup;
  5. use Drupal\comment\Entity\CommentType;
  6. use Drupal\comment\Entity\Comment;
  7. use Drupal\comment\CommentInterface;
  8. use Drupal\field\Entity\FieldConfig;
  9. use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
  10. use Drupal\node\Entity\NodeType;
  11. use Drupal\simpletest\WebTestBase;
  12. /**
  13. * Provides setup and helper methods for comment tests.
  14. *
  15. * @deprecated in drupal:8.4.0 and is removed from drupal:9.0.0.
  16. * Use \Drupal\Tests\comment\Functional\CommentTestBase instead.
  17. *
  18. * @see https://www.drupal.org/node/2908490
  19. */
  20. abstract class CommentTestBase extends WebTestBase {
  21. use CommentTestTrait;
  22. /**
  23. * Modules to install.
  24. *
  25. * @var array
  26. */
  27. public static $modules = [
  28. 'block',
  29. 'comment',
  30. 'node',
  31. 'history',
  32. 'field_ui',
  33. 'datetime',
  34. ];
  35. /**
  36. * An administrative user with permission to configure comment settings.
  37. *
  38. * @var \Drupal\user\UserInterface
  39. */
  40. protected $adminUser;
  41. /**
  42. * A normal user with permission to post comments.
  43. *
  44. * @var \Drupal\user\UserInterface
  45. */
  46. protected $webUser;
  47. /**
  48. * A test node to which comments will be posted.
  49. *
  50. * @var \Drupal\node\NodeInterface
  51. */
  52. protected $node;
  53. protected function setUp() {
  54. parent::setUp();
  55. // Create an article content type only if it does not yet exist, so that
  56. // child classes may specify the standard profile.
  57. $types = NodeType::loadMultiple();
  58. if (empty($types['article'])) {
  59. $this->drupalCreateContentType(['type' => 'article', 'name' => t('Article')]);
  60. }
  61. // Create two test users.
  62. $this->adminUser = $this->drupalCreateUser([
  63. 'administer content types',
  64. 'administer comments',
  65. 'administer comment types',
  66. 'administer comment fields',
  67. 'administer comment display',
  68. 'skip comment approval',
  69. 'post comments',
  70. 'access comments',
  71. // Usernames aren't shown in comment edit form autocomplete unless this
  72. // permission is granted.
  73. 'access user profiles',
  74. 'access content',
  75. ]);
  76. $this->webUser = $this->drupalCreateUser([
  77. 'access comments',
  78. 'post comments',
  79. 'create article content',
  80. 'edit own comments',
  81. 'skip comment approval',
  82. 'access content',
  83. ]);
  84. // Create comment field on article.
  85. $this->addDefaultCommentField('node', 'article');
  86. // Create a test node authored by the web user.
  87. $this->node = $this->drupalCreateNode(['type' => 'article', 'promote' => 1, 'uid' => $this->webUser->id()]);
  88. $this->drupalPlaceBlock('local_tasks_block');
  89. }
  90. /**
  91. * Posts a comment.
  92. *
  93. * @param \Drupal\Core\Entity\EntityInterface|null $entity
  94. * Node to post comment on or NULL to post to the previously loaded page.
  95. * @param string $comment
  96. * Comment body.
  97. * @param string $subject
  98. * Comment subject.
  99. * @param string $contact
  100. * Set to NULL for no contact info, TRUE to ignore success checking, and
  101. * array of values to set contact info.
  102. * @param string $field_name
  103. * (optional) Field name through which the comment should be posted.
  104. * Defaults to 'comment'.
  105. *
  106. * @return \Drupal\comment\CommentInterface|null
  107. * The posted comment or NULL when posted comment was not found.
  108. */
  109. public function postComment($entity, $comment, $subject = '', $contact = NULL, $field_name = 'comment') {
  110. $edit = [];
  111. $edit['comment_body[0][value]'] = $comment;
  112. if ($entity !== NULL) {
  113. $field = FieldConfig::loadByName($entity->getEntityTypeId(), $entity->bundle(), $field_name);
  114. }
  115. else {
  116. $field = FieldConfig::loadByName('node', 'article', $field_name);
  117. }
  118. $preview_mode = $field->getSetting('preview');
  119. // Must get the page before we test for fields.
  120. if ($entity !== NULL) {
  121. $this->drupalGet('comment/reply/' . $entity->getEntityTypeId() . '/' . $entity->id() . '/' . $field_name);
  122. }
  123. // Determine the visibility of subject form field.
  124. if (\Drupal::service('entity_display.repository')->getFormDisplay('comment', 'comment')->getComponent('subject')) {
  125. // Subject input allowed.
  126. $edit['subject[0][value]'] = $subject;
  127. }
  128. else {
  129. $this->assertNoFieldByName('subject[0][value]', '', 'Subject field not found.');
  130. }
  131. if ($contact !== NULL && is_array($contact)) {
  132. $edit += $contact;
  133. }
  134. switch ($preview_mode) {
  135. case DRUPAL_REQUIRED:
  136. // Preview required so no save button should be found.
  137. $this->assertNoFieldByName('op', t('Save'), 'Save button not found.');
  138. $this->drupalPostForm(NULL, $edit, t('Preview'));
  139. // Don't break here so that we can test post-preview field presence and
  140. // function below.
  141. case DRUPAL_OPTIONAL:
  142. $this->assertFieldByName('op', t('Preview'), 'Preview button found.');
  143. $this->assertFieldByName('op', t('Save'), 'Save button found.');
  144. $this->drupalPostForm(NULL, $edit, t('Save'));
  145. break;
  146. case DRUPAL_DISABLED:
  147. $this->assertNoFieldByName('op', t('Preview'), 'Preview button not found.');
  148. $this->assertFieldByName('op', t('Save'), 'Save button found.');
  149. $this->drupalPostForm(NULL, $edit, t('Save'));
  150. break;
  151. }
  152. $match = [];
  153. // Get comment ID
  154. preg_match('/#comment-([0-9]+)/', $this->getURL(), $match);
  155. // Get comment.
  156. if ($contact !== TRUE) {
  157. // If true then attempting to find error message.
  158. if ($subject) {
  159. $this->assertText($subject, 'Comment subject posted.');
  160. }
  161. $this->assertText($comment, 'Comment body posted.');
  162. $this->assertTrue((!empty($match) && !empty($match[1])), 'Comment id found.');
  163. }
  164. if (isset($match[1])) {
  165. \Drupal::entityTypeManager()->getStorage('comment')->resetCache([$match[1]]);
  166. return Comment::load($match[1]);
  167. }
  168. }
  169. /**
  170. * Checks current page for specified comment.
  171. *
  172. * @param \Drupal\comment\CommentInterface $comment
  173. * The comment object.
  174. * @param bool $reply
  175. * Boolean indicating whether the comment is a reply to another comment.
  176. *
  177. * @return bool
  178. * Boolean indicating whether the comment was found.
  179. */
  180. public function commentExists(CommentInterface $comment = NULL, $reply = FALSE) {
  181. if ($comment) {
  182. $comment_element = $this->cssSelect('.comment-wrapper ' . ($reply ? '.indented ' : '') . 'article#comment-' . $comment->id());
  183. if (empty($comment_element)) {
  184. return FALSE;
  185. }
  186. $comment_title = $comment_element[0]->xpath('div/h3/a');
  187. if (empty($comment_title) || ((string) $comment_title[0]) !== $comment->getSubject()) {
  188. return FALSE;
  189. }
  190. $comment_body = $comment_element[0]->xpath('div/div/p');
  191. if (empty($comment_body) || ((string) $comment_body[0]) !== $comment->comment_body->value) {
  192. return FALSE;
  193. }
  194. return TRUE;
  195. }
  196. else {
  197. return FALSE;
  198. }
  199. }
  200. /**
  201. * Deletes a comment.
  202. *
  203. * @param \Drupal\comment\CommentInterface $comment
  204. * Comment to delete.
  205. */
  206. public function deleteComment(CommentInterface $comment) {
  207. $this->drupalPostForm('comment/' . $comment->id() . '/delete', [], t('Delete'));
  208. $this->assertText(t('The comment and all its replies have been deleted.'), 'Comment deleted.');
  209. }
  210. /**
  211. * Sets the value governing whether the subject field should be enabled.
  212. *
  213. * @param bool $enabled
  214. * Boolean specifying whether the subject field should be enabled.
  215. */
  216. public function setCommentSubject($enabled) {
  217. $form_display = \Drupal::service('entity_display.repository')
  218. ->getFormDisplay('comment', 'comment');
  219. if ($enabled) {
  220. $form_display->setComponent('subject', [
  221. 'type' => 'string_textfield',
  222. ]);
  223. }
  224. else {
  225. $form_display->removeComponent('subject');
  226. }
  227. $form_display->save();
  228. // Display status message.
  229. $this->pass('Comment subject ' . ($enabled ? 'enabled' : 'disabled') . '.');
  230. }
  231. /**
  232. * Sets the value governing the previewing mode for the comment form.
  233. *
  234. * @param int $mode
  235. * The preview mode: DRUPAL_DISABLED, DRUPAL_OPTIONAL or DRUPAL_REQUIRED.
  236. * @param string $field_name
  237. * (optional) Field name through which the comment should be posted.
  238. * Defaults to 'comment'.
  239. */
  240. public function setCommentPreview($mode, $field_name = 'comment') {
  241. switch ($mode) {
  242. case DRUPAL_DISABLED:
  243. $mode_text = 'disabled';
  244. break;
  245. case DRUPAL_OPTIONAL:
  246. $mode_text = 'optional';
  247. break;
  248. case DRUPAL_REQUIRED:
  249. $mode_text = 'required';
  250. break;
  251. }
  252. $this->setCommentSettings('preview', $mode, new FormattableMarkup('Comment preview @mode_text.', ['@mode_text' => $mode_text]), $field_name);
  253. }
  254. /**
  255. * Sets the value governing whether the comment form is on its own page.
  256. *
  257. * @param bool $enabled
  258. * TRUE if the comment form should be displayed on the same page as the
  259. * comments; FALSE if it should be displayed on its own page.
  260. * @param string $field_name
  261. * (optional) Field name through which the comment should be posted.
  262. * Defaults to 'comment'.
  263. */
  264. public function setCommentForm($enabled, $field_name = 'comment') {
  265. $this->setCommentSettings('form_location', ($enabled ? CommentItemInterface::FORM_BELOW : CommentItemInterface::FORM_SEPARATE_PAGE), 'Comment controls ' . ($enabled ? 'enabled' : 'disabled') . '.', $field_name);
  266. }
  267. /**
  268. * Sets the value governing restrictions on anonymous comments.
  269. *
  270. * @param int $level
  271. * The level of the contact information allowed for anonymous comments:
  272. * - 0: No contact information allowed.
  273. * - 1: Contact information allowed but not required.
  274. * - 2: Contact information required.
  275. */
  276. public function setCommentAnonymous($level) {
  277. $this->setCommentSettings('anonymous', $level, new FormattableMarkup('Anonymous commenting set to level @level.', ['@level' => $level]));
  278. }
  279. /**
  280. * Sets the value specifying the default number of comments per page.
  281. *
  282. * @param int $number
  283. * Comments per page value.
  284. * @param string $field_name
  285. * (optional) Field name through which the comment should be posted.
  286. * Defaults to 'comment'.
  287. */
  288. public function setCommentsPerPage($number, $field_name = 'comment') {
  289. $this->setCommentSettings('per_page', $number, new FormattableMarkup('Number of comments per page set to @number.', ['@number' => $number]), $field_name);
  290. }
  291. /**
  292. * Sets a comment settings variable for the article content type.
  293. *
  294. * @param string $name
  295. * Name of variable.
  296. * @param string $value
  297. * Value of variable.
  298. * @param string $message
  299. * Status message to display.
  300. * @param string $field_name
  301. * (optional) Field name through which the comment should be posted.
  302. * Defaults to 'comment'.
  303. */
  304. public function setCommentSettings($name, $value, $message, $field_name = 'comment') {
  305. $field = FieldConfig::loadByName('node', 'article', $field_name);
  306. $field->setSetting($name, $value);
  307. $field->save();
  308. // Display status message.
  309. $this->pass($message);
  310. }
  311. /**
  312. * Checks whether the commenter's contact information is displayed.
  313. *
  314. * @return bool
  315. * Contact info is available.
  316. */
  317. public function commentContactInfoAvailable() {
  318. return preg_match('/(input).*?(name="name").*?(input).*?(name="mail").*?(input).*?(name="homepage")/s', $this->getRawContent());
  319. }
  320. /**
  321. * Performs the specified operation on the specified comment.
  322. *
  323. * @param \Drupal\comment\CommentInterface $comment
  324. * Comment to perform operation on.
  325. * @param string $operation
  326. * Operation to perform.
  327. * @param bool $approval
  328. * Operation is found on approval page.
  329. */
  330. public function performCommentOperation(CommentInterface $comment, $operation, $approval = FALSE) {
  331. $edit = [];
  332. $edit['operation'] = $operation;
  333. $edit['comments[' . $comment->id() . ']'] = TRUE;
  334. $this->drupalPostForm('admin/content/comment' . ($approval ? '/approval' : ''), $edit, t('Update'));
  335. if ($operation == 'delete') {
  336. $this->drupalPostForm(NULL, [], t('Delete'));
  337. $this->assertRaw(\Drupal::translation()->formatPlural(1, 'Deleted 1 comment.', 'Deleted @count comments.'), new FormattableMarkup('Operation "@operation" was performed on comment.', ['@operation' => $operation]));
  338. }
  339. else {
  340. $this->assertText(t('The update has been performed.'), new FormattableMarkup('Operation "@operation" was performed on comment.', ['@operation' => $operation]));
  341. }
  342. }
  343. /**
  344. * Gets the comment ID for an unapproved comment.
  345. *
  346. * @param string $subject
  347. * Comment subject to find.
  348. *
  349. * @return int
  350. * Comment id.
  351. */
  352. public function getUnapprovedComment($subject) {
  353. $this->drupalGet('admin/content/comment/approval');
  354. preg_match('/href="(.*?)#comment-([^"]+)"(.*?)>(' . $subject . ')/', $this->getRawContent(), $match);
  355. return $match[2];
  356. }
  357. /**
  358. * Creates a comment comment type (bundle).
  359. *
  360. * @param string $label
  361. * The comment type label.
  362. *
  363. * @return \Drupal\comment\Entity\CommentType
  364. * Created comment type.
  365. */
  366. protected function createCommentType($label) {
  367. $bundle = CommentType::create([
  368. 'id' => $label,
  369. 'label' => $label,
  370. 'description' => '',
  371. 'target_entity_type_id' => 'node',
  372. ]);
  373. $bundle->save();
  374. return $bundle;
  375. }
  376. }