Commit b1c7365e authored by alexpott's avatar alexpott

Issue #2605684 by chx, dawehner: Routing silently fails in kernel tests

parent fa9d7124
......@@ -200,15 +200,22 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) {
// The menu link can just be updated if there is already an menu link entry
// on both entity and menu link plugin level.
if ($update && $menu_link_manager->getDefinition($this->getPluginId())) {
$definition = $this->getPluginDefinition();
// Even when $update is FALSE, for top level links it is possible the link
// already is in the storage because of the getPluginDefinition() call
// above, see https://www.drupal.org/node/2605684#comment-10515450 for the
// call chain. Because of this the $update flag is ignored and only the
// existence of the definition (equals to being in the tree storage) is
// checked.
if ($menu_link_manager->getDefinition($this->getPluginId(), FALSE)) {
// When the entity is saved via a plugin instance, we should not call
// the menu tree manager to update the definition a second time.
if (!$this->insidePlugin) {
$menu_link_manager->updateDefinition($this->getPluginId(), $this->getPluginDefinition(), FALSE);
$menu_link_manager->updateDefinition($this->getPluginId(), $definition, FALSE);
}
}
else {
$menu_link_manager->addDefinition($this->getPluginId(), $this->getPluginDefinition());
$menu_link_manager->addDefinition($this->getPluginId(), $definition);
}
}
......
<?php
/**
* @file
* Contains \Drupal\Core\ProxyClass\Routing\RouteProvider.
*/
namespace Drupal\simpletest;
use Drupal\Core\Routing\PreloadableRouteProviderInterface;
use Symfony\Cmf\Component\Routing\PagedRouteProviderInterface;
use Symfony\Component\HttpFoundation\Request;
/**
* Rebuilds the router when the provider is instantiated.
*/
class RouteProvider implements PreloadableRouteProviderInterface, PagedRouteProviderInterface {
use \Drupal\Core\DependencyInjection\DependencySerializationTrait;
/**
* Loads the real route provider from the container and rebuilds the router.
*
* @return \Drupal\Core\Routing\PreloadableRouteProviderInterface|\Symfony\Cmf\Component\Routing\PagedRouteProviderInterface|\Symfony\Component\EventDispatcher\EventSubscriberInterface
* The route provider.
*/
protected function lazyLoadItself() {
if (!isset($this->service)) {
$container = \Drupal::getContainer();
$this->service = $container->get('simpletest.router.route_provider');
$container->get('router.builder')->rebuild();
}
return $this->service;
}
/**
* {@inheritdoc}
*/
public function getRouteCollectionForRequest(Request $request) {
return $this->lazyLoadItself()->getRouteCollectionForRequest($request);
}
/**
* {@inheritdoc}
*/
public function getRouteByName($name) {
return $this->lazyLoadItself()->getRouteByName($name);
}
/**
* {@inheritdoc}
*/
public function preLoadRoutes($names){
return $this->lazyLoadItself()->preLoadRoutes($names);
}
/**
* {@inheritdoc}
*/
public function getRoutesByNames($names) {
return $this->lazyLoadItself()->getRoutesByNames($names);
}
/**
* {@inheritdoc}
*/
public function getCandidateOutlines(array $parts) {
return $this->lazyLoadItself()->getCandidateOutlines($parts);
}
/**
* {@inheritdoc}
*/
public function getRoutesByPattern($pattern) {
return $this->lazyLoadItself()->getRoutesByPattern($pattern);
}
/**
* {@inheritdoc}
*/
public function routeProviderRouteCompare(array $a, array $b) {
return $this->lazyLoadItself()->routeProviderRouteCompare($a, $b);
}
/**
* {@inheritdoc}
*/
public function getAllRoutes() {
return $this->lazyLoadItself()->getAllRoutes();
}
/**
* {@inheritdoc}
*/
public function reset() {
return $this->lazyLoadItself()->reset();
}
/**
* {@inheritdoc}
*/
public function getRoutesPaged($offset, $length = NULL) {
return $this->lazyLoadItself()->getRoutesPaged($offset, $length);
}
/**
* {@inheritdoc}
*/
public function getRoutesCount() {
return $this->lazyLoadItself()->getRoutesCount();
}
}
......@@ -8,9 +8,11 @@
namespace Drupal\simpletest;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceModifierInterface;
use Drupal\Core\DependencyInjection\ServiceProviderInterface;
use Symfony\Component\DependencyInjection\Definition;
class TestServiceProvider implements ServiceProviderInterface {
class TestServiceProvider implements ServiceProviderInterface, ServiceModifierInterface {
/**
* @var \Drupal\simpletest\TestBase;
......@@ -25,4 +27,21 @@ function register(ContainerBuilder $container) {
static::$currentTest->containerBuild($container);
}
}
/**
* {@inheritdoc}
*/
public function alter(ContainerBuilder $container) {
if (static::$currentTest instanceof KernelTestBase) {
// While $container->get() does a recursive resolve, getDefinition() does
// not, so do it ourselves.
foreach (['router.route_provider' => 'RouteProvider'] as $original_id => $class) {
for ($id = $original_id; $container->hasAlias($id); $id = (string) $container->getAlias($id));
$definition = $container->getDefinition($id);
$definition->clearTag('needs_destruction');
$container->setDefinition("simpletest.$original_id", $definition);
$container->setDefinition($id, new Definition('Drupal\simpletest\\' . $class));
}
}
}
}
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