Commit 1506b0af authored by catch's avatar catch

Issue #3037970 by Berdir, Baysaa: Custom serialized field's data should be...

Issue #3037970 by Berdir, Baysaa: Custom serialized field's data should be normalized even if it's empty
parent 82fed915
......@@ -3,6 +3,7 @@
namespace Drupal\Tests\hal\Kernel;
use Drupal\Core\Url;
use Drupal\entity_test\Entity\EntitySerializedField;
use Drupal\field\Entity\FieldConfig;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
......@@ -139,4 +140,52 @@ public function testMarkFieldForDeletion() {
$this->assertEqual($entity->field_test_text->count(), 0);
}
/**
* Tests normalizing/denormalizing serialized columns.
*/
public function testDenormalizeSerializedItem() {
$entity = EntitySerializedField::create(['serialized' => 'boo']);
$normalized = $this->serializer->normalize($entity, $this->format);
$this->setExpectedException(\LogicException::class, 'The generic FieldItemNormalizer cannot denormalize string values for "value" properties of the "serialized" field (field item class: Drupal\entity_test\Plugin\Field\FieldType\SerializedItem).');
$this->serializer->denormalize($normalized, EntitySerializedField::class, $this->format);
}
/**
* Tests normalizing/denormalizing invalid custom serialized fields.
*/
public function testDenormalizeInvalidCustomSerializedField() {
$entity = EntitySerializedField::create(['serialized_long' => serialize(['Hello world!'])]);
$normalized = $this->serializer->normalize($entity);
$this->assertEquals($normalized['serialized_long'][0]['value'], ['Hello world!']);
$normalized['serialized_long'][0]['value'] = 'boo';
$this->setExpectedException(\LogicException::class, 'The generic FieldItemNormalizer cannot denormalize string values for "value" properties of the "serialized_long" field (field item class: Drupal\Core\Field\Plugin\Field\FieldType\StringLongItem).');
$this->serializer->denormalize($normalized, EntitySerializedField::class);
}
/**
* Tests normalizing/denormalizing empty custom serialized fields.
*/
public function testDenormalizeEmptyCustomSerializedField() {
$entity = EntitySerializedField::create(['serialized_long' => serialize([])]);
$normalized = $this->serializer->normalize($entity);
$this->assertEquals([], $normalized['serialized_long'][0]['value']);
$entity = $this->serializer->denormalize($normalized, EntitySerializedField::class);
$this->assertEquals(serialize([]), $entity->get('serialized_long')->value);
}
/**
* Tests normalizing/denormalizing valid custom serialized fields.
*/
public function testDenormalizeValidCustomSerializedField() {
$entity = EntitySerializedField::create(['serialized_long' => serialize(['key' => 'value'])]);
$normalized = $this->serializer->normalize($entity);
$this->assertEquals(['key' => 'value'], $normalized['serialized_long'][0]['value']);
$entity = $this->serializer->denormalize($normalized, EntitySerializedField::class);
$this->assertEquals(serialize(['key' => 'value']), $entity->get('serialized_long')->value);
}
}
......@@ -80,4 +80,25 @@ public function testLinkSerialization() {
$this->assertSame($options_expected, $deserialized->field_test->options);
}
/**
* Tests the deserialization.
*/
public function testLinkDeserialization() {
// Create entity.
$entity = EntityTest::create();
$url = 'https://www.drupal.org?test_param=test_value';
$parsed_url = UrlHelper::parse($url);
$title = $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']);
$json = json_decode($this->serializer->serialize($entity, 'json'), TRUE);
$json['field_test'][0]['options'] = 'string data';
$serialized = json_encode($json, TRUE);
$this->setExpectedException(\LogicException::class, 'The generic FieldItemNormalizer cannot denormalize string values for "options" properties of the "field_test" field (field item class: Drupal\link\Plugin\Field\FieldType\LinkItem).');
$this->serializer->deserialize($serialized, EntityTest::class, 'json');
}
}
......@@ -4,6 +4,7 @@
use Drupal\Component\Serialization\Json;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\entity_test\Entity\EntitySerializedField;
use Drupal\entity_test\Entity\EntityTestMulRev;
use Drupal\filter\Entity\FilterFormat;
use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait;
......@@ -260,4 +261,92 @@ public function testDenormalize() {
}
}
/**
* Tests denormalizing serialized columns.
*/
public function testDenormalizeSerializedItem() {
$this->setExpectedException(\LogicException::class, 'The generic FieldItemNormalizer cannot denormalize string values for "value" properties of the "serialized" field (field item class: Drupal\entity_test\Plugin\Field\FieldType\SerializedItem).');
$this->serializer->denormalize([
'serialized' => [
[
'value' => 'boo',
],
],
'type' => 'entity_test_serialized_field',
], EntitySerializedField::class);
}
/**
* Tests normalizing/denormalizing custom serialized columns.
*/
public function testDenormalizeCustomSerializedItem() {
$entity = EntitySerializedField::create(['serialized_text' => serialize(['Hello world!'])]);
$normalized = $this->serializer->normalize($entity);
$this->assertEquals($normalized['serialized_text'][0]['value'], ['Hello world!']);
$this->setExpectedException(\LogicException::class, 'The generic FieldItemNormalizer cannot denormalize string values for "value" properties of the "serialized_text" field (field item class: Drupal\entity_test\Plugin\Field\FieldType\SerializedPropertyItem).');
$this->serializer->denormalize([
'serialized_text' => [
[
'value' => 'boo',
],
],
'type' => 'entity_test_serialized_field',
], EntitySerializedField::class);
}
/**
* Tests normalizing/denormalizing invalid custom serialized fields.
*/
public function testDenormalizeInvalidCustomSerializedField() {
$entity = EntitySerializedField::create(['serialized_long' => serialize(['Hello world!'])]);
$normalized = $this->serializer->normalize($entity);
$this->assertEquals($normalized['serialized_long'][0]['value'], ['Hello world!']);
$this->setExpectedException(\LogicException::class, 'The generic FieldItemNormalizer cannot denormalize string values for "value" properties of the "serialized_long" field (field item class: Drupal\Core\Field\Plugin\Field\FieldType\StringLongItem).');
$this->serializer->denormalize([
'serialized_long' => [
[
'value' => 'boo',
],
],
'type' => 'entity_test_serialized_field',
], EntitySerializedField::class);
}
/**
* Tests normalizing/denormalizing empty custom serialized fields.
*/
public function testDenormalizeEmptyCustomSerializedField() {
$entity = EntitySerializedField::create(['serialized_long' => serialize([])]);
$normalized = $this->serializer->normalize($entity);
$this->assertEquals([], $normalized['serialized_long'][0]['value']);
$entity = $this->serializer->denormalize($normalized, EntitySerializedField::class);
$this->assertEquals(serialize([]), $entity->get('serialized_long')->value);
}
/**
* Tests normalizing/denormalizing valid custom serialized fields.
*/
public function testDenormalizeValidCustomSerializedField() {
$entity = EntitySerializedField::create(['serialized_long' => serialize(['key' => 'value'])]);
$normalized = $this->serializer->normalize($entity);
$this->assertEquals(['key' => 'value'], $normalized['serialized_long'][0]['value']);
$entity = $this->serializer->denormalize($normalized, EntitySerializedField::class);
$this->assertEquals(serialize(['key' => 'value']), $entity->get('serialized_long')->value);
}
/**
* Tests normalizing/denormalizing using string values.
*/
public function testDenormalizeStringValue() {
$this->setExpectedException(\LogicException::class, 'The generic FieldItemNormalizer cannot denormalize string values for "value" properties of the "serialized_long" field (field item class: Drupal\Core\Field\Plugin\Field\FieldType\StringLongItem).');
$this->serializer->denormalize([
'serialized_long' => ['boo'],
'type' => 'entity_test_serialized_field',
], EntitySerializedField::class);
}
}
......@@ -436,7 +436,7 @@ protected function assertDenormalize(array $data) {
->shouldBeCalled();
}
// Avoid a static method call by returning dummy property data.
// Avoid a static method call by returning dummy serialized property data.
$this->fieldDefinition
->getFieldStorageDefinition()
->willReturn()
......
......@@ -123,7 +123,7 @@ public function testDenormalize() {
$timestamp_item->setValue(['value' => $timestamp_data_denormalization])
->shouldBeCalled();
// Avoid a static method call by returning dummy property data.
// Avoid a static method call by returning dummy serialized property data.
$field_definition = $this->prophesize(FieldDefinitionInterface::class);
$timestamp_item
->getFieldDefinition()
......
<?php
namespace Drupal\entity_test\Entity;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
/**
* Defines a test class for testing fields with a serialized column.
*
* @ContentEntityType(
* id = "entity_test_serialized_field",
* label = @Translation("Test serialized fields"),
* entity_keys = {
* "id" = "id",
* "uuid" = "uuid",
* "bundle" = "type",
* "label" = "name"
* },
* base_table = "entity_test_serialized_fields",
* persistent_cache = FALSE,
* serialized_field_property_names = {
* "serialized_long" = {
* "value"
* }
* }
* )
*/
class EntitySerializedField extends EntityTest {
/**
* {@inheritdoc}
*/
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
$fields = parent::baseFieldDefinitions($entity_type);
$fields['serialized'] = BaseFieldDefinition::create('serialized_item_test')
->setLabel(t('Serialized'));
$fields['serialized_text'] = BaseFieldDefinition::create('serialized_property_item_test')
->setLabel(t('Serialized text'));
$fields['serialized_long'] = BaseFieldDefinition::create('string_long')
->setLabel(t('Serialized long string'));
return $fields;
}
}
<?php
namespace Drupal\entity_test\Plugin\Field\FieldType;
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\TypedData\DataDefinition;
/**
* Defines the 'serialized_item' entity field type.
*
* @FieldType(
* id = "serialized_item_test",
* label = @Translation("Test serialized field item"),
* description = @Translation("A field containing a serialized string value."),
* category = @Translation("Field"),
* )
*/
class SerializedItem extends FieldItemBase {
/**
* {@inheritdoc}
*/
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
$properties['value'] = DataDefinition::create('string')
->setLabel(new TranslatableMarkup('Test serialized value'))
->setRequired(TRUE);
return $properties;
}
/**
* {@inheritdoc}
*/
public static function schema(FieldStorageDefinitionInterface $field_definition) {
return [
'columns' => [
'value' => [
'type' => 'blob',
'size' => 'big',
'serialize' => TRUE,
],
],
];
}
}
<?php
namespace Drupal\entity_test\Plugin\Field\FieldType;
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\TypedData\DataDefinition;
/**
* Defines the 'serialized_property_item_test' entity field type.
*
* @FieldType(
* id = "serialized_property_item_test",
* label = @Translation("Test serialized property field item"),
* description = @Translation("A field containing a string representing serialized data."),
* category = @Translation("Field"),
* serialized_property_names = {
* "value"
* }
* )
*/
class SerializedPropertyItem extends FieldItemBase {
/**
* {@inheritdoc}
*/
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
$properties['value'] = DataDefinition::create('string')
->setLabel(new TranslatableMarkup('Test serialized value'))
->setRequired(TRUE);
return $properties;
}
/**
* {@inheritdoc}
*/
public static function schema(FieldStorageDefinitionInterface $field_definition) {
return [
'columns' => [
'value' => [
'type' => 'text',
'size' => 'big',
],
],
];
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment