knowledge-8.x-1.x-dev/tests/src/Functional/KnowledgeNewIndicatorTest.php
tests/src/Functional/KnowledgeNewIndicatorTest.php
<?php
namespace Drupal\Tests\knowledge\Functional;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Url;
use Drupal\knowledge\Entity\Knowledge;
use Drupal\knowledge\KnowledgeInterface;
/**
* Tests the 'new' indicator posted on knowledge.
*
* @group knowledge
*/
class KnowledgeNewIndicatorTest extends KnowledgeTestBase {
/**
* Use the main node listing to test rendering on teasers.
*
* @var array
*
* @todo Remove this dependency.
*/
protected static $modules = ['views'];
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* Get node "x new knowledge" metadata from the server for the current user.
*
* @param array $node_ids
* An array of node IDs.
*
* @return \Psr\Http\Message\ResponseInterface
* The HTTP response.
*/
protected function renderNewKnowledgesNodeLinks(array $node_ids) {
$client = $this->getHttpClient();
$url = Url::fromRoute('knowledge.new_knowledge_node_links');
return $client->request('POST', $this->buildUrl($url), [
'cookies' => $this->getSessionCookies(),
'http_errors' => FALSE,
'form_params' => [
'node_ids' => $node_ids,
'field_name' => 'knowledge',
],
]);
}
/**
* Tests new knowledge marker.
*/
public function testKnowledgeNewKnowledgesIndicator() {
// Test if the right links are displayed when no knowledge is present for
// the node.
$this->drupalLogin($this->adminUser);
$this->drupalGet('node');
$this->assertSession()->linkNotExists('0 knowledge');
$this->assertSession()->linkExists('Read more');
// Verify the data-history-node-last-knowledge-timestamp attribute, which is
// used by the drupal.node-new-knowledge-link library to determine whether
// a "x new knowledge" link might be necessary or not. We do this in
// JavaScript to prevent breaking the render cache.
$this->assertCount(0, $this->xpath('//*[@data-history-node-last-knowledge-timestamp]'), 'data-history-node-last-knowledge-timestamp attribute is not set.');
// Create a new knowledge. This helper function may be run with different
// knowledge settings so use $knowledge->save() to avoid complex setup.
/** @var \Drupal\knowledge\KnowledgeInterface $knowledge */
$knowledge = Knowledge::create([
'kid' => NULL,
'entity_id' => $this->node->id(),
'entity_type' => 'node',
'field_name' => 'knowledge',
'uid' => $this->loggedInUser->id(),
'status' => KnowledgeInterface::PUBLISHED,
'subject' => $this->randomMachineName(),
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
'knowledge_body' => [LanguageInterface::LANGCODE_NOT_SPECIFIED => [$this->randomMachineName()]],
]);
$knowledge->save();
$this->drupalLogout();
// Log in with 'web user' and check knowledge links.
$this->drupalLogin($this->webUser);
$this->drupalGet('node');
// Verify the data-history-node-last-knowledge-timestamp attribute. Given
// its value, the drupal.node-new-knowledge-link library would determine
// that the node received a knowledge after the user last viewed it, and
// hence it would perform an HTTP request to render the "new knowledge"
// node link.
$this->assertCount(1, $this->xpath('//*[@data-history-node-last-knowledge-timestamp="' . $knowledge->getChangedTime() . '"]'), 'data-history-node-last-knowledge-timestamp attribute is set to the correct value.');
$this->assertCount(1, $this->xpath('//*[@data-history-node-field-name="knowledge"]'), 'data-history-node-field-name attribute is set to the correct value.');
// The data will be pre-seeded on this particular page in drupalSettings, to
// avoid the need for the client to make a separate request to the server.
$settings = $this->getDrupalSettings();
$this->assertEquals(['lastReadTimestamps' => [1 => 0]], $settings['history']);
$this->assertEquals([
'newKnowledgesLinks' => [
'node' => [
'knowledge' => [
1 => [
'new_total_count' => 1,
'first_new_knowledge_link' => Url::fromRoute('entity.node.canonical', ['node' => 1])->setOptions([
'fragment' => 'new',
])->toString(),
],
],
],
],
], $settings['knowledge']);
// Pretend the data was not present in drupalSettings, i.e. test the
// separate request to the server.
$response = $this->renderNewKnowledgesNodeLinks([$this->node->id()]);
$this->assertSame(200, $response->getStatusCode());
$json = Json::decode($response->getBody());
$expected = [
$this->node->id() => [
'new_total_count' => 1,
'first_new_knowledge_link' => $this->node->toUrl('canonical', ['fragment' => 'new'])->toString(),
],
];
$this->assertSame($expected, $json);
// Failing to specify node IDs for the endpoint should return a 404.
$response = $this->renderNewKnowledgesNodeLinks([]);
$this->assertSame(404, $response->getStatusCode());
// Accessing the endpoint as the anonymous user should return a 403.
$this->drupalLogout();
$response = $this->renderNewKnowledgesNodeLinks([$this->node->id()]);
$this->assertSame(403, $response->getStatusCode());
$response = $this->renderNewKnowledgesNodeLinks([]);
$this->assertSame(403, $response->getStatusCode());
}
}
