Chris@0: $value) { Chris@0: // Encode according to application/x-www-form-urlencoded Chris@0: // Both names and values needs to be urlencoded, according to Chris@0: // http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1 Chris@0: $post[$key] = urlencode($key) . '=' . urlencode($value); Chris@0: } Chris@0: $post = implode('&', $post); Chris@0: Chris@0: // Perform HTTP request. Chris@0: return $this->curlExec([ Chris@0: CURLOPT_URL => \Drupal::url('comment.new_comments_node_links', [], ['absolute' => TRUE]), Chris@0: CURLOPT_POST => TRUE, Chris@0: CURLOPT_POSTFIELDS => $post, Chris@0: CURLOPT_HTTPHEADER => [ Chris@0: 'Accept: application/json', Chris@0: 'Content-Type: application/x-www-form-urlencoded', Chris@0: ], Chris@0: ]); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests new comment marker. Chris@0: */ Chris@0: public function testCommentNewCommentsIndicator() { Chris@0: // Test if the right links are displayed when no comment is present for the Chris@0: // node. Chris@0: $this->drupalLogin($this->adminUser); Chris@0: $this->drupalGet('node'); Chris@0: $this->assertNoLink(t('@count comments', ['@count' => 0])); Chris@0: $this->assertLink(t('Read more')); Chris@0: // Verify the data-history-node-last-comment-timestamp attribute, which is Chris@0: // used by the drupal.node-new-comments-link library to determine whether Chris@0: // a "x new comments" link might be necessary or not. We do this in Chris@0: // JavaScript to prevent breaking the render cache. Chris@0: $this->assertIdentical(0, count($this->xpath('//*[@data-history-node-last-comment-timestamp]')), 'data-history-node-last-comment-timestamp attribute is not set.'); Chris@0: Chris@0: // Create a new comment. This helper function may be run with different Chris@0: // comment settings so use $comment->save() to avoid complex setup. Chris@0: /** @var \Drupal\comment\CommentInterface $comment */ Chris@0: $comment = Comment::create([ Chris@0: 'cid' => NULL, Chris@0: 'entity_id' => $this->node->id(), Chris@0: 'entity_type' => 'node', Chris@0: 'field_name' => 'comment', Chris@0: 'pid' => 0, Chris@0: 'uid' => $this->loggedInUser->id(), Chris@0: 'status' => CommentInterface::PUBLISHED, Chris@0: 'subject' => $this->randomMachineName(), Chris@0: 'hostname' => '127.0.0.1', Chris@0: 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, Chris@0: 'comment_body' => [LanguageInterface::LANGCODE_NOT_SPECIFIED => [$this->randomMachineName()]], Chris@0: ]); Chris@0: $comment->save(); Chris@0: $this->drupalLogout(); Chris@0: Chris@0: // Log in with 'web user' and check comment links. Chris@0: $this->drupalLogin($this->webUser); Chris@0: $this->drupalGet('node'); Chris@0: // Verify the data-history-node-last-comment-timestamp attribute. Given its Chris@0: // value, the drupal.node-new-comments-link library would determine that the Chris@0: // node received a comment after the user last viewed it, and hence it would Chris@0: // perform an HTTP request to render the "new comments" node link. Chris@0: $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: $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: // The data will be pre-seeded on this particular page in drupalSettings, to Chris@0: // avoid the need for the client to make a separate request to the server. Chris@0: $settings = $this->getDrupalSettings(); Chris@0: $this->assertEqual($settings['history'], ['lastReadTimestamps' => [1 => 0]]); Chris@0: $this->assertEqual($settings['comment'], [ Chris@0: 'newCommentsLinks' => [ Chris@0: 'node' => [ Chris@0: 'comment' => [ Chris@0: 1 => [ Chris@0: 'new_comment_count' => 1, Chris@0: 'first_new_comment_link' => Url::fromRoute('entity.node.canonical', ['node' => 1])->setOptions([ Chris@0: 'fragment' => 'new', Chris@0: ])->toString(), Chris@0: ], Chris@0: ], Chris@0: ], Chris@0: ], Chris@0: ]); Chris@0: // Pretend the data was not present in drupalSettings, i.e. test the Chris@0: // separate request to the server. Chris@0: $response = $this->renderNewCommentsNodeLinks([$this->node->id()]); Chris@0: $this->assertResponse(200); Chris@0: $json = Json::decode($response); Chris@0: $expected = [ Chris@0: $this->node->id() => [ Chris@0: 'new_comment_count' => 1, Chris@0: 'first_new_comment_link' => $this->node->url('canonical', ['fragment' => 'new']), Chris@0: ], Chris@0: ]; Chris@0: $this->assertIdentical($expected, $json); Chris@0: Chris@0: // Failing to specify node IDs for the endpoint should return a 404. Chris@0: $this->renderNewCommentsNodeLinks([]); Chris@0: $this->assertResponse(404); Chris@0: Chris@0: // Accessing the endpoint as the anonymous user should return a 403. Chris@0: $this->drupalLogout(); Chris@0: $this->renderNewCommentsNodeLinks([$this->node->id()]); Chris@0: $this->assertResponse(403); Chris@0: $this->renderNewCommentsNodeLinks([]); Chris@0: $this->assertResponse(403); Chris@0: } Chris@0: Chris@0: }