diff --git a/core/modules/history/src/Tests/HistoryTest.php b/core/modules/history/src/Tests/HistoryTest.php deleted file mode 100644 index b74ba6b4548b9087c024641838b7ccc27e0550a9..0000000000000000000000000000000000000000 --- a/core/modules/history/src/Tests/HistoryTest.php +++ /dev/null @@ -1,148 +0,0 @@ -drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); - - $this->user = $this->drupalCreateUser(['create page content', 'access content']); - $this->drupalLogin($this->user); - $this->testNode = $this->drupalCreateNode(['type' => 'page', 'uid' => $this->user->id()]); - } - - /** - * Get node read timestamps from the server for the current user. - * - * @param array $node_ids - * An array of node IDs. - * - * @return string - * The response body. - */ - protected function getNodeReadTimestamps(array $node_ids) { - // Build POST values. - $post = []; - for ($i = 0; $i < count($node_ids); $i++) { - $post['node_ids[' . $i . ']'] = $node_ids[$i]; - } - - // Serialize POST values. - foreach ($post as $key => $value) { - // Encode according to application/x-www-form-urlencoded - // Both names and values needs to be urlencoded, according to - // http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1 - $post[$key] = urlencode($key) . '=' . urlencode($value); - } - $post = implode('&', $post); - - // Perform HTTP request. - return $this->curlExec([ - CURLOPT_URL => \Drupal::url('history.get_last_node_view', [], ['absolute' => TRUE]), - CURLOPT_POST => TRUE, - CURLOPT_POSTFIELDS => $post, - CURLOPT_HTTPHEADER => [ - 'Accept: application/json', - 'Content-Type: application/x-www-form-urlencoded', - ], - ]); - } - - /** - * Mark a node as read for the current user. - * - * @param int $node_id - * A node ID. - * - * @return string - * The response body. - */ - protected function markNodeAsRead($node_id) { - return $this->curlExec([ - CURLOPT_URL => \Drupal::url('history.read_node', ['node' => $node_id], ['absolute' => TRUE]), - CURLOPT_HTTPHEADER => [ - 'Accept: application/json', - ], - ]); - } - - /** - * Verifies that the history endpoints work. - */ - public function testHistory() { - $nid = $this->testNode->id(); - - // Retrieve "last read" timestamp for test node, for the current user. - $response = $this->getNodeReadTimestamps([$nid]); - $this->assertResponse(200); - $json = Json::decode($response); - $this->assertIdentical([1 => 0], $json, 'The node has not yet been read.'); - - // View the node. - $this->drupalGet('node/' . $nid); - $this->assertCacheContext('user.roles:authenticated'); - // JavaScript present to record the node read. - $settings = $this->getDrupalSettings(); - $libraries = explode(',', $settings['ajaxPageState']['libraries']); - $this->assertTrue(in_array('history/mark-as-read', $libraries), 'history/mark-as-read library is present.'); - $this->assertEqual([$nid => TRUE], $settings['history']['nodesToMarkAsRead'], 'drupalSettings to mark node as read are present.'); - - // Simulate JavaScript: perform HTTP request to mark node as read. - $response = $this->markNodeAsRead($nid); - $this->assertResponse(200); - $timestamp = Json::decode($response); - $this->assertTrue(is_numeric($timestamp), 'Node has been marked as read. Timestamp received.'); - - // Retrieve "last read" timestamp for test node, for the current user. - $response = $this->getNodeReadTimestamps([$nid]); - $this->assertResponse(200); - $json = Json::decode($response); - $this->assertIdentical([1 => $timestamp], $json, 'The node has been read.'); - - // Failing to specify node IDs for the first endpoint should return a 404. - $this->getNodeReadTimestamps([]); - $this->assertResponse(404); - - // Accessing either endpoint as the anonymous user should return a 403. - $this->drupalLogout(); - $this->getNodeReadTimestamps([$nid]); - $this->assertResponse(403); - $this->getNodeReadTimestamps([]); - $this->assertResponse(403); - $this->markNodeAsRead($nid); - $this->assertResponse(403); - } - -} diff --git a/core/modules/history/tests/src/Functional/HistoryTest.php b/core/modules/history/tests/src/Functional/HistoryTest.php new file mode 100644 index 0000000000000000000000000000000000000000..6b4708b89801a29a4c63478b07ec6b73eb5b942d --- /dev/null +++ b/core/modules/history/tests/src/Functional/HistoryTest.php @@ -0,0 +1,174 @@ +drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); + + $this->user = $this->drupalCreateUser(['create page content', 'access content']); + $this->drupalLogin($this->user); + $this->testNode = $this->drupalCreateNode(['type' => 'page', 'uid' => $this->user->id()]); + + $this->client = $this->getHttpClient(); + } + + /** + * Get node read timestamps from the server for the current user. + * + * @param array $node_ids + * An array of node IDs. + * + * @return \Psr\Http\Message\ResponseInterface + * The response object. + */ + protected function getNodeReadTimestamps(array $node_ids) { + // Perform HTTP request. + $url = Url::fromRoute('history.get_last_node_view') + ->setAbsolute() + ->toString(); + return $this->client->post($url, [ + 'body' => http_build_query(['node_ids' => $node_ids]), + 'cookies' => $this->cookies, + 'headers' => [ + 'Accept' => 'application/json', + 'Content-Type' => 'application/x-www-form-urlencoded', + ], + 'http_errors' => FALSE, + ]); + } + + /** + * Mark a node as read for the current user. + * + * @param int $node_id + * A node ID. + * + * @return \Psr\Http\Message\ResponseInterface + * The response body. + */ + protected function markNodeAsRead($node_id) { + $url = Url::fromRoute('history.read_node', ['node' => $node_id], ['absolute' => TRUE])->toString(); + return $this->client->post($url, [ + 'cookies' => $this->cookies, + 'headers' => [ + 'Accept' => 'application/json', + ], + 'http_errors' => FALSE, + ]); + } + + /** + * Verifies that the history endpoints work. + */ + public function testHistory() { + $nid = $this->testNode->id(); + + // Retrieve "last read" timestamp for test node, for the current user. + $response = $this->getNodeReadTimestamps([$nid]); + $this->assertEquals(200, $response->getStatusCode()); + $json = Json::decode($response->getBody()); + $this->assertIdentical([1 => 0], $json, 'The node has not yet been read.'); + + // View the node. + $this->drupalGet('node/' . $nid); + $this->assertCacheContext('user.roles:authenticated'); + // JavaScript present to record the node read. + $settings = $this->getDrupalSettings(); + $libraries = explode(',', $settings['ajaxPageState']['libraries']); + $this->assertTrue(in_array('history/mark-as-read', $libraries), 'history/mark-as-read library is present.'); + $this->assertEqual([$nid => TRUE], $settings['history']['nodesToMarkAsRead'], 'drupalSettings to mark node as read are present.'); + + // Simulate JavaScript: perform HTTP request to mark node as read. + $response = $this->markNodeAsRead($nid); + $this->assertEquals(200, $response->getStatusCode()); + $timestamp = Json::decode($response->getBody()); + $this->assertTrue(is_numeric($timestamp), 'Node has been marked as read. Timestamp received.'); + + // Retrieve "last read" timestamp for test node, for the current user. + $response = $this->getNodeReadTimestamps([$nid]); + $this->assertEquals(200, $response->getStatusCode()); + $json = Json::decode($response->getBody()); + $this->assertIdentical([1 => $timestamp], $json, 'The node has been read.'); + + // Failing to specify node IDs for the first endpoint should return a 404. + $response = $this->getNodeReadTimestamps([]); + $this->assertEquals(404, $response->getStatusCode()); + + // Accessing either endpoint as the anonymous user should return a 403. + $this->drupalLogout(); + $response = $this->getNodeReadTimestamps([$nid]); + $this->assertEquals(403, $response->getStatusCode()); + $response = $this->getNodeReadTimestamps([]); + $this->assertEquals(403, $response->getStatusCode()); + $response = $this->markNodeAsRead($nid); + $this->assertEquals(403, $response->getStatusCode()); + } + + /** + * Obtain the HTTP client and set the cookies. + * + * @return \GuzzleHttp\Client + * The client with BrowserTestBase configuration. + */ + protected function getHttpClient() { + // Similar code is also employed to test CSRF tokens. + // @see \Drupal\Tests\system\Functional\CsrfRequestHeaderTest::testRouteAccess() + $domain = parse_url($this->getUrl(), PHP_URL_HOST); + $session_id = $this->getSession()->getCookie($this->getSessionName()); + $this->cookies = CookieJar::fromArray([$this->getSessionName() => $session_id], $domain); + return $this->getSession()->getDriver()->getClient()->getClient(); + } + +}