Skip to content
Snippets Groups Projects
Commit 2526049b authored by catch's avatar catch
Browse files

Issue #3132578 by prudloff, smustgrave, joachim: MenuActiveTrail creates...

Issue #3132578 by prudloff, smustgrave, joachim: MenuActiveTrail creates invalid cache tags when called without a menu name

(cherry picked from commit 90f99d25)
parent 2536e3ac
No related branches found
No related tags found
No related merge requests found
...@@ -69,7 +69,14 @@ protected function getCid() { ...@@ -69,7 +69,14 @@ protected function getCid() {
*/ */
protected function resolveCacheMiss($menu_name) { protected function resolveCacheMiss($menu_name) {
$this->storage[$menu_name] = $this->doGetActiveTrailIds($menu_name); $this->storage[$menu_name] = $this->doGetActiveTrailIds($menu_name);
$this->tags[] = 'config:system.menu.' . $menu_name; if (empty($menu_name)) {
// We look in every menu so invalidate when any menu or menu item changes.
$this->tags[] = 'config:menu_list';
$this->tags[] = 'menu_link_content_list';
}
else {
$this->tags[] = 'config:system.menu.' . $menu_name;
}
$this->persist($menu_name); $this->persist($menu_name);
return $this->storage[$menu_name]; return $this->storage[$menu_name];
......
...@@ -4,11 +4,13 @@ ...@@ -4,11 +4,13 @@
namespace Drupal\Tests\Core\Menu; namespace Drupal\Tests\Core\Menu;
use Drupal\Core\Cache\CacheTagsInvalidatorInterface;
use Drupal\Core\Menu\MenuActiveTrail; use Drupal\Core\Menu\MenuActiveTrail;
use Drupal\Core\Routing\CurrentRouteMatch; use Drupal\Core\Routing\CurrentRouteMatch;
use Drupal\Tests\UnitTestCase; use Drupal\Tests\UnitTestCase;
use Drupal\TestTools\Random; use Drupal\TestTools\Random;
use Drupal\Core\Routing\RouteObjectInterface; use Drupal\Core\Routing\RouteObjectInterface;
use PHPUnit\Framework\MockObject\MockObject;
use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\HttpFoundation\InputBag; use Symfony\Component\HttpFoundation\InputBag;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
...@@ -66,6 +68,13 @@ class MenuActiveTrailTest extends UnitTestCase { ...@@ -66,6 +68,13 @@ class MenuActiveTrailTest extends UnitTestCase {
*/ */
protected $lock; protected $lock;
/**
* The mocked cache tags invalidator.
*
* @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface|\PHPUnit\Framework\MockObject\MockObject
*/
protected CacheTagsInvalidatorInterface|MockObject $cacheTagsInvalidator;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
...@@ -77,11 +86,12 @@ protected function setUp(): void { ...@@ -77,11 +86,12 @@ protected function setUp(): void {
$this->menuLinkManager = $this->createMock('Drupal\Core\Menu\MenuLinkManagerInterface'); $this->menuLinkManager = $this->createMock('Drupal\Core\Menu\MenuLinkManagerInterface');
$this->cache = $this->createMock('\Drupal\Core\Cache\CacheBackendInterface'); $this->cache = $this->createMock('\Drupal\Core\Cache\CacheBackendInterface');
$this->lock = $this->createMock('\Drupal\Core\Lock\LockBackendInterface'); $this->lock = $this->createMock('\Drupal\Core\Lock\LockBackendInterface');
$this->cacheTagsInvalidator = $this->createMock('\Drupal\Core\Cache\CacheTagsInvalidatorInterface');
$this->menuActiveTrail = new MenuActiveTrail($this->menuLinkManager, $this->currentRouteMatch, $this->cache, $this->lock); $this->menuActiveTrail = new MenuActiveTrail($this->menuLinkManager, $this->currentRouteMatch, $this->cache, $this->lock);
$container = new Container(); $container = new Container();
$container->set('cache_tags.invalidator', $this->createMock('\Drupal\Core\Cache\CacheTagsInvalidatorInterface')); $container->set('cache_tags.invalidator', $this->cacheTagsInvalidator);
\Drupal::setContainer($container); \Drupal::setContainer($container);
} }
...@@ -169,12 +179,12 @@ public function testGetActiveTrailIds(Request $request, $links, $menu_name, $exp ...@@ -169,12 +179,12 @@ public function testGetActiveTrailIds(Request $request, $links, $menu_name, $exp
if ($links !== FALSE) { if ($links !== FALSE) {
// We expect exactly two calls, one for the first call, and one after the // We expect exactly two calls, one for the first call, and one after the
// cache clearing below. // cache clearing below.
$this->menuLinkManager->expects($this->exactly(2)) $this->menuLinkManager->expects($this->exactly(3))
->method('loadLinksByRoute') ->method('loadLinksByRoute')
->with('baby_llama') ->with('baby_llama')
->willReturn($links); ->willReturn($links);
if ($expected_link !== NULL) { if ($expected_link !== NULL) {
$this->menuLinkManager->expects($this->exactly(2)) $this->menuLinkManager->expects($this->exactly(3))
->method('getParentIds') ->method('getParentIds')
->willReturnMap([ ->willReturnMap([
[$expected_link->getPluginId(), $expected_trail_ids], [$expected_link->getPluginId(), $expected_trail_ids],
...@@ -186,8 +196,21 @@ public function testGetActiveTrailIds(Request $request, $links, $menu_name, $exp ...@@ -186,8 +196,21 @@ public function testGetActiveTrailIds(Request $request, $links, $menu_name, $exp
$this->assertSame($expected_trail_ids, $this->menuActiveTrail->getActiveTrailIds($menu_name)); $this->assertSame($expected_trail_ids, $this->menuActiveTrail->getActiveTrailIds($menu_name));
$this->assertSame($expected_trail_ids, $this->menuActiveTrail->getActiveTrailIds($menu_name)); $this->assertSame($expected_trail_ids, $this->menuActiveTrail->getActiveTrailIds($menu_name));
$this->cacheTagsInvalidator->expects($this->exactly(2))
->method('invalidateTags')
->willReturnCallback(fn($tags) =>
match($tags) {
['config:system.menu.' . $menu_name] => NULL,
['config:system.menu.' . $menu_name, 'config:system.menu.' . $menu_name, 'config:menu_list', 'menu_link_content_list'] => NULL,
}
);
$this->menuActiveTrail->clear(); $this->menuActiveTrail->clear();
$this->assertSame($expected_trail_ids, $this->menuActiveTrail->getActiveTrailIds($menu_name)); $this->assertSame($expected_trail_ids, $this->menuActiveTrail->getActiveTrailIds($menu_name));
// Test without menu name.
$this->assertSame($expected_trail_ids, $this->menuActiveTrail->getActiveTrailIds(NULL));
$this->assertSame($expected_trail_ids, $this->menuActiveTrail->getActiveTrailIds(NULL));
$this->menuActiveTrail->clear();
} }
/** /**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment