From df127208e73328c7edaa1659fa6063001bbdbd75 Mon Sep 17 00:00:00 2001
From: catch <catch@35733.no-reply.drupal.org>
Date: Thu, 7 May 2020 19:38:39 +0100
Subject: [PATCH] Issue #2907402 by Berdir, neel24, Wim Leers, damiankloip,
 tedbow: HAL normalization of file fields don't provide file entity id or file
 entity REST URL

---
 .../src/Functional/Hal/ItemHalJsonTestBase.php  |  2 +-
 .../src/Normalizer/ContentEntityNormalizer.php  | 17 +++++++++++++++--
 .../Functional/Rest/MediaResourceTestBase.php   | 13 +++++++++++++
 .../Functional/Hal/PathAliasHalJsonTestBase.php |  2 +-
 .../Functional/FileUploadResourceTestBase.php   | 13 +++++++++++++
 .../Hal/EntityTestLabelHalJsonAnonTest.php      |  2 +-
 .../Hal/EntityTestMapFieldHalJsonAnonTest.php   |  2 +-
 7 files changed, 45 insertions(+), 6 deletions(-)

diff --git a/core/modules/aggregator/tests/src/Functional/Hal/ItemHalJsonTestBase.php b/core/modules/aggregator/tests/src/Functional/Hal/ItemHalJsonTestBase.php
index 5c5120b945db..207ff1eba714 100644
--- a/core/modules/aggregator/tests/src/Functional/Hal/ItemHalJsonTestBase.php
+++ b/core/modules/aggregator/tests/src/Functional/Hal/ItemHalJsonTestBase.php
@@ -60,7 +60,7 @@ protected function getExpectedNormalizedEntity() {
       ],
       '_links' => [
         'self' => [
-          'href' => '',
+          'href' => $this->baseUrl . '/entity/aggregator_item/1?_format=hal_json',
         ],
         'type' => [
           'href' => $this->baseUrl . '/rest/type/aggregator_item/aggregator_item',
diff --git a/core/modules/hal/src/Normalizer/ContentEntityNormalizer.php b/core/modules/hal/src/Normalizer/ContentEntityNormalizer.php
index d0cadee16c8e..f7c5552f0192 100644
--- a/core/modules/hal/src/Normalizer/ContentEntityNormalizer.php
+++ b/core/modules/hal/src/Normalizer/ContentEntityNormalizer.php
@@ -10,6 +10,7 @@
 use Drupal\Core\Entity\EntityTypeRepositoryInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\TypedData\TypedDataInternalPropertiesHelper;
+use Drupal\Core\Url;
 use Drupal\hal\LinkManager\LinkManagerInterface;
 use Drupal\serialization\Normalizer\FieldableEntityNormalizerTrait;
 use Symfony\Component\Serializer\Exception\UnexpectedValueException;
@@ -198,10 +199,22 @@ public function denormalize($data, $class, $format = NULL, array $context = [])
    */
   protected function getEntityUri(EntityInterface $entity, array $context = []) {
     // Some entity types don't provide a canonical link template.
-    if ($entity->isNew() || !$entity->hasLinkTemplate('canonical')) {
+    if ($entity->isNew()) {
       return '';
     }
-    $url = $entity->toUrl('canonical', ['absolute' => TRUE]);
+
+    $route_name = 'rest.entity.' . $entity->getEntityTypeId() . '.GET';
+    if ($entity->hasLinkTemplate('canonical')) {
+      $url = $entity->toUrl('canonical');
+    }
+    elseif (\Drupal::service('router.route_provider')->getRoutesByNames([$route_name])) {
+      $url = Url::fromRoute('rest.entity.' . $entity->getEntityTypeId() . '.GET', [$entity->getEntityTypeId() => $entity->id()]);
+    }
+    else {
+      return '';
+    }
+
+    $url->setAbsolute(TRUE);
     if (!$url->isExternal()) {
       $url->setRouteParameter('_format', 'hal_json');
     }
diff --git a/core/modules/media/tests/src/Functional/Rest/MediaResourceTestBase.php b/core/modules/media/tests/src/Functional/Rest/MediaResourceTestBase.php
index 98bab3f58bee..e3889ca80202 100644
--- a/core/modules/media/tests/src/Functional/Rest/MediaResourceTestBase.php
+++ b/core/modules/media/tests/src/Functional/Rest/MediaResourceTestBase.php
@@ -49,6 +49,19 @@ public function setUp() {
       ->set('standalone_url', TRUE)
       ->save(TRUE);
 
+    // Provisioning the Media REST resource without the File REST resource does
+    // not make sense.
+    $this->resourceConfigStorage->create([
+      'id' => 'entity.file',
+      'granularity' => RestResourceConfigInterface::RESOURCE_GRANULARITY,
+      'configuration' => [
+        'methods' => ['GET'],
+        'formats' => [static::$format],
+        'authentication' => isset(static::$auth) ? [static::$auth] : [],
+      ],
+      'status' => TRUE,
+    ])->save();
+
     $this->container->get('router.builder')->rebuild();
   }
 
diff --git a/core/modules/path_alias/tests/src/Functional/Hal/PathAliasHalJsonTestBase.php b/core/modules/path_alias/tests/src/Functional/Hal/PathAliasHalJsonTestBase.php
index 1e28291e02b5..69874cfecd83 100644
--- a/core/modules/path_alias/tests/src/Functional/Hal/PathAliasHalJsonTestBase.php
+++ b/core/modules/path_alias/tests/src/Functional/Hal/PathAliasHalJsonTestBase.php
@@ -21,7 +21,7 @@ protected function getExpectedNormalizedEntity() {
     return $normalization + [
       '_links' => [
         'self' => [
-          'href' => '',
+          'href' => $this->baseUrl . '/entity/path_alias/1?_format=hal_json',
         ],
         'type' => [
           'href' => $this->baseUrl . '/rest/type/path_alias/path_alias',
diff --git a/core/modules/rest/tests/src/Functional/FileUploadResourceTestBase.php b/core/modules/rest/tests/src/Functional/FileUploadResourceTestBase.php
index 4297c189dfbc..0ae7fbda7ed1 100644
--- a/core/modules/rest/tests/src/Functional/FileUploadResourceTestBase.php
+++ b/core/modules/rest/tests/src/Functional/FileUploadResourceTestBase.php
@@ -141,6 +141,19 @@ public function setUp() {
       'status' => TRUE,
     ])->save();
 
+    // Provisioning the file upload REST resource without the File REST resource
+    // does not make sense.
+    $this->resourceConfigStorage->create([
+      'id' => 'entity.file',
+      'granularity' => RestResourceConfigInterface::RESOURCE_GRANULARITY,
+      'configuration' => [
+        'methods' => ['GET'],
+        'formats' => [static::$format],
+        'authentication' => isset(static::$auth) ? [static::$auth] : [],
+      ],
+      'status' => TRUE,
+    ])->save();
+
     $this->refreshTestStateAfterRestConfigChange();
   }
 
diff --git a/core/modules/system/tests/modules/entity_test/tests/src/Functional/Hal/EntityTestLabelHalJsonAnonTest.php b/core/modules/system/tests/modules/entity_test/tests/src/Functional/Hal/EntityTestLabelHalJsonAnonTest.php
index 9a04335c0f92..2204d72f08d3 100644
--- a/core/modules/system/tests/modules/entity_test/tests/src/Functional/Hal/EntityTestLabelHalJsonAnonTest.php
+++ b/core/modules/system/tests/modules/entity_test/tests/src/Functional/Hal/EntityTestLabelHalJsonAnonTest.php
@@ -47,7 +47,7 @@ protected function getExpectedNormalizedEntity() {
     return $normalization + [
       '_links' => [
         'self' => [
-          'href' => '',
+          'href' => $this->baseUrl . '/entity/entity_test_label/1?_format=hal_json',
         ],
         'type' => [
           'href' => $this->baseUrl . '/rest/type/entity_test_label/entity_test_label',
diff --git a/core/modules/system/tests/modules/entity_test/tests/src/Functional/Hal/EntityTestMapFieldHalJsonAnonTest.php b/core/modules/system/tests/modules/entity_test/tests/src/Functional/Hal/EntityTestMapFieldHalJsonAnonTest.php
index 7502ef0fc7db..27f30dda972c 100644
--- a/core/modules/system/tests/modules/entity_test/tests/src/Functional/Hal/EntityTestMapFieldHalJsonAnonTest.php
+++ b/core/modules/system/tests/modules/entity_test/tests/src/Functional/Hal/EntityTestMapFieldHalJsonAnonTest.php
@@ -47,7 +47,7 @@ protected function getExpectedNormalizedEntity() {
     return $normalization + [
       '_links' => [
         'self' => [
-          'href' => '',
+          'href' => $this->baseUrl . '/entity/entity_test_map_field/1?_format=hal_json',
         ],
         'type' => [
           'href' => $this->baseUrl . '/rest/type/entity_test_map_field/entity_test_map_field',
-- 
GitLab