Commit ef16fa1c authored by catch's avatar catch

Issue #2775553 by Wim Leers, naveenvalecha: Convert web tests to browser tests for REST module

parent 42c492cd
<?php
namespace Drupal\rest\Tests;
namespace Drupal\Tests\rest\Functional;
use Drupal\Core\Session\AccountInterface;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\rest\Entity\RestResourceConfig;
use Drupal\rest\RestResourceConfigInterface;
use Drupal\Tests\BrowserTestBase;
use Drupal\user\Entity\Role;
use Drupal\user\RoleInterface;
use GuzzleHttp\RequestOptions;
/**
* Tests the structure of a REST resource.
*
* @group rest
*/
class ResourceTest extends RESTTestBase {
class ResourceTest extends BrowserTestBase {
/**
* Modules to install.
......@@ -34,7 +38,14 @@ class ResourceTest extends RESTTestBase {
protected function setUp() {
parent::setUp();
// Create an entity programmatic.
$this->entity = $this->entityCreate('entity_test');
$this->entity = EntityTest::create([
'name' => $this->randomMachineName(),
'user_id' => 1,
'field_test_text' => [0 => [
'value' => $this->randomString(),
'format' => 'plain_text',
]],
]);
$this->entity->save();
Role::load(AccountInterface::ANONYMOUS_ROLE)
......@@ -46,7 +57,7 @@ protected function setUp() {
* Tests that a resource without formats cannot be enabled.
*/
public function testFormats() {
$this->resourceConfigStorage->create([
RestResourceConfig::create([
'id' => 'entity.entity_test',
'granularity' => RestResourceConfigInterface::METHOD_GRANULARITY,
'configuration' => [
......@@ -59,21 +70,20 @@ public function testFormats() {
])->save();
// Verify that accessing the resource returns 406.
$response = $this->httpRequest($this->entity->urlInfo()->setRouteParameter('_format', $this->defaultFormat), 'GET');
$this->drupalGet($this->entity->urlInfo()->setRouteParameter('_format', 'hal_json'));
// \Drupal\Core\Routing\RequestFormatRouteFilter considers the canonical,
// non-REST route a match, but a lower quality one: no format restrictions
// means there's always a match and hence when there is no matching REST
// route, the non-REST route is used, but can't render into
// application/hal+json, so it returns a 406.
$this->assertResponse('406', 'HTTP response code is 406 when the resource does not define formats, because it falls back to the canonical, non-REST route.');
$this->curlClose();
}
/**
* Tests that a resource without authentication cannot be enabled.
*/
public function testAuthentication() {
$this->resourceConfigStorage->create([
RestResourceConfig::create([
'id' => 'entity.entity_test',
'granularity' => RestResourceConfigInterface::METHOD_GRANULARITY,
'configuration' => [
......@@ -86,37 +96,55 @@ public function testAuthentication() {
])->save();
// Verify that accessing the resource returns 401.
$response = $this->httpRequest($this->entity->urlInfo()->setRouteParameter('_format', $this->defaultFormat), 'GET');
$this->drupalGet($this->entity->urlInfo()->setRouteParameter('_format', 'hal_json'));
// \Drupal\Core\Routing\RequestFormatRouteFilter considers the canonical,
// non-REST route a match, but a lower quality one: no format restrictions
// means there's always a match and hence when there is no matching REST
// route, the non-REST route is used, but can't render into
// application/hal+json, so it returns a 406.
$this->assertResponse('406', 'HTTP response code is 406 when the resource does not define formats, because it falls back to the canonical, non-REST route.');
$this->curlClose();
}
/**
* Tests that serialization_class is optional.
*/
public function testSerializationClassIsOptional() {
$this->enableService('serialization_test', 'POST', 'json');
RestResourceConfig::create([
'id' => 'serialization_test',
'granularity' => RestResourceConfigInterface::METHOD_GRANULARITY,
'configuration' => [
'POST' => [
'supported_formats' => [
'json',
],
'supported_auth' => [
'cookie',
]
],
],
])->save();
\Drupal::service('router.builder')->rebuildIfNeeded();
Role::load(RoleInterface::ANONYMOUS_ID)
->grantPermission('restful post serialization_test')
->save();
$serialized = $this->container->get('serializer')->serialize(['foo', 'bar'], 'json');
$this->httpRequest('serialization_test', 'POST', $serialized, 'application/json');
$this->assertResponse(200);
$this->assertResponseBody('["foo","bar"]');
$request_options = [
RequestOptions::HEADERS => ['Content-Type' => 'application/json'],
RequestOptions::BODY => $serialized,
];
/** @var \GuzzleHttp\ClientInterface $client */
$client = $this->getSession()->getDriver()->getClient()->getClient();
$response = $client->request('POST', $this->buildUrl('serialization_test', ['query' => ['_format' => 'json']]), $request_options);
$this->assertSame(200, $response->getStatusCode());
$this->assertSame('["foo","bar"]', (string) $response->getBody());
}
/**
* Tests that resource URI paths are formatted properly.
*/
public function testUriPaths() {
$this->enableService('entity:entity_test');
/** @var \Drupal\rest\Plugin\Type\ResourcePluginManager $manager */
$manager = \Drupal::service('plugin.manager.rest');
......
<?php
namespace Drupal\rest\Tests\Views;
namespace Drupal\Tests\rest\Functional\Views;
use Drupal\node\Entity\Node;
use Drupal\views\Tests\ViewTestBase;
use Drupal\Tests\views\Functional\ViewTestBase;
use Drupal\views\Tests\ViewTestData;
use Drupal\views\Views;
......@@ -43,8 +43,8 @@ class ExcludedFieldTokenTest extends ViewTestBase {
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
protected function setUp($import_test_views = TRUE) {
parent::setUp($import_test_views);
ViewTestData::createTestViews(get_class($this), ['rest_test_views']);
......@@ -66,7 +66,7 @@ protected function setUp() {
* Tests the display of an excluded title field when used as a token.
*/
public function testExcludedTitleTokenDisplay() {
$actual_json = $this->drupalGetWithFormat($this->view->getPath(), 'json');
$actual_json = $this->drupalGet($this->view->getPath(), ['query' => ['_format' => 'json']]);
$this->assertResponse(200);
$expected = [
......
<?php
namespace Drupal\rest\Tests\Views;
namespace Drupal\Tests\rest\Functional\Views;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Cache\Cache;
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
......@@ -10,10 +11,10 @@
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
use Drupal\Tests\views\Functional\ViewTestBase;
use Drupal\views\Entity\View;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Drupal\views\Views;
use Drupal\views\Tests\Plugin\PluginTestBase;
use Drupal\views\Tests\ViewTestData;
use Symfony\Component\HttpFoundation\Request;
......@@ -26,15 +27,10 @@
* @see \Drupal\rest\Plugin\views\row\DataEntityRow
* @see \Drupal\rest\Plugin\views\row\DataFieldRow
*/
class StyleSerializerTest extends PluginTestBase {
class StyleSerializerTest extends ViewTestBase {
use AssertPageCacheContextsAndTagsTrait;
/**
* {@inheritdoc}
*/
protected $dumpHeaders = TRUE;
/**
* Modules to install.
*
......@@ -54,8 +50,8 @@ class StyleSerializerTest extends PluginTestBase {
*/
protected $adminUser;
protected function setUp() {
parent::setUp();
protected function setUp($import_test_views = TRUE) {
parent::setUp($import_test_views);
ViewTestData::createTestViews(get_class($this), ['rest_test_views']);
......@@ -74,13 +70,13 @@ protected function setUp() {
*/
public function testRestViewsAuthentication() {
// Assume the view is hidden behind a permission.
$this->drupalGetWithFormat('test/serialize/auth_with_perm', 'json');
$this->drupalGet('test/serialize/auth_with_perm', ['query' => ['_format' => 'json']]);
$this->assertResponse(401);
// Not even logging in would make it possible to see the view, because then
// we are denied based on authentication method (cookie).
$this->drupalLogin($this->adminUser);
$this->drupalGetWithFormat('test/serialize/auth_with_perm', 'json');
$this->drupalGet('test/serialize/auth_with_perm', ['query' => ['_format' => 'json']]);
$this->assertResponse(403);
$this->drupalLogout();
......@@ -94,11 +90,6 @@ public function testRestViewsAuthentication() {
// Ensure that any changes to variables in the other thread are picked up.
$this->refreshVariables();
$headers = $response->getHeaders();
$this->verbose('GET request to: ' . $url .
'<hr />Code: ' . curl_getinfo($this->curlHandle, CURLINFO_HTTP_CODE) .
'<hr />Response headers: ' . nl2br(print_r($headers, TRUE)) .
'<hr />Response body: ' . (string) $response->getBody());
$this->assertResponse(200);
}
......@@ -111,7 +102,7 @@ public function testSerializerResponses() {
$view->initDisplay();
$this->executeView($view);
$actual_json = $this->drupalGetWithFormat('test/serialize/field', 'json');
$actual_json = $this->drupalGet('test/serialize/field', ['query' => ['_format' => 'json']]);
$this->assertResponse(200);
$this->assertCacheTags($view->getCacheTags());
$this->assertCacheContexts(['languages:language_interface', 'theme', 'request_format']);
......@@ -120,7 +111,7 @@ public function testSerializerResponses() {
// Test the http Content-type.
$headers = $this->drupalGetHeaders();
$this->assertEqual($headers['content-type'], 'application/json', 'The header Content-type is correct.');
$this->assertSame(['application/json'], $headers['Content-Type']);
$expected = [];
foreach ($view->result as $row) {
......@@ -161,7 +152,7 @@ public function testSerializerResponses() {
$expected = $serializer->serialize($entities, 'json');
$actual_json = $this->drupalGetWithFormat('test/serialize/entity', 'json');
$actual_json = $this->drupalGet('test/serialize/entity', ['query' => ['_format' => 'json']]);
$this->assertResponse(200);
$this->assertIdentical($actual_json, $expected, 'The expected JSON output was found.');
$expected_cache_tags = $view->getCacheTags();
......@@ -174,7 +165,7 @@ public function testSerializerResponses() {
$this->assertCacheContexts(['languages:language_interface', 'theme', 'entity_test_view_grants', 'request_format']);
$expected = $serializer->serialize($entities, 'hal_json');
$actual_json = $this->drupalGetWithFormat('test/serialize/entity', 'hal_json');
$actual_json = $this->drupalGet('test/serialize/entity', ['query' => ['_format' => 'hal_json']]);
$this->assertIdentical($actual_json, $expected, 'The expected HAL output was found.');
$this->assertCacheTags($expected_cache_tags);
......@@ -191,8 +182,8 @@ public function testSerializerResponses() {
]);
$view->save();
$expected = $serializer->serialize($entities, 'xml');
$actual_xml = $this->drupalGet('test/serialize/entity');
$this->assertIdentical($actual_xml, $expected, 'The expected XML output was found.');
$actual_xml = $this->drupalGet('test/serialize/entity', ['query' => ['_format' => 'xml']]);
$this->assertSame(trim($expected), $actual_xml);
$this->assertCacheContexts(['languages:language_interface', 'theme', 'entity_test_view_grants', 'request_format']);
// Allow multiple formats.
......@@ -209,11 +200,11 @@ public function testSerializerResponses() {
]);
$view->save();
$expected = $serializer->serialize($entities, 'json');
$actual_json = $this->drupalGetWithFormat('test/serialize/entity', 'json');
$actual_json = $this->drupalGet('test/serialize/entity', ['query' => ['_format' => 'json']]);
$this->assertIdentical($actual_json, $expected, 'The expected JSON output was found.');
$expected = $serializer->serialize($entities, 'xml');
$actual_xml = $this->drupalGetWithFormat('test/serialize/entity', 'xml');
$this->assertIdentical($actual_xml, $expected, 'The expected XML output was found.');
$actual_xml = $this->drupalGet('test/serialize/entity', ['query' => ['_format' => 'xml']]);
$this->assertSame(trim($expected), $actual_xml);
}
/**
......@@ -227,7 +218,7 @@ public function testSiteMaintenance() {
// Set the site to maintenance mode.
$this->container->get('state')->set('system.maintenance_mode', TRUE);
$this->drupalGetWithFormat('test/serialize/entity', 'json');
$this->drupalGet('test/serialize/entity', ['query' => ['_format' => 'json']]);
// Verify that the endpoint is unavailable for anonymous users.
$this->assertResponse(503);
}
......@@ -294,14 +285,14 @@ public function testRestRenderCaching() {
// Request the page, once in XML and once in JSON to ensure that the caching
// varies by it.
$result1 = $this->drupalGetJSON('test/serialize/entity');
$result1 = Json::decode($this->drupalGet('test/serialize/entity', ['query' => ['_format' => 'json']]));
$this->addRequestWithFormat('json');
$this->assertHeader('content-type', 'application/json');
$this->assertCacheContexts($cache_contexts);
$this->assertCacheTags($cache_tags);
$this->assertTrue($render_cache->get($original));
$result_xml = $this->drupalGetWithFormat('test/serialize/entity', 'xml');
$result_xml = $this->drupalGet('test/serialize/entity', ['query' => ['_format' => 'xml']]);
$this->addRequestWithFormat('xml');
$this->assertHeader('content-type', 'text/xml; charset=UTF-8');
$this->assertCacheContexts($cache_contexts);
......@@ -312,7 +303,7 @@ public function testRestRenderCaching() {
$this->assertNotEqual($result1, $result_xml);
// Ensure that the cached page works.
$result2 = $this->drupalGetJSON('test/serialize/entity');
$result2 = Json::decode($this->drupalGet('test/serialize/entity', ['query' => ['_format' => 'json']]));
$this->addRequestWithFormat('json');
$this->assertHeader('content-type', 'application/json');
$this->assertEqual($result2, $result1);
......@@ -322,7 +313,7 @@ public function testRestRenderCaching() {
// Create a new entity and ensure that the cache tags are taken over.
EntityTest::create(['name' => 'test_11', 'user_id' => $this->adminUser->id()])->save();
$result3 = $this->drupalGetJSON('test/serialize/entity');
$result3 = Json::decode($this->drupalGet('test/serialize/entity', ['query' => ['_format' => 'json']]));
$this->addRequestWithFormat('json');
$this->assertHeader('content-type', 'application/json');
$this->assertNotEqual($result3, $result2);
......@@ -350,11 +341,11 @@ public function testResponseFormatConfiguration() {
$this->drupalPostForm(NULL, [], t('Save'));
// Should return a 406.
$this->drupalGetWithFormat('test/serialize/field', 'json');
$this->drupalGet('test/serialize/field', ['query' => ['_format' => 'json']]);
$this->assertHeader('content-type', 'application/json');
$this->assertResponse(406, 'A 406 response was returned when JSON was requested.');
// Should return a 200.
$this->drupalGetWithFormat('test/serialize/field', 'xml');
$this->drupalGet('test/serialize/field', ['query' => ['_format' => 'xml']]);
$this->assertHeader('content-type', 'text/xml; charset=UTF-8');
$this->assertResponse(200, 'A 200 response was returned when XML was requested.');
......@@ -374,19 +365,19 @@ public function testResponseFormatConfiguration() {
$this->assertResponse(200, 'A 200 response was returned when a browser accept header was requested.');
// Should return a 200.
$this->drupalGetWithFormat('test/serialize/field', 'json');
$this->drupalGet('test/serialize/field', ['query' => ['_format' => 'json']]);
$this->assertHeader('content-type', 'application/json');
$this->assertResponse(200, 'A 200 response was returned when JSON was requested.');
$headers = $this->drupalGetHeaders();
$this->assertEqual($headers['content-type'], 'application/json', 'The header Content-type is correct.');
$this->assertEqual($headers['Content-Type'], ['application/json'], 'The header Content-type is correct.');
// Should return a 200.
$this->drupalGetWithFormat('test/serialize/field', 'xml');
$this->drupalGet('test/serialize/field', ['query' => ['_format' => 'xml']]);
$this->assertHeader('content-type', 'text/xml; charset=UTF-8');
$this->assertResponse(200, 'A 200 response was returned when XML was requested');
$headers = $this->drupalGetHeaders();
$this->assertTrue(strpos($headers['content-type'], 'text/xml') !== FALSE, 'The header Content-type is correct.');
$this->assertSame(['text/xml; charset=UTF-8'], $headers['Content-Type']);
// Should return a 406.
$this->drupalGetWithFormat('test/serialize/field', 'html');
$this->drupalGet('test/serialize/field', ['query' => ['_format' => 'html']]);
// We want to show the first format by default, see
// \Drupal\rest\Plugin\views\style\Serializer::render.
$this->assertHeader('content-type', 'application/json');
......@@ -396,15 +387,15 @@ public function testResponseFormatConfiguration() {
$this->drupalPostForm($style_options, ['style_options[formats][json]' => '0', 'style_options[formats][xml]' => '0'], t('Apply'));
// Should return a 200.
$this->drupalGetWithFormat('test/serialize/field', 'json');
$this->drupalGet('test/serialize/field', ['query' => ['_format' => 'json']]);
$this->assertHeader('content-type', 'application/json');
$this->assertResponse(200, 'A 200 response was returned when JSON was requested.');
// Should return a 200.
$this->drupalGetWithFormat('test/serialize/field', 'xml');
$this->drupalGet('test/serialize/field', ['query' => ['_format' => 'xml']]);
$this->assertHeader('content-type', 'text/xml; charset=UTF-8');
$this->assertResponse(200, 'A 200 response was returned when XML was requested');
// Should return a 200.
$this->drupalGetWithFormat('test/serialize/field', 'html');
$this->drupalGet('test/serialize/field', ['query' => ['_format' => 'html']]);
// We want to show the first format by default, see
// \Drupal\rest\Plugin\views\style\Serializer::render.
$this->assertHeader('content-type', 'application/json');
......@@ -440,7 +431,7 @@ public function testUIFieldAlias() {
$expected[] = $expected_row;
}
$this->assertIdentical($this->drupalGetJSON('test/serialize/field'), $this->castSafeStrings($expected));
$this->assertIdentical(Json::decode($this->drupalGet('test/serialize/field', ['query' => ['_format' => 'json']])), $this->castSafeStrings($expected));
// Test a random aliases for fields, they should be replaced.
$alias_map = [
......@@ -475,7 +466,7 @@ public function testUIFieldAlias() {
$expected[] = $expected_row;
}
$this->assertIdentical($this->drupalGetJSON('test/serialize/field'), $this->castSafeStrings($expected));
$this->assertIdentical(Json::decode($this->drupalGet('test/serialize/field', ['query' => ['_format' => 'json']])), $this->castSafeStrings($expected));
}
/**
......@@ -512,7 +503,7 @@ public function testFieldRawOutput() {
}
// Just test the raw 'created' value against each row.
foreach ($this->drupalGetJSON('test/serialize/field') as $index => $values) {
foreach (Json::decode($this->drupalGet('test/serialize/field', ['query' => ['_format' => 'json']])) as $index => $values) {
$this->assertIdentical($values['created'], $view->result[$index]->views_test_data_created, 'Expected raw created value found.');
$this->assertIdentical($values['name'], $view->result[$index]->views_test_data_name, 'Expected raw name value found.');
}
......@@ -536,7 +527,7 @@ public function testFieldRawOutput() {
]);
$view->save();
$this->executeView($view);
foreach ($this->drupalGetJSON('test/serialize/field') as $index => $values) {
foreach (Json::decode($this->drupalGet('test/serialize/field', ['query' => ['_format' => 'json']])) as $index => $values) {
$this->assertTrue(!isset($values['created']), 'Excluded value not found.');
}
// Test that the excluded field is not shown in the row options.
......@@ -606,7 +597,8 @@ public function testSerializerViewsUI() {
$this->assertResponse(200);
// Check if we receive the expected result.
$result = $this->xpath('//div[@id="views-live-preview"]/pre');
$this->assertIdentical($this->drupalGet('test/serialize/field'), (string) $result[0], 'The expected JSON preview output was found.');
$json_preview = $result[0]->getText();
$this->assertSame($json_preview, $this->drupalGet('test/serialize/field'), 'The expected JSON preview output was found.');
}
/**
......@@ -616,7 +608,7 @@ public function testFieldapiField() {
$this->drupalCreateContentType(['type' => 'page']);
$node = $this->drupalCreateNode();
$result = $this->drupalGetJSON('test/serialize/node-field');
$result = Json::decode($this->drupalGet('test/serialize/node-field', ['query' => ['_format' => 'json']]));
$this->assertEqual($result[0]['nid'], $node->id());
$this->assertEqual($result[0]['body'], $node->body->processed);
......@@ -627,7 +619,7 @@ public function testFieldapiField() {
'format' => filter_default_format(),
];
$node->save();
$result = $this->drupalGetJSON('test/serialize/node-field');
$result = Json::decode($this->drupalGet('test/serialize/node-field', ['query' => ['_format' => 'json']]));
$this->assertEqual($result[1]['nid'], $node->id());
$this->assertTrue(strpos($this->getRawContent(), "<script") === FALSE, "No script tag is present in the raw page contents.");
......@@ -646,7 +638,7 @@ public function testFieldapiField() {
$this->executeView($view);
// Test the raw 'created' value against each row.
foreach ($this->drupalGetJSON('test/serialize/node-field') as $index => $values) {
foreach (Json::decode($this->drupalGet('test/serialize/node-field', ['query' => ['_format' => 'json']])) as $index => $values) {
$this->assertIdentical($values['title'], $view->result[$index]->_entity->title->value, 'Expected raw title value found.');
}
......@@ -673,7 +665,7 @@ public function testFieldapiField() {
$view->setDisplay('rest_export_1');
$this->executeView($view);
$result = $this->drupalGetJSON('test/serialize/node-field');
$result = Json::decode($this->drupalGet('test/serialize/node-field', ['query' => ['_format' => 'json']]));
$this->assertEqual(count($result[2]['body']), $node->body->count(), 'Expected count of values');
$this->assertEqual($result[2]['body'], array_map(function($item) { return $item['value']; }, $node->body->getValue()), 'Expected raw body values found.');
}
......@@ -755,7 +747,7 @@ public function testRestViewExposedFilter() {
$node2 = $this->drupalCreateNode(['title' => 'Node 111']);
// Test that no filter brings back all three nodes.
$result = $this->drupalGetJSON('test/serialize/node-exposed-filter');
$result = Json::decode($this->drupalGet('test/serialize/node-exposed-filter', ['query' => ['_format' => 'json']]));
$expected = [
0 => [
......@@ -775,7 +767,7 @@ public function testRestViewExposedFilter() {
$this->assertEqual($result, $expected, 'Querying a view with no exposed filter returns all nodes.');
// Test that title starts with 'Node 11' query finds 2 of the 3 nodes.
$result = $this->drupalGetJSON('test/serialize/node-exposed-filter', ['query' => ['title' => 'Node 11']]);
$result = Json::decode($this->drupalGet('test/serialize/node-exposed-filter', ['query' => ['_format' => 'json', 'title' => 'Node 11']]));
$expected = [
0 => [
......@@ -822,7 +814,7 @@ public function testMulEntityRows() {
$entity->addTranslation('l1', ['name' => 'mul-l2-l1'])->save();
// Get the names of the output.
$json = $this->drupalGetWithFormat('test/serialize/translated_entity', 'json');
$json = $this->drupalGet('test/serialize/translated_entity', ['query' => ['_format' => 'json']]);
$decoded = $this->container->get('serializer')->decode($json, 'hal_json');
$names = [];
foreach ($decoded as $item) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment