3 namespace Drupal\Tests\comment\Functional;
5 use Drupal\Component\Serialization\Json;
6 use Drupal\Core\Language\LanguageInterface;
7 use Drupal\comment\CommentInterface;
9 use Drupal\comment\Entity\Comment;
12 * Tests the 'new' indicator posted on comments.
16 class CommentNewIndicatorTest extends CommentTestBase {
19 * Use the main node listing to test rendering on teasers.
23 * @todo Remove this dependency.
25 public static $modules = ['views'];
28 * Get node "x new comments" metadata from the server for the current user.
30 * @param array $node_ids
31 * An array of node IDs.
33 * @return \Psr\Http\Message\ResponseInterface
36 protected function renderNewCommentsNodeLinks(array $node_ids) {
37 $client = $this->getHttpClient();
38 $url = Url::fromRoute('comment.new_comments_node_links');
40 return $client->request('POST', $this->buildUrl($url), [
41 'cookies' => $this->getSessionCookies(),
42 'http_errors' => FALSE,
44 'node_ids' => $node_ids,
45 'field_name' => 'comment',
51 * Tests new comment marker.
53 public function testCommentNewCommentsIndicator() {
54 // Test if the right links are displayed when no comment is present for the
56 $this->drupalLogin($this->adminUser);
57 $this->drupalGet('node');
58 $this->assertNoLink(t('@count comments', ['@count' => 0]));
59 $this->assertLink(t('Read more'));
60 // Verify the data-history-node-last-comment-timestamp attribute, which is
61 // used by the drupal.node-new-comments-link library to determine whether
62 // a "x new comments" link might be necessary or not. We do this in
63 // JavaScript to prevent breaking the render cache.
64 $this->assertIdentical(0, count($this->xpath('//*[@data-history-node-last-comment-timestamp]')), 'data-history-node-last-comment-timestamp attribute is not set.');
66 // Create a new comment. This helper function may be run with different
67 // comment settings so use $comment->save() to avoid complex setup.
68 /** @var \Drupal\comment\CommentInterface $comment */
69 $comment = Comment::create([
71 'entity_id' => $this->node->id(),
72 'entity_type' => 'node',
73 'field_name' => 'comment',
75 'uid' => $this->loggedInUser->id(),
76 'status' => CommentInterface::PUBLISHED,
77 'subject' => $this->randomMachineName(),
78 'hostname' => '127.0.0.1',
79 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
80 'comment_body' => [LanguageInterface::LANGCODE_NOT_SPECIFIED => [$this->randomMachineName()]],
83 $this->drupalLogout();
85 // Log in with 'web user' and check comment links.
86 $this->drupalLogin($this->webUser);
87 $this->drupalGet('node');
88 // Verify the data-history-node-last-comment-timestamp attribute. Given its
89 // value, the drupal.node-new-comments-link library would determine that the
90 // node received a comment after the user last viewed it, and hence it would
91 // perform an HTTP request to render the "new comments" node link.
92 $this->assertIdentical(1, count($this->xpath('//*[@data-history-node-last-comment-timestamp="' . $comment->getChangedTime() . '"]')), 'data-history-node-last-comment-timestamp attribute is set to the correct value.');
93 $this->assertIdentical(1, count($this->xpath('//*[@data-history-node-field-name="comment"]')), 'data-history-node-field-name attribute is set to the correct value.');
94 // The data will be pre-seeded on this particular page in drupalSettings, to
95 // avoid the need for the client to make a separate request to the server.
96 $settings = $this->getDrupalSettings();
97 $this->assertEqual($settings['history'], ['lastReadTimestamps' => [1 => 0]]);
98 $this->assertEqual($settings['comment'], [
99 'newCommentsLinks' => [
103 'new_comment_count' => 1,
104 'first_new_comment_link' => Url::fromRoute('entity.node.canonical', ['node' => 1])->setOptions([
112 // Pretend the data was not present in drupalSettings, i.e. test the
113 // separate request to the server.
114 $response = $this->renderNewCommentsNodeLinks([$this->node->id()]);
115 $this->assertSame(200, $response->getStatusCode());
116 $json = Json::decode($response->getBody());
118 $this->node->id() => [
119 'new_comment_count' => 1,
120 'first_new_comment_link' => $this->node->url('canonical', ['fragment' => 'new']),
123 $this->assertIdentical($expected, $json);
125 // Failing to specify node IDs for the endpoint should return a 404.
126 $response = $this->renderNewCommentsNodeLinks([]);
127 $this->assertSame(404, $response->getStatusCode());
129 // Accessing the endpoint as the anonymous user should return a 403.
130 $this->drupalLogout();
131 $response = $this->renderNewCommentsNodeLinks([$this->node->id()]);
132 $this->assertSame(403, $response->getStatusCode());
133 $response = $this->renderNewCommentsNodeLinks([]);
134 $this->assertSame(403, $response->getStatusCode());