From a46c46194d2998f3f6a5c09d387512cc98c7c25c Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Mon, 18 Jun 2018 09:28:31 +0100 Subject: [PATCH] Issue #2935738 by samuel.mortenson, Wim Leers, Berdir: Entity reference field subclasses (such as file and image fields) lose the non-default properties upon denormalization, in both hal_json and json --- .../EntityReferenceItemNormalizer.php | 2 +- .../Functional/FileUploadResourceTestBase.php | 4 -- .../EntityReferenceFieldItemNormalizer.php | 2 +- ...EntityReferenceFieldItemNormalizerTest.php | 40 +++++++++++++++++++ 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/core/modules/hal/src/Normalizer/EntityReferenceItemNormalizer.php b/core/modules/hal/src/Normalizer/EntityReferenceItemNormalizer.php index de9fdc73610a..a9fc7e6b3b58 100644 --- a/core/modules/hal/src/Normalizer/EntityReferenceItemNormalizer.php +++ b/core/modules/hal/src/Normalizer/EntityReferenceItemNormalizer.php @@ -149,7 +149,7 @@ protected function constructValue($data, $context) { $target_type = $field_definition->getSetting('target_type'); $id = $this->entityResolver->resolve($this, $data, $target_type); if (isset($id)) { - return ['target_id' => $id]; + return ['target_id' => $id] + array_intersect_key($data, $field_item->getProperties()); } return NULL; } diff --git a/core/modules/rest/tests/src/Functional/FileUploadResourceTestBase.php b/core/modules/rest/tests/src/Functional/FileUploadResourceTestBase.php index 05aa5ea58657..42c7b2c50a83 100644 --- a/core/modules/rest/tests/src/Functional/FileUploadResourceTestBase.php +++ b/core/modules/rest/tests/src/Functional/FileUploadResourceTestBase.php @@ -199,10 +199,6 @@ public function testPostFileUpload() { $response = $this->request('POST', $entity_test_post_url, $request_options); $this->assertResourceResponse(201, FALSE, $response); $this->assertTrue($this->fileStorage->loadUnchanged(1)->isPermanent()); - // @todo Remove this early return in https://www.drupal.org/project/drupal/issues/2935738. - if (static::$format === 'hal_json') { - return; - } $this->assertSame([ [ 'target_id' => '1', diff --git a/core/modules/serialization/src/Normalizer/EntityReferenceFieldItemNormalizer.php b/core/modules/serialization/src/Normalizer/EntityReferenceFieldItemNormalizer.php index 2d3c6f012b89..4865c909795f 100644 --- a/core/modules/serialization/src/Normalizer/EntityReferenceFieldItemNormalizer.php +++ b/core/modules/serialization/src/Normalizer/EntityReferenceFieldItemNormalizer.php @@ -78,7 +78,7 @@ protected function constructValue($data, $context) { throw new UnexpectedValueException(sprintf('The field "%s" property "target_type" must be set to "%s" or omitted.', $field_item->getFieldDefinition()->getName(), $target_type)); } if ($entity = $this->entityRepository->loadEntityByUuid($target_type, $data['target_uuid'])) { - return ['target_id' => $entity->id()]; + return ['target_id' => $entity->id()] + array_intersect_key($data, $field_item->getProperties()); } else { // Unable to load entity by uuid. diff --git a/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php b/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php index 9320d17ba27f..96274a675fdf 100644 --- a/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php +++ b/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php @@ -4,12 +4,14 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Field\FieldDefinitionInterface; +use Drupal\Core\TypedData\Type\IntegerInterface; use Drupal\Core\TypedData\TypedDataInterface; use Drupal\Core\Entity\EntityRepositoryInterface; use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\Core\Field\FieldItemInterface; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem; +use Drupal\locale\StringInterface; use Drupal\serialization\Normalizer\EntityReferenceFieldItemNormalizer; use Drupal\Tests\UnitTestCase; use Prophecy\Argument; @@ -237,6 +239,9 @@ public function testDenormalizeWithTypeAndUuid() { ->willReturn($entity) ->shouldBeCalled(); + $this->fieldItem->getProperties()->willReturn([ + 'target_id' => $this->prophesize(IntegerInterface::class), + ]); $this->fieldItem->setValue(['target_id' => 'test'])->shouldBeCalled(); $this->assertDenormalize($data); @@ -260,6 +265,9 @@ public function testDenormalizeWithUuidWithoutType() { ->willReturn($entity) ->shouldBeCalled(); + $this->fieldItem->getProperties()->willReturn([ + 'target_id' => $this->prophesize(IntegerInterface::class), + ]); $this->fieldItem->setValue(['target_id' => 'test'])->shouldBeCalled(); $this->assertDenormalize($data); @@ -361,4 +369,36 @@ protected function assertDenormalize(array $data) { $this->assertSame($context['target_instance'], $denormalized); } + /** + * @covers ::constructValue + */ + public function testConstructValueProperties() { + $data = [ + 'target_id' => 'test', + 'target_type' => 'test_type', + 'target_uuid' => '080e3add-f9d5-41ac-9821-eea55b7b42fb', + 'extra_property' => 'extra_value', + ]; + + $entity = $this->prophesize(FieldableEntityInterface::class); + $entity->id() + ->willReturn('test') + ->shouldBeCalled(); + $this->entityRepository + ->loadEntityByUuid($data['target_type'], $data['target_uuid']) + ->willReturn($entity) + ->shouldBeCalled(); + + $this->fieldItem->getProperties()->willReturn([ + 'target_id' => $this->prophesize(IntegerInterface::class), + 'extra_property' => $this->prophesize(StringInterface::class), + ]); + $this->fieldItem->setValue([ + 'target_id' => 'test', + 'extra_property' => 'extra_value', + ])->shouldBeCalled(); + + $this->assertDenormalize($data); + } + } -- GitLab