diff --git a/core/modules/hal/tests/src/Functional/EntityResource/Shortcut/ShortcutHalJsonAnonTest.php b/core/modules/hal/tests/src/Functional/EntityResource/Shortcut/ShortcutHalJsonAnonTest.php
new file mode 100644
index 0000000..ae49987
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/Shortcut/ShortcutHalJsonAnonTest.php
@@ -0,0 +1,74 @@
+<?php
+
+namespace Drupal\Tests\hal\Functional\EntityResource\Shortcut;
+
+use Drupal\Core\Cache\Cache;
+use Drupal\Tests\hal\Functional\EntityResource\HalEntityNormalizationTrait;
+use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
+use Drupal\Tests\rest\Functional\EntityResource\Shortcut\ShortcutResourceTestBase;
+
+/**
+ * @group hal
+ */
+class ShortcutHalJsonAnonTest extends ShortcutResourceTestBase {
+
+  use HalEntityNormalizationTrait;
+  use AnonResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['hal'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'hal_json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/hal+json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getExpectedNormalizedEntity() {
+  $default_normalization = parent::getExpectedNormalizedEntity();
+
+  $normalization = $this->applyHalFieldNormalization($default_normalization);
+
+  return  $normalization + [
+    '_links' => [
+      'self' => [
+      'href' => $this->baseUrl . '/admin/config/user-interface/shortcut/link/1?_format=hal_json',
+      ],
+      'type' => [
+      'href' => $this->baseUrl . '/rest/type/shortcut/default',
+      ],
+    ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getNormalizedPostEntity() {
+  return parent::getNormalizedPostEntity() + [
+    '_links' => [
+      'type' => [
+      'href' => $this->baseUrl . '/rest/type/shortcut/default',
+      ],
+    ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getExpectedCacheContexts() {
+    // The 'url.site' cache context is added for '_links' in the response.
+    return Cache::mergeContexts(parent::getExpectedCacheContexts(), ['url.site']);
+  }
+
+}
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/Shortcut/ShortcutHalJsonBasicAuthTest.php b/core/modules/hal/tests/src/Functional/EntityResource/Shortcut/ShortcutHalJsonBasicAuthTest.php
new file mode 100644
index 0000000..a5be6db
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/Shortcut/ShortcutHalJsonBasicAuthTest.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Drupal\Tests\hal\Functional\EntityResource\Shortcut;
+
+use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
+
+/**
+ * @group hal
+ */
+class ShortcutHalJsonBasicAuthTest extends ShortcutHalJsonAnonTest {
+
+  use BasicAuthResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['basic_auth'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'basic_auth';
+
+}
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/Shortcut/ShortcutHalJsonCookieTest.php b/core/modules/hal/tests/src/Functional/EntityResource/Shortcut/ShortcutHalJsonCookieTest.php
new file mode 100644
index 0000000..a48a61f
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/Shortcut/ShortcutHalJsonCookieTest.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Drupal\Tests\hal\Functional\EntityResource\Shortcut;
+
+use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
+
+/**
+ * @group hal
+ */
+class ShortcutHalJsonCookieTest extends ShortcutHalJsonAnonTest {
+
+  use CookieResourceTestTrait;
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'cookie';
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
index 822d8d7..a90ca56 100644
--- a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
+++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
@@ -407,7 +407,7 @@ public function testGet() {
     ksort($expected);
     $actual = $this->serializer->decode((string) $response->getBody(), static::$format);
     ksort($actual);
-    $this->assertSame($expected, $actual);
+    $this->assertEquals($expected, $actual);
 
     // Not only assert the normalization, also assert deserialization of the
     // response results in the expected object.
@@ -470,7 +470,7 @@ public function testGet() {
       ksort($expected);
       $actual = $this->serializer->decode((string) $response->getBody(), static::$format);
       ksort($actual);
-      $this->assertSame($expected, $actual);
+      $this->assertEquals($expected, $actual);
     }
 
 
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Shortcut/ShortcutJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Shortcut/ShortcutJsonAnonTest.php
new file mode 100644
index 0000000..8f317b3
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/Shortcut/ShortcutJsonAnonTest.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\Shortcut;
+
+use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
+
+/**
+ * @group rest
+ */
+class ShortcutJsonAnonTest extends ShortcutResourceTestBase {
+
+  use AnonResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/json';
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Shortcut/ShortcutJsonBasicAuthTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Shortcut/ShortcutJsonBasicAuthTest.php
new file mode 100644
index 0000000..31f1117
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/Shortcut/ShortcutJsonBasicAuthTest.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\Shortcut;
+
+use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
+
+/**
+ * @group rest
+ */
+class ShortcutJsonBasicAuthTest extends ShortcutResourceTestBase {
+
+  use BasicAuthResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['basic_auth'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'basic_auth';
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Shortcut/ShortcutJsonCookieTest.php b/core/modules/rest/tests/src/Functional/EntityResource/Shortcut/ShortcutJsonCookieTest.php
new file mode 100644
index 0000000..3a043c8
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/Shortcut/ShortcutJsonCookieTest.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\Shortcut;
+
+use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
+
+/**
+ * @group rest
+ */
+class ShortcutJsonCookieTest extends ShortcutResourceTestBase {
+
+  use CookieResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'cookie';
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Shortcut/ShortcutResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/Shortcut/ShortcutResourceTestBase.php
new file mode 100644
index 0000000..51064f6
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/Shortcut/ShortcutResourceTestBase.php
@@ -0,0 +1,160 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\Shortcut;
+
+use Drupal\shortcut\Entity\Shortcut;
+use Drupal\shortcut\Entity\ShortcutSet;
+use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
+
+/**
+ * ResourceTestBase for Shortcut entity.
+ */
+abstract class ShortcutResourceTestBase extends EntityResourceTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['comment', 'shortcut'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $entityTypeId = 'shortcut';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $patchProtectedFieldNames = [];
+
+  /**
+   * The Shortcut entity.
+   *
+   * @var \Drupal\Shortcut\ShortcutInterface
+   */
+  protected $entity;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUpAuthorization($method) {
+  switch ($method) {
+    case 'GET':
+    $this->grantPermissionsToTestedRole(['access shortcuts', 'customize shortcut links']);
+    break;
+    case 'POST':
+    case 'PATCH':
+    case 'DELETE':
+    $this->grantPermissionsToTestedRole(['administer shortcuts']);
+    break;
+  }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function createEntity() {
+  // Create shortcut.
+  $shortcut = Shortcut::create(array(
+    'shortcut_set' => 'default',
+    'title' => t('Comments'),
+    'weight' => -20,
+    'link' => array(
+    'uri' => 'internal:/admin/content/comment',
+    ),
+  ));
+  $shortcut->save();
+
+  return $shortcut;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getExpectedNormalizedEntity() {
+  return [
+    'uuid' => [
+    [
+      'value' => $this->entity->uuid(),
+    ],
+    ],
+    'id' => [
+    [
+      'value' => (int) $this->entity->id(),
+    ],
+    ],
+    'title' => [
+    [
+      'value' => 'Comments',
+    ],
+    ],
+    'shortcut_set' => [
+    [
+      'target_id' => 'default',
+      'target_type' => 'shortcut_set',
+      'target_uuid' => ShortcutSet::load('default')->uuid(),
+    ],
+    ],
+    'link' => [
+    [
+      'uri' => 'internal:/admin/content/comment',
+      'title' => NULL,
+      'options' => [],
+    ],
+    ],
+    'weight' => [
+    [
+      'value' => -20,
+    ],
+    ],
+    'langcode' => [
+    [
+      'value' => 'en',
+    ],
+    ],
+    'default_langcode' => [
+      [
+        'value' => TRUE,
+      ],
+    ],
+  ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getNormalizedPostEntity() {
+    return [
+    'title' => [
+    [
+      'value' => 'Comments',
+    ],
+    ],
+    'link' => [
+    [
+      'uri' => 'internal:/', # 'internal:/', 'route:<front>', 'route:<test>', ...?
+    ],
+    ],
+      'shortcut_set' => 'default',
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getExpectedUnauthorizedAccessMessage($method) {
+    if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) {
+      return parent::getExpectedUnauthorizedAccessMessage($method);
+    }
+
+    switch ($method) {
+      case 'GET':
+      case 'POST':
+      case 'PATCH':
+      case 'DELETE':
+        return "The 'access shortcuts, customize shortcut links' permissions is required.";
+      default:
+        return parent::getExpectedUnauthorizedAccessMessage($method);
+    }
+  }
+
+}
diff --git a/core/modules/shortcut/shortcut.module b/core/modules/shortcut/shortcut.module
index 156b491..037feca 100644
--- a/core/modules/shortcut/shortcut.module
+++ b/core/modules/shortcut/shortcut.module
@@ -65,7 +65,10 @@ function shortcut_set_edit_access(ShortcutSetInterface $shortcut_set = NULL) {
   // Sufficiently-privileged users can edit their currently displayed shortcut
   // set, but not other sets. They must also be able to access shortcuts.
   $may_edit_current_shortcut_set = $account->hasPermission('customize shortcut links') && (!isset($shortcut_set) || $shortcut_set == shortcut_current_displayed_set()) && $account->hasPermission('access shortcuts');
-  return AccessResult::allowedIf($may_edit_current_shortcut_set)->cachePerPermissions();
+  if (!$may_edit_current_shortcut_set) {    
+    return AccessResult::neutral("The 'access shortcuts, customize shortcut links' permissions is required.")->cachePerPermissions();
+  }
+  return AccessResult::allowed()->cachePerPermissions();
 }
 
 /**
