Issue #2895532 by caseylau, Wim Leers, tedbow, dawehner, DamienMcKenna, gabesullice, Berdir, mistermoper, skyredwang, larowlan, bojanz: @DataType=map cannot be normalized, affects @FieldType=link, @FieldType=map
parent
3f44f5bbcb
commit
725e36091e
|
@ -168,9 +168,8 @@ class TypedDataManager extends DefaultPluginManager implements TypedDataManagerI
|
|||
// a shorter string than the serialized form, so array access is faster.
|
||||
$parts[] = json_encode($settings);
|
||||
}
|
||||
// Property path for the requested data object. When creating a list item,
|
||||
// use 0 in the key as all items look the same.
|
||||
$parts[] = $object->getPropertyPath() . '.' . (is_numeric($property_name) ? 0 : $property_name);
|
||||
// Property path for the requested data object.
|
||||
$parts[] = $object->getPropertyPath() . '.' . $property_name;
|
||||
$key = implode(':', $parts);
|
||||
|
||||
// Create the prototype if needed.
|
||||
|
|
|
@ -92,7 +92,10 @@ class FieldItemNormalizer extends NormalizerBase {
|
|||
// We normalize each individual property, so each can do their own casting,
|
||||
// if needed.
|
||||
/** @var \Drupal\Core\TypedData\TypedDataInterface $property */
|
||||
foreach (TypedDataInternalPropertiesHelper::getNonInternalProperties($field_item) as $property_name => $property) {
|
||||
$field_properties = !empty($field_item->getProperties(TRUE))
|
||||
? TypedDataInternalPropertiesHelper::getNonInternalProperties($field_item)
|
||||
: $field_item->getValue();
|
||||
foreach ($field_properties as $property_name => $property) {
|
||||
$normalized[$property_name] = $this->serializer->normalize($property, $format, $context);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ class LinkNotExistingInternalConstraintValidator extends ConstraintValidator {
|
|||
if ($url->isRouted()) {
|
||||
$allowed = TRUE;
|
||||
try {
|
||||
$url->toString();
|
||||
$url->toString(TRUE);
|
||||
}
|
||||
// The following exceptions are all possible during URL generation, and
|
||||
// should be considered as disallowed URLs.
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\link\Kernel;
|
||||
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\link\LinkItemInterface;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\Component\Utility\UrlHelper;
|
||||
use Drupal\Tests\field\Kernel\FieldKernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests link field serialization.
|
||||
*
|
||||
* @group link
|
||||
*/
|
||||
class LinkItemSerializationTest extends FieldKernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['link', 'serialization'];
|
||||
|
||||
/**
|
||||
* The serializer service.
|
||||
*
|
||||
* @var \Symfony\Component\Serializer\SerializerInterface
|
||||
*/
|
||||
protected $serializer;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('user');
|
||||
$this->serializer = \Drupal::service('serializer');
|
||||
|
||||
// Create a generic, external, and internal link fields for validation.
|
||||
FieldStorageConfig::create([
|
||||
'entity_type' => 'entity_test',
|
||||
'field_name' => 'field_test',
|
||||
'type' => 'link',
|
||||
])->save();
|
||||
|
||||
FieldConfig::create([
|
||||
'entity_type' => 'entity_test',
|
||||
'field_name' => 'field_test',
|
||||
'bundle' => 'entity_test',
|
||||
'settings' => ['link_type' => LinkItemInterface::LINK_GENERIC],
|
||||
])->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the serialization.
|
||||
*/
|
||||
public function testLinkSerialization() {
|
||||
// Create entity.
|
||||
$entity = EntityTest::create();
|
||||
$url = 'https://www.drupal.org?test_param=test_value';
|
||||
$parsed_url = UrlHelper::parse($url);
|
||||
$title = $this->randomMachineName();
|
||||
$class = $this->randomMachineName();
|
||||
$entity->field_test->uri = $parsed_url['path'];
|
||||
$entity->field_test->title = $title;
|
||||
$entity->field_test->first()
|
||||
->get('options')
|
||||
->set('query', $parsed_url['query']);
|
||||
$entity->field_test->first()
|
||||
->get('options')
|
||||
->set('attributes', ['class' => $class]);
|
||||
$entity->save();
|
||||
$serialized = $this->serializer->serialize($entity, 'json');
|
||||
$deserialized = $this->serializer->deserialize($serialized, EntityTest::class, 'json');
|
||||
$options_expected = [
|
||||
'query' => $parsed_url['query'],
|
||||
'attributes' => ['class' => $class],
|
||||
];
|
||||
$this->assertSame($options_expected, $deserialized->field_test->options);
|
||||
}
|
||||
|
||||
}
|
|
@ -59,7 +59,15 @@ abstract class MenuLinkContentResourceTestBase extends EntityResourceTestBase {
|
|||
'id' => 'llama',
|
||||
'title' => 'Llama Gabilondo',
|
||||
'description' => 'Llama Gabilondo',
|
||||
'link' => 'https://nl.wikipedia.org/wiki/Llama',
|
||||
'link' => [
|
||||
'uri' => 'https://nl.wikipedia.org/wiki/Llama',
|
||||
'options' => [
|
||||
'fragment' => 'a-fragment',
|
||||
'attributes' => [
|
||||
'class' => ['example-class'],
|
||||
],
|
||||
],
|
||||
],
|
||||
'weight' => 0,
|
||||
'menu_name' => 'main',
|
||||
]);
|
||||
|
@ -81,6 +89,12 @@ abstract class MenuLinkContentResourceTestBase extends EntityResourceTestBase {
|
|||
'link' => [
|
||||
[
|
||||
'uri' => 'http://www.urbandictionary.com/define.php?term=drama%20llama',
|
||||
'options' => [
|
||||
'fragment' => 'a-fragment',
|
||||
'attributes' => [
|
||||
'class' => ['example-class'],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'bundle' => [
|
||||
|
@ -115,7 +129,12 @@ abstract class MenuLinkContentResourceTestBase extends EntityResourceTestBase {
|
|||
[
|
||||
'uri' => 'https://nl.wikipedia.org/wiki/Llama',
|
||||
'title' => NULL,
|
||||
'options' => [],
|
||||
'options' => [
|
||||
'fragment' => 'a-fragment',
|
||||
'attributes' => [
|
||||
'class' => ['example-class'],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'weight' => [
|
||||
|
|
|
@ -617,7 +617,10 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
|
|||
// Only run this for fieldable entities. It doesn't make sense for config
|
||||
// entities as config values are already casted. They also run through the
|
||||
// ConfigEntityNormalizer, which doesn't deal with fields individually.
|
||||
if ($this->entity instanceof FieldableEntityInterface) {
|
||||
// Also exclude entity_test_map_field — that has a "map" base field, which
|
||||
// only became normalizable since Drupal 8.6, so its normalization
|
||||
// containing non-stringified numbers or booleans does not break BC.
|
||||
if ($this->entity instanceof FieldableEntityInterface && static::$entityTypeId !== 'entity_test_map_field') {
|
||||
// Test primitive data casting BC (strings).
|
||||
$this->config('serialization.settings')->set('bc_primitives_as_strings', TRUE)->save(TRUE);
|
||||
// Rebuild the container so new config is reflected in the addition of the
|
||||
|
@ -921,17 +924,7 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
|
|||
$created_entity = $this->entityStorage->loadUnchanged(static::$firstCreatedEntityId);
|
||||
$created_entity_normalization = $this->serializer->normalize($created_entity, static::$format, ['account' => $this->account]);
|
||||
$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);
|
||||
}
|
||||
}
|
||||
$this->assertStoredEntityMatchesSentNormalization($this->getNormalizedPostEntity(), $created_entity);
|
||||
}
|
||||
|
||||
$this->config('rest.settings')->set('bc_entity_resource_permissions', TRUE)->save(TRUE);
|
||||
|
@ -1182,16 +1175,7 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
|
|||
$updated_entity = $this->entityStorage->loadUnchanged($this->entity->id());
|
||||
$updated_entity_normalization = $this->serializer->normalize($updated_entity, static::$format, ['account' => $this->account]);
|
||||
$this->assertSame($updated_entity_normalization, $this->serializer->decode((string) $response->getBody(), static::$format));
|
||||
// Assert that the entity was indeed created using the PATCHed values.
|
||||
foreach ($this->getNormalizedPatchEntity() 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 ($updated_entity->hasField($field_name)) {
|
||||
// Subset, not same, because we can e.g. send just the target_id for the
|
||||
// bundle in a PATCH request; the response will include more properties.
|
||||
$this->assertArraySubset(static::castToString($field_normalization), $updated_entity->get($field_name)->getValue(), TRUE);
|
||||
}
|
||||
}
|
||||
$this->assertStoredEntityMatchesSentNormalization($this->getNormalizedPatchEntity(), $updated_entity);
|
||||
// Ensure that fields do not get deleted if they're not present in the PATCH
|
||||
// request. Test this using the configurable field that we added, but which
|
||||
// is not sent in the PATCH request.
|
||||
|
@ -1516,4 +1500,33 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the stored entity matches the sent normalization.
|
||||
*
|
||||
* @param array $sent_normalization
|
||||
* An entity normalization.
|
||||
* @param \Drupal\Core\Entity\FieldableEntityInterface $modified_entity
|
||||
* The entity object of the modified (PATCHed or POSTed) entity.
|
||||
*/
|
||||
protected function assertStoredEntityMatchesSentNormalization(array $sent_normalization, FieldableEntityInterface $modified_entity) {
|
||||
foreach ($sent_normalization 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 ($modified_entity->hasField($field_name)) {
|
||||
$field_type = $modified_entity->get($field_name)->getFieldDefinition()->getType();
|
||||
// Fields are stored in the database, when read they are represented
|
||||
// as strings in PHP memory. The exception: field types that are
|
||||
// stored in a serialized way. Hence we need to cast most expected
|
||||
// field normalizations to strings.
|
||||
$expected_field_normalization = ($field_type !== 'map')
|
||||
? static::castToString($field_normalization)
|
||||
: $field_normalization;
|
||||
// Subset, not same, because we can e.g. send just the target_id for the
|
||||
// bundle in a PATCH or POST request; the response will include more
|
||||
// properties.
|
||||
$this->assertArraySubset($expected_field_normalization, $modified_entity->get($field_name)->getValue(), TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,7 +34,10 @@ class ComplexDataNormalizer extends NormalizerBase {
|
|||
// Other normalizers that extend this class may only provide $object that
|
||||
// implements \Traversable.
|
||||
if ($object instanceof ComplexDataInterface) {
|
||||
$object = TypedDataInternalPropertiesHelper::getNonInternalProperties($object);
|
||||
// If there are no properties to normalize, just normalize the value.
|
||||
$object = !empty($object->getProperties(TRUE))
|
||||
? TypedDataInternalPropertiesHelper::getNonInternalProperties($object)
|
||||
: $object->getValue();
|
||||
}
|
||||
/** @var \Drupal\Core\TypedData\TypedDataInterface $property */
|
||||
foreach ($object as $name => $property) {
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\serialization\Kernel;
|
||||
|
||||
use Drupal\Core\TypedData\DataDefinition;
|
||||
use Drupal\Core\TypedData\MapDataDefinition;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* @group typedData
|
||||
*/
|
||||
class MapDataNormalizerTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['system', 'serialization'];
|
||||
|
||||
/**
|
||||
* The serializer service.
|
||||
*
|
||||
* @var \Symfony\Component\Serializer\Serializer
|
||||
*/
|
||||
protected $serializer;
|
||||
|
||||
/**
|
||||
* The typed data manager.
|
||||
*
|
||||
* @var \Drupal\Core\TypedData\TypedDataManagerInterface
|
||||
*/
|
||||
protected $typedDataManager;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->serializer = \Drupal::service('serializer');
|
||||
$this->typedDataManager = \Drupal::typedDataManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether map data can be normalized.
|
||||
*/
|
||||
public function testMapNormalize() {
|
||||
$typed_data = $this->buildExampleTypedData();
|
||||
$data = $this->serializer->normalize($typed_data, 'json');
|
||||
$expect_value = [
|
||||
'key1' => 'value1',
|
||||
'key2' => 'value2',
|
||||
'key3' => 3,
|
||||
'key4' => [
|
||||
0 => TRUE,
|
||||
1 => 'value6',
|
||||
'key7' => 'value7',
|
||||
],
|
||||
];
|
||||
$this->assertSame($expect_value, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether map data with properties can be normalized.
|
||||
*/
|
||||
public function testMapWithPropertiesNormalize() {
|
||||
$typed_data = $this->buildExampleTypedDataWithProperties();
|
||||
$data = $this->serializer->normalize($typed_data, 'json');
|
||||
$expect_value = [
|
||||
'key1' => 'value1',
|
||||
'key2' => 'value2',
|
||||
'key3' => 3,
|
||||
'key4' => [
|
||||
0 => TRUE,
|
||||
1 => 'value6',
|
||||
'key7' => 'value7',
|
||||
],
|
||||
];
|
||||
$this->assertSame($expect_value, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds some example typed data object with no properties.
|
||||
*/
|
||||
protected function buildExampleTypedData() {
|
||||
$tree = [
|
||||
'key1' => 'value1',
|
||||
'key2' => 'value2',
|
||||
'key3' => 3,
|
||||
'key4' => [
|
||||
0 => TRUE,
|
||||
1 => 'value6',
|
||||
'key7' => 'value7',
|
||||
],
|
||||
];
|
||||
$map_data_definition = MapDataDefinition::create();
|
||||
$typed_data = $this->typedDataManager->create(
|
||||
$map_data_definition,
|
||||
$tree,
|
||||
'test name'
|
||||
);
|
||||
return $typed_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds some example typed data object with properties.
|
||||
*/
|
||||
protected function buildExampleTypedDataWithProperties() {
|
||||
$tree = [
|
||||
'key1' => 'value1',
|
||||
'key2' => 'value2',
|
||||
'key3' => 3,
|
||||
'key4' => [
|
||||
0 => TRUE,
|
||||
1 => 'value6',
|
||||
'key7' => 'value7',
|
||||
],
|
||||
];
|
||||
$map_data_definition = MapDataDefinition::create()
|
||||
->setPropertyDefinition('key1', DataDefinition::create('string'))
|
||||
->setPropertyDefinition('key2', DataDefinition::create('string'))
|
||||
->setPropertyDefinition('key3', DataDefinition::create('integer'))
|
||||
->setPropertyDefinition('key4', MapDataDefinition::create()
|
||||
->setPropertyDefinition(0, DataDefinition::create('boolean'))
|
||||
->setPropertyDefinition(1, DataDefinition::create('string'))
|
||||
->setPropertyDefinition('key7', DataDefinition::create('string'))
|
||||
);
|
||||
|
||||
$typed_data = $this->typedDataManager->create(
|
||||
$map_data_definition,
|
||||
$tree,
|
||||
'test name'
|
||||
);
|
||||
|
||||
return $typed_data;
|
||||
}
|
||||
|
||||
}
|
|
@ -58,6 +58,9 @@ abstract class ShortcutResourceTestBase extends EntityResourceTestBase {
|
|||
'weight' => -20,
|
||||
'link' => [
|
||||
'uri' => 'internal:/admin/content/comment',
|
||||
'options' => [
|
||||
'fragment' => 'new',
|
||||
],
|
||||
],
|
||||
]);
|
||||
$shortcut->save();
|
||||
|
@ -96,7 +99,9 @@ abstract class ShortcutResourceTestBase extends EntityResourceTestBase {
|
|||
[
|
||||
'uri' => 'internal:/admin/content/comment',
|
||||
'title' => NULL,
|
||||
'options' => [],
|
||||
'options' => [
|
||||
'fragment' => 'new',
|
||||
],
|
||||
],
|
||||
],
|
||||
'weight' => [
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\entity_test\Entity;
|
||||
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
|
||||
/**
|
||||
* An entity used for testing map base field values.
|
||||
*
|
||||
* @ContentEntityType(
|
||||
* id = "entity_test_map_field",
|
||||
* label = @Translation("Entity Test map field"),
|
||||
* base_table = "entity_test_map_field",
|
||||
* entity_keys = {
|
||||
* "uuid" = "uuid",
|
||||
* "id" = "id",
|
||||
* "label" = "name",
|
||||
* "langcode" = "langcode",
|
||||
* },
|
||||
* admin_permission = "administer entity_test content",
|
||||
* )
|
||||
*/
|
||||
class EntityTestMapField extends EntityTest {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
|
||||
$fields = parent::baseFieldDefinitions($entity_type);
|
||||
|
||||
$fields['data'] = BaseFieldDefinition::create('map')
|
||||
->setLabel(t('Data'))
|
||||
->setDescription(t('A serialized array of additional data.'));
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\entity_test\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\entity_test\Functional\Rest\EntityTestMapFieldResourceTestBase;
|
||||
use Drupal\Tests\hal\Functional\EntityResource\HalEntityNormalizationTrait;
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class EntityTestMapFieldHalJsonAnonTest extends EntityTestMapFieldResourceTestBase {
|
||||
|
||||
use HalEntityNormalizationTrait;
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedNormalizedEntity() {
|
||||
$default_normalization = parent::getExpectedNormalizedEntity();
|
||||
|
||||
$normalization = $this->applyHalFieldNormalization($default_normalization);
|
||||
|
||||
$author = User::load(0);
|
||||
return $normalization + [
|
||||
'_links' => [
|
||||
'self' => [
|
||||
'href' => '',
|
||||
],
|
||||
'type' => [
|
||||
'href' => $this->baseUrl . '/rest/type/entity_test_map_field/entity_test_map_field',
|
||||
],
|
||||
$this->baseUrl . '/rest/relation/entity_test_map_field/entity_test_map_field/user_id' => [
|
||||
[
|
||||
'href' => $this->baseUrl . '/user/0?_format=hal_json',
|
||||
'lang' => 'en',
|
||||
],
|
||||
],
|
||||
],
|
||||
'_embedded' => [
|
||||
$this->baseUrl . '/rest/relation/entity_test_map_field/entity_test_map_field/user_id' => [
|
||||
[
|
||||
'_links' => [
|
||||
'self' => [
|
||||
'href' => $this->baseUrl . '/user/0?_format=hal_json',
|
||||
],
|
||||
'type' => [
|
||||
'href' => $this->baseUrl . '/rest/type/user/user',
|
||||
],
|
||||
],
|
||||
'uuid' => [
|
||||
[
|
||||
'value' => $author->uuid(),
|
||||
],
|
||||
],
|
||||
'lang' => 'en',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getNormalizedPostEntity() {
|
||||
return parent::getNormalizedPostEntity() + [
|
||||
'_links' => [
|
||||
'type' => [
|
||||
'href' => $this->baseUrl . '/rest/type/entity_test_map_field/entity_test_map_field',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedCacheContexts() {
|
||||
return [
|
||||
'url.site',
|
||||
'user.permissions',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\entity_test\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class EntityTestMapFieldJsonAnonTest extends EntityTestMapFieldResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/json';
|
||||
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\entity_test\Functional\Rest;
|
||||
|
||||
use Drupal\entity_test\Entity\EntityTestMapField;
|
||||
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 EntityTestMapFieldResourceTestBase extends EntityResourceTestBase {
|
||||
|
||||
use BcTimestampNormalizerUnixTestTrait;
|
||||
use ExpectDeprecationTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['entity_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $entityTypeId = 'entity_test_map_field';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $patchProtectedFieldNames = [];
|
||||
|
||||
/**
|
||||
* @var \Drupal\entity_test\Entity\EntityTestMapField
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* The complex nested value to assign to a @FieldType=map field.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $mapValue = [
|
||||
'key1' => 'value',
|
||||
'key2' => 'no, val you',
|
||||
'π' => 3.14159,
|
||||
TRUE => 42,
|
||||
'nested' => [
|
||||
'bird' => 'robin',
|
||||
'doll' => 'Russian',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpAuthorization($method) {
|
||||
$this->grantPermissionsToTestedRole(['administer entity_test content']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createEntity() {
|
||||
$entity = EntityTestMapField::create([
|
||||
'name' => 'Llama',
|
||||
'type' => 'entity_test_map_field',
|
||||
'data' => [
|
||||
static::$mapValue,
|
||||
],
|
||||
]);
|
||||
$entity->setOwnerId(0);
|
||||
$entity->save();
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedNormalizedEntity() {
|
||||
$author = User::load(0);
|
||||
return [
|
||||
'uuid' => [
|
||||
[
|
||||
'value' => $this->entity->uuid(),
|
||||
],
|
||||
],
|
||||
'id' => [
|
||||
[
|
||||
'value' => 1,
|
||||
],
|
||||
],
|
||||
'name' => [
|
||||
[
|
||||
'value' => 'Llama',
|
||||
],
|
||||
],
|
||||
'langcode' => [
|
||||
[
|
||||
'value' => 'en',
|
||||
],
|
||||
],
|
||||
'created' => [
|
||||
$this->formatExpectedTimestampItemValues((int) $this->entity->get('created')->value),
|
||||
],
|
||||
'user_id' => [
|
||||
[
|
||||
'target_id' => (int) $author->id(),
|
||||
'target_type' => 'user',
|
||||
'target_uuid' => $author->uuid(),
|
||||
'url' => $author->toUrl()->toString(),
|
||||
],
|
||||
],
|
||||
'data' => [
|
||||
static::$mapValue,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getNormalizedPostEntity() {
|
||||
return [
|
||||
'name' => [
|
||||
[
|
||||
'value' => 'Dramallama',
|
||||
],
|
||||
],
|
||||
'data' => [
|
||||
0 => static::$mapValue,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedUnauthorizedAccessMessage($method) {
|
||||
if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) {
|
||||
return parent::getExpectedUnauthorizedAccessMessage($method);
|
||||
}
|
||||
|
||||
return "The 'administer entity_test content' permission is required.";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedCacheContexts() {
|
||||
return ['user.permissions'];
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue