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