From 6d2c634ea1baf081c2092b757ae54ccf908c2a54 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Mon, 6 Mar 2017 10:54:34 +0000
Subject: [PATCH] Issue #2844046 by Wim Leers, dawehner, tedbow: REST Resource
 config entities do not respect the status (enabled/disabled)

---
 .../rest/src/Routing/ResourceRoutes.php       |  9 +--
 .../EntityResource/EntityResourceTestBase.php | 63 +++++++++++++------
 .../tests/src/Functional/ResourceTestBase.php | 20 ++++--
 3 files changed, 63 insertions(+), 29 deletions(-)

diff --git a/core/modules/rest/src/Routing/ResourceRoutes.php b/core/modules/rest/src/Routing/ResourceRoutes.php
index 3151420201b6..6aec267db2ce 100644
--- a/core/modules/rest/src/Routing/ResourceRoutes.php
+++ b/core/modules/rest/src/Routing/ResourceRoutes.php
@@ -59,13 +59,14 @@ public function __construct(ResourcePluginManager $manager, EntityTypeManagerInt
    * @return array
    */
   protected function alterRoutes(RouteCollection $collection) {
-    // Iterate over all enabled REST resource configs.
+    // Iterate over all enabled REST resource config entities.
     /** @var \Drupal\rest\RestResourceConfigInterface[] $resource_configs */
     $resource_configs = $this->resourceConfigStorage->loadMultiple();
-    // Iterate over all enabled resource plugins.
     foreach ($resource_configs as $resource_config) {
-      $resource_routes = $this->getRoutesForResourceConfig($resource_config);
-      $collection->addCollection($resource_routes);
+      if ($resource_config->status()) {
+        $resource_routes = $this->getRoutesForResourceConfig($resource_config);
+        $collection->addCollection($resource_routes);
+      }
     }
   }
 
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
index ebb03e2c6f4d..4cc0d5889890 100644
--- a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
+++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
@@ -131,22 +131,13 @@ abstract class EntityResourceTestBase extends ResourceTestBase {
   public static $modules = ['rest_test', 'text'];
 
   /**
-   * {@inheritdoc}
+   * Provides an entity resource.
    */
   protected function provisionEntityResource() {
     // It's possible to not have any authentication providers enabled, when
     // testing public (anonymous) usage of a REST resource.
     $auth = isset(static::$auth) ? [static::$auth] : [];
-    $this->provisionResource('entity.' . static::$entityTypeId, [static::$format], $auth);
-  }
-
-  /**
-   * Deprovisions the tested entity resource.
-   */
-  protected function deprovisionEntityResource() {
-    $this->resourceConfigStorage->load('entity.' . static::$entityTypeId)
-      ->delete();
-    $this->refreshTestStateAfterRestConfigChange();
+    $this->provisionResource([static::$format], $auth);
   }
 
   /**
@@ -155,6 +146,9 @@ protected function deprovisionEntityResource() {
   public function setUp() {
     parent::setUp();
 
+    // Calculate REST Resource config entity ID.
+    static::$resourceConfigId = 'entity.' . static::$entityTypeId;
+
     $this->serializer = $this->container->get('serializer');
     $this->entityStorage = $this->container->get('entity_type.manager')
       ->getStorage(static::$entityTypeId);
@@ -498,17 +492,29 @@ public function testGet() {
     $this->assertResourceResponse(200, FALSE, $response);
 
 
-    $this->deprovisionEntityResource();
+    $this->resourceConfigStorage->load(static::$resourceConfigId)->disable()->save();
+    $this->refreshTestStateAfterRestConfigChange();
+
+
+    // DX: upon disabling a resource, it's immediately no longer available.
+    $this->assertResourceNotAvailable($url, $request_options);
 
 
-    // DX: upon deprovisioning, immediate 404 if no route, 406 otherwise.
+    $this->resourceConfigStorage->load(static::$resourceConfigId)->enable()->save();
+    $this->refreshTestStateAfterRestConfigChange();
+
+
+    // DX: upon re-enabling a resource, immediate 200.
     $response = $this->request('GET', $url, $request_options);
-    if (!$has_canonical_url) {
-      $this->assertSame(404, $response->getStatusCode());
-    }
-    else {
-      $this->assert406Response($response);
-    }
+    $this->assertResourceResponse(200, FALSE, $response);
+
+
+    $this->resourceConfigStorage->load(static::$resourceConfigId)->delete();
+    $this->refreshTestStateAfterRestConfigChange();
+
+
+    // DX: upon deleting a resource, it's immediately no longer available.
+    $this->assertResourceNotAvailable($url, $request_options);
 
 
     $this->provisionEntityResource();
@@ -1176,4 +1182,23 @@ protected function assert406Response(ResponseInterface $response) {
     }
   }
 
+  /**
+   * Asserts that a resource is unavailable: 404, 406 if it has canonical route.
+   *
+   * @param \Drupal\Core\Url $url
+   *   URL to request.
+   * @param array $request_options
+   *   Request options to apply.
+   */
+  protected function assertResourceNotAvailable(Url $url, array $request_options) {
+    $has_canonical_url = $this->entity->hasLinkTemplate('canonical');
+    $response = $this->request('GET', $url, $request_options);
+    if (!$has_canonical_url) {
+      $this->assertSame(404, $response->getStatusCode());
+    }
+    else {
+      $this->assert406Response($response);
+    }
+  }
+
 }
diff --git a/core/modules/rest/tests/src/Functional/ResourceTestBase.php b/core/modules/rest/tests/src/Functional/ResourceTestBase.php
index 3f76c4364df5..c346157beaa6 100644
--- a/core/modules/rest/tests/src/Functional/ResourceTestBase.php
+++ b/core/modules/rest/tests/src/Functional/ResourceTestBase.php
@@ -56,6 +56,15 @@ abstract class ResourceTestBase extends BrowserTestBase {
    */
   protected static $auth = FALSE;
 
+  /**
+   * The REST Resource Config entity ID under test (i.e. a resource type).
+   *
+   * The REST Resource plugin ID can be calculated from this.
+   *
+   * @var string
+   */
+  protected static $resourceConfigId = NULL;
+
   /**
    * The account to use for authentication, if any.
    *
@@ -133,24 +142,23 @@ public function setUp() {
   }
 
   /**
-   * Provisions a REST resource.
+   * Provisions the REST resource under test.
    *
-   * @param string $resource_type
-   *   The resource type (REST resource plugin ID).
    * @param string[] $formats
    *   The allowed formats for this resource.
    * @param string[] $authentication
    *   The allowed authentication providers for this resource.
    */
-  protected function provisionResource($resource_type, $formats = [], $authentication = []) {
+  protected function provisionResource($formats = [], $authentication = []) {
     $this->resourceConfigStorage->create([
-      'id' => $resource_type,
+      'id' => static::$resourceConfigId,
       'granularity' => RestResourceConfigInterface::RESOURCE_GRANULARITY,
       'configuration' => [
         'methods' => ['GET', 'POST', 'PATCH', 'DELETE'],
         'formats' => $formats,
         'authentication' => $authentication,
-      ]
+      ],
+      'status' => TRUE,
     ])->save();
     $this->refreshTestStateAfterRestConfigChange();
   }
-- 
GitLab