updated core from 8.4 to 8.5 : bug with login_destination
This commit is contained in:
@@ -5,8 +5,8 @@ package: Web services
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# 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
|
||||
|
||||
@@ -10,6 +10,10 @@ use Symfony\Component\Serializer\Encoder\JsonEncoder as BaseJsonEncoder;
|
||||
|
||||
/**
|
||||
* Adds 'ajax to the supported content types of the JSON encoder'
|
||||
*
|
||||
* @internal
|
||||
* This encoder should not be used directly. Rather, use the `serializer`
|
||||
* service.
|
||||
*/
|
||||
class JsonEncoder extends BaseJsonEncoder implements EncoderInterface, DecoderInterface {
|
||||
|
||||
|
||||
@@ -12,6 +12,10 @@ use Symfony\Component\Serializer\Encoder\XmlEncoder as BaseXmlEncoder;
|
||||
*
|
||||
* This acts as a wrapper class for Symfony's XmlEncoder so that it is not
|
||||
* implementing NormalizationAwareInterface, and can be normalized externally.
|
||||
*
|
||||
* @internal
|
||||
* This encoder should not be used directly. Rather, use the `serializer`
|
||||
* service.
|
||||
*/
|
||||
class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, DecoderInterface {
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Drupal\serialization\EventSubscriber;
|
||||
|
||||
use Drupal\Core\Cache\CacheableDependencyInterface;
|
||||
use Drupal\Core\Cache\CacheableResponse;
|
||||
use Drupal\Core\EventSubscriber\HttpExceptionSubscriberBase;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
|
||||
@@ -51,8 +53,12 @@ class DefaultExceptionSubscriber extends HttpExceptionSubscriberBase {
|
||||
*/
|
||||
protected static function getPriority() {
|
||||
// This will fire after the most common HTML handler, since HTML requests
|
||||
// are still more common than HTTP requests.
|
||||
return -75;
|
||||
// are still more common than HTTP requests. But it has a lower priority
|
||||
// than \Drupal\Core\EventSubscriber\ExceptionJsonSubscriber::on4xx(), so
|
||||
// that this also handles the 'json' format. Then all serialization formats
|
||||
// (::getHandledFormats()) are handled by this exception subscriber, which
|
||||
// results in better consistency.
|
||||
return -70;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,14 +73,22 @@ class DefaultExceptionSubscriber extends HttpExceptionSubscriberBase {
|
||||
$request = $event->getRequest();
|
||||
|
||||
$format = $request->getRequestFormat();
|
||||
$content = ['message' => $event->getException()->getMessage()];
|
||||
$content = ['message' => $exception->getMessage()];
|
||||
$encoded_content = $this->serializer->serialize($content, $format);
|
||||
$headers = $exception->getHeaders();
|
||||
|
||||
// Add the MIME type from the request to send back in the header.
|
||||
$headers['Content-Type'] = $request->getMimeType($format);
|
||||
|
||||
$response = new Response($encoded_content, $exception->getStatusCode(), $headers);
|
||||
// If the exception is cacheable, generate a cacheable response.
|
||||
if ($exception instanceof CacheableDependencyInterface) {
|
||||
$response = new CacheableResponse($encoded_content, $exception->getStatusCode(), $headers);
|
||||
$response->addCacheableDependency($exception);
|
||||
}
|
||||
else {
|
||||
$response = new Response($encoded_content, $exception->getStatusCode(), $headers);
|
||||
}
|
||||
|
||||
$event->setResponse($response);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\serialization\Normalizer;
|
||||
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
|
||||
/**
|
||||
* Defines the interface for normalizers producing cacheable normalizations.
|
||||
*
|
||||
* @see cache
|
||||
*/
|
||||
interface CacheableNormalizerInterface extends NormalizerInterface {
|
||||
|
||||
/**
|
||||
* Name of key for bubbling cacheability metadata via serialization context.
|
||||
*
|
||||
* @see \Symfony\Component\Serializer\Normalizer\NormalizerInterface::normalize()
|
||||
* @see \Symfony\Component\Serializer\SerializerInterface::serialize()
|
||||
* @see \Drupal\rest\EventSubscriber\ResourceResponseSubscriber::renderResponseBody()
|
||||
*/
|
||||
const SERIALIZATION_CONTEXT_CACHEABILITY = 'cacheability';
|
||||
|
||||
}
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
namespace Drupal\serialization\Normalizer;
|
||||
|
||||
use Drupal\Core\TypedData\ComplexDataInterface;
|
||||
use Drupal\Core\TypedData\TypedDataInternalPropertiesHelper;
|
||||
|
||||
/**
|
||||
* Converts the Drupal entity object structures to a normalized array.
|
||||
*
|
||||
@@ -26,6 +29,13 @@ class ComplexDataNormalizer extends NormalizerBase {
|
||||
*/
|
||||
public function normalize($object, $format = NULL, array $context = []) {
|
||||
$attributes = [];
|
||||
// $object will not always match $supportedInterfaceOrClass.
|
||||
// @see \Drupal\serialization\Normalizer\EntityNormalizer
|
||||
// Other normalizers that extend this class may only provide $object that
|
||||
// implements \Traversable.
|
||||
if ($object instanceof ComplexDataInterface) {
|
||||
$object = TypedDataInternalPropertiesHelper::getNonInternalProperties($object);
|
||||
}
|
||||
/** @var \Drupal\Core\TypedData\TypedDataInterface $property */
|
||||
foreach ($object as $name => $property) {
|
||||
$attributes[$name] = $this->serializer->normalize($property, $format, $context);
|
||||
|
||||
@@ -18,7 +18,33 @@ class ConfigEntityNormalizer extends EntityNormalizer {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function normalize($object, $format = NULL, array $context = []) {
|
||||
return $object->toArray();
|
||||
return static::getDataWithoutInternals($object->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function denormalize($data, $class, $format = NULL, array $context = []) {
|
||||
return parent::denormalize(static::getDataWithoutInternals($data), $class, $format, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the given data without the internal implementation details.
|
||||
*
|
||||
* @param array $data
|
||||
* The data that is either currently or about to be stored in configuration.
|
||||
*
|
||||
* @return array
|
||||
* The same data, but without internals. Currently, that is only the '_core'
|
||||
* key, which is reserved by Drupal core to handle complex edge cases
|
||||
* correctly. Data in the '_core' key is irrelevant to clients reading
|
||||
* configuration, and is not allowed to be set by clients writing
|
||||
* configuration: it is for Drupal core only, and managed by Drupal core.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2653358
|
||||
*/
|
||||
protected static function getDataWithoutInternals(array $data) {
|
||||
return array_diff_key($data, ['_core' => TRUE]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Drupal\serialization\Normalizer;
|
||||
|
||||
use Drupal\Core\TypedData\TypedDataInternalPropertiesHelper;
|
||||
|
||||
/**
|
||||
* Normalizes/denormalizes Drupal content entities into an array structure.
|
||||
*/
|
||||
@@ -21,7 +23,8 @@ class ContentEntityNormalizer extends EntityNormalizer {
|
||||
];
|
||||
|
||||
$attributes = [];
|
||||
foreach ($entity as $name => $field_items) {
|
||||
/** @var \Drupal\Core\Entity\Entity $entity */
|
||||
foreach (TypedDataInternalPropertiesHelper::getNonInternalProperties($entity->getTypedData()) as $name => $field_items) {
|
||||
if ($field_items->access('view', $context['account'])) {
|
||||
$attributes[$name] = $this->serializer->normalize($field_items, $format, $context);
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
namespace Drupal\serialization\Normalizer;
|
||||
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
use Drupal\Core\Cache\CacheableDependencyInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\SerializerAwareNormalizer;
|
||||
|
||||
/**
|
||||
* Base class for Normalizers.
|
||||
*/
|
||||
abstract class NormalizerBase extends SerializerAwareNormalizer implements NormalizerInterface {
|
||||
abstract class NormalizerBase extends SerializerAwareNormalizer implements CacheableNormalizerInterface {
|
||||
|
||||
/**
|
||||
* The interface or class that this Normalizer supports.
|
||||
@@ -81,4 +81,18 @@ abstract class NormalizerBase extends SerializerAwareNormalizer implements Norma
|
||||
return in_array($format, (array) $this->format, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds cacheability if applicable.
|
||||
*
|
||||
* @param array $context
|
||||
* Context options for the normalizer.
|
||||
* @param $data
|
||||
* The data that might have cacheability information.
|
||||
*/
|
||||
protected function addCacheableDependency(array $context, $data) {
|
||||
if ($data instanceof CacheableDependencyInterface && isset($context[static::SERIALIZATION_CONTEXT_CACHEABILITY])) {
|
||||
$context[static::SERIALIZATION_CONTEXT_CACHEABILITY]->addCacheableDependency($data);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ trait TimeStampItemNormalizerTrait {
|
||||
*
|
||||
* @var string[]
|
||||
*
|
||||
* @see http://php.net/manual/en/datetime.createfromformat.php
|
||||
* @see http://php.net/manual/datetime.createfromformat.php
|
||||
*/
|
||||
protected $allowedFormats = [
|
||||
'UNIX timestamp' => 'U',
|
||||
|
||||
@@ -18,7 +18,13 @@ class TypedDataNormalizer extends NormalizerBase {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function normalize($object, $format = NULL, array $context = []) {
|
||||
return $object->getValue();
|
||||
$this->addCacheableDependency($context, $object);
|
||||
$value = $object->getValue();
|
||||
// Support for stringable value objects: avoid numerous custom normalizers.
|
||||
if (is_object($value) && method_exists($value, '__toString')) {
|
||||
$value = (string) $value;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# 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
|
||||
|
||||
+3
-3
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# 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
|
||||
|
||||
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# 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
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
namespace Drupal\Tests\serialization\Kernel;
|
||||
|
||||
use Drupal\Component\Serialization\Json;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\entity_test\Entity\EntityTestMulRev;
|
||||
use Drupal\filter\Entity\FilterFormat;
|
||||
use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait;
|
||||
|
||||
/**
|
||||
@@ -63,6 +65,27 @@ class EntitySerializationTest extends NormalizerTestBase {
|
||||
// User create needs sequence table.
|
||||
$this->installSchema('system', ['sequences']);
|
||||
|
||||
FilterFormat::create([
|
||||
'format' => 'my_text_format',
|
||||
'name' => 'My Text Format',
|
||||
'filters' => [
|
||||
'filter_html' => [
|
||||
'module' => 'filter',
|
||||
'status' => TRUE,
|
||||
'weight' => 10,
|
||||
'settings' => [
|
||||
'allowed_html' => '<p>',
|
||||
],
|
||||
],
|
||||
'filter_autop' => [
|
||||
'module' => 'filter',
|
||||
'status' => TRUE,
|
||||
'weight' => 10,
|
||||
'settings' => [],
|
||||
],
|
||||
],
|
||||
])->save();
|
||||
|
||||
// Create a test user to use as the entity owner.
|
||||
$this->user = \Drupal::entityManager()->getStorage('user')->create([
|
||||
'name' => 'serialization_test_user',
|
||||
@@ -72,12 +95,13 @@ class EntitySerializationTest extends NormalizerTestBase {
|
||||
$this->user->save();
|
||||
|
||||
// Create a test entity to serialize.
|
||||
$test_text_value = $this->randomMachineName();
|
||||
$this->values = [
|
||||
'name' => $this->randomMachineName(),
|
||||
'user_id' => $this->user->id(),
|
||||
'field_test_text' => [
|
||||
'value' => $this->randomMachineName(),
|
||||
'format' => 'full_html',
|
||||
'value' => $test_text_value,
|
||||
'format' => 'my_text_format',
|
||||
],
|
||||
];
|
||||
$this->entity = EntityTestMulRev::create($this->values);
|
||||
@@ -130,10 +154,12 @@ class EntitySerializationTest extends NormalizerTestBase {
|
||||
['value' => TRUE],
|
||||
],
|
||||
'non_rev_field' => [],
|
||||
'non_mul_field' => [],
|
||||
'field_test_text' => [
|
||||
[
|
||||
'value' => $this->values['field_test_text']['value'],
|
||||
'format' => $this->values['field_test_text']['format'],
|
||||
'processed' => "<p>{$this->values['field_test_text']['value']}</p>",
|
||||
],
|
||||
],
|
||||
];
|
||||
@@ -174,7 +200,7 @@ class EntitySerializationTest extends NormalizerTestBase {
|
||||
// JsonEncoder. The output of ComplexDataNormalizer::normalize() is tested
|
||||
// elsewhere, so we can just assume that it works properly here.
|
||||
$normalized = $this->serializer->normalize($this->entity, 'json');
|
||||
$expected = json_encode($normalized);
|
||||
$expected = Json::encode($normalized);
|
||||
// Test 'json'.
|
||||
$actual = $this->serializer->serialize($this->entity, 'json');
|
||||
$this->assertIdentical($actual, $expected, 'Entity serializes to JSON when "json" is requested.');
|
||||
@@ -201,8 +227,9 @@ class EntitySerializationTest extends NormalizerTestBase {
|
||||
'revision_id' => '<revision_id><value>' . $this->entity->getRevisionId() . '</value></revision_id>',
|
||||
'default_langcode' => '<default_langcode><value>1</value></default_langcode>',
|
||||
'revision_translation_affected' => '<revision_translation_affected><value>1</value></revision_translation_affected>',
|
||||
'non_mul_field' => '<non_mul_field/>',
|
||||
'non_rev_field' => '<non_rev_field/>',
|
||||
'field_test_text' => '<field_test_text><value>' . $this->values['field_test_text']['value'] . '</value><format>' . $this->values['field_test_text']['format'] . '</format></field_test_text>',
|
||||
'field_test_text' => '<field_test_text><value>' . $this->values['field_test_text']['value'] . '</value><format>' . $this->values['field_test_text']['format'] . '</format><processed><![CDATA[<p>' . $this->values['field_test_text']['value'] . '</p>]]></processed></field_test_text>',
|
||||
];
|
||||
// Sort it in the same order as normalised.
|
||||
$expected = array_merge($normalized, $expected);
|
||||
|
||||
+54
-79
@@ -8,7 +8,6 @@
|
||||
namespace Drupal\Tests\serialization\Unit\Normalizer;
|
||||
|
||||
use Drupal\Core\TypedData\ComplexDataInterface;
|
||||
use Drupal\Core\TypedData\TraversableTypedDataInterface;
|
||||
use Drupal\serialization\Normalizer\ComplexDataNormalizer;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
use Symfony\Component\Serializer\Serializer;
|
||||
@@ -19,6 +18,8 @@ use Symfony\Component\Serializer\Serializer;
|
||||
*/
|
||||
class ComplexDataNormalizerTest extends UnitTestCase {
|
||||
|
||||
use InternalTypedDataTestTrait;
|
||||
|
||||
/**
|
||||
* Test format string.
|
||||
*
|
||||
@@ -44,103 +45,77 @@ class ComplexDataNormalizerTest extends UnitTestCase {
|
||||
* @covers ::supportsNormalization
|
||||
*/
|
||||
public function testSupportsNormalization() {
|
||||
$this->assertTrue($this->normalizer->supportsNormalization(new TestComplexData()));
|
||||
$complex_data = $this->prophesize(ComplexDataInterface::class)->reveal();
|
||||
$this->assertTrue($this->normalizer->supportsNormalization($complex_data));
|
||||
// Also test that an object not implementing ComplexDataInterface fails.
|
||||
$this->assertFalse($this->normalizer->supportsNormalization(new \stdClass()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test normalizing complex data.
|
||||
*
|
||||
* @covers ::normalize
|
||||
*/
|
||||
public function testNormalize() {
|
||||
$context = ['test' => 'test'];
|
||||
|
||||
public function testNormalizeComplexData() {
|
||||
$serializer_prophecy = $this->prophesize(Serializer::class);
|
||||
|
||||
$serializer_prophecy->normalize('A', static::TEST_FORMAT, $context)
|
||||
->shouldBeCalled();
|
||||
$serializer_prophecy->normalize('B', static::TEST_FORMAT, $context)
|
||||
$non_internal_property = $this->getTypedDataProperty(FALSE);
|
||||
|
||||
$serializer_prophecy->normalize($non_internal_property, static::TEST_FORMAT, [])
|
||||
->willReturn('A-normalized')
|
||||
->shouldBeCalled();
|
||||
|
||||
$this->normalizer->setSerializer($serializer_prophecy->reveal());
|
||||
|
||||
$complex_data = new TestComplexData(['a' => 'A', 'b' => 'B']);
|
||||
$this->normalizer->normalize($complex_data, static::TEST_FORMAT, $context);
|
||||
$complex_data = $this->prophesize(ComplexDataInterface::class);
|
||||
$complex_data->getProperties(TRUE)
|
||||
->willReturn([
|
||||
'prop:a' => $non_internal_property,
|
||||
'prop:internal' => $this->getTypedDataProperty(TRUE),
|
||||
])
|
||||
->shouldBeCalled();
|
||||
|
||||
$normalized = $this->normalizer->normalize($complex_data->reveal(), static::TEST_FORMAT);
|
||||
$this->assertEquals(['prop:a' => 'A-normalized'], $normalized);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test normalize() where $object does not implement ComplexDataInterface.
|
||||
*
|
||||
* Normalizers extending ComplexDataNormalizer may have a different supported
|
||||
* class.
|
||||
*
|
||||
* @covers ::normalize
|
||||
*/
|
||||
public function testNormalizeNonComplex() {
|
||||
$normalizer = new TestExtendedNormalizer();
|
||||
$serialization_context = ['test' => 'test'];
|
||||
|
||||
$serializer_prophecy = $this->prophesize(Serializer::class);
|
||||
$serializer_prophecy->normalize('A', static::TEST_FORMAT, $serialization_context)
|
||||
->willReturn('A-normalized')
|
||||
->shouldBeCalled();
|
||||
$serializer_prophecy->normalize('B', static::TEST_FORMAT, $serialization_context)
|
||||
->willReturn('B-normalized')
|
||||
->shouldBeCalled();
|
||||
|
||||
$normalizer->setSerializer($serializer_prophecy->reveal());
|
||||
|
||||
$stdClass = new \stdClass();
|
||||
$stdClass->a = 'A';
|
||||
$stdClass->b = 'B';
|
||||
|
||||
$normalized = $normalizer->normalize($stdClass, static::TEST_FORMAT, $serialization_context);
|
||||
$this->assertEquals(['a' => 'A-normalized', 'b' => 'B-normalized'], $normalized);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test class implementing ComplexDataInterface and IteratorAggregate.
|
||||
* Test normalizer with a different supported class.
|
||||
*/
|
||||
class TestComplexData implements \IteratorAggregate, ComplexDataInterface {
|
||||
|
||||
private $values;
|
||||
|
||||
public function __construct(array $values = []) {
|
||||
$this->values = $values;
|
||||
}
|
||||
|
||||
public function getIterator() {
|
||||
return new \ArrayIterator($this->values);
|
||||
}
|
||||
|
||||
public function applyDefaultValue($notify = TRUE) {
|
||||
}
|
||||
|
||||
public static function createInstance($definition, $name = NULL, TraversableTypedDataInterface $parent = NULL) {
|
||||
}
|
||||
|
||||
public function get($property_name) {
|
||||
}
|
||||
|
||||
public function getConstraints() {
|
||||
}
|
||||
|
||||
public function getDataDefinition() {
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
}
|
||||
|
||||
public function getParent() {
|
||||
}
|
||||
|
||||
public function getProperties($include_computed = FALSE) {
|
||||
}
|
||||
|
||||
public function getPropertyPath() {
|
||||
}
|
||||
|
||||
public function getRoot() {
|
||||
}
|
||||
|
||||
public function getString() {
|
||||
}
|
||||
|
||||
public function getValue() {
|
||||
}
|
||||
|
||||
public function isEmpty() {
|
||||
}
|
||||
|
||||
public function onChange($name) {
|
||||
}
|
||||
|
||||
public function set($property_name, $value, $notify = TRUE) {
|
||||
}
|
||||
|
||||
public function setContext($name = NULL, TraversableTypedDataInterface $parent = NULL) {
|
||||
}
|
||||
|
||||
public function setValue($value, $notify = TRUE) {
|
||||
}
|
||||
|
||||
public function toArray() {
|
||||
}
|
||||
|
||||
public function validate() {
|
||||
}
|
||||
class TestExtendedNormalizer extends ComplexDataNormalizer {
|
||||
protected $supportedInterfaceOrClass = \stdClass::class;
|
||||
|
||||
}
|
||||
|
||||
+65
-2
@@ -2,6 +2,9 @@
|
||||
|
||||
namespace Drupal\Tests\serialization\Unit\Normalizer;
|
||||
|
||||
use Drupal\Core\Config\Entity\ConfigEntityTypeInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\serialization\Normalizer\ConfigEntityNormalizer;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
@@ -17,7 +20,13 @@ class ConfigEntityNormalizerTest extends UnitTestCase {
|
||||
* @covers ::normalize
|
||||
*/
|
||||
public function testNormalize() {
|
||||
$test_export_properties = ['test' => 'test'];
|
||||
$test_export_properties = [
|
||||
'test' => 'test',
|
||||
'_core' => [
|
||||
'default_config_hash' => $this->randomMachineName(),
|
||||
$this->randomMachineName() => 'some random key',
|
||||
],
|
||||
];
|
||||
|
||||
$entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
|
||||
$normalizer = new ConfigEntityNormalizer($entity_manager);
|
||||
@@ -27,7 +36,61 @@ class ConfigEntityNormalizerTest extends UnitTestCase {
|
||||
->method('toArray')
|
||||
->will($this->returnValue($test_export_properties));
|
||||
|
||||
$this->assertSame($test_export_properties, $normalizer->normalize($config_entity));
|
||||
$this->assertSame(['test' => 'test'], $normalizer->normalize($config_entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::denormalize
|
||||
*/
|
||||
public function testDenormalize() {
|
||||
$test_value = $this->randomMachineName();
|
||||
$data = [
|
||||
'test' => $test_value,
|
||||
'_core' => [
|
||||
'default_config_hash' => $this->randomMachineName(),
|
||||
$this->randomMachineName() => 'some random key',
|
||||
],
|
||||
];
|
||||
|
||||
$expected_storage_data = [
|
||||
'test' => $test_value,
|
||||
];
|
||||
|
||||
// Mock of the entity storage, to test our expectation that the '_core' key
|
||||
// never makes it to that point, thanks to the denormalizer omitting it.
|
||||
$entity_storage = $this->prophesize(EntityStorageInterface::class);
|
||||
$entity_storage->create($expected_storage_data)
|
||||
->shouldBeCalled()
|
||||
->will(function ($args) {
|
||||
$entity = new \stdClass();
|
||||
$entity->received_data = $args[0];
|
||||
return $entity;
|
||||
});
|
||||
|
||||
// Stubs for the denormalizer going from entity manager to entity storage.
|
||||
$entity_type_id = $this->randomMachineName();
|
||||
$entity_type_class = $this->randomMachineName();
|
||||
$entity_manager = $this->prophesize(EntityManagerInterface::class);
|
||||
$entity_manager->getEntityTypeFromClass($entity_type_class)
|
||||
->willReturn($entity_type_id);
|
||||
$entity_manager->getDefinition($entity_type_id, FALSE)
|
||||
->willReturn($this->prophesize(ConfigEntityTypeInterface::class)->reveal());
|
||||
$entity_manager->getStorage($entity_type_id)
|
||||
->willReturn($entity_storage->reveal());
|
||||
$normalizer = new ConfigEntityNormalizer($entity_manager->reveal());
|
||||
|
||||
// Verify the denormalizer still works correctly: the mock above creates an
|
||||
// artificial entity object containing exactly the data it received. It also
|
||||
// should still set _restSubmittedFields correctly.
|
||||
$expected_denormalization = (object) [
|
||||
'_restSubmittedFields' => [
|
||||
'test',
|
||||
],
|
||||
'received_data' => [
|
||||
'test' => $test_value,
|
||||
],
|
||||
];
|
||||
$this->assertEquals($expected_denormalization, $normalizer->denormalize($data, $entity_type_class, 'json'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+37
-16
@@ -2,6 +2,9 @@
|
||||
|
||||
namespace Drupal\Tests\serialization\Unit\Normalizer;
|
||||
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\TypedData\ComplexDataInterface;
|
||||
use Drupal\Core\TypedData\DataDefinitionInterface;
|
||||
use Drupal\serialization\Normalizer\ContentEntityNormalizer;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
@@ -67,16 +70,20 @@ class ContentEntityNormalizerTest extends UnitTestCase {
|
||||
->will($this->returnValue('test'));
|
||||
|
||||
$definitions = [
|
||||
'field_1' => $this->createMockFieldListItem(),
|
||||
'field_2' => $this->createMockFieldListItem(FALSE),
|
||||
'field_accessible_external' => $this->createMockFieldListItem(TRUE, FALSE),
|
||||
'field_non-accessible_external' => $this->createMockFieldListItem(FALSE, FALSE),
|
||||
'field_accessible_internal' => $this->createMockFieldListItem(TRUE, TRUE),
|
||||
'field_non-accessible_internal' => $this->createMockFieldListItem(FALSE, TRUE),
|
||||
];
|
||||
$content_entity_mock = $this->createMockForContentEntity($definitions);
|
||||
|
||||
$normalized = $this->contentEntityNormalizer->normalize($content_entity_mock, 'test_format');
|
||||
|
||||
$this->assertArrayHasKey('field_1', $normalized);
|
||||
$this->assertEquals('test', $normalized['field_1']);
|
||||
$this->assertArrayNotHasKey('field_2', $normalized);
|
||||
$this->assertArrayHasKey('field_accessible_external', $normalized);
|
||||
$this->assertEquals('test', $normalized['field_accessible_external']);
|
||||
$this->assertArrayNotHasKey('field_non-accessible_external', $normalized);
|
||||
$this->assertArrayNotHasKey('field_accessible_internal', $normalized);
|
||||
$this->assertArrayNotHasKey('field_non-accessible_internal', $normalized);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,8 +106,8 @@ class ContentEntityNormalizerTest extends UnitTestCase {
|
||||
// The mock account should get passed directly into the access() method on
|
||||
// field items from $context['account'].
|
||||
$definitions = [
|
||||
'field_1' => $this->createMockFieldListItem(TRUE, $mock_account),
|
||||
'field_2' => $this->createMockFieldListItem(FALSE, $mock_account),
|
||||
'field_1' => $this->createMockFieldListItem(TRUE, FALSE, $mock_account),
|
||||
'field_2' => $this->createMockFieldListItem(FALSE, FALSE, $mock_account),
|
||||
];
|
||||
$content_entity_mock = $this->createMockForContentEntity($definitions);
|
||||
|
||||
@@ -121,11 +128,15 @@ class ContentEntityNormalizerTest extends UnitTestCase {
|
||||
public function createMockForContentEntity($definitions) {
|
||||
$content_entity_mock = $this->getMockBuilder('Drupal\Core\Entity\ContentEntityBase')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(['getFields'])
|
||||
->setMethods(['getTypedData'])
|
||||
->getMockForAbstractClass();
|
||||
$content_entity_mock->expects($this->once())
|
||||
->method('getFields')
|
||||
->will($this->returnValue($definitions));
|
||||
$typed_data = $this->prophesize(ComplexDataInterface::class);
|
||||
$typed_data->getProperties(TRUE)
|
||||
->willReturn($definitions)
|
||||
->shouldBeCalled();
|
||||
$content_entity_mock->expects($this->any())
|
||||
->method('getTypedData')
|
||||
->will($this->returnValue($typed_data->reveal()));
|
||||
|
||||
return $content_entity_mock;
|
||||
}
|
||||
@@ -134,16 +145,26 @@ class ContentEntityNormalizerTest extends UnitTestCase {
|
||||
* Creates a mock field list item.
|
||||
*
|
||||
* @param bool $access
|
||||
* @param bool $internal
|
||||
* @param \Drupal\Core\Session\AccountInterface $user_context
|
||||
*
|
||||
* @return \Drupal\Core\Field\FieldItemListInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
protected function createMockFieldListItem($access = TRUE, $user_context = NULL) {
|
||||
protected function createMockFieldListItem($access, $internal, AccountInterface $user_context = NULL) {
|
||||
$data_definition = $this->prophesize(DataDefinitionInterface::class);
|
||||
$mock = $this->getMock('Drupal\Core\Field\FieldItemListInterface');
|
||||
$mock->expects($this->once())
|
||||
->method('access')
|
||||
->with('view', $user_context)
|
||||
->will($this->returnValue($access));
|
||||
|
||||
->method('getDataDefinition')
|
||||
->will($this->returnValue($data_definition->reveal()));
|
||||
$data_definition->isInternal()
|
||||
->willReturn($internal)
|
||||
->shouldBeCalled();
|
||||
if (!$internal) {
|
||||
$mock->expects($this->once())
|
||||
->method('access')
|
||||
->with('view', $user_context)
|
||||
->will($this->returnValue($access));
|
||||
}
|
||||
return $mock;
|
||||
}
|
||||
|
||||
|
||||
+19
-9
@@ -23,6 +23,8 @@ use Symfony\Component\Serializer\Serializer;
|
||||
*/
|
||||
class EntityReferenceFieldItemNormalizerTest extends UnitTestCase {
|
||||
|
||||
use InternalTypedDataTestTrait;
|
||||
|
||||
/**
|
||||
* The mock serializer.
|
||||
*
|
||||
@@ -68,7 +70,7 @@ class EntityReferenceFieldItemNormalizerTest extends UnitTestCase {
|
||||
$this->serializer = $this->prophesize(Serializer::class);
|
||||
// Set up the serializer to return an entity property.
|
||||
$this->serializer->normalize(Argument::cetera())
|
||||
->willReturn(['value' => 'test']);
|
||||
->willReturn('test');
|
||||
|
||||
$this->normalizer->setSerializer($this->serializer->reveal());
|
||||
|
||||
@@ -122,10 +124,14 @@ class EntityReferenceFieldItemNormalizerTest extends UnitTestCase {
|
||||
->willReturn($entity_reference)
|
||||
->shouldBeCalled();
|
||||
|
||||
$this->fieldItem->getProperties(TRUE)
|
||||
->willReturn(['target_id' => $this->getTypedDataProperty(FALSE)])
|
||||
->shouldBeCalled();
|
||||
|
||||
$normalized = $this->normalizer->normalize($this->fieldItem->reveal());
|
||||
|
||||
$expected = [
|
||||
'target_id' => ['value' => 'test'],
|
||||
'target_id' => 'test',
|
||||
'target_type' => 'test_type',
|
||||
'target_uuid' => '080e3add-f9d5-41ac-9821-eea55b7b42fb',
|
||||
'url' => $test_url,
|
||||
@@ -146,10 +152,14 @@ class EntityReferenceFieldItemNormalizerTest extends UnitTestCase {
|
||||
->willReturn($entity_reference->reveal())
|
||||
->shouldBeCalled();
|
||||
|
||||
$this->fieldItem->getProperties(TRUE)
|
||||
->willReturn(['target_id' => $this->getTypedDataProperty(FALSE)])
|
||||
->shouldBeCalled();
|
||||
|
||||
$normalized = $this->normalizer->normalize($this->fieldItem->reveal());
|
||||
|
||||
$expected = [
|
||||
'target_id' => ['value' => 'test'],
|
||||
'target_id' => 'test',
|
||||
];
|
||||
$this->assertSame($expected, $normalized);
|
||||
}
|
||||
@@ -159,7 +169,7 @@ class EntityReferenceFieldItemNormalizerTest extends UnitTestCase {
|
||||
*/
|
||||
public function testDenormalizeWithTypeAndUuid() {
|
||||
$data = [
|
||||
'target_id' => ['value' => 'test'],
|
||||
'target_id' => 'test',
|
||||
'target_type' => 'test_type',
|
||||
'target_uuid' => '080e3add-f9d5-41ac-9821-eea55b7b42fb',
|
||||
];
|
||||
@@ -183,7 +193,7 @@ class EntityReferenceFieldItemNormalizerTest extends UnitTestCase {
|
||||
*/
|
||||
public function testDenormalizeWithUuidWithoutType() {
|
||||
$data = [
|
||||
'target_id' => ['value' => 'test'],
|
||||
'target_id' => 'test',
|
||||
'target_uuid' => '080e3add-f9d5-41ac-9821-eea55b7b42fb',
|
||||
];
|
||||
|
||||
@@ -208,7 +218,7 @@ class EntityReferenceFieldItemNormalizerTest extends UnitTestCase {
|
||||
$this->setExpectedException(UnexpectedValueException::class, 'The field "field_reference" property "target_type" must be set to "test_type" or omitted.');
|
||||
|
||||
$data = [
|
||||
'target_id' => ['value' => 'test'],
|
||||
'target_id' => 'test',
|
||||
'target_type' => 'wrong_type',
|
||||
'target_uuid' => '080e3add-f9d5-41ac-9821-eea55b7b42fb',
|
||||
];
|
||||
@@ -228,7 +238,7 @@ class EntityReferenceFieldItemNormalizerTest extends UnitTestCase {
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'No "test_type" entity found with UUID "unique-but-none-non-existent" for field "field_reference"');
|
||||
|
||||
$data = [
|
||||
'target_id' => ['value' => 'test'],
|
||||
'target_id' => 'test',
|
||||
'target_type' => 'test_type',
|
||||
'target_uuid' => 'unique-but-none-non-existent',
|
||||
];
|
||||
@@ -251,7 +261,7 @@ class EntityReferenceFieldItemNormalizerTest extends UnitTestCase {
|
||||
$this->setExpectedException(InvalidArgumentException::class, 'If provided "target_uuid" cannot be empty for field "test_type".');
|
||||
|
||||
$data = [
|
||||
'target_id' => ['value' => 'test'],
|
||||
'target_id' => 'test',
|
||||
'target_type' => 'test_type',
|
||||
'target_uuid' => '',
|
||||
];
|
||||
@@ -268,7 +278,7 @@ class EntityReferenceFieldItemNormalizerTest extends UnitTestCase {
|
||||
*/
|
||||
public function testDenormalizeWithId() {
|
||||
$data = [
|
||||
'target_id' => ['value' => 'test'],
|
||||
'target_id' => 'test',
|
||||
];
|
||||
$this->fieldItem->setValue($data)->shouldBeCalled();
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\serialization\Unit\Normalizer;
|
||||
|
||||
use Drupal\Core\TypedData\DataDefinitionInterface;
|
||||
use Drupal\Core\TypedData\TypedDataInterface;
|
||||
|
||||
/**
|
||||
* Trait that provides mocked typed data objects.
|
||||
*/
|
||||
trait InternalTypedDataTestTrait {
|
||||
|
||||
/**
|
||||
* Gets a typed data property.
|
||||
*
|
||||
* @param bool $internal
|
||||
* Whether the typed data property is internal.
|
||||
*
|
||||
* @return \Drupal\Core\TypedData\TypedDataInterface
|
||||
* The typed data property.
|
||||
*/
|
||||
protected function getTypedDataProperty($internal = TRUE) {
|
||||
$definition = $this->prophesize(DataDefinitionInterface::class);
|
||||
$definition->isInternal()
|
||||
->willReturn($internal)
|
||||
->shouldBeCalled();
|
||||
$definition = $definition->reveal();
|
||||
|
||||
$property = $this->prophesize(TypedDataInterface::class);
|
||||
$property->getDataDefinition()
|
||||
->willReturn($definition)
|
||||
->shouldBeCalled();
|
||||
return $property->reveal();
|
||||
}
|
||||
|
||||
}
|
||||
+14
-2
@@ -18,6 +18,8 @@ use Symfony\Component\Serializer\Serializer;
|
||||
*/
|
||||
class TimestampItemNormalizerTest extends UnitTestCase {
|
||||
|
||||
use InternalTypedDataTestTrait;
|
||||
|
||||
/**
|
||||
* @var \Drupal\serialization\Normalizer\TimestampItemNormalizer
|
||||
*/
|
||||
@@ -77,8 +79,18 @@ class TimestampItemNormalizerTest extends UnitTestCase {
|
||||
$timestamp_item->getIterator()
|
||||
->willReturn(new \ArrayIterator(['value' => 1478422920]));
|
||||
|
||||
$serializer = new Serializer();
|
||||
$this->normalizer->setSerializer($serializer);
|
||||
$value_property = $this->getTypedDataProperty(FALSE);
|
||||
$timestamp_item->getProperties(TRUE)
|
||||
->willReturn(['value' => $value_property])
|
||||
->shouldBeCalled();
|
||||
|
||||
$serializer_prophecy = $this->prophesize(Serializer::class);
|
||||
|
||||
$serializer_prophecy->normalize($value_property, NULL, [])
|
||||
->willReturn(1478422920)
|
||||
->shouldBeCalled();
|
||||
|
||||
$this->normalizer->setSerializer($serializer_prophecy->reveal());
|
||||
|
||||
$normalized = $this->normalizer->normalize($timestamp_item->reveal());
|
||||
$this->assertSame($expected, $normalized);
|
||||
|
||||
Reference in New Issue
Block a user