3 namespace Drupal\Tests\history\Functional;
5 use Drupal\Component\Serialization\Json;
7 use Drupal\Tests\BrowserTestBase;
8 use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait;
11 * Tests the History endpoints.
15 class HistoryTest extends BrowserTestBase {
17 use AssertPageCacheContextsAndTagsTrait;
24 public static $modules = ['node', 'history'];
27 * The main user for testing.
34 * A page node for which to check content statistics.
40 protected function setUp() {
43 $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']);
45 $this->user = $this->drupalCreateUser(['create page content', 'access content']);
46 $this->drupalLogin($this->user);
47 $this->testNode = $this->drupalCreateNode(['type' => 'page', 'uid' => $this->user->id()]);
51 * Get node read timestamps from the server for the current user.
53 * @param array $node_ids
54 * An array of node IDs.
56 * @return \Psr\Http\Message\ResponseInterface
57 * The response object.
59 protected function getNodeReadTimestamps(array $node_ids) {
60 // Perform HTTP request.
61 $http_client = $this->getHttpClient();
62 $url = Url::fromRoute('history.get_last_node_view')
66 return $http_client->request('POST', $url, [
67 'form_params' => ['node_ids' => $node_ids],
68 'cookies' => $this->getSessionCookies(),
69 'http_errors' => FALSE,
74 * Mark a node as read for the current user.
79 * @return \Psr\Http\Message\ResponseInterface
82 protected function markNodeAsRead($node_id) {
83 $http_client = $this->getHttpClient();
84 $url = Url::fromRoute('history.read_node', ['node' => $node_id], ['absolute' => TRUE])->toString();
86 return $http_client->request('POST', $url, [
87 'cookies' => $this->getSessionCookies(),
88 'http_errors' => FALSE,
93 * Verifies that the history endpoints work.
95 public function testHistory() {
96 $nid = $this->testNode->id();
98 // Retrieve "last read" timestamp for test node, for the current user.
99 $response = $this->getNodeReadTimestamps([$nid]);
100 $this->assertEquals(200, $response->getStatusCode());
101 $json = Json::decode($response->getBody());
102 $this->assertIdentical([1 => 0], $json, 'The node has not yet been read.');
105 $this->drupalGet('node/' . $nid);
106 $this->assertCacheContext('user.roles:authenticated');
107 // JavaScript present to record the node read.
108 $settings = $this->getDrupalSettings();
109 $libraries = explode(',', $settings['ajaxPageState']['libraries']);
110 $this->assertTrue(in_array('history/mark-as-read', $libraries), 'history/mark-as-read library is present.');
111 $this->assertEqual([$nid => TRUE], $settings['history']['nodesToMarkAsRead'], 'drupalSettings to mark node as read are present.');
113 // Simulate JavaScript: perform HTTP request to mark node as read.
114 $response = $this->markNodeAsRead($nid);
115 $this->assertEquals(200, $response->getStatusCode());
116 $timestamp = Json::decode($response->getBody());
117 $this->assertTrue(is_numeric($timestamp), 'Node has been marked as read. Timestamp received.');
119 // Retrieve "last read" timestamp for test node, for the current user.
120 $response = $this->getNodeReadTimestamps([$nid]);
121 $this->assertEquals(200, $response->getStatusCode());
122 $json = Json::decode($response->getBody());
123 $this->assertIdentical([1 => $timestamp], $json, 'The node has been read.');
125 // Failing to specify node IDs for the first endpoint should return a 404.
126 $response = $this->getNodeReadTimestamps([]);
127 $this->assertEquals(404, $response->getStatusCode());
129 // Accessing either endpoint as the anonymous user should return a 403.
130 $this->drupalLogout();
131 $response = $this->getNodeReadTimestamps([$nid]);
132 $this->assertEquals(403, $response->getStatusCode());
133 $response = $this->getNodeReadTimestamps([]);
134 $this->assertEquals(403, $response->getStatusCode());
135 $response = $this->markNodeAsRead($nid);
136 $this->assertEquals(403, $response->getStatusCode());