Version 1
[yaffs-website] / web / core / modules / comment / src / Tests / CommentNewIndicatorTest.php
1 <?php
2
3 namespace Drupal\comment\Tests;
4
5 use Drupal\Component\Serialization\Json;
6 use Drupal\Core\Language\LanguageInterface;
7 use Drupal\comment\CommentInterface;
8 use Drupal\Core\Url;
9 use Drupal\comment\Entity\Comment;
10
11 /**
12  * Tests the 'new' indicator posted on comments.
13  *
14  * @group comment
15  */
16 class CommentNewIndicatorTest extends CommentTestBase {
17
18   /**
19    * Use the main node listing to test rendering on teasers.
20    *
21    * @var array
22    *
23    * @todo Remove this dependency.
24    */
25   public static $modules = ['views'];
26
27   /**
28    * Get node "x new comments" metadata from the server for the current user.
29    *
30    * @param array $node_ids
31    *   An array of node IDs.
32    *
33    * @return string
34    *   The response body.
35    */
36   protected function renderNewCommentsNodeLinks(array $node_ids) {
37     // Build POST values.
38     $post = [];
39     for ($i = 0; $i < count($node_ids); $i++) {
40       $post['node_ids[' . $i . ']'] = $node_ids[$i];
41     }
42     $post['field_name'] = 'comment';
43
44     // Serialize POST values.
45     foreach ($post as $key => $value) {
46       // Encode according to application/x-www-form-urlencoded
47       // Both names and values needs to be urlencoded, according to
48       // http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1
49       $post[$key] = urlencode($key) . '=' . urlencode($value);
50     }
51     $post = implode('&', $post);
52
53     // Perform HTTP request.
54     return $this->curlExec([
55       CURLOPT_URL => \Drupal::url('comment.new_comments_node_links', [], ['absolute' => TRUE]),
56       CURLOPT_POST => TRUE,
57       CURLOPT_POSTFIELDS => $post,
58       CURLOPT_HTTPHEADER => [
59         'Accept: application/json',
60         'Content-Type: application/x-www-form-urlencoded',
61       ],
62     ]);
63   }
64
65   /**
66    * Tests new comment marker.
67    */
68   public function testCommentNewCommentsIndicator() {
69     // Test if the right links are displayed when no comment is present for the
70     // node.
71     $this->drupalLogin($this->adminUser);
72     $this->drupalGet('node');
73     $this->assertNoLink(t('@count comments', ['@count' => 0]));
74     $this->assertLink(t('Read more'));
75     // Verify the data-history-node-last-comment-timestamp attribute, which is
76     // used by the drupal.node-new-comments-link library to determine whether
77     // a "x new comments" link might be necessary or not. We do this in
78     // JavaScript to prevent breaking the render cache.
79     $this->assertIdentical(0, count($this->xpath('//*[@data-history-node-last-comment-timestamp]')), 'data-history-node-last-comment-timestamp attribute is not set.');
80
81     // Create a new comment. This helper function may be run with different
82     // comment settings so use $comment->save() to avoid complex setup.
83     /** @var \Drupal\comment\CommentInterface $comment */
84     $comment = Comment::create([
85       'cid' => NULL,
86       'entity_id' => $this->node->id(),
87       'entity_type' => 'node',
88       'field_name' => 'comment',
89       'pid' => 0,
90       'uid' => $this->loggedInUser->id(),
91       'status' => CommentInterface::PUBLISHED,
92       'subject' => $this->randomMachineName(),
93       'hostname' => '127.0.0.1',
94       'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
95       'comment_body' => [LanguageInterface::LANGCODE_NOT_SPECIFIED => [$this->randomMachineName()]],
96     ]);
97     $comment->save();
98     $this->drupalLogout();
99
100     // Log in with 'web user' and check comment links.
101     $this->drupalLogin($this->webUser);
102     $this->drupalGet('node');
103     // Verify the data-history-node-last-comment-timestamp attribute. Given its
104     // value, the drupal.node-new-comments-link library would determine that the
105     // node received a comment after the user last viewed it, and hence it would
106     // perform an HTTP request to render the "new comments" node link.
107     $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.');
108     $this->assertIdentical(1, count($this->xpath('//*[@data-history-node-field-name="comment"]')), 'data-history-node-field-name attribute is set to the correct value.');
109     // The data will be pre-seeded on this particular page in drupalSettings, to
110     // avoid the need for the client to make a separate request to the server.
111     $settings = $this->getDrupalSettings();
112     $this->assertEqual($settings['history'], ['lastReadTimestamps' => [1 => 0]]);
113     $this->assertEqual($settings['comment'], [
114       'newCommentsLinks' => [
115         'node' => [
116           'comment' => [
117             1 => [
118               'new_comment_count' => 1,
119               'first_new_comment_link' => Url::fromRoute('entity.node.canonical', ['node' => 1])->setOptions([
120                 'fragment' => 'new',
121               ])->toString(),
122             ],
123           ],
124         ],
125       ],
126     ]);
127     // Pretend the data was not present in drupalSettings, i.e. test the
128     // separate request to the server.
129     $response = $this->renderNewCommentsNodeLinks([$this->node->id()]);
130     $this->assertResponse(200);
131     $json = Json::decode($response);
132     $expected = [$this->node->id() => [
133       'new_comment_count' => 1,
134       'first_new_comment_link' => $this->node->url('canonical', ['fragment' => 'new']),
135     ]];
136     $this->assertIdentical($expected, $json);
137
138     // Failing to specify node IDs for the endpoint should return a 404.
139     $this->renderNewCommentsNodeLinks([]);
140     $this->assertResponse(404);
141
142     // Accessing the endpoint as the anonymous user should return a 403.
143     $this->drupalLogout();
144     $this->renderNewCommentsNodeLinks([$this->node->id()]);
145     $this->assertResponse(403);
146     $this->renderNewCommentsNodeLinks([]);
147     $this->assertResponse(403);
148   }
149
150 }