.../src/Functional/CookieResourceTestTrait.php | 2 +- .../EntityResource/EntityResourceTestBase.php | 6 +- .../EntityResource/Node/NodeXmlAnonTest.php | 2 + .../EntityResource/Node/NodeXmlBasicAuthTest.php | 36 +++++++ .../EntityResource/Node/NodeXmlCookieTest.php | 31 ++++++ .../XmlEntityNormalizationQuirksTrait.php | 111 +++++++++++++++++++++ .../src/Functional/XmlNormalizationQuirksTrait.php | 33 ++++++ 7 files changed, 218 insertions(+), 3 deletions(-) diff --git a/core/modules/rest/tests/src/Functional/CookieResourceTestTrait.php b/core/modules/rest/tests/src/Functional/CookieResourceTestTrait.php index 8975c3f..689fa83 100644 --- a/core/modules/rest/tests/src/Functional/CookieResourceTestTrait.php +++ b/core/modules/rest/tests/src/Functional/CookieResourceTestTrait.php @@ -61,7 +61,7 @@ protected function initAuthentication() { '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, ]; diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php index bb7c8eb..97a3941 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php @@ -464,8 +464,10 @@ public function testGet() { // 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()); + if (static::$format !== 'xml') { + $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()); diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeXmlAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeXmlAnonTest.php index 5f8fc23..eb06390 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeXmlAnonTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeXmlAnonTest.php @@ -3,6 +3,7 @@ namespace Drupal\Tests\rest\Functional\EntityResource\Node; use Drupal\Tests\rest\Functional\AnonResourceTestTrait; +use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait; /** * @group rest @@ -10,6 +11,7 @@ class NodeXmlAnonTest extends NodeResourceTestBase { use AnonResourceTestTrait; + use XmlEntityNormalizationQuirksTrait; /** * {@inheritdoc} diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeXmlBasicAuthTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeXmlBasicAuthTest.php new file mode 100644 index 0000000..93838f2 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeXmlBasicAuthTest.php @@ -0,0 +1,36 @@ +applyXmlFieldDecodingQuirks($default_normalization); + $normalization = $this->applyXmlDecodingQuirks($normalization); + + return $normalization; + } + + /** + * Applies the XML entity field encoding quirks that remain after decoding. + * + * The XML encoding: + * - loses type data (int and bool become string) + * + * @param array $normalization + * An entity normalization. + * + * @return array + * The updated entity normalization. + * + * @see \Symfony\Component\Serializer\Encoder\XmlEncoder + */ + protected function applyXmlFieldDecodingQuirks(array $normalization) { + if (!$this->entity instanceof FieldableEntityInterface) { + throw new \LogicException('This trait should only be used for fieldable entity types.'); + } + + foreach ($this->entity->getFields(TRUE) as $field_name => $field) { + // Not every field is accessible. + if (!isset($normalization[$field_name])) { + continue; + } + + for ($i = 0; $i < count($normalization[$field_name]); $i++) { + switch ($field->getItemDefinition()->getClass()) { + case BooleanItem::class: + $value = &$normalization[$field_name][$i]['value']; + $value = $value === TRUE ? '1' : '0'; + break; + case IntegerItem::class: + $value = &$normalization[$field_name][$i]['value']; + $value = (string) $value; + break; + case PathItem::class: + $pid = &$normalization[$field_name][$i]['pid']; + $pid = (string) $pid; + break; + case EntityReferenceItem::class: + $target_id = &$normalization[$field_name][$i]['target_id']; + $target_id = (string) $target_id; + break; + case ChangedItem::class: + case CreatedItem::class: + $value = &$normalization[$field_name][$i]['value']; + if (is_numeric($value)) { + $value = (string) $value; + } + + break; + } + } + + if (!empty($normalization[$field_name])) { + $normalization[$field_name] = $normalization[$field_name][0]; + } + } + + return $normalization; + } + + /** + * {@inheritdoc} + */ + public function testPost() { + // Deserialization of the XML format is not supported. + $this->markTestSkipped(); + } + + /** + * {@inheritdoc} + */ + public function testPatch() { + // Deserialization of the XML format is not supported. + $this->markTestSkipped(); + } + +} diff --git a/core/modules/rest/tests/src/Functional/XmlNormalizationQuirksTrait.php b/core/modules/rest/tests/src/Functional/XmlNormalizationQuirksTrait.php new file mode 100644 index 0000000..11c77810 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/XmlNormalizationQuirksTrait.php @@ -0,0 +1,33 @@ + $value) { + if ($value === []) { + $normalization[$key] = ''; + } + } + return $normalization; + } + +}