updated core from 8.4 to 8.5 : bug with login_destination

This commit is contained in:
Bachir Soussi Chiadmi
2018-03-13 14:01:21 +01:00
parent 0d78da249b
commit e668535a4e
3486 changed files with 89604 additions and 33283 deletions
@@ -6,8 +6,8 @@ package: Testing
dependencies:
- config_test
# Information added by Drupal.org packaging script on 2018-01-03
version: '8.4.4'
# Information added by Drupal.org packaging script on 2018-03-07
version: '8.5.0'
core: '8.x'
project: 'drupal'
datestamp: 1515021228
datestamp: 1520457825
@@ -7,8 +7,8 @@ package: Testing
dependencies:
- rest
# Information added by Drupal.org packaging script on 2018-01-03
version: '8.4.4'
# Information added by Drupal.org packaging script on 2018-03-07
version: '8.5.0'
core: '8.x'
project: 'drupal'
datestamp: 1515021228
datestamp: 1520457825
@@ -14,19 +14,32 @@ use Drupal\Core\Access\AccessResult;
* Implements hook_entity_field_access().
*
* @see \Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase::setUp()
* @see \Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase::testPost()
*/
function rest_test_entity_field_access($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
// @see \Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase::testPost()
// @see \Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase::testPatch()
if ($field_definition->getName() === 'field_rest_test') {
switch ($operation) {
case 'view':
// Never ever allow this field to be viewed: this lets EntityResourceTestBase::testGet() test in a "vanilla" way.
// Never ever allow this field to be viewed: this lets
// EntityResourceTestBase::testGet() test in a "vanilla" way.
return AccessResult::forbidden();
case 'edit':
return AccessResult::forbidden();
}
}
// @see \Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase::testGet()
// @see \Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase::testPatch()
if ($field_definition->getName() === 'field_rest_test_multivalue') {
switch ($operation) {
case 'view':
// Never ever allow this field to be viewed: this lets
// EntityResourceTestBase::testGet() test in a "vanilla" way.
return AccessResult::forbidden();
}
}
// No opinion.
return AccessResult::neutral();
}
@@ -7,3 +7,8 @@ services:
class: Drupal\rest_test\Authentication\Provider\TestAuthGlobal
tags:
- { name: authentication_provider, provider_id: 'rest_test_auth_global', global: TRUE }
rest_test.page_cache_request_policy.deny_test_auth_requests:
class: Drupal\rest_test\PageCache\RequestPolicy\DenyTestAuthRequests
public: false
tags:
- { name: page_cache_request_policy }
@@ -0,0 +1,31 @@
<?php
namespace Drupal\rest_test\PageCache\RequestPolicy;
use Drupal\Core\PageCache\RequestPolicyInterface;
use Symfony\Component\HttpFoundation\Request;
/**
* Cache policy for pages requested with REST Test Auth.
*
* This policy disallows caching of requests that use the REST Test Auth
* authentication provider for security reasons (just like basic_auth).
* Otherwise responses for authenticated requests can get into the page cache
* and could be delivered to unprivileged users.
*
* @see \Drupal\rest_test\Authentication\Provider\TestAuth
* @see \Drupal\rest_test\Authentication\Provider\TestAuthGlobal
* @see \Drupal\basic_auth\PageCache\DisallowBasicAuthRequests
*/
class DenyTestAuthRequests implements RequestPolicyInterface {
/**
* {@inheritdoc}
*/
public function check(Request $request) {
if ($request->headers->has('REST-test-auth') || $request->headers->has('REST-test-auth-global')) {
return self::DENY;
}
}
}
@@ -25,7 +25,7 @@ class NoSerializationClassTestResource extends ResourceBase {
*
* @return \Drupal\rest\ResourceResponse
*/
public function post(array $data = []) {
public function post(array $data) {
return new ResourceResponse($data);
}
@@ -8,8 +8,8 @@ dependencies:
- rest
- views
# Information added by Drupal.org packaging script on 2018-01-03
version: '8.4.4'
# Information added by Drupal.org packaging script on 2018-03-07
version: '8.5.0'
core: '8.x'
project: 'drupal'
datestamp: 1515021228
datestamp: 1520457825
@@ -0,0 +1,70 @@
langcode: en
status: true
dependencies:
module:
- rest
- user
id: test_serializer_shared_path
label: 'Test serializer shared path'
module: rest
description: ''
tag: ''
base_table: entity_test
base_field: id
core: 8.x
display:
default:
display_plugin: default
id: default
display_title: Master
position: null
display_options:
access:
type: perm
options:
perm: 'access content'
cache:
type: tag
query:
type: views_query
exposed_form:
type: basic
style:
type: serializer
row:
type: data_entity
sorts:
id:
id: standard
table: entity_test
field: id
order: DESC
plugin_id: date
entity_type: entity_test
entity_field: id
title: 'Test serialize'
arguments: { }
rest_export_1:
display_plugin: rest_export
id: rest_export_1
display_title: serializer
position: null
display_options:
defaults:
access: false
path: test/serialize/shared
page_1:
display_plugin: page
id: page_1
display_title: page
position: null
display_options:
defaults:
access: false
style: false
row: false
style:
type: default
row:
type: entity:entity_test
path: test/serialize/shared
@@ -24,7 +24,7 @@ trait AnonResourceTestTrait {
/**
* {@inheritdoc}
*/
protected function assertResponseWhenMissingAuthentication(ResponseInterface $response) {
protected function assertResponseWhenMissingAuthentication($method, ResponseInterface $response) {
throw new \LogicException('When testing for anonymous users, authentication cannot be missing.');
}
@@ -14,6 +14,8 @@ use Psr\Http\Message\ResponseInterface;
* authenticated, a 401 response must be sent.
* - Because every request must send an authorization, there is no danger of
* CSRF attacks.
*
* @see \Drupal\Tests\rest\Functional\BasicAuthResourceWithInterfaceTranslationTestTrait
*/
trait BasicAuthResourceTestTrait {
@@ -31,8 +33,11 @@ trait BasicAuthResourceTestTrait {
/**
* {@inheritdoc}
*/
protected function assertResponseWhenMissingAuthentication(ResponseInterface $response) {
$this->assertResourceErrorResponse(401, 'No authentication credentials provided.', $response);
protected function assertResponseWhenMissingAuthentication($method, ResponseInterface $response) {
$expected_page_cache_header_value = $method === 'GET' ? 'MISS' : FALSE;
// @see \Drupal\basic_auth\Authentication\Provider\BasicAuth::challengeException()
$expected_dynamic_page_cache_header_value = $expected_page_cache_header_value;
$this->assertResourceErrorResponse(401, 'No authentication credentials provided.', $response, ['4xx-response', 'config:system.site', 'config:user.role.anonymous', 'http_response'], ['user.roles:anonymous'], $expected_page_cache_header_value, $expected_dynamic_page_cache_header_value);
}
/**
@@ -0,0 +1,28 @@
<?php
namespace Drupal\Tests\rest\Functional;
use Psr\Http\Message\ResponseInterface;
/**
* Trait for ResourceTestBase subclasses testing $auth=basic_auth + 'language'.
*
* @see \Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait
*/
trait BasicAuthResourceWithInterfaceTranslationTestTrait {
use BasicAuthResourceTestTrait;
/**
* {@inheritdoc}
*/
protected function assertResponseWhenMissingAuthentication($method, ResponseInterface $response) {
// Because BasicAuth::challengeException() relies on the 'system.site'
// configuration, and this test installs the 'language' module, all config
// may be translated and therefore gets the 'languages:language_interface'
// cache context.
$expected_page_cache_header_value = $method === 'GET' ? 'MISS' : FALSE;
$this->assertResourceErrorResponse(401, 'No authentication credentials provided.', $response, ['4xx-response', 'config:system.site', 'config:user.role.anonymous', 'http_response'], ['languages:language_interface', 'user.roles:anonymous'], $expected_page_cache_header_value, $expected_page_cache_header_value);
}
}
@@ -61,7 +61,7 @@ trait CookieResourceTestTrait {
'pass' => $this->account->passRaw,
];
$request_options[RequestOptions::BODY] = $this->serializer->encode($request_body, 'json');
$request_options[RequestOptions::BODY] = $this->serializer->encode($request_body, static::$format);
$request_options[RequestOptions::HEADERS] = [
'Content-Type' => static::$mimeType,
];
@@ -91,11 +91,31 @@ trait CookieResourceTestTrait {
/**
* {@inheritdoc}
*/
protected function assertResponseWhenMissingAuthentication(ResponseInterface $response) {
protected function assertResponseWhenMissingAuthentication($method, ResponseInterface $response) {
// Requests needing cookie authentication but missing it results in a 403
// response. The cookie authentication mechanism sets no response message.
// Hence, effectively, this is just the 403 response that one gets as the
// anonymous user trying to access a certain REST resource.
// @see \Drupal\user\Authentication\Provider\Cookie
// @todo https://www.drupal.org/node/2847623
$this->assertResourceErrorResponse(403, FALSE, $response);
if ($method === 'GET') {
$expected_cookie_403_cacheability = $this->getExpectedUnauthorizedAccessCacheability();
// - \Drupal\Core\EventSubscriber\AnonymousUserResponseSubscriber applies
// to cacheable anonymous responses: it updates their cacheability.
// - A 403 response to a GET request is cacheable.
// Therefore we must update our cacheability expectations accordingly.
if (in_array('user.permissions', $expected_cookie_403_cacheability->getCacheContexts(), TRUE)) {
$expected_cookie_403_cacheability->addCacheTags(['config:user.role.anonymous']);
}
// @todo Fix \Drupal\block\BlockAccessControlHandler::mergeCacheabilityFromConditions() in https://www.drupal.org/node/2867881
if (static::$entityTypeId === 'block') {
$expected_cookie_403_cacheability->setCacheTags(str_replace('user:2', 'user:0', $expected_cookie_403_cacheability->getCacheTags()));
}
$this->assertResourceErrorResponse(403, FALSE, $response, $expected_cookie_403_cacheability->getCacheTags(), $expected_cookie_403_cacheability->getCacheContexts(), 'MISS', 'MISS');
}
else {
$this->assertResourceErrorResponse(403, FALSE, $response);
}
}
/**
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\Action;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class ActionXmlAnonTest extends ActionResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\Action;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class ActionXmlBasicAuthTest extends ActionResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\Action;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class ActionXmlCookieTest extends ActionResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\BaseFieldOverride;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class BaseFieldOverrideXmlAnonTest extends BaseFieldOverrideResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\BaseFieldOverride;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class BaseFieldOverrideXmlBasicAuthTest extends BaseFieldOverrideResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\BaseFieldOverride;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class BaseFieldOverrideXmlCookieTest extends BaseFieldOverrideResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -141,4 +141,19 @@ abstract class BlockResourceTestBase extends EntityResourceTestBase {
}
}
/**
* {@inheritdoc}
*/
protected function getExpectedUnauthorizedAccessCacheability() {
// @see \Drupal\block\BlockAccessControlHandler::checkAccess()
return parent::getExpectedUnauthorizedAccessCacheability()
->setCacheTags([
'4xx-response',
'config:block.block.llama',
'http_response',
static::$auth ? 'user:2' : 'user:0',
])
->setCacheContexts(['user.roles']);
}
}
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\Block;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class BlockXmlAnonTest extends BlockResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\Block;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class BlockXmlBasicAuthTest extends BlockResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\Block;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class BlockXmlCookieTest extends BlockResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,24 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\BlockContent;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
/**
* @group rest
*/
class BlockContentJsonAnonTest extends BlockContentResourceTestBase {
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
}
@@ -0,0 +1,34 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\BlockContent;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
/**
* @group rest
*/
class BlockContentJsonBasicAuthTest extends BlockContentResourceTestBase {
use BasicAuthResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,29 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\BlockContent;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
/**
* @group rest
*/
class BlockContentJsonCookieTest extends BlockContentResourceTestBase {
use CookieResourceTestTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,199 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\BlockContent;
use Drupal\block_content\Entity\BlockContent;
use Drupal\block_content\Entity\BlockContentType;
use Drupal\Core\Cache\Cache;
use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
/**
* ResourceTestBase for BlockContent entity.
*/
abstract class BlockContentResourceTestBase extends EntityResourceTestBase {
use BcTimestampNormalizerUnixTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['block_content'];
/**
* {@inheritdoc}
*/
protected static $entityTypeId = 'block_content';
/**
* {@inheritdoc}
*/
protected static $patchProtectedFieldNames = [
'changed',
];
/**
* @var \Drupal\block_content\BlockContentInterface
*/
protected $entity;
/**
* {@inheritdoc}
*/
protected function setUpAuthorization($method) {
$this->grantPermissionsToTestedRole(['administer blocks']);
}
/**
* {@inheritdoc}
*/
protected function createEntity() {
if (!BlockContentType::load('basic')) {
$block_content_type = BlockContentType::create([
'id' => 'basic',
'label' => 'basic',
'revision' => TRUE,
]);
$block_content_type->save();
block_content_add_body_field($block_content_type->id());
}
// Create a "Llama" custom block.
$block_content = BlockContent::create([
'info' => 'Llama',
'type' => 'basic',
'body' => [
'value' => 'The name "llama" was adopted by European settlers from native Peruvians.',
'format' => 'plain_text',
],
])
->setPublished(FALSE);
$block_content->save();
return $block_content;
}
/**
* {@inheritdoc}
*/
protected function getExpectedNormalizedEntity() {
return [
'id' => [
[
'value' => 1,
],
],
'uuid' => [
[
'value' => $this->entity->uuid(),
],
],
'langcode' => [
[
'value' => 'en',
],
],
'type' => [
[
'target_id' => 'basic',
'target_type' => 'block_content_type',
'target_uuid' => BlockContentType::load('basic')->uuid(),
],
],
'info' => [
[
'value' => 'Llama',
],
],
'revision_log' => [],
'changed' => [
$this->formatExpectedTimestampItemValues($this->entity->getChangedTime()),
],
'revision_id' => [
[
'value' => 1,
],
],
'revision_created' => [
$this->formatExpectedTimestampItemValues((int) $this->entity->getRevisionCreationTime()),
],
'revision_user' => [],
'revision_translation_affected' => [
[
'value' => TRUE,
],
],
'default_langcode' => [
[
'value' => TRUE,
],
],
'body' => [
[
'value' => 'The name "llama" was adopted by European settlers from native Peruvians.',
'format' => 'plain_text',
'summary' => NULL,
'processed' => "<p>The name &quot;llama&quot; was adopted by European settlers from native Peruvians.</p>\n",
],
],
'status' => [
[
'value' => FALSE,
],
],
];
}
/**
* {@inheritdoc}
*/
protected function getNormalizedPostEntity() {
return [
'type' => [
[
'target_id' => 'basic',
],
],
'info' => [
[
'value' => 'Dramallama',
],
],
];
}
/**
* {@inheritdoc}
*/
protected function getExpectedUnauthorizedAccessMessage($method) {
if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) {
return parent::getExpectedUnauthorizedAccessMessage($method);
}
return parent::getExpectedUnauthorizedAccessMessage($method);
}
/**
* {@inheritdoc}
*/
protected function getExpectedUnauthorizedAccessCacheability() {
// @see \Drupal\block_content\BlockContentAccessControlHandler()
return parent::getExpectedUnauthorizedAccessCacheability()
->addCacheTags(['block_content:1']);
}
/**
* {@inheritdoc}
*/
protected function getExpectedCacheTags() {
return Cache::mergeTags(parent::getExpectedCacheTags(), ['config:filter.format.plain_text']);
}
/**
* {@inheritdoc}
*/
protected function getExpectedCacheContexts() {
return Cache::mergeContexts(['url.site'], $this->container->getParameter('renderer.config')['required_cache_contexts']);
}
}
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\BlockContent;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class BlockContentXmlAnonTest extends BlockContentResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\BlockContent;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class BlockContentXmlBasicAuthTest extends BlockContentResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\BlockContent;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class BlockContentXmlCookieTest extends BlockContentResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\BlockContentType;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class BlockContentTypeXmlAnonTest extends BlockContentTypeResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\BlockContentType;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class BlockContentTypeXmlBasicAuthTest extends BlockContentTypeResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\BlockContentType;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class BlockContentTypeXmlCookieTest extends BlockContentTypeResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -5,6 +5,7 @@ namespace Drupal\Tests\rest\Functional\EntityResource\Comment;
use Drupal\comment\Entity\Comment;
use Drupal\comment\Entity\CommentType;
use Drupal\comment\Tests\CommentTestTrait;
use Drupal\Core\Cache\Cache;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
@@ -197,6 +198,7 @@ abstract class CommentResourceTestBase extends EntityResourceTestBase {
[
'value' => 'The name "llama" was adopted by European settlers from native Peruvians.',
'format' => 'plain_text',
'processed' => '<p>The name &quot;llama&quot; was adopted by European settlers from native Peruvians.</p>' . "\n",
],
],
];
@@ -248,6 +250,20 @@ abstract class CommentResourceTestBase extends EntityResourceTestBase {
return array_diff_key($this->getNormalizedPostEntity(), ['entity_type' => TRUE, 'entity_id' => TRUE, 'field_name' => TRUE]);
}
/**
* {@inheritdoc}
*/
protected function getExpectedCacheTags() {
return Cache::mergeTags(parent::getExpectedCacheTags(), ['config:filter.format.plain_text']);
}
/**
* {@inheritdoc}
*/
protected function getExpectedCacheContexts() {
return Cache::mergeContexts(['languages:language_interface', 'theme'], parent::getExpectedCacheContexts());
}
/**
* Tests POSTing a comment without critical base fields.
*
@@ -357,4 +373,13 @@ abstract class CommentResourceTestBase extends EntityResourceTestBase {
$this->assertTrue($unserialized->getStatus());
}
/**
* {@inheritdoc}
*/
protected function getExpectedUnauthorizedAccessCacheability() {
// @see \Drupal\comment\CommentAccessControlHandler::checkAccess()
return parent::getExpectedUnauthorizedAccessCacheability()
->addCacheTags(['comment:1']);
}
}
@@ -0,0 +1,63 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\Comment;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class CommentXmlAnonTest extends CommentResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*
* Anononymous users cannot edit their own comments.
*
* @see \Drupal\comment\CommentAccessControlHandler::checkAccess
*
* Therefore we grant them the 'administer comments' permission for the
* purpose of this test.
*
* @see ::setUpAuthorization
*/
protected static $patchProtectedFieldNames = [
'pid',
'entity_id',
'changed',
'thread',
'entity_type',
'field_name',
];
/**
* {@inheritdoc}
*/
public function testPostDxWithoutCriticalBaseFields() {
// Deserialization of the XML format is not supported.
$this->markTestSkipped();
}
/**
* {@inheritdoc}
*/
public function testPostSkipCommentApproval() {
// Deserialization of the XML format is not supported.
$this->markTestSkipped();
}
}
@@ -0,0 +1,52 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\Comment;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class CommentXmlBasicAuthTest extends CommentResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
/**
* {@inheritdoc}
*/
public function testPostDxWithoutCriticalBaseFields() {
// Deserialization of the XML format is not supported.
$this->markTestSkipped();
}
/**
* {@inheritdoc}
*/
public function testPostSkipCommentApproval() {
// Deserialization of the XML format is not supported.
$this->markTestSkipped();
}
}
@@ -0,0 +1,47 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\Comment;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class CommentXmlCookieTest extends CommentResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
/**
* {@inheritdoc}
*/
public function testPostDxWithoutCriticalBaseFields() {
// Deserialization of the XML format is not supported.
$this->markTestSkipped();
}
/**
* {@inheritdoc}
*/
public function testPostSkipCommentApproval() {
// Deserialization of the XML format is not supported.
$this->markTestSkipped();
}
}
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\CommentType;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class CommentTypeXmlAnonTest extends CommentTypeResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\CommentType;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class CommentTypeXmlBasicAuthTest extends CommentTypeResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\CommentType;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class CommentTypeXmlCookieTest extends CommentTypeResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\ConfigTest;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class ConfigTestXmlAnonTest extends ConfigTestResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\ConfigTest;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class ConfigTestXmlBasicAuthTest extends ConfigTestResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\ConfigTest;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class ConfigTestXmlCookieTest extends ConfigTestResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -2,14 +2,14 @@
namespace Drupal\Tests\rest\Functional\EntityResource\ConfigurableLanguage;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\BasicAuthResourceWithInterfaceTranslationTestTrait;
/**
* @group rest
*/
class ConfigurableLanguageJsonBasicAuthTest extends ConfigurableLanguageResourceTestBase {
use BasicAuthResourceTestTrait;
use BasicAuthResourceWithInterfaceTranslationTestTrait;
/**
* {@inheritdoc}
@@ -3,6 +3,7 @@
namespace Drupal\Tests\rest\Functional\EntityResource\ConfigurableLanguage;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Url;
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
use Drupal\language\Entity\ConfigurableLanguage;
@@ -74,4 +75,21 @@ abstract class ConfigurableLanguageResourceTestBase extends EntityResourceTestBa
// @todo Update in https://www.drupal.org/node/2300677.
}
/**
* Test a GET request for a default config entity, which has a _core key.
*
* @see https://www.drupal.org/node/2915414
*/
public function testGetDefaultConfig() {
$this->initAuthentication();
$url = Url::fromUri('base:/entity/configurable_language/en')->setOption('query', ['_format' => static::$format]);;
$request_options = $this->getAuthenticationRequestOptions('GET');
$this->provisionEntityResource();
$this->setUpAuthorization('GET');
$response = $this->request('GET', $url, $request_options);
$normalization = $this->serializer->decode((string) $response->getBody(), static::$format);
$this->assertArrayNotHasKey('_core', $normalization);
}
}
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\ConfigurableLanguage;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class ConfigurableLanguageXmlAnonTest extends ConfigurableLanguageResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\ConfigurableLanguage;
use Drupal\Tests\rest\Functional\BasicAuthResourceWithInterfaceTranslationTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class ConfigurableLanguageXmlBasicAuthTest extends ConfigurableLanguageResourceTestBase {
use BasicAuthResourceWithInterfaceTranslationTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\ConfigurableLanguage;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class ConfigurableLanguageXmlCookieTest extends ConfigurableLanguageResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\ContactForm;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class ContactFormXmlAnonTest extends ContactFormResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\ContactForm;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class ContactFormXmlBasicAuthTest extends ContactFormResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\ContactForm;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class ContactFormXmlCookieTest extends ContactFormResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -2,14 +2,14 @@
namespace Drupal\Tests\rest\Functional\EntityResource\ContentLanguageSettings;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\BasicAuthResourceWithInterfaceTranslationTestTrait;
/**
* @group rest
*/
class ContentLanguageSettingsJsonBasicAuthTest extends ContentLanguageSettingsResourceTestBase {
use BasicAuthResourceTestTrait;
use BasicAuthResourceWithInterfaceTranslationTestTrait;
/**
* {@inheritdoc}
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\ContentLanguageSettings;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class ContentLanguageSettingsXmlAnonTest extends ContentLanguageSettingsResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\ContentLanguageSettings;
use Drupal\Tests\rest\Functional\BasicAuthResourceWithInterfaceTranslationTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class ContentLanguageSettingsXmlBasicAuthTest extends ContentLanguageSettingsResourceTestBase {
use BasicAuthResourceWithInterfaceTranslationTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\ContentLanguageSettings;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class ContentLanguageSettingsXmlCookieTest extends ContentLanguageSettingsResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\DateFormat;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class DateFormatXmlAnonTest extends DateFormatResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\DateFormat;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class DateFormatXmlBasicAuthTest extends DateFormatResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\DateFormat;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class DateFormatXmlCookieTest extends DateFormatResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\Editor;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EditorXmlAnonTest extends EditorResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\Editor;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EditorXmlBasicAuthTest extends EditorResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\Editor;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EditorXmlCookieTest extends EditorResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,24 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityFormDisplay;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
/**
* @group rest
*/
class EntityFormDisplayJsonAnonTest extends EntityFormDisplayResourceTestBase {
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
}
@@ -0,0 +1,34 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityFormDisplay;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
/**
* @group rest
*/
class EntityFormDisplayJsonBasicAuthTest extends EntityFormDisplayResourceTestBase {
use BasicAuthResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,29 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityFormDisplay;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
/**
* @group rest
*/
class EntityFormDisplayJsonCookieTest extends EntityFormDisplayResourceTestBase {
use CookieResourceTestTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,161 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityFormDisplay;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\node\Entity\NodeType;
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
abstract class EntityFormDisplayResourceTestBase extends EntityResourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['node'];
/**
* {@inheritdoc}
*/
protected static $entityTypeId = 'entity_form_display';
/**
* @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface
*/
protected $entity;
/**
* {@inheritdoc}
*/
protected function setUpAuthorization($method) {
$this->grantPermissionsToTestedRole(['administer node form display']);
}
/**
* {@inheritdoc}
*/
protected function createEntity() {
// Create a "Camelids" node type.
$camelids = NodeType::create([
'name' => 'Camelids',
'type' => 'camelids',
]);
$camelids->save();
// Create a form display.
$form_display = EntityFormDisplay::create([
'targetEntityType' => 'node',
'bundle' => 'camelids',
'mode' => 'default',
]);
$form_display->save();
return $form_display;
}
/**
* {@inheritdoc}
*/
protected function getExpectedNormalizedEntity() {
return [
'bundle' => 'camelids',
'content' => [
'created' => [
'type' => 'datetime_timestamp',
'weight' => 10,
'region' => 'content',
'settings' => [],
'third_party_settings' => [],
],
'promote' => [
'type' => 'boolean_checkbox',
'settings' => [
'display_label' => TRUE,
],
'weight' => 15,
'region' => 'content',
'third_party_settings' => [],
],
'status' => [
'type' => 'boolean_checkbox',
'weight' => 120,
'region' => 'content',
'settings' => [
'display_label' => TRUE,
],
'third_party_settings' => [],
],
'sticky' => [
'type' => 'boolean_checkbox',
'settings' => [
'display_label' => TRUE,
],
'weight' => 16,
'region' => 'content',
'third_party_settings' => [],
],
'title' => [
'type' => 'string_textfield',
'weight' => -5,
'region' => 'content',
'settings' => [
'size' => 60,
'placeholder' => '',
],
'third_party_settings' => [],
],
'uid' => [
'type' => 'entity_reference_autocomplete',
'weight' => 5,
'settings' => [
'match_operator' => 'CONTAINS',
'size' => 60,
'placeholder' => '',
],
'region' => 'content',
'third_party_settings' => [],
],
],
'dependencies' => [
'config' => [
'node.type.camelids',
],
],
'hidden' => [],
'id' => 'node.camelids.default',
'langcode' => 'en',
'mode' => 'default',
'status' => NULL,
'targetEntityType' => 'node',
'uuid' => $this->entity->uuid(),
];
}
/**
* {@inheritdoc}
*/
protected function getNormalizedPostEntity() {
// @todo Update in https://www.drupal.org/node/2300677.
}
/**
* {@inheritdoc}
*/
protected function getExpectedCacheContexts() {
return [
'user.permissions',
];
}
/**
* {@inheritdoc}
*/
protected function getExpectedUnauthorizedAccessMessage($method) {
if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) {
return parent::getExpectedUnauthorizedAccessMessage($method);
}
return "The 'administer node form display' permission is required.";
}
}
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityFormDisplay;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EntityFormDisplayXmlAnonTest extends EntityFormDisplayResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityFormDisplay;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EntityFormDisplayXmlBasicAuthTest extends EntityFormDisplayResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityFormDisplay;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EntityFormDisplayXmlCookieTest extends EntityFormDisplayResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityFormMode;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EntityFormModeXmlAnonTest extends EntityFormModeResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityFormMode;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EntityFormModeXmlBasicAuthTest extends EntityFormModeResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityFormMode;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EntityFormModeXmlCookieTest extends EntityFormModeResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,158 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Tests\BrowserTestBase;
/**
* Checks that all core content/config entity types have REST test coverage.
*
* Every entity type must have test coverage for:
* - every format in core (json + xml + hal_json)
* - every authentication provider in core (anon, cookie, basic_auth)
*
* @group rest
*/
class EntityResourceRestTestCoverageTest extends BrowserTestBase {
/**
* Entity definitions array.
*
* @var array
*/
protected $definitions;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$all_modules = system_rebuild_module_data();
$stable_core_modules = array_filter($all_modules, function ($module) {
// Filter out contrib, hidden, testing, and experimental modules. We also
// don't need to enable modules that are already enabled.
return
$module->origin === 'core' &&
empty($module->info['hidden']) &&
$module->status == FALSE &&
$module->info['package'] !== 'Testing' &&
$module->info['package'] !== 'Core (Experimental)';
});
$this->container->get('module_installer')->install(array_keys($stable_core_modules));
$this->rebuildContainer();
$this->definitions = $this->container->get('entity_type.manager')->getDefinitions();
// Entity types marked as "internal" are not exposed by the entity REST
// resource plugin and hence also don't need test coverage.
$this->definitions = array_filter($this->definitions, function (EntityTypeInterface $entity_type) {
return !$entity_type->isInternal();
});
}
/**
* Tests that all core content/config entity types have REST test coverage.
*/
public function testEntityTypeRestTestCoverage() {
$default_test_locations = [
// Test coverage for formats provided by the 'serialization' module.
'serialization' => [
'possible paths' => [
'\Drupal\Tests\rest\Functional\EntityResource\CLASS\CLASS',
],
'class suffix' => [
'JsonAnonTest',
'JsonBasicAuthTest',
'JsonCookieTest',
'XmlAnonTest',
'XmlBasicAuthTest',
'XmlCookieTest',
],
],
// Test coverage for formats provided by the 'hal' module.
'hal' => [
'possible paths' => [
'\Drupal\Tests\hal\Functional\EntityResource\CLASS\CLASS',
],
'class suffix' => [
'HalJsonAnonTest',
'HalJsonBasicAuthTest',
'HalJsonCookieTest',
],
],
];
$problems = [];
foreach ($this->definitions as $entity_type_id => $info) {
$class_name_full = $info->getClass();
$parts = explode('\\', $class_name_full);
$class_name = end($parts);
$module_name = $parts[1];
// The test class can live either in the REST/HAL module, or in the module
// providing the entity type.
$tests = $default_test_locations;
$tests['serialization']['possible paths'][] = '\Drupal\Tests\\' . $module_name . '\Functional\Rest\CLASS';
$tests['hal']['possible paths'][] = '\Drupal\Tests\\' . $module_name . '\Functional\Hal\CLASS';
foreach ($tests as $module => $info) {
$possible_paths = $info['possible paths'];
$missing_tests = [];
foreach ($info['class suffix'] as $postfix) {
foreach ($possible_paths as $path) {
$class = str_replace('CLASS', $class_name, $path . $postfix);
if (class_exists($class)) {
continue 2;
}
}
$missing_tests[] = $postfix;
}
if (!empty($missing_tests)) {
$missing_tests_list = implode(', ', array_map(function ($missing_test) use ($class_name) {
return $class_name . $missing_test;
}, $missing_tests));
$which_normalization = $module === 'serialization' ? 'default' : $module;
$problems[] = "$entity_type_id: $class_name ($class_name_full), $which_normalization normalization (expected tests: $missing_tests_list)";
}
}
}
$all = count($this->definitions);
$good = $all - count($problems);
$this->assertSame([], $problems, $this->getLlamaMessage($good, $all));
}
/**
* Message from Llama.
*
* @param int $g
* A count of entities with test coverage.
* @param int $a
* A count of all entities.
*
* @return string
* An information about progress of REST test coverage.
*/
protected function getLlamaMessage($g, $a) {
return "
________________________
/ Hi! \\
| It's llame to not have |
| complete REST tests! |
| |
| Progress: $g/$a. |
| ________________________/
|/
// o
l'>
ll
llama
|| ||
'' ''
";
}
}
@@ -3,13 +3,20 @@
namespace Drupal\Tests\rest\Functional\EntityResource;
use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Utility\Random;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheableResponseInterface;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Config\Entity\ConfigEntityInterface;
use Drupal\Core\Entity\ContentEntityNullStorage;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Field\Plugin\Field\FieldType\BooleanItem;
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
use Drupal\Core\Url;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\path\Plugin\Field\FieldType\PathItem;
use Drupal\rest\ResourceResponseInterface;
use Drupal\Tests\rest\Functional\ResourceTestBase;
use GuzzleHttp\RequestOptions;
@@ -79,6 +86,14 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
*/
protected static $patchProtectedFieldNames;
/**
* The fields that need a different (random) value for each new entity created
* by a POST request.
*
* @var string[]
*/
protected static $uniqueFieldNames = [];
/**
* Optionally specify which field is the 'label' field. Some entities specify
* a 'label_callback', but not a 'label' entity key. For example: User.
@@ -118,6 +133,13 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
*/
protected $entity;
/**
* Another entity of the same type used for testing.
*
* @var \Drupal\Core\Entity\EntityInterface
*/
protected $anotherEntity;
/**
* The entity storage.
*
@@ -175,12 +197,34 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
->setTranslatable(FALSE)
->save();
// Reload entity so that it has the new field.
$this->entity = $this->entityStorage->loadUnchanged($this->entity->id());
// Add multi-value field.
FieldStorageConfig::create([
'entity_type' => static::$entityTypeId,
'field_name' => 'field_rest_test_multivalue',
'type' => 'string',
])
->setCardinality(3)
->save();
FieldConfig::create([
'entity_type' => static::$entityTypeId,
'field_name' => 'field_rest_test_multivalue',
'bundle' => $this->entity->bundle(),
])
->setLabel('Test field: multi-value')
->setTranslatable(FALSE)
->save();
// Set a default value on the field.
$this->entity->set('field_rest_test', ['value' => 'All the faith he had had had had no effect on the outcome of his life.']);
$this->entity->save();
// Reload entity so that it has the new field.
$reloaded_entity = $this->entityStorage->loadUnchanged($this->entity->id());
// Some entity types are not stored, hence they cannot be reloaded.
if ($reloaded_entity !== NULL) {
$this->entity = $reloaded_entity;
// Set a default value on the fields.
$this->entity->set('field_rest_test', ['value' => 'All the faith he had had had had no effect on the outcome of his life.']);
$this->entity->set('field_rest_test_multivalue', [['value' => 'One'], ['value' => 'Two']]);
$this->entity->save();
}
}
}
@@ -192,6 +236,22 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
*/
abstract protected function createEntity();
/**
* Creates another entity to be tested.
*
* @return \Drupal\Core\Entity\EntityInterface
* Another entity based on $this->entity.
*/
protected function createAnotherEntity() {
$entity = $this->entity->createDuplicate();
$label_key = $entity->getEntityType()->getKey('label');
if ($label_key) {
$entity->set($label_key, $entity->label() . '_dupe');
}
$entity->save();
return $entity;
}
/**
* Returns the expected normalization of the entity.
*
@@ -224,6 +284,46 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
return $this->getNormalizedPostEntity();
}
/**
* Gets the second normalized POST entity.
*
* Entity types can have non-sequential IDs, and in that case the second
* entity created for POST testing needs to be able to specify a different ID.
*
* @see ::testPost
* @see ::getNormalizedPostEntity
*
* @return array
* An array structure as returned by ::getNormalizedPostEntity().
*/
protected function getSecondNormalizedPostEntity() {
// Return the values of the "parent" method by default.
return $this->getNormalizedPostEntity();
}
/**
* Gets the normalized POST entity with random values for its unique fields.
*
* @see ::testPost
* @see ::getNormalizedPostEntity
*
* @return array
* An array structure as returned by ::getNormalizedPostEntity().
*/
protected function getModifiedEntityForPostTesting() {
$normalized_entity = $this->getNormalizedPostEntity();
// Ensure that all the unique fields of the entity type get a new random
// value.
foreach (static::$uniqueFieldNames as $field_name) {
$field_definition = $this->entity->getFieldDefinition($field_name);
$field_type_class = $field_definition->getItemDefinition()->getClass();
$normalized_entity[$field_name] = $field_type_class::generateSampleValue($field_definition);
}
return $normalized_entity;
}
/**
* {@inheritdoc}
*/
@@ -254,6 +354,17 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
return "$message.";
}
/**
* {@inheritdoc}
*/
protected function getExpectedUnauthorizedAccessCacheability() {
return (new CacheableMetadata())
->setCacheTags(static::$auth
? ['4xx-response', 'http_response']
: ['4xx-response', 'config:user.role.anonymous', 'http_response'])
->setCacheContexts(['user.permissions']);
}
/**
* The expected cache tags for the GET/HEAD response of the test entity.
*
@@ -264,6 +375,9 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
protected function getExpectedCacheTags() {
$expected_cache_tags = [
'config:rest.resource.entity.' . static::$entityTypeId,
// Necessary for 'bc_entity_resource_permissions'.
// @see \Drupal\rest\Plugin\rest\resource\EntityResource::permissions()
'config:rest.settings',
];
if (!static::$auth) {
$expected_cache_tags[] = 'config:user.role.anonymous';
@@ -339,7 +453,7 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
// response.
if (static::$auth) {
$response = $this->request('GET', $url, $request_options);
$this->assertResponseWhenMissingAuthentication($response);
$this->assertResponseWhenMissingAuthentication('GET', $response);
}
$request_options[RequestOptions::HEADERS]['REST-test-auth'] = '1';
@@ -360,87 +474,55 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
// DX: 403 when unauthorized.
$response = $this->request('GET', $url, $request_options);
$this->assertResourceErrorResponse(403, $this->getExpectedUnauthorizedAccessMessage('GET'), $response);
$expected_403_cacheability = $this->getExpectedUnauthorizedAccessCacheability();
$this->assertResourceErrorResponse(403, $this->getExpectedUnauthorizedAccessMessage('GET'), $response, $expected_403_cacheability->getCacheTags(), $expected_403_cacheability->getCacheContexts(), static::$auth ? FALSE : 'MISS', 'MISS');
$this->assertArrayNotHasKey('Link', $response->getHeaders());
$this->setUpAuthorization('GET');
// 200 for well-formed HEAD request.
$response = $this->request('HEAD', $url, $request_options);
$this->assertResourceResponse(200, '', $response);
// @todo Entity resources with URLs that begin with '/admin/' are marked as
// administrative (see https://www.drupal.org/node/2874938), which
// excludes them from Dynamic Page Cache (see
// https://www.drupal.org/node/2877528). When either of those issues is
// fixed, remove the if-test and the 'else' block.
if (strpos($this->entity->getEntityType()->getLinkTemplate('canonical'), '/admin/') !== 0) {
$this->assertTrue($response->hasHeader('X-Drupal-Dynamic-Cache'));
$this->assertSame(['MISS'], $response->getHeader('X-Drupal-Dynamic-Cache'));
}
else {
$this->assertFalse($response->hasHeader('X-Drupal-Dynamic-Cache'));
}
if (!$this->account) {
$this->assertSame(['MISS'], $response->getHeader('X-Drupal-Cache'));
}
else {
$this->assertFalse($response->hasHeader('X-Drupal-Cache'));
}
$this->assertResourceResponse(200, '', $response, $this->getExpectedCacheTags(), $this->getExpectedCacheContexts(), static::$auth ? FALSE : 'MISS', 'MISS');
$head_headers = $response->getHeaders();
// 200 for well-formed GET request. Page Cache hit because of HEAD request.
// Same for Dynamic Page Cache hit.
$response = $this->request('GET', $url, $request_options);
$this->assertResourceResponse(200, FALSE, $response);
// @todo Entity resources with URLs that begin with '/admin/' are marked as
// administrative (see https://www.drupal.org/node/2874938), which
// excludes them from Dynamic Page Cache (see
// https://www.drupal.org/node/2877528). When either of those issues is
// fixed, remove the if-test and the 'else' block.
if (strpos($this->entity->getEntityType()->getLinkTemplate('canonical'), '/admin/') !== 0) {
$this->assertTrue($response->hasHeader('X-Drupal-Dynamic-Cache'));
if (!static::$auth) {
$this->assertSame(['HIT'], $response->getHeader('X-Drupal-Cache'));
$this->assertSame(['MISS'], $response->getHeader('X-Drupal-Dynamic-Cache'));
$this->assertResourceResponse(200, FALSE, $response, $this->getExpectedCacheTags(), $this->getExpectedCacheContexts(), static::$auth ? FALSE : 'HIT', static::$auth ? 'HIT' : 'MISS');
// Assert that Dynamic Page Cache did not store a ResourceResponse object,
// which needs serialization after every cache hit. Instead, it should
// contain a flattened response. Otherwise performance suffers.
// @see \Drupal\rest\EventSubscriber\ResourceResponseSubscriber::flattenResponse()
$cache_items = $this->container->get('database')
->query("SELECT cid, data FROM {cache_dynamic_page_cache} WHERE cid LIKE :pattern", [
':pattern' => '%[route]=rest.%',
])
->fetchAllAssoc('cid');
$this->assertTrue(count($cache_items) >= 2);
$found_cache_redirect = FALSE;
$found_cached_200_response = FALSE;
$other_cached_responses_are_4xx = TRUE;
foreach ($cache_items as $cid => $cache_item) {
$cached_data = unserialize($cache_item->data);
if (!isset($cached_data['#cache_redirect'])) {
$cached_response = $cached_data['#response'];
if ($cached_response->getStatusCode() === 200) {
$found_cached_200_response = TRUE;
}
elseif (!$cached_response->isClientError()) {
$other_cached_responses_are_4xx = FALSE;
}
$this->assertNotInstanceOf(ResourceResponseInterface::class, $cached_response);
$this->assertInstanceOf(CacheableResponseInterface::class, $cached_response);
}
else {
$this->assertFalse($response->hasHeader('X-Drupal-Cache'));
$this->assertSame(['HIT'], $response->getHeader('X-Drupal-Dynamic-Cache'));
// Assert that Dynamic Page Cache did not store a ResourceResponse object,
// which needs serialization after every cache hit. Instead, it should
// contain a flattened response. Otherwise performance suffers.
// @see \Drupal\rest\EventSubscriber\ResourceResponseSubscriber::flattenResponse()
$cache_items = $this->container->get('database')
->query("SELECT cid, data FROM {cache_dynamic_page_cache} WHERE cid LIKE :pattern", [
':pattern' => '%[route]=rest.%',
])
->fetchAllAssoc('cid');
$this->assertCount(2, $cache_items);
$found_cache_redirect = FALSE;
$found_cached_response = FALSE;
foreach ($cache_items as $cid => $cache_item) {
$cached_data = unserialize($cache_item->data);
if (!isset($cached_data['#cache_redirect'])) {
$found_cached_response = TRUE;
$cached_response = $cached_data['#response'];
$this->assertNotInstanceOf(ResourceResponseInterface::class, $cached_response);
$this->assertInstanceOf(CacheableResponseInterface::class, $cached_response);
}
else {
$found_cache_redirect = TRUE;
}
}
$this->assertTrue($found_cache_redirect);
$this->assertTrue($found_cached_response);
$found_cache_redirect = TRUE;
}
}
else {
$this->assertFalse($response->hasHeader('X-Drupal-Dynamic-Cache'));
}
$cache_tags_header_value = $response->getHeader('X-Drupal-Cache-Tags')[0];
$this->assertEquals($this->getExpectedCacheTags(), empty($cache_tags_header_value) ? [] : explode(' ', $cache_tags_header_value));
$cache_contexts_header_value = $response->getHeader('X-Drupal-Cache-Contexts')[0];
$this->assertEquals($this->getExpectedCacheContexts(), empty($cache_contexts_header_value) ? [] : explode(' ', $cache_contexts_header_value));
$this->assertTrue($found_cache_redirect);
$this->assertTrue($found_cached_200_response);
$this->assertTrue($other_cached_responses_are_4xx);
// Sort the serialization data first so we can do an identical comparison
// for the keys with the array order the same (it needs to match with
// identical comparison).
@@ -452,8 +534,17 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
// Not only assert the normalization, also assert deserialization of the
// response results in the expected object.
$unserialized = $this->serializer->deserialize((string) $response->getBody(), get_class($this->entity), static::$format);
$this->assertSame($unserialized->uuid(), $this->entity->uuid());
// Note: deserialization of the XML format is not supported, so only test
// this for other formats.
if (static::$format !== 'xml') {
// @todo Work-around for HAL's FileEntityNormalizer::denormalize() being
// broken, being fixed in https://www.drupal.org/node/1927648, where this
// if-test should be removed.
if (!(static::$entityTypeId === 'file' && static::$format === 'hal_json')) {
$unserialized = $this->serializer->deserialize((string) $response->getBody(), get_class($this->entity), static::$format);
$this->assertSame($unserialized->uuid(), $this->entity->uuid());
}
}
// Finally, assert that the expected 'Link' headers are present.
if ($this->entity->getEntityType()->getLinkTemplates()) {
$this->assertArrayHasKey('Link', $response->getHeaders());
@@ -476,15 +567,21 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
$get_headers = $response->getHeaders();
// Verify that the GET and HEAD responses are the same. The only difference
// is that there's no body. For this reason the 'Transfer-Encoding' header
// is also added to the list of headers to ignore, as this could be added to
// GET requests - depending on web server configuration. This would usually
// be 'Transfer-Encoding: chunked'.
$ignored_headers = ['Date', 'Content-Length', 'X-Drupal-Cache', 'X-Drupal-Dynamic-Cache', 'Transfer-Encoding'];
foreach ($ignored_headers as $ignored_header) {
unset($head_headers[$ignored_header]);
unset($get_headers[$ignored_header]);
}
// is that there's no body. For this reason the 'Transfer-Encoding' and
// 'Vary' headers are also added to the list of headers to ignore, as they
// may be added to GET requests, depending on web server configuration. They
// are usually 'Transfer-Encoding: chunked' and 'Vary: Accept-Encoding'.
$ignored_headers = ['Date', 'Content-Length', 'X-Drupal-Cache', 'X-Drupal-Dynamic-Cache', 'Transfer-Encoding', 'Vary'];
$header_cleaner = function ($headers) use ($ignored_headers) {
foreach ($headers as $header => $value) {
if (strpos($header, 'X-Drupal-Assertion-') === 0 || in_array($header, $ignored_headers)) {
unset($headers[$header]);
}
}
return $headers;
};
$get_headers = $header_cleaner($get_headers);
$head_headers = $header_cleaner($head_headers);
$this->assertSame($get_headers, $head_headers);
// BC: serialization_update_8302().
@@ -499,7 +596,7 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
$this->rebuildAll();
$response = $this->request('GET', $url, $request_options);
$this->assertResourceResponse(200, FALSE, $response);
$this->assertResourceResponse(200, FALSE, $response, $this->getExpectedCacheTags(), $this->getExpectedCacheContexts(), static::$auth ? FALSE : 'MISS', 'MISS');
// Again do an identical comparison, but this time transform the expected
// normalized entity's values to strings. This ensures the BC layer for
@@ -531,7 +628,7 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
$this->rebuildAll();
$response = $this->request('GET', $url, $request_options);
$this->assertResourceResponse(200, FALSE, $response);
$this->assertResourceResponse(200, FALSE, $response, $this->getExpectedCacheTags(), $this->getExpectedCacheContexts(), static::$auth ? FALSE : 'MISS', 'MISS');
// This ensures the BC layer for bc_timestamp_normalizer_unix works as
// expected. This method should be using
@@ -562,7 +659,21 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
// 200 for well-formed request.
$response = $this->request('GET', $url, $request_options);
$this->assertResourceResponse(200, FALSE, $response);
$expected_cache_tags = $this->getExpectedCacheTags();
$expected_cache_contexts = $this->getExpectedCacheContexts();
// @todo Fix BlockAccessControlHandler::mergeCacheabilityFromConditions() in
// https://www.drupal.org/node/2867881
if (static::$entityTypeId === 'block') {
$expected_cache_contexts = Cache::mergeContexts($expected_cache_contexts, ['user.permissions']);
}
// \Drupal\Core\EventSubscriber\AnonymousUserResponseSubscriber applies to
// cacheable anonymous responses: it updates their cacheability. Therefore
// we must update our cacheability expectations for anonymous responses
// accordingly.
if (!static::$auth && in_array('user.permissions', $expected_cache_contexts, TRUE)) {
$expected_cache_tags = Cache::mergeTags($expected_cache_tags, ['config:user.role.anonymous']);
}
$this->assertResourceResponse(200, FALSE, $response, $expected_cache_tags, $expected_cache_contexts, static::$auth ? FALSE : 'MISS', 'MISS');
$this->resourceConfigStorage->load(static::$resourceConfigId)->disable()->save();
$this->refreshTestStateAfterRestConfigChange();
@@ -575,7 +686,7 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
// DX: upon re-enabling a resource, immediate 200.
$response = $this->request('GET', $url, $request_options);
$this->assertResourceResponse(200, FALSE, $response);
$this->assertResourceResponse(200, FALSE, $response, $expected_cache_tags, $expected_cache_contexts, static::$auth ? FALSE : 'MISS', 'MISS');
$this->resourceConfigStorage->load(static::$resourceConfigId)->delete();
$this->refreshTestStateAfterRestConfigChange();
@@ -599,14 +710,14 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
$this->assert406Response($response);
$this->assertSame(['text/plain; charset=UTF-8'], $response->getHeader('Content-Type'));
$url = Url::fromRoute('rest.entity.' . static::$entityTypeId . '.GET.' . static::$format);
$url = Url::fromRoute('rest.entity.' . static::$entityTypeId . '.GET');
$url->setRouteParameter(static::$entityTypeId, 987654321);
$url->setOption('query', ['_format' => static::$format]);
// DX: 404 when GETting non-existing entity.
$response = $this->request('GET', $url, $request_options);
$path = str_replace('987654321', '{' . static::$entityTypeId . '}', $url->setAbsolute()->setOptions(['base_url' => '', 'query' => []])->toString());
$message = 'The "' . static::$entityTypeId . '" parameter was not converted for the path "' . $path . '" (route name: "rest.entity.' . static::$entityTypeId . '.GET.' . static::$format . '")';
$message = 'The "' . static::$entityTypeId . '" parameter was not converted for the path "' . $path . '" (route name: "rest.entity.' . static::$entityTypeId . '.GET")';
$this->assertResourceErrorResponse(404, $message, $response);
}
@@ -671,8 +782,8 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
// Try with all of the following request bodies.
$unparseable_request_body = '!{>}<';
$parseable_valid_request_body = $this->serializer->encode($this->getNormalizedPostEntity(), static::$format);
$parseable_valid_request_body_2 = $this->serializer->encode($this->getNormalizedPostEntity(), static::$format);
$parseable_invalid_request_body = $this->serializer->encode($this->makeNormalizationInvalid($this->getNormalizedPostEntity()), static::$format);
$parseable_valid_request_body_2 = $this->serializer->encode($this->getSecondNormalizedPostEntity(), static::$format);
$parseable_invalid_request_body = $this->serializer->encode($this->makeNormalizationInvalid($this->getNormalizedPostEntity(), 'label'), static::$format);
$parseable_invalid_request_body_2 = $this->serializer->encode($this->getNormalizedPostEntity() + ['uuid' => [$this->randomMachineName(129)]], static::$format);
$parseable_invalid_request_body_3 = $this->serializer->encode($this->getNormalizedPostEntity() + ['field_rest_test' => [['value' => $this->randomString()]]], static::$format);
@@ -731,7 +842,7 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
// DX: forgetting authentication: authentication provider-specific error
// response.
$response = $this->request('POST', $url, $request_options);
$this->assertResponseWhenMissingAuthentication($response);
$this->assertResponseWhenMissingAuthentication('POST', $response);
}
$request_options = NestedArray::mergeDeep($request_options, $this->getAuthenticationRequestOptions('POST'));
@@ -789,23 +900,27 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
$this->assertSame([], $response->getHeader('Location'));
}
$this->assertFalse($response->hasHeader('X-Drupal-Cache'));
// Assert that the entity was indeed created, and that the response body
// contains the serialized created entity.
$created_entity = $this->entityStorage->loadUnchanged(static::$firstCreatedEntityId);
$created_entity_normalization = $this->serializer->normalize($created_entity, static::$format, ['account' => $this->account]);
// @todo Remove this if-test in https://www.drupal.org/node/2543726: execute
// its body unconditionally.
if (static::$entityTypeId !== 'taxonomy_term') {
$this->assertSame($created_entity_normalization, $this->serializer->decode((string) $response->getBody(), static::$format));
}
// Assert that the entity was indeed created using the POSTed values.
foreach ($this->getNormalizedPostEntity() as $field_name => $field_normalization) {
// Some top-level keys in the normalization may not be fields on the
// entity (for example '_links' and '_embedded' in the HAL normalization).
if ($created_entity->hasField($field_name)) {
// Subset, not same, because we can e.g. send just the target_id for the
// bundle in a POST request; the response will include more properties.
$this->assertArraySubset(static::castToString($field_normalization), $created_entity->get($field_name)->getValue(), TRUE);
// If the entity is stored, perform extra checks.
if (get_class($this->entityStorage) !== ContentEntityNullStorage::class) {
// Assert that the entity was indeed created, and that the response body
// contains the serialized created entity.
$created_entity = $this->entityStorage->loadUnchanged(static::$firstCreatedEntityId);
$created_entity_normalization = $this->serializer->normalize($created_entity, static::$format, ['account' => $this->account]);
// @todo Remove this if-test in https://www.drupal.org/node/2543726: execute
// its body unconditionally.
if (static::$entityTypeId !== 'taxonomy_term') {
$this->assertSame($created_entity_normalization, $this->serializer->decode((string) $response->getBody(), static::$format));
}
// Assert that the entity was indeed created using the POSTed values.
foreach ($this->getNormalizedPostEntity() as $field_name => $field_normalization) {
// Some top-level keys in the normalization may not be fields on the
// entity (for example '_links' and '_embedded' in the HAL normalization).
if ($created_entity->hasField($field_name)) {
// Subset, not same, because we can e.g. send just the target_id for the
// bundle in a POST request; the response will include more properties.
$this->assertArraySubset(static::castToString($field_normalization), $created_entity->get($field_name)
->getValue(), TRUE);
}
}
}
@@ -820,12 +935,16 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
$this->grantPermissionsToTestedRole(['restful post entity:' . static::$entityTypeId]);
// 201 for well-formed request.
// Delete the first created entity in case there is a uniqueness constraint.
$this->entityStorage->load(static::$firstCreatedEntityId)->delete();
// If the entity is stored, delete the first created entity (in case there
// is a uniqueness constraint).
if (get_class($this->entityStorage) !== ContentEntityNullStorage::class) {
$this->entityStorage->load(static::$firstCreatedEntityId)->delete();
}
$response = $this->request('POST', $url, $request_options);
$this->assertResourceResponse(201, FALSE, $response);
$created_entity = $this->entityStorage->load(static::$secondCreatedEntityId);
if ($has_canonical_url) {
$location = $this->entityStorage->load(static::$secondCreatedEntityId)->toUrl('canonical')->setAbsolute(TRUE)->toString();
$location = $created_entity->toUrl('canonical')->setAbsolute(TRUE)->toString();
$this->assertSame([$location], $response->getHeader('Location'));
}
else {
@@ -833,6 +952,32 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
}
$this->assertFalse($response->hasHeader('X-Drupal-Cache'));
if ($this->entity->getEntityType()->getStorageClass() !== ContentEntityNullStorage::class && $this->entity->getEntityType()->hasKey('uuid')) {
// 500 when creating an entity with a duplicate UUID.
$normalized_entity = $this->getModifiedEntityForPostTesting();
$normalized_entity[$created_entity->getEntityType()->getKey('uuid')] = [['value' => $created_entity->uuid()]];
$normalized_entity[$label_field] = [['value' => $this->randomMachineName()]];
$request_options[RequestOptions::BODY] = $this->serializer->encode($normalized_entity, static::$format);
$response = $this->request('POST', $url, $request_options);
$this->assertSame(500, $response->getStatusCode());
$this->assertContains('Internal Server Error', (string) $response->getBody());
// 201 when successfully creating an entity with a new UUID.
$normalized_entity = $this->getModifiedEntityForPostTesting();
$new_uuid = \Drupal::service('uuid')->generate();
$normalized_entity[$created_entity->getEntityType()->getKey('uuid')] = [['value' => $new_uuid]];
$normalized_entity[$label_field] = [['value' => $this->randomMachineName()]];
$request_options[RequestOptions::BODY] = $this->serializer->encode($normalized_entity, static::$format);
$response = $this->request('POST', $url, $request_options);
$this->assertResourceResponse(201, FALSE, $response);
$entities = $this->entityStorage->loadByProperties([$created_entity->getEntityType()->getKey('uuid') => $new_uuid]);
$new_entity = reset($entities);
$this->assertNotNull($new_entity);
$new_entity->delete();
}
// BC: old default POST URLs have their path updated by the inbound path
// processor \Drupal\rest\PathProcessor\PathProcessorEntityResourceBC to the
// new URL, which is derived from the 'create' link template if an entity
@@ -840,6 +985,7 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
if ($this->entity->getEntityType()->hasLinkTemplate('create')) {
$this->entityStorage->load(static::$secondCreatedEntityId)->delete();
$old_url = Url::fromUri('base:entity/' . static::$entityTypeId);
$old_url->setOption('query', ['_format' => static::$format]);
$response = $this->request('POST', $old_url, $request_options);
$this->assertResourceResponse(201, FALSE, $response);
}
@@ -855,6 +1001,9 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
return;
}
// Patch testing requires that another entity of the same type exists.
$this->anotherEntity = $this->createAnotherEntity();
$this->initAuthentication();
$has_canonical_url = $this->entity->hasLinkTemplate('canonical');
@@ -862,8 +1011,12 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
$unparseable_request_body = '!{>}<';
$parseable_valid_request_body = $this->serializer->encode($this->getNormalizedPatchEntity(), static::$format);
$parseable_valid_request_body_2 = $this->serializer->encode($this->getNormalizedPatchEntity(), static::$format);
$parseable_invalid_request_body = $this->serializer->encode($this->makeNormalizationInvalid($this->getNormalizedPatchEntity()), static::$format);
$parseable_invalid_request_body = $this->serializer->encode($this->makeNormalizationInvalid($this->getNormalizedPatchEntity(), 'label'), static::$format);
$parseable_invalid_request_body_2 = $this->serializer->encode($this->getNormalizedPatchEntity() + ['field_rest_test' => [['value' => $this->randomString()]]], static::$format);
// The 'field_rest_test' field does not allow 'view' access, so does not end
// up in the normalization. Even when we explicitly add it the normalization
// that we send in the body of a PATCH request, it is considered invalid.
$parseable_invalid_request_body_3 = $this->serializer->encode($this->getNormalizedPatchEntity() + ['field_rest_test' => $this->entity->get('field_rest_test')->getValue()], static::$format);
// The URL and Guzzle request options that will be used in this test. The
// request options will be modified/expanded throughout this test:
@@ -932,7 +1085,7 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
// DX: forgetting authentication: authentication provider-specific error
// response.
$response = $this->request('PATCH', $url, $request_options);
$this->assertResponseWhenMissingAuthentication($response);
$this->assertResponseWhenMissingAuthentication('PATCH', $response);
}
$request_options = NestedArray::mergeDeep($request_options, $this->getAuthenticationRequestOptions('PATCH'));
@@ -955,22 +1108,43 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
$response = $this->request('PATCH', $url, $request_options);
$this->assertResourceErrorResponse(403, "Access denied on updating field 'field_rest_test'.", $response);
// DX: 403 when sending PATCH request with read-only fields.
// First send all fields (the "maximum normalization"). Assert the expected
// error message for the first PATCH-protected field. Remove that field from
// the normalization, send another request, assert the next PATCH-protected
// field error message. And so on.
$max_normalization = $this->getNormalizedPatchEntity() + $this->serializer->normalize($this->entity, static::$format);
for ($i = 0; $i < count(static::$patchProtectedFieldNames); $i++) {
$max_normalization = $this->removeFieldsFromNormalization($max_normalization, array_slice(static::$patchProtectedFieldNames, 0, $i));
$request_options[RequestOptions::BODY] = $this->serializer->serialize($max_normalization, static::$format);
// DX: 403 when entity trying to update an entity's ID field.
$request_options[RequestOptions::BODY] = $this->serializer->encode($this->makeNormalizationInvalid($this->getNormalizedPatchEntity(), 'id'), static::$format);;
$response = $this->request('PATCH', $url, $request_options);
$this->assertResourceErrorResponse(403, "Access denied on updating field '{$this->entity->getEntityType()->getKey('id')}'.", $response);
if ($this->entity->getEntityType()->hasKey('uuid')) {
// DX: 403 when entity trying to update an entity's UUID field.
$request_options[RequestOptions::BODY] = $this->serializer->encode($this->makeNormalizationInvalid($this->getNormalizedPatchEntity(), 'uuid'), static::$format);;
$response = $this->request('PATCH', $url, $request_options);
$this->assertResourceErrorResponse(403, "Access denied on updating field '" . static::$patchProtectedFieldNames[$i] . "'.", $response);
$this->assertResourceErrorResponse(403, "Access denied on updating field '{$this->entity->getEntityType()->getKey('uuid')}'.", $response);
}
// 200 for well-formed request that sends the maximum number of fields.
$max_normalization = $this->removeFieldsFromNormalization($max_normalization, static::$patchProtectedFieldNames);
$request_options[RequestOptions::BODY] = $this->serializer->serialize($max_normalization, static::$format);
$request_options[RequestOptions::BODY] = $parseable_invalid_request_body_3;
// DX: 403 when entity contains field without 'edit' nor 'view' access, even
// when the value for that field matches the current value. This is allowed
// in principle, but leads to information disclosure.
$response = $this->request('PATCH', $url, $request_options);
$this->assertResourceErrorResponse(403, "Access denied on updating field 'field_rest_test'.", $response);
// DX: 403 when sending PATCH request with updated read-only fields.
list($modified_entity, $original_values) = static::getModifiedEntityForPatchTesting($this->entity);
// Send PATCH request by serializing the modified entity, assert the error
// response, change the modified entity field that caused the error response
// back to its original value, repeat.
for ($i = 0; $i < count(static::$patchProtectedFieldNames); $i++) {
$patch_protected_field_name = static::$patchProtectedFieldNames[$i];
$request_options[RequestOptions::BODY] = $this->serializer->serialize($modified_entity, static::$format);
$response = $this->request('PATCH', $url, $request_options);
$this->assertResourceErrorResponse(403, "Access denied on updating field '" . $patch_protected_field_name . "'.", $response);
$modified_entity->get($patch_protected_field_name)->setValue($original_values[$patch_protected_field_name]);
}
// 200 for well-formed PATCH request that sends all fields (even including
// read-only ones, but with unchanged values).
$valid_request_body = $this->getNormalizedPatchEntity() + $this->serializer->normalize($this->entity, static::$format);
$request_options[RequestOptions::BODY] = $this->serializer->serialize($valid_request_body, static::$format);
$response = $this->request('PATCH', $url, $request_options);
$this->assertResourceResponse(200, FALSE, $response);
@@ -1013,6 +1187,25 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
// is not sent in the PATCH request.
$this->assertSame('All the faith he had had had had no effect on the outcome of his life.', $updated_entity->get('field_rest_test')->value);
// Multi-value field: remove item 0. Then item 1 becomes item 0.
$normalization_multi_value_tests = $this->getNormalizedPatchEntity();
$normalization_multi_value_tests['field_rest_test_multivalue'] = $this->entity->get('field_rest_test_multivalue')->getValue();
$normalization_remove_item = $normalization_multi_value_tests;
unset($normalization_remove_item['field_rest_test_multivalue'][0]);
$request_options[RequestOptions::BODY] = $this->serializer->encode($normalization_remove_item, static::$format);
$response = $this->request('PATCH', $url, $request_options);
$this->assertResourceResponse(200, FALSE, $response);
$this->assertSame([0 => ['value' => 'Two']], $this->entityStorage->loadUnchanged($this->entity->id())->get('field_rest_test_multivalue')->getValue());
// Multi-value field: add one item before the existing one, and one after.
$normalization_add_items = $normalization_multi_value_tests;
$normalization_add_items['field_rest_test_multivalue'][2] = ['value' => 'Three'];
$request_options[RequestOptions::BODY] = $this->serializer->encode($normalization_add_items, static::$format);
$response = $this->request('PATCH', $url, $request_options);
$this->assertResourceResponse(200, FALSE, $response);
$this->assertSame([0 => ['value' => 'One'], 1 => ['value' => 'Two'], 2 => ['value' => 'Three']], $this->entityStorage->loadUnchanged($this->entity->id())->get('field_rest_test_multivalue')->getValue());
// BC: rest_update_8203().
$this->config('rest.settings')->set('bc_entity_resource_permissions', TRUE)->save(TRUE);
$this->refreshTestStateAfterRestConfigChange();
$request_options[RequestOptions::BODY] = $parseable_valid_request_body_2;
@@ -1082,7 +1275,7 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
// DX: forgetting authentication: authentication provider-specific error
// response.
$response = $this->request('DELETE', $url, $request_options);
$this->assertResponseWhenMissingAuthentication($response);
$this->assertResponseWhenMissingAuthentication('DELETE', $response);
}
$request_options = NestedArray::mergeDeep($request_options, $this->getAuthenticationRequestOptions('PATCH'));
@@ -1099,14 +1292,7 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
// 204 for well-formed request.
$response = $this->request('DELETE', $url, $request_options);
$this->assertSame(204, $response->getStatusCode());
// DELETE responses should not include a Content-Type header. But Apache
// sets it to 'text/html' by default. We also cannot detect the presence of
// Apache either here in the CLI. For now having this documented here is all
// we can do.
// $this->assertSame(FALSE, $response->hasHeader('Content-Type'));
$this->assertSame('', (string) $response->getBody());
$this->assertFalse($response->hasHeader('X-Drupal-Cache'));
$this->assertResourceResponse(204, '', $response);
$this->config('rest.settings')->set('bc_entity_resource_permissions', TRUE)->save(TRUE);
$this->refreshTestStateAfterRestConfigChange();
@@ -1121,11 +1307,7 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
// 204 for well-formed request.
$response = $this->request('DELETE', $url, $request_options);
$this->assertSame(204, $response->getStatusCode());
// @todo Uncomment the following line when https://www.drupal.org/node/2821711 is fixed.
// $this->assertSame(FALSE, $response->hasHeader('Content-Type'));
$this->assertSame('', (string) $response->getBody());
$this->assertFalse($response->hasHeader('X-Drupal-Cache'));
$this->assertResourceResponse(204, '', $response);
}
/**
@@ -1184,40 +1366,84 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
return $has_create_url ? Url::fromUri('internal:' . $this->entity->getEntityType()->getLinkTemplate('create')) : Url::fromUri('base:entity/' . static::$entityTypeId);
}
/**
* Clones the given entity and modifies all PATCH-protected fields.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity being tested and to modify.
*
* @return array
* Contains two items:
* 1. The modified entity object.
* 2. The original field values, keyed by field name.
*
* @internal
*/
protected static function getModifiedEntityForPatchTesting(EntityInterface $entity) {
$modified_entity = clone $entity;
$original_values = [];
foreach (static::$patchProtectedFieldNames as $field_name) {
$field = $modified_entity->get($field_name);
$original_values[$field_name] = $field->getValue();
switch ($field->getItemDefinition()->getClass()) {
case EntityReferenceItem::class:
// EntityReferenceItem::generateSampleValue() picks one of the last 50
// entities of the supported type & bundle. We don't care if the value
// is valid, we only care that it's different.
$field->setValue(['target_id' => 99999]);
break;
case BooleanItem::class:
// BooleanItem::generateSampleValue() picks either 0 or 1. So a 50%
// chance of not picking a different value.
$field->value = ((int) $field->value) === 1 ? '0' : '1';
break;
case PathItem::class:
// PathItem::generateSampleValue() doesn't set a PID, which causes
// PathItem::postSave() to fail. Keep the PID (and other properties),
// just modify the alias.
$field->alias = str_replace(' ', '-', strtolower((new Random())->sentences(3)));
break;
default:
$original_field = clone $field;
while ($field->equals($original_field)) {
$field->generateSampleItems();
}
break;
}
}
return [$modified_entity, $original_values];
}
/**
* Makes the given entity normalization invalid.
*
* @param array $normalization
* An entity normalization.
* @param string $entity_key
* The entity key whose normalization to make invalid.
*
* @return array
* The updated entity normalization, now invalid.
*/
protected function makeNormalizationInvalid(array $normalization) {
// Add a second label to this entity to make it invalid.
$label_field = $this->entity->getEntityType()->hasKey('label') ? $this->entity->getEntityType()->getKey('label') : static::$labelFieldName;
$normalization[$label_field][1]['value'] = 'Second Title';
protected function makeNormalizationInvalid(array $normalization, $entity_key) {
$entity_type = $this->entity->getEntityType();
switch ($entity_key) {
case 'label':
// Add a second label to this entity to make it invalid.
$label_field = $entity_type->hasKey('label') ? $entity_type->getKey('label') : static::$labelFieldName;
$normalization[$label_field][1]['value'] = 'Second Title';
break;
case 'id':
$normalization[$entity_type->getKey('id')][0]['value'] = $this->anotherEntity->id();
break;
case 'uuid':
$normalization[$entity_type->getKey('uuid')][0]['value'] = $this->anotherEntity->uuid();
break;
}
return $normalization;
}
/**
* Removes fields from a normalization.
*
* @param array $normalization
* An entity normalization.
* @param string[] $field_names
* The field names to remove from the entity normalization.
*
* @return array
* The updated entity normalization.
*
* @see ::testPatch
*/
protected function removeFieldsFromNormalization(array $normalization, $field_names) {
return array_diff_key($normalization, array_flip($field_names));
}
/**
* Asserts a 406 response… or in some cases a 403 response, because weirdness.
*
@@ -3,6 +3,7 @@
namespace Drupal\Tests\rest\Functional\EntityResource\EntityTest;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\FormatSpecificGetBcRouteTestTrait;
/**
* @group rest
@@ -10,6 +11,7 @@ use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
class EntityTestJsonAnonTest extends EntityTestResourceTestBase {
use AnonResourceTestTrait;
use FormatSpecificGetBcRouteTestTrait;
/**
* {@inheritdoc}
@@ -0,0 +1,102 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityTest;
use Drupal\Core\Cache\Cache;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
/**
* Test that internal properties are not exposed in the 'json' format.
*
* @group rest
*/
class EntityTestJsonInternalPropertyNormalizerTest extends EntityTestResourceTestBase {
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected function getExpectedNormalizedEntity() {
$expected = parent::getExpectedNormalizedEntity();
// The 'internal_value' property in test field type is not exposed in the
// normalization because setInternal(FALSE) was not called for this
// property.
// @see \Drupal\entity_test\Plugin\Field\FieldType\InternalPropertyTestFieldItem::propertyDefinitions
$expected['field_test_internal'] = [
[
'value' => 'This value shall not be internal!',
'non_internal_value' => 'Computed! This value shall not be internal!',
],
];
return $expected;
}
/**
* {@inheritdoc}
*/
protected function createEntity() {
if (!FieldStorageConfig::loadByName('entity_test', 'field_test_internal')) {
FieldStorageConfig::create([
'entity_type' => 'entity_test',
'field_name' => 'field_test_internal',
'type' => 'internal_property_test',
'cardinality' => 1,
'translatable' => FALSE,
])->save();
FieldConfig::create([
'entity_type' => 'entity_test',
'field_name' => 'field_test_internal',
'bundle' => 'entity_test',
'label' => 'Test field with internal and non-internal properties',
])->save();
}
$entity = parent::createEntity();
$entity->field_test_internal = [
'value' => 'This value shall not be internal!',
];
$entity->save();
return $entity;
}
/**
* {@inheritdoc}
*/
protected function getNormalizedPostEntity() {
return parent::getNormalizedPostEntity() + [
'field_test_internal' => [
[
'value' => 'This value shall not be internal!',
],
],
];
}
/**
* {@inheritdoc}
*/
protected function getExpectedCacheContexts() {
return Cache::mergeContexts(parent::getExpectedCacheContexts(), ['request_format']);
}
/**
* {@inheritdoc}
*/
protected function getExpectedCacheTags() {
return Cache::mergeTags(parent::getExpectedCacheTags(), ['you_are_it', 'no_tag_backs']);
}
}
@@ -5,11 +5,13 @@ namespace Drupal\Tests\rest\Functional\EntityResource\EntityTest;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
use Drupal\Tests\Traits\ExpectDeprecationTrait;
use Drupal\user\Entity\User;
abstract class EntityTestResourceTestBase extends EntityResourceTestBase {
use BcTimestampNormalizerUnixTestTrait;
use ExpectDeprecationTrait;
/**
* {@inheritdoc}
@@ -53,9 +55,20 @@ abstract class EntityTestResourceTestBase extends EntityResourceTestBase {
* {@inheritdoc}
*/
protected function createEntity() {
// Set flag so that internal field 'internal_string_field' is created.
// @see entity_test_entity_base_field_info()
$this->container->get('state')->set('entity_test.internal_field', TRUE);
\Drupal::entityDefinitionUpdateManager()->applyUpdates();
$entity_test = EntityTest::create([
'name' => 'Llama',
'type' => 'entity_test',
// Set a value for the internal field to confirm that it will not be
// returned in normalization.
// @see entity_test_entity_base_field_info().
'internal_string_field' => [
'value' => 'This value shall not be internal!',
],
]);
$entity_test->setOwnerId(0);
$entity_test->save();
@@ -0,0 +1,195 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityTest;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Language\LanguageInterface;
use Drupal\filter\Entity\FilterFormat;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
/**
* @group rest
*/
class EntityTestTextItemNormalizerTest extends EntityTestResourceTestBase {
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['filter_test'];
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected function setUpAuthorization($method) {
parent::setUpAuthorization($method);
if (in_array($method, ['POST', 'PATCH'], TRUE)) {
$this->grantPermissionsToTestedRole(['use text format my_text_format']);
}
}
/**
* {@inheritdoc}
*/
protected function getExpectedNormalizedEntity() {
$expected = parent::getExpectedNormalizedEntity();
$expected['field_test_text'] = [
[
'value' => 'Cádiz is the oldest continuously inhabited city in Spain and a nice place to spend a Sunday with friends.',
'format' => 'my_text_format',
'processed' => '<p>Cádiz is the oldest continuously inhabited city in Spain and a nice place to spend a Sunday with friends.</p>' . "\n" . '<p>This is a dynamic llama.</p>',
],
];
return $expected;
}
/**
* {@inheritdoc}
*/
protected function createEntity() {
$entity = parent::createEntity();
if (!FilterFormat::load('my_text_format')) {
FilterFormat::create([
'format' => 'my_text_format',
'name' => 'My Text Format',
'filters' => [
'filter_test_assets' => [
'weight' => -1,
'status' => TRUE,
],
'filter_test_cache_tags' => [
'weight' => 0,
'status' => TRUE,
],
'filter_test_cache_contexts' => [
'weight' => 0,
'status' => TRUE,
],
'filter_test_cache_merge' => [
'weight' => 0,
'status' => TRUE,
],
'filter_test_placeholders' => [
'weight' => 1,
'status' => TRUE,
],
'filter_autop' => [
'status' => TRUE,
],
],
])->save();
}
$entity->field_test_text = [
'value' => 'Cádiz is the oldest continuously inhabited city in Spain and a nice place to spend a Sunday with friends.',
'format' => 'my_text_format',
];
$entity->save();
return $entity;
}
/**
* {@inheritdoc}
*/
protected function getNormalizedPostEntity() {
$post_entity = parent::getNormalizedPostEntity();
$post_entity['field_test_text'] = [
[
'value' => 'Llamas are awesome.',
'format' => 'my_text_format',
],
];
return $post_entity;
}
/**
* {@inheritdoc}
*/
protected function getExpectedCacheTags() {
return Cache::mergeTags([
// The cache tag set by the processed_text element itself.
'config:filter.format.my_text_format',
// The cache tags set by the filter_test_cache_tags filter.
'foo:bar',
'foo:baz',
// The cache tags set by the filter_test_cache_merge filter.
'merge:tag'
], parent::getExpectedCacheTags());
}
/**
* {@inheritdoc}
*/
protected function getExpectedCacheContexts() {
return Cache::mergeContexts([
// The cache context set by the filter_test_cache_contexts filter.
'languages:' . LanguageInterface::TYPE_CONTENT,
// The default cache contexts for Renderer.
'languages:' . LanguageInterface::TYPE_INTERFACE,
'theme',
// The cache tags set by the filter_test_cache_merge filter.
'user.permissions',
], parent::getExpectedCacheContexts());
}
/**
* Tests GETting an entity with the test text field set to a specific format.
*
* @dataProvider providerTestGetWithFormat
*/
public function testGetWithFormat($text_format_id, array $expected_cache_tags) {
FilterFormat::create([
'name' => 'Pablo Piccasso',
'format' => 'pablo',
'langcode' => 'es',
'filters' => [],
])->save();
// Set TextItemBase field's value for testing, using the given text format.
$value = [
'value' => $this->randomString(),
];
if ($text_format_id !== FALSE) {
$value['format'] = $text_format_id;
}
$this->entity->set('field_test_text', $value)->save();
$this->initAuthentication();
$url = $this->getEntityResourceUrl();
$url->setOption('query', ['_format' => static::$format]);
$request_options = $this->getAuthenticationRequestOptions('GET');
$this->provisionEntityResource();
$this->setUpAuthorization('GET');
$response = $this->request('GET', $url, $request_options);
$expected_cache_tags = Cache::mergeTags($expected_cache_tags, parent::getExpectedCacheTags());
$this->assertSame($expected_cache_tags, explode(' ', $response->getHeader('X-Drupal-Cache-Tags')[0]));
}
public function providerTestGetWithFormat() {
return [
'format specified (different from fallback format)' => [
'pablo',
['config:filter.format.pablo'],
],
'format specified (happens to be the same as fallback format)' => [
'plain_text',
['config:filter.format.plain_text'],
],
'no format specified: fallback format used automatically' => [
FALSE,
['config:filter.format.plain_text', 'config:filter.settings'],
],
];
}
}
@@ -0,0 +1,28 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityTest;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\FormatSpecificGetBcRouteTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EntityTestXmlAnonTest extends EntityTestResourceTestBase {
use AnonResourceTestTrait;
use FormatSpecificGetBcRouteTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityTest;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EntityTestXmlBasicAuthTest extends EntityTestResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityTest;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EntityTestXmlCookieTest extends EntityTestResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityTestBundle;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EntityTestBundleXmlAnonTest extends EntityTestBundleResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityTestBundle;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EntityTestBundleXmlBasicAuthTest extends EntityTestBundleResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityTestBundle;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EntityTestBundleXmlCookieTest extends EntityTestBundleResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityTestLabel;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EntityTestLabelXmlAnonTest extends EntityTestLabelResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityTestLabel;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EntityTestLabelXmlBasicAuthTest extends EntityTestLabelResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityTestLabel;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EntityTestLabelXmlCookieTest extends EntityTestLabelResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,24 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityViewDisplay;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
/**
* @group rest
*/
class EntityViewDisplayJsonAnonTest extends EntityViewDisplayResourceTestBase {
use AnonResourceTestTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
}
@@ -0,0 +1,34 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityViewDisplay;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
/**
* @group rest
*/
class EntityViewDisplayJsonBasicAuthTest extends EntityViewDisplayResourceTestBase {
use BasicAuthResourceTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,29 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityViewDisplay;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
/**
* @group rest
*/
class EntityViewDisplayJsonCookieTest extends EntityViewDisplayResourceTestBase {
use CookieResourceTestTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'json';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'application/json';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,118 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityViewDisplay;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\node\Entity\NodeType;
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
abstract class EntityViewDisplayResourceTestBase extends EntityResourceTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['node'];
/**
* {@inheritdoc}
*/
protected static $entityTypeId = 'entity_view_display';
/**
* {@inheritdoc}
*/
protected static $patchProtectedFieldNames = [];
/**
* @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface
*/
protected $entity;
/**
* {@inheritdoc}
*/
protected function setUpAuthorization($method) {
$this->grantPermissionsToTestedRole(['administer node display']);
}
/**
* {@inheritdoc}
*/
protected function createEntity() {
// Create a "Camelids" node type.
$camelids = NodeType::create([
'name' => 'Camelids',
'type' => 'camelids',
]);
$camelids->save();
// Create a view display.
$view_display = EntityViewDisplay::create([
'targetEntityType' => 'node',
'bundle' => 'camelids',
'mode' => 'default',
'status' => TRUE,
]);
$view_display->save();
return $view_display;
}
/**
* {@inheritdoc}
*/
protected function getExpectedNormalizedEntity() {
return [
'bundle' => 'camelids',
'content' => [
'links' => [
'region' => 'content',
'weight' => 100,
],
],
'dependencies' => [
'config' => [
'node.type.camelids',
],
'module' => [
'user',
],
],
'hidden' => [],
'id' => 'node.camelids.default',
'langcode' => 'en',
'mode' => 'default',
'status' => TRUE,
'targetEntityType' => 'node',
'uuid' => $this->entity->uuid(),
];
}
/**
* {@inheritdoc}
*/
protected function getNormalizedPostEntity() {
// @todo Update in https://www.drupal.org/node/2300677.
}
/**
* {@inheritdoc}
*/
protected function getExpectedCacheContexts() {
return [
'user.permissions',
];
}
/**
* {@inheritdoc}
*/
protected function getExpectedUnauthorizedAccessMessage($method) {
if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) {
return parent::getExpectedUnauthorizedAccessMessage($method);
}
return "The 'administer node display' permission is required.";
}
}
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityViewDisplay;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EntityViewDisplayXmlAnonTest extends EntityViewDisplayResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityViewDisplay;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EntityViewDisplayXmlBasicAuthTest extends EntityViewDisplayResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityViewDisplay;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EntityViewDisplayXmlCookieTest extends EntityViewDisplayResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityViewMode;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EntityViewModeXmlAnonTest extends EntityViewModeResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityViewMode;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EntityViewModeXmlBasicAuthTest extends EntityViewModeResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\EntityViewMode;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class EntityViewModeXmlCookieTest extends EntityViewModeResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -3,10 +3,10 @@
namespace Drupal\Tests\rest\Functional\EntityResource\Feed;
use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\EntityTest\EntityTestResourceTestBase;
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
use Drupal\aggregator\Entity\Feed;
abstract class FeedResourceTestBase extends EntityTestResourceTestBase {
abstract class FeedResourceTestBase extends EntityResourceTestBase {
use BcTimestampNormalizerUnixTestTrait;
@@ -20,6 +20,16 @@ abstract class FeedResourceTestBase extends EntityTestResourceTestBase {
*/
public static $entityTypeId = 'aggregator_feed';
/**
* {@inheritdoc}
*/
protected static $patchProtectedFieldNames = [];
/**
* {@inheritdoc}
*/
protected static $uniqueFieldNames = ['url'];
/**
* {@inheritdoc}
*/
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\Feed;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class FeedXmlAnonTest extends FeedResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}
@@ -0,0 +1,36 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\Feed;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class FeedXmlBasicAuthTest extends FeedResourceTestBase {
use BasicAuthResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['basic_auth'];
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'basic_auth';
}
@@ -0,0 +1,31 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\Feed;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class FeedXmlCookieTest extends FeedResourceTestBase {
use CookieResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
/**
* {@inheritdoc}
*/
protected static $auth = 'cookie';
}
@@ -0,0 +1,26 @@
<?php
namespace Drupal\Tests\rest\Functional\EntityResource\FieldConfig;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
/**
* @group rest
*/
class FieldConfigXmlAnonTest extends FieldConfigResourceTestBase {
use AnonResourceTestTrait;
use XmlEntityNormalizationQuirksTrait;
/**
* {@inheritdoc}
*/
protected static $format = 'xml';
/**
* {@inheritdoc}
*/
protected static $mimeType = 'text/xml; charset=UTF-8';
}

Some files were not shown because too many files have changed in this diff Show More