Commit 21707245 authored by catch's avatar catch
Browse files

Issue #2864816 by Wim Leers, dawehner, larowlan, tedbow: HAL LinkManager...

Issue #2864816 by Wim Leers, dawehner, larowlan, tedbow: HAL LinkManager doesn't add 'url.site' cache context when needed
parent f73e8057
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
namespace Drupal\hal\LinkManager; namespace Drupal\hal\LinkManager;
use Drupal\rest\EventSubscriber\ResourceResponseSubscriber;
/** /**
* Defines an abstract base-class for HAL link manager objects. * Defines an abstract base-class for HAL link manager objects.
*/ */
...@@ -39,17 +41,32 @@ public function setLinkDomain($domain) { ...@@ -39,17 +41,32 @@ public function setLinkDomain($domain) {
/** /**
* Gets the link domain. * Gets the link domain.
* *
* @param array $context
* Normalization/serialization context.
*
* @return string * @return string
* The link domain. * The link domain.
*
* @see \Symfony\Component\Serializer\Normalizer\NormalizerInterface::normalize()
* @see \Symfony\Component\Serializer\SerializerInterface::serialize()
* @see \Drupal\rest\EventSubscriber\ResourceResponseSubscriber::SERIALIZATION_CONTEXT_CACHEABILITY
*/ */
protected function getLinkDomain() { protected function getLinkDomain(array $context = []) {
if (empty($this->linkDomain)) { if (empty($this->linkDomain)) {
if ($domain = $this->configFactory->get('hal.settings')->get('link_domain')) { if ($domain = $this->configFactory->get('hal.settings')->get('link_domain')) {
$this->linkDomain = rtrim($domain, '/'); // Bubble the appropriate cacheability metadata whenever possible.
if (isset($context[ResourceResponseSubscriber::SERIALIZATION_CONTEXT_CACHEABILITY])) {
$context[ResourceResponseSubscriber::SERIALIZATION_CONTEXT_CACHEABILITY]->addCacheableDependency($this->configFactory->get('hal.settings'));
}
return rtrim($domain, '/');
} }
else { else {
// Bubble the relevant cacheability metadata whenever possible.
if (isset($context[ResourceResponseSubscriber::SERIALIZATION_CONTEXT_CACHEABILITY])) {
$context[ResourceResponseSubscriber::SERIALIZATION_CONTEXT_CACHEABILITY]->addCacheContexts(['url.site']);
}
$request = $this->requestStack->getCurrentRequest(); $request = $this->requestStack->getCurrentRequest();
$this->linkDomain = $request->getSchemeAndHttpHost() . $request->getBasePath(); return $request->getSchemeAndHttpHost() . $request->getBasePath();
} }
} }
return $this->linkDomain; return $this->linkDomain;
......
...@@ -68,7 +68,7 @@ public function getRelationUri($entity_type, $bundle, $field_name, $context = [] ...@@ -68,7 +68,7 @@ public function getRelationUri($entity_type, $bundle, $field_name, $context = []
// module is installed that adds such content, but requires this URL to be // module is installed that adds such content, but requires this URL to be
// different (e.g., include a language prefix), then the module must also // different (e.g., include a language prefix), then the module must also
// override the RelationLinkManager class/service to return the desired URL. // override the RelationLinkManager class/service to return the desired URL.
$uri = $this->getLinkDomain() . "/rest/relation/$entity_type/$bundle/$field_name"; $uri = $this->getLinkDomain($context) . "/rest/relation/$entity_type/$bundle/$field_name";
$this->moduleHandler->alter('hal_relation_uri', $uri, $context); $this->moduleHandler->alter('hal_relation_uri', $uri, $context);
// @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This // @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This
// hook is invoked to maintain backwards compatibility // hook is invoked to maintain backwards compatibility
......
...@@ -69,7 +69,7 @@ public function getTypeUri($entity_type, $bundle, $context = []) { ...@@ -69,7 +69,7 @@ public function getTypeUri($entity_type, $bundle, $context = []) {
// installed that adds such content, but requires this URL to be different // installed that adds such content, but requires this URL to be different
// (e.g., include a language prefix), then the module must also override the // (e.g., include a language prefix), then the module must also override the
// TypeLinkManager class/service to return the desired URL. // TypeLinkManager class/service to return the desired URL.
$uri = $this->getLinkDomain() . "/rest/type/$entity_type/$bundle"; $uri = $this->getLinkDomain($context) . "/rest/type/$entity_type/$bundle";
$this->moduleHandler->alter('hal_type_uri', $uri, $context); $this->moduleHandler->alter('hal_type_uri', $uri, $context);
// @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This // @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This
// hook is invoked to maintain backwards compatibility // hook is invoked to maintain backwards compatibility
......
...@@ -2,11 +2,13 @@ ...@@ -2,11 +2,13 @@
namespace Drupal\Tests\hal\Kernel; namespace Drupal\Tests\hal\Kernel;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Url; use Drupal\Core\Url;
use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig; use Drupal\field\Entity\FieldStorageConfig;
use Drupal\KernelTests\KernelTestBase; use Drupal\KernelTests\KernelTestBase;
use Drupal\node\Entity\NodeType; use Drupal\node\Entity\NodeType;
use Drupal\rest\EventSubscriber\ResourceResponseSubscriber;
/** /**
* @coversDefaultClass \Drupal\hal\LinkManager\LinkManager * @coversDefaultClass \Drupal\hal\LinkManager\LinkManager
...@@ -67,6 +69,13 @@ public function testGetTypeUri($link_domain, $entity_type, $bundle, array $conte ...@@ -67,6 +69,13 @@ public function testGetTypeUri($link_domain, $entity_type, $bundle, array $conte
} }
public function providerTestGetTypeUri() { public function providerTestGetTypeUri() {
$serialization_context_collecting_cacheability = [
ResourceResponseSubscriber::SERIALIZATION_CONTEXT_CACHEABILITY => new CacheableMetadata()
];
$expected_serialization_context_cacheability_url_site = [
ResourceResponseSubscriber::SERIALIZATION_CONTEXT_CACHEABILITY => (new CacheableMetadata())->setCacheContexts(['url.site'])
];
$base_test_case = [ $base_test_case = [
'link_domain' => NULL, 'link_domain' => NULL,
'entity_type' => 'node', 'entity_type' => 'node',
...@@ -80,18 +89,35 @@ public function providerTestGetTypeUri() { ...@@ -80,18 +89,35 @@ public function providerTestGetTypeUri() {
'expected return' => 'BASE_URL/rest/type/node/page', 'expected return' => 'BASE_URL/rest/type/node/page',
'expected context' => [], 'expected context' => [],
], ],
'site URL, with optional context to collect cacheability metadata' => $base_test_case + [
'context' => $serialization_context_collecting_cacheability,
'expected return' => 'BASE_URL/rest/type/node/page',
'expected context' => $expected_serialization_context_cacheability_url_site,
],
// Test hook_hal_type_uri_alter(). // Test hook_hal_type_uri_alter().
'site URL, with optional context, to test hook_hal_type_uri_alter()' => $base_test_case + [ 'site URL, with optional context, to test hook_hal_type_uri_alter()' => $base_test_case + [
'context' => ['hal_test' => TRUE], 'context' => ['hal_test' => TRUE],
'expected return' => 'hal_test_type', 'expected return' => 'hal_test_type',
'expected context' => ['hal_test' => TRUE], 'expected context' => ['hal_test' => TRUE],
], ],
'site URL, with optional context, to test hook_hal_type_uri_alter(), and collecting cacheability metadata' => $base_test_case + [
'context' => ['hal_test' => TRUE] + $serialization_context_collecting_cacheability,
'expected return' => 'hal_test_type',
// No cacheability metadata bubbled.
'expected context' => ['hal_test' => TRUE] + $serialization_context_collecting_cacheability,
],
// Test hook_rest_type_uri_alter() — for backwards compatibility. // Test hook_rest_type_uri_alter() — for backwards compatibility.
'site URL, with optional context, to test hook_rest_type_uri_alter()' => $base_test_case + [ 'site URL, with optional context, to test hook_rest_type_uri_alter()' => $base_test_case + [
'context' => ['rest_test' => TRUE], 'context' => ['rest_test' => TRUE],
'expected return' => 'rest_test_type', 'expected return' => 'rest_test_type',
'expected context' => ['rest_test' => TRUE], 'expected context' => ['rest_test' => TRUE],
], ],
'site URL, with optional context, to test hook_rest_type_uri_alter(), and collecting cacheability metadata' => $base_test_case + [
'context' => ['rest_test' => TRUE] + $serialization_context_collecting_cacheability,
'expected return' => 'rest_test_type',
// No cacheability metadata bubbled.
'expected context' => ['rest_test' => TRUE] + $serialization_context_collecting_cacheability,
],
'configured URL' => [ 'configured URL' => [
'link_domain' => 'http://llamas-rock.com/for-real/', 'link_domain' => 'http://llamas-rock.com/for-real/',
'entity_type' => 'node', 'entity_type' => 'node',
...@@ -100,6 +126,16 @@ public function providerTestGetTypeUri() { ...@@ -100,6 +126,16 @@ public function providerTestGetTypeUri() {
'expected return' => 'http://llamas-rock.com/for-real/rest/type/node/page', 'expected return' => 'http://llamas-rock.com/for-real/rest/type/node/page',
'expected context' => [], 'expected context' => [],
], ],
'configured URL, with optional context to collect cacheability metadata' => [
'link_domain' => 'http://llamas-rock.com/for-real/',
'entity_type' => 'node',
'bundle' => 'page',
'context' => $serialization_context_collecting_cacheability,
'expected return' => 'http://llamas-rock.com/for-real/rest/type/node/page',
'expected context' => [
ResourceResponseSubscriber::SERIALIZATION_CONTEXT_CACHEABILITY => (new CacheableMetadata())->setCacheTags(['config:hal.settings']),
],
],
]; ];
} }
...@@ -126,6 +162,13 @@ public function testGetRelationUri($link_domain, $entity_type, $bundle, $field_n ...@@ -126,6 +162,13 @@ public function testGetRelationUri($link_domain, $entity_type, $bundle, $field_n
} }
public function providerTestGetRelationUri() { public function providerTestGetRelationUri() {
$serialization_context_collecting_cacheability = [
ResourceResponseSubscriber::SERIALIZATION_CONTEXT_CACHEABILITY => new CacheableMetadata()
];
$expected_serialization_context_cacheability_url_site = [
ResourceResponseSubscriber::SERIALIZATION_CONTEXT_CACHEABILITY => (new CacheableMetadata())->setCacheContexts(['url.site'])
];
$field_name = $this->randomMachineName(); $field_name = $this->randomMachineName();
$base_test_case = [ $base_test_case = [
'link_domain' => NULL, 'link_domain' => NULL,
...@@ -141,18 +184,35 @@ public function providerTestGetRelationUri() { ...@@ -141,18 +184,35 @@ public function providerTestGetRelationUri() {
'expected return' => 'BASE_URL/rest/relation/node/page/' . $field_name, 'expected return' => 'BASE_URL/rest/relation/node/page/' . $field_name,
'expected context' => [], 'expected context' => [],
], ],
'site URL, with optional context to collect cacheability metadata' => $base_test_case + [
'context' => $serialization_context_collecting_cacheability,
'expected return' => 'BASE_URL/rest/relation/node/page/' . $field_name,
'expected context' => $expected_serialization_context_cacheability_url_site,
],
// Test hook_hal_relation_uri_alter(). // Test hook_hal_relation_uri_alter().
'site URL, with optional context, to test hook_hal_relation_uri_alter()' => $base_test_case + [ 'site URL, with optional context, to test hook_hal_relation_uri_alter()' => $base_test_case + [
'context' => ['hal_test' => TRUE], 'context' => ['hal_test' => TRUE],
'expected return' => 'hal_test_relation', 'expected return' => 'hal_test_relation',
'expected context' => ['hal_test' => TRUE], 'expected context' => ['hal_test' => TRUE],
], ],
'site URL, with optional context, to test hook_hal_relation_uri_alter(), and collecting cacheability metadata' => $base_test_case + [
'context' => ['hal_test' => TRUE] + $serialization_context_collecting_cacheability,
'expected return' => 'hal_test_relation',
// No cacheability metadata bubbled.
'expected context' => ['hal_test' => TRUE] + $serialization_context_collecting_cacheability,
],
// Test hook_rest_relation_uri_alter() — for backwards compatibility. // Test hook_rest_relation_uri_alter() — for backwards compatibility.
'site URL, with optional context, to test hook_rest_relation_uri_alter()' => $base_test_case + [ 'site URL, with optional context, to test hook_rest_relation_uri_alter()' => $base_test_case + [
'context' => ['rest_test' => TRUE], 'context' => ['rest_test' => TRUE],
'expected return' => 'rest_test_relation', 'expected return' => 'rest_test_relation',
'expected context' => ['rest_test' => TRUE], 'expected context' => ['rest_test' => TRUE],
], ],
'site URL, with optional context, to test hook_rest_relation_uri_alter(), and collecting cacheability metadata' => $base_test_case + [
'context' => ['rest_test' => TRUE] + $serialization_context_collecting_cacheability,
'expected return' => 'rest_test_relation',
// No cacheability metadata bubbled.
'expected context' => ['rest_test' => TRUE] + $serialization_context_collecting_cacheability,
],
'configured URL' => [ 'configured URL' => [
'link_domain' => 'http://llamas-rock.com/for-real/', 'link_domain' => 'http://llamas-rock.com/for-real/',
'entity_type' => 'node', 'entity_type' => 'node',
...@@ -162,6 +222,17 @@ public function providerTestGetRelationUri() { ...@@ -162,6 +222,17 @@ public function providerTestGetRelationUri() {
'expected return' => 'http://llamas-rock.com/for-real/rest/relation/node/page/' . $field_name, 'expected return' => 'http://llamas-rock.com/for-real/rest/relation/node/page/' . $field_name,
'expected context' => [], 'expected context' => [],
], ],
'configured URL, with optional context to collect cacheability metadata' => [
'link_domain' => 'http://llamas-rock.com/for-real/',
'entity_type' => 'node',
'bundle' => 'page',
'field_name' => $field_name,
'context' => $serialization_context_collecting_cacheability,
'expected return' => 'http://llamas-rock.com/for-real/rest/relation/node/page/' . $field_name,
'expected context' => [
ResourceResponseSubscriber::SERIALIZATION_CONTEXT_CACHEABILITY => (new CacheableMetadata())->setCacheTags(['config:hal.settings']),
],
],
]; ];
} }
...@@ -186,13 +257,19 @@ public function testGetRelationInternalIds() { ...@@ -186,13 +257,19 @@ public function testGetRelationInternalIds() {
* @covers ::setLinkDomain * @covers ::setLinkDomain
*/ */
public function testHalLinkManagersSetLinkDomain() { public function testHalLinkManagersSetLinkDomain() {
$serialization_context = [
ResourceResponseSubscriber::SERIALIZATION_CONTEXT_CACHEABILITY => new CacheableMetadata()
];
/* @var \Drupal\rest\LinkManager\LinkManager $link_manager */ /* @var \Drupal\rest\LinkManager\LinkManager $link_manager */
$link_manager = \Drupal::service('hal.link_manager'); $link_manager = \Drupal::service('hal.link_manager');
$link_manager->setLinkDomain('http://example.com/'); $link_manager->setLinkDomain('http://example.com/');
$link = $link_manager->getTypeUri('node', 'page'); $link = $link_manager->getTypeUri('node', 'page', $serialization_context);
$this->assertEqual($link, 'http://example.com/rest/type/node/page'); $this->assertEqual($link, 'http://example.com/rest/type/node/page');
$link = $link_manager->getRelationUri('node', 'page', 'field_ref'); $this->assertEqual(new CacheableMetadata(), $serialization_context[ResourceResponseSubscriber::SERIALIZATION_CONTEXT_CACHEABILITY]);
$link = $link_manager->getRelationUri('node', 'page', 'field_ref', $serialization_context);
$this->assertEqual($link, 'http://example.com/rest/relation/node/page/field_ref'); $this->assertEqual($link, 'http://example.com/rest/relation/node/page/field_ref');
$this->assertEqual(new CacheableMetadata(), $serialization_context[ResourceResponseSubscriber::SERIALIZATION_CONTEXT_CACHEABILITY]);
} }
} }
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