diff --git a/Neos.Flow/Classes/Command/RoutingCommandController.php b/Neos.Flow/Classes/Command/RoutingCommandController.php
index acb33fe95c..ae43d4907a 100644
--- a/Neos.Flow/Classes/Command/RoutingCommandController.php
+++ b/Neos.Flow/Classes/Command/RoutingCommandController.php
@@ -17,7 +17,6 @@
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Cli\CommandController;
use Neos\Flow\Cli\Exception\StopCommandException;
-use Neos\Flow\Configuration\ConfigurationManager;
use Neos\Flow\Http\Helper\RequestInformationHelper;
use Neos\Flow\Mvc\Exception\InvalidRoutePartValueException;
use Neos\Flow\Mvc\Routing\Dto\ResolveContext;
@@ -26,7 +25,7 @@
use Neos\Flow\Mvc\Routing\Dto\RouteTags;
use Neos\Flow\Mvc\Routing\Dto\UriConstraints;
use Neos\Flow\Mvc\Routing\Route;
-use Neos\Flow\Mvc\Routing\Router;
+use Neos\Flow\Mvc\Routing\RoutesProviderInterface;
use Neos\Flow\ObjectManagement\ObjectManagerInterface;
use Neos\Http\Factories\ServerRequestFactory;
use Neos\Utility\Arrays;
@@ -40,15 +39,9 @@ class RoutingCommandController extends CommandController
{
/**
* @Flow\Inject
- * @var ConfigurationManager
+ * @var RoutesProviderInterface
*/
- protected $configurationManager;
-
- /**
- * @Flow\Inject
- * @var Router
- */
- protected $router;
+ protected $routesProvider;
/**
* @Flow\Inject
@@ -73,8 +66,7 @@ public function listCommand(): void
{
$this->outputLine('Currently registered routes:');
$rows = [];
- /** @var Route $route */
- foreach ($this->router->getRoutes() as $index => $route) {
+ foreach ($this->routesProvider->getRoutes() as $index => $route) {
$routeNumber = $index + 1;
$rows[] = [
'#' => $routeNumber,
@@ -99,15 +91,12 @@ public function listCommand(): void
*/
public function showCommand(int $index): void
{
- /** @var Route[] $routes */
- $routes = $this->router->getRoutes();
- if (!isset($routes[$index - 1])) {
+ $route = $this->routesProvider->getRoutes()[$index - 1] ?? null;
+ if ($route === null) {
$this->outputLine('Route %d was not found!', [$index]);
$this->outputLine('Run ./flow routing:list to show all registered routes');
$this->quit(1);
- return;
}
- $route = $routes[$index - 1];
$this->outputLine('Information for route #' . $index . ':');
$this->outputLine();
@@ -203,8 +192,8 @@ public function resolveCommand(string $package, string $controller = null, strin
/** @var Route|null $resolvedRoute */
$resolvedRoute = null;
$resolvedRouteNumber = 0;
- /** @var int $index */
- foreach ($this->router->getRoutes() as $index => $route) {
+
+ foreach ($this->routesProvider->getRoutes() as $index => $route) {
/** @var Route $route */
if ($route->resolves($resolveContext) === true) {
$resolvedRoute = $route;
@@ -216,7 +205,6 @@ public function resolveCommand(string $package, string $controller = null, strin
if ($resolvedRoute === null) {
$this->outputLine('No route could resolve these values...');
$this->quit(1);
- return;
}
/** @var UriConstraints $uriConstraints */
@@ -273,7 +261,6 @@ public function matchCommand(string $uri, string $method = null, string $paramet
if (isset($requestUri->getPath()[0]) && $requestUri->getPath()[0] !== '/') {
$this->outputLine('The URI "%s" is not valid. The path has to start with a "/"', [$requestUri]);
$this->quit(1);
- return;
}
$httpRequest = $this->serverRequestFactory->createServerRequest($method, $requestUri);
$routeParameters = $this->createRouteParametersFromJson($parameters);
@@ -292,8 +279,7 @@ public function matchCommand(string $uri, string $method = null, string $paramet
/** @var Route|null $matchedRoute */
$matchedRoute = null;
$matchedRouteNumber = 0;
- /** @var int $index */
- foreach ($this->router->getRoutes() as $index => $route) {
+ foreach ($this->routesProvider->getRoutes() as $index => $route) {
/** @var Route $route */
if ($route->matches($routeContext) === true) {
$matchedRoute = $route;
@@ -305,7 +291,6 @@ public function matchCommand(string $uri, string $method = null, string $paramet
if ($matchedRoute === null) {
$this->outputLine('No route could match %s request to URL %s...', [$method, $requestUri]);
$this->quit(1);
- return;
}
$this->outputLine('Route matched!');
@@ -365,12 +350,10 @@ private function parseJsonToArray(?string $json): array
if ($parsedValue === null && \json_last_error() !== JSON_ERROR_NONE) {
$this->outputLine('Failed to parse %s as JSON: %s', [$json, \json_last_error_msg()]);
$this->quit(1);
- return [];
}
if (!is_array($parsedValue)) {
$this->outputLine('Failed to parse %s to an array, please a provide valid JSON object that can be represented as PHP array', [$json]);
$this->quit(1);
- return [];
}
return $parsedValue;
}
diff --git a/Neos.Flow/Classes/Mvc/Routing/ConfigurationRoutesProvider.php b/Neos.Flow/Classes/Mvc/Routing/ConfigurationRoutesProvider.php
new file mode 100644
index 0000000000..f876008e8c
--- /dev/null
+++ b/Neos.Flow/Classes/Mvc/Routing/ConfigurationRoutesProvider.php
@@ -0,0 +1,27 @@
+configurationManager = $configurationManager;
+ }
+
+ public function getRoutes(): Routes
+ {
+ return Routes::fromConfiguration($this->configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_ROUTES));
+ }
+}
diff --git a/Neos.Flow/Classes/Mvc/Routing/Route.php b/Neos.Flow/Classes/Mvc/Routing/Route.php
index 2f60eedc2a..0b073796b9 100644
--- a/Neos.Flow/Classes/Mvc/Routing/Route.php
+++ b/Neos.Flow/Classes/Mvc/Routing/Route.php
@@ -31,6 +31,7 @@
/**
* Implementation of a standard route
+ * @phpstan-consistent-constructor
*/
class Route
{
@@ -172,6 +173,41 @@ class Route
*/
protected $persistenceManager;
+ public static function fromConfiguration(array $configuration): static
+ {
+ /** @phpstan-ignore-next-line phpstan doesn't respekt the consistent constructor flag in the class doc block */
+ $route = new static();
+ if (isset($configuration['name'])) {
+ $route->setName($configuration['name']);
+ }
+ $uriPattern = $configuration['uriPattern'];
+ $route->setUriPattern($uriPattern);
+ if (isset($configuration['defaults'])) {
+ $route->setDefaults($configuration['defaults']);
+ }
+ if (isset($configuration['routeParts'])) {
+ $route->setRoutePartsConfiguration($configuration['routeParts']);
+ }
+ if (isset($configuration['toLowerCase'])) {
+ $route->setLowerCase($configuration['toLowerCase']);
+ }
+ if (isset($configuration['appendExceedingArguments'])) {
+ $route->setAppendExceedingArguments($configuration['appendExceedingArguments']);
+ }
+ if (isset($configuration['cache'])) {
+ if (isset($configuration['cache']['lifetime'])) {
+ $route->setCacheLifetime(RouteLifetime::fromInt($configuration['cache']['lifetime']));
+ }
+ if (isset($configuration['cache']['tags']) && !empty($configuration['cache']['lifetime'])) {
+ $route->setCacheTags(RouteTags::createFromArray($configuration['cache']['tags']));
+ }
+ }
+ if (isset($configuration['httpMethods'])) {
+ $route->setHttpMethods($configuration['httpMethods']);
+ }
+ return $route;
+ }
+
/**
* Sets Route name.
*
diff --git a/Neos.Flow/Classes/Mvc/Routing/Router.php b/Neos.Flow/Classes/Mvc/Routing/Router.php
index c66110009d..b4ebe8267c 100644
--- a/Neos.Flow/Classes/Mvc/Routing/Router.php
+++ b/Neos.Flow/Classes/Mvc/Routing/Router.php
@@ -12,7 +12,6 @@
*/
use Neos\Flow\Annotations as Flow;
-use Neos\Flow\Configuration\ConfigurationManager;
use Neos\Flow\Http\Helper\RequestInformationHelper;
use Neos\Flow\Http\Helper\UriHelper;
use Neos\Flow\Log\Utility\LogEnvironment;
@@ -21,8 +20,6 @@
use Neos\Flow\Mvc\Exception\NoMatchingRouteException;
use Neos\Flow\Mvc\Routing\Dto\ResolveContext;
use Neos\Flow\Mvc\Routing\Dto\RouteContext;
-use Neos\Flow\Mvc\Routing\Dto\RouteLifetime;
-use Neos\Flow\Mvc\Routing\Dto\RouteTags;
use Psr\Http\Message\UriInterface;
use Psr\Log\LoggerInterface;
@@ -35,16 +32,16 @@
class Router implements RouterInterface
{
/**
- * @Flow\Inject(name="Neos.Flow:SystemLogger")
- * @var LoggerInterface
+ * @Flow\Inject
+ * @var RoutesProviderInterface
*/
- protected $logger;
+ protected $routesProvider;
/**
- * @Flow\Inject
- * @var ConfigurationManager
+ * @Flow\Inject(name="Neos.Flow:SystemLogger")
+ * @var LoggerInterface
*/
- protected $configurationManager;
+ protected $logger;
/**
* @Flow\Inject
@@ -52,27 +49,6 @@ class Router implements RouterInterface
*/
protected $routerCachingService;
- /**
- * Array containing the configuration for all routes
- *
- * @var array
- */
- protected $routesConfiguration = null;
-
- /**
- * Array of routes to match against
- *
- * @var array
- */
- protected $routes = [];
-
- /**
- * true if route object have been created, otherwise false
- *
- * @var boolean
- */
- protected $routesCreated = false;
-
/**
* @var Route
*/
@@ -94,25 +70,13 @@ public function injectLogger(LoggerInterface $logger)
$this->logger = $logger;
}
- /**
- * Sets the routes configuration.
- *
- * @param array|null $routesConfiguration The routes configuration or NULL if it should be fetched from configuration
- * @return void
- */
- public function setRoutesConfiguration(array $routesConfiguration = null)
- {
- $this->routesConfiguration = $routesConfiguration;
- $this->routesCreated = false;
- }
-
/**
* Iterates through all configured routes and calls matches() on them.
* Returns the matchResults of the matching route or NULL if no matching
* route could be found.
*
* @param RouteContext $routeContext The Route Context containing the current HTTP Request and, optional, Routing RouteParameters
- * @return array The results of the matching route
+ * @return array The results of the matching route or NULL if no route matched
* @throws InvalidRouteSetupException
* @throws NoMatchingRouteException if no route matched the given $routeContext
* @throws InvalidRoutePartValueException
@@ -124,10 +88,10 @@ public function route(RouteContext $routeContext): array
if ($cachedRouteResult !== false) {
return $cachedRouteResult;
}
- $this->createRoutesFromConfiguration();
+
$httpRequest = $routeContext->getHttpRequest();
- foreach ($this->routes as $route) {
+ foreach ($this->routesProvider->getRoutes() as $route) {
if ($route->matches($routeContext) === true) {
$this->lastMatchedRoute = $route;
$matchResults = $route->getMatchResults();
@@ -152,29 +116,6 @@ public function getLastMatchedRoute()
return $this->lastMatchedRoute;
}
- /**
- * Returns a list of configured routes
- *
- * @return array
- */
- public function getRoutes()
- {
- $this->createRoutesFromConfiguration();
- return $this->routes;
- }
-
- /**
- * Manually adds a route to the beginning of the configured routes
- *
- * @param Route $route
- * @return void
- */
- public function addRoute(Route $route)
- {
- $this->createRoutesFromConfiguration();
- array_unshift($this->routes, $route);
- }
-
/**
* Builds the corresponding uri (excluding protocol and host) by iterating
* through all configured routes and calling their respective resolves()
@@ -193,9 +134,7 @@ public function resolve(ResolveContext $resolveContext): UriInterface
return $cachedResolvedUriConstraints->applyTo($resolveContext->getBaseUri(), $resolveContext->isForceAbsoluteUri());
}
- $this->createRoutesFromConfiguration();
-
- foreach ($this->routes as $route) {
+ foreach ($this->routesProvider->getRoutes() as $route) {
if ($route->resolves($resolveContext) === true) {
$uriConstraints = $route->getResolvedUriConstraints()->withPathPrefix($resolveContext->getUriPathPrefix());
$resolvedUri = $uriConstraints->applyTo($resolveContext->getBaseUri(), $resolveContext->isForceAbsoluteUri());
@@ -218,75 +157,4 @@ public function getLastResolvedRoute()
{
return $this->lastResolvedRoute;
}
-
- /**
- * Creates \Neos\Flow\Mvc\Routing\Route objects from the injected routes
- * configuration.
- *
- * @return void
- * @throws InvalidRouteSetupException
- */
- protected function createRoutesFromConfiguration()
- {
- if ($this->routesCreated === true) {
- return;
- }
- $this->initializeRoutesConfiguration();
- $this->routes = [];
- $routesWithHttpMethodConstraints = [];
- foreach ($this->routesConfiguration as $routeConfiguration) {
- $route = new Route();
- if (isset($routeConfiguration['name'])) {
- $route->setName($routeConfiguration['name']);
- }
- $uriPattern = $routeConfiguration['uriPattern'];
- $route->setUriPattern($uriPattern);
- if (isset($routeConfiguration['defaults'])) {
- $route->setDefaults($routeConfiguration['defaults']);
- }
- if (isset($routeConfiguration['routeParts'])) {
- $route->setRoutePartsConfiguration($routeConfiguration['routeParts']);
- }
- if (isset($routeConfiguration['toLowerCase'])) {
- $route->setLowerCase($routeConfiguration['toLowerCase']);
- }
- if (isset($routeConfiguration['appendExceedingArguments'])) {
- $route->setAppendExceedingArguments($routeConfiguration['appendExceedingArguments']);
- }
- if (isset($routeConfiguration['httpMethods'])) {
- if (isset($routesWithHttpMethodConstraints[$uriPattern]) && $routesWithHttpMethodConstraints[$uriPattern] === false) {
- throw new InvalidRouteSetupException(sprintf('There are multiple routes with the uriPattern "%s" and "httpMethods" option set. Please specify accepted HTTP methods for all of these, or adjust the uriPattern', $uriPattern), 1365678427);
- }
- $routesWithHttpMethodConstraints[$uriPattern] = true;
- $route->setHttpMethods($routeConfiguration['httpMethods']);
- } else {
- if (isset($routesWithHttpMethodConstraints[$uriPattern]) && $routesWithHttpMethodConstraints[$uriPattern] === true) {
- throw new InvalidRouteSetupException(sprintf('There are multiple routes with the uriPattern "%s" and "httpMethods" option set. Please specify accepted HTTP methods for all of these, or adjust the uriPattern', $uriPattern), 1365678432);
- }
- $routesWithHttpMethodConstraints[$uriPattern] = false;
- }
- if (isset($routeConfiguration['cache'])) {
- if (isset($routeConfiguration['cache']['lifetime']) && !is_null($routeConfiguration['cache']['lifetime'])) {
- $route->setCacheLifetime(RouteLifetime::fromInt($routeConfiguration['cache']['lifetime']));
- }
- if (isset($routeConfiguration['cache']['tags']) && !empty($routeConfiguration['cache']['lifetime'])) {
- $route->setCacheTags(RouteTags::createFromArray($routeConfiguration['cache']['tags']));
- }
- }
- $this->routes[] = $route;
- }
- $this->routesCreated = true;
- }
-
- /**
- * Checks if a routes configuration was set and otherwise loads the configuration from the configuration manager.
- *
- * @return void
- */
- protected function initializeRoutesConfiguration()
- {
- if ($this->routesConfiguration === null) {
- $this->routesConfiguration = $this->configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_ROUTES);
- }
- }
}
diff --git a/Neos.Flow/Classes/Mvc/Routing/Routes.php b/Neos.Flow/Classes/Mvc/Routing/Routes.php
new file mode 100644
index 0000000000..cc0822c971
--- /dev/null
+++ b/Neos.Flow/Classes/Mvc/Routing/Routes.php
@@ -0,0 +1,75 @@
+
+ */
+final class Routes implements \IteratorAggregate
+{
+ /**
+ * @var array
+ */
+ private array $routes;
+
+ private function __construct(
+ Route ...$routes
+ ) {
+ $this->routes = $routes;
+
+ // validate that each route is unique
+ $routesWithHttpMethodConstraints = [];
+ foreach ($this->routes as $route) {
+ $uriPattern = $route->getUriPattern();
+ if ($route->hasHttpMethodConstraints()) {
+ if (isset($routesWithHttpMethodConstraints[$uriPattern]) && $routesWithHttpMethodConstraints[$uriPattern] === false) {
+ throw new InvalidRouteSetupException(sprintf('There are multiple routes with the uriPattern "%s" and "httpMethods" option set. Please specify accepted HTTP methods for all of these, or adjust the uriPattern', $uriPattern), 1365678427);
+ }
+ $routesWithHttpMethodConstraints[$uriPattern] = true;
+ } else {
+ if (isset($routesWithHttpMethodConstraints[$uriPattern]) && $routesWithHttpMethodConstraints[$uriPattern] === true) {
+ throw new InvalidRouteSetupException(sprintf('There are multiple routes with the uriPattern "%s" and "httpMethods" option set. Please specify accepted HTTP methods for all of these, or adjust the uriPattern', $uriPattern), 1365678432);
+ }
+ $routesWithHttpMethodConstraints[$uriPattern] = false;
+ }
+ }
+ }
+
+ public static function create(Route ...$routes): self
+ {
+ return new self(...$routes);
+ }
+
+ public static function fromConfiguration(array $configuration): self
+ {
+ $routes = [];
+ foreach ($configuration as $routeConfiguration) {
+ $routes[] = Route::fromConfiguration($routeConfiguration);
+ }
+ return new self(...$routes);
+ }
+
+ public static function empty(): self
+ {
+ return new self();
+ }
+
+ public function merge(Routes $other): self
+ {
+ return new self(...$this->routes, ...$other->routes);
+ }
+
+ /**
+ * @return \Traversable
+ */
+ public function getIterator(): Traversable
+ {
+ yield from $this->routes;
+ }
+}
diff --git a/Neos.Flow/Classes/Mvc/Routing/RoutesProviderInterface.php b/Neos.Flow/Classes/Mvc/Routing/RoutesProviderInterface.php
new file mode 100644
index 0000000000..5cd3f98ae6
--- /dev/null
+++ b/Neos.Flow/Classes/Mvc/Routing/RoutesProviderInterface.php
@@ -0,0 +1,18 @@
+additionalRoutes = Routes::empty();
+ }
+
+ /**
+ * Prepends a route additionally to the routes form the Testing context configuration
+ *
+ * @internal Please use {@see FunctionalTestCase::registerRoute} instead.
+ */
+ public function addRoute(Route $route)
+ {
+ // we prepended the route, like the old Router::addRoute
+ $this->additionalRoutes = Routes::create($route)->merge($this->additionalRoutes);
+ }
+
+ public function reset(): void
+ {
+ $this->additionalRoutes = Routes::empty();
+ }
+
+ public function getRoutes(): Routes
+ {
+ // we prepended all additional routes, like the old Router::addRoute
+ return $this->additionalRoutes->merge(
+ $this->configurationRoutesProvider->getRoutes()
+ );
+ }
+}
diff --git a/Neos.Flow/Configuration/Objects.yaml b/Neos.Flow/Configuration/Objects.yaml
index be14f55c1e..4f116f465d 100644
--- a/Neos.Flow/Configuration/Objects.yaml
+++ b/Neos.Flow/Configuration/Objects.yaml
@@ -257,6 +257,9 @@ Neos\Flow\Http\Middleware\MiddlewaresChain:
Neos\Flow\Mvc\Routing\RouterInterface:
className: Neos\Flow\Mvc\Routing\Router
+Neos\Flow\Mvc\Routing\RoutesProviderInterface:
+ className: Neos\Flow\Mvc\Routing\ConfigurationRoutesProvider
+
Neos\Flow\Mvc\Routing\RouterCachingService:
properties:
routeCache:
diff --git a/Neos.Flow/Configuration/Testing/Objects.yaml b/Neos.Flow/Configuration/Testing/Objects.yaml
index 35c3348b3b..5ab4af6180 100644
--- a/Neos.Flow/Configuration/Testing/Objects.yaml
+++ b/Neos.Flow/Configuration/Testing/Objects.yaml
@@ -15,6 +15,11 @@ Neos\Flow\Http\Client\Browser:
properties:
requestEngine:
object: Neos\Flow\Http\Client\InternalRequestEngine
+#
+# Routing will be extended to be able to add custom routes at runtime
+#
+Neos\Flow\Mvc\Routing\RoutesProviderInterface:
+ className: Neos\Flow\Mvc\Routing\TestingRoutesProvider
#
# Security and PersistentResource handling need specialized testing classes:
diff --git a/Neos.Flow/Tests/Functional/Http/Client/InternalRequestEngineTest.php b/Neos.Flow/Tests/Functional/Http/Client/InternalRequestEngineTest.php
index d779fe9949..4af43df7cb 100644
--- a/Neos.Flow/Tests/Functional/Http/Client/InternalRequestEngineTest.php
+++ b/Neos.Flow/Tests/Functional/Http/Client/InternalRequestEngineTest.php
@@ -11,7 +11,6 @@
* source code.
*/
-use Neos\Flow\Mvc\Routing\Route;
use Neos\Flow\Tests\FunctionalTestCase;
/**
@@ -31,17 +30,17 @@ protected function setUp(): void
{
parent::setUp();
- $route = new Route();
- $route->setName('Functional Test - Http::Client::InternalRequestEngine');
- $route->setUriPattern('test/security/restricted');
- $route->setDefaults([
- '@package' => 'Neos.Flow',
- '@subpackage' => 'Tests\Functional\Security\Fixtures',
- '@controller' => 'Restricted',
- '@action' => 'admin',
- '@format' => 'html'
- ]);
- $this->router->addRoute($route);
+ $this->registerRoute(
+ 'Functional Test - Http::Client::InternalRequestEngine',
+ 'test/security/restricted',
+ [
+ '@package' => 'Neos.Flow',
+ '@subpackage' => 'Tests\Functional\Security\Fixtures',
+ '@controller' => 'Restricted',
+ '@action' => 'admin',
+ '@format' => 'html'
+ ]
+ );
}
/**
diff --git a/Neos.Flow/Tests/Functional/Http/RequestHandlerTest.php b/Neos.Flow/Tests/Functional/Http/RequestHandlerTest.php
index 93a7dfac36..9851abb58f 100644
--- a/Neos.Flow/Tests/Functional/Http/RequestHandlerTest.php
+++ b/Neos.Flow/Tests/Functional/Http/RequestHandlerTest.php
@@ -11,6 +11,7 @@
* source code.
*/
+use Neos\Flow\Configuration\ConfigurationManager;
use Neos\Flow\Http\RequestHandler;
use Neos\Flow\Tests\FunctionalTestCase;
use PHPUnit\Framework\MockObject\MockObject;
@@ -31,14 +32,11 @@ class RequestHandlerTest extends FunctionalTestCase
*/
public function httpRequestIsConvertedToAnActionRequestAndDispatchedToTheRespectiveController(): void
{
- $foundRoute = false;
- foreach ($this->router->getRoutes() as $route) {
- if ($route->getName() === 'Neos.Flow :: Functional Test: HTTP - FooController') {
- $foundRoute = true;
- }
- }
- if (!$foundRoute) {
- self::markTestSkipped('In this distribution the Flow routes are not included into the global configuration.');
+ if (
+ ($this->objectManager->get(ConfigurationManager::class)
+ ->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, 'Neos.Flow.mvc.routes')['Neos.Flow'] ?? false) !== true
+ ) {
+ self::markTestSkipped(sprintf('In this distribution the Flow routes are not included into the global configuration and thus cannot be tested. Please set in Neos.Flow.mvc.routes "Neos.Flow": true.'));
}
$_SERVER = [
diff --git a/Neos.Flow/Tests/Functional/Mvc/AbstractControllerTest.php b/Neos.Flow/Tests/Functional/Mvc/AbstractControllerTest.php
index cf238db8db..facf6d3ef0 100644
--- a/Neos.Flow/Tests/Functional/Mvc/AbstractControllerTest.php
+++ b/Neos.Flow/Tests/Functional/Mvc/AbstractControllerTest.php
@@ -11,7 +11,6 @@
* source code.
*/
-use Neos\Flow\Mvc\Routing\Route;
use Neos\Flow\Tests\FunctionalTestCase;
class AbstractControllerTest extends FunctionalTestCase
@@ -27,18 +26,17 @@ class AbstractControllerTest extends FunctionalTestCase
protected function setUp(): void
{
parent::setUp();
-
- $route = new Route();
- $route->setName('AbstractControllerTest Route 1');
- $route->setUriPattern('test/mvc/abstractcontrollertesta/{@action}');
- $route->setDefaults([
- '@package' => 'Neos.Flow',
- '@subpackage' => 'Tests\Functional\Mvc\Fixtures',
- '@controller' => 'AbstractControllerTestA',
- '@format' =>'html'
- ]);
- $route->setAppendExceedingArguments(true);
- $this->router->addRoute($route);
+ $this->registerRoute(
+ 'AbstractControllerTest Route 1',
+ 'test/mvc/abstractcontrollertesta/{@action}',
+ [
+ '@package' => 'Neos.Flow',
+ '@subpackage' => 'Tests\Functional\Mvc\Fixtures',
+ '@controller' => 'AbstractControllerTestA',
+ '@format' =>'html'
+ ],
+ true
+ );
}
/**
diff --git a/Neos.Flow/Tests/Functional/Mvc/RoutingTest.php b/Neos.Flow/Tests/Functional/Mvc/RoutingTest.php
index 726aeddce6..814e8a2700 100644
--- a/Neos.Flow/Tests/Functional/Mvc/RoutingTest.php
+++ b/Neos.Flow/Tests/Functional/Mvc/RoutingTest.php
@@ -12,12 +12,14 @@
*/
use GuzzleHttp\Psr7\Uri;
+use Neos\Flow\Configuration\ConfigurationManager;
use Neos\Flow\Mvc\ActionRequest;
use Neos\Flow\Mvc\Exception\NoMatchingRouteException;
use Neos\Flow\Mvc\Routing\Dto\RouteParameters;
use Neos\Flow\Mvc\Routing\Dto\ResolveContext;
use Neos\Flow\Mvc\Routing\Dto\RouteContext;
use Neos\Flow\Mvc\Routing\Route;
+use Neos\Flow\Mvc\Routing\TestingRoutesProvider;
use Neos\Flow\Tests\Functional\Mvc\Fixtures\Controller\ActionControllerTestAController;
use Neos\Flow\Tests\Functional\Mvc\Fixtures\Controller\RoutingTestAController;
use Neos\Flow\Tests\FunctionalTestCase;
@@ -46,18 +48,11 @@ protected function setUp(): void
parent::setUp();
$this->serverRequestFactory = $this->objectManager->get(ServerRequestFactoryInterface::class);
- $foundRoute = false;
- /** @var $route Route */
- foreach ($this->router->getRoutes() as $route) {
- if ($route->getName() === 'Neos.Flow :: Functional Test: HTTP - FooController') {
- $foundRoute = true;
- break;
- }
- }
-
- if (!$foundRoute) {
- self::markTestSkipped('In this distribution the Flow routes are not included into the global configuration.');
- return;
+ if (
+ ($this->objectManager->get(ConfigurationManager::class)
+ ->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, 'Neos.Flow.mvc.routes')['Neos.Flow'] ?? false) !== true
+ ) {
+ self::markTestSkipped(sprintf('In this distribution the Flow routes are not included into the global configuration and thus cannot be tested. Please set in Neos.Flow.mvc.routes "Neos.Flow": true.'));
}
}
@@ -386,7 +381,7 @@ public function uriPathPrefixIsRespectedInRoute()
/**
* @test
*/
- public function explicitlySpecifiedRoutesOverruleConfiguredRoutes()
+ public function testingRoutesProviderCanRegisterOwnRoute()
{
$routeValues = [
'@package' => 'Neos.Flow',
@@ -395,24 +390,20 @@ public function explicitlySpecifiedRoutesOverruleConfiguredRoutes()
'@action' => 'index',
'@format' => 'html'
];
- $routesConfiguration = [
- [
- 'uriPattern' => 'custom/uri/pattern',
- 'defaults' => [
- '@package' => 'Neos.Flow',
- '@subpackage' => 'Tests\Functional\Http\Fixtures',
- '@controller' => 'Foo',
- '@action' => 'index',
- '@format' => 'html'
- ],
- ]
- ];
- $this->router->setRoutesConfiguration($routesConfiguration);
+
+ $this->objectManager->get(TestingRoutesProvider::class)->addRoute(Route::fromConfiguration([
+ 'uriPattern' => 'custom/uri/pattern',
+ 'defaults' => [
+ '@package' => 'Neos.Flow',
+ '@subpackage' => 'Tests\Functional\Http\Fixtures',
+ '@controller' => 'Foo',
+ '@action' => 'index',
+ '@format' => 'html'
+ ],
+ ]));
+
$baseUri = new Uri('http://localhost');
$actualResult = $this->router->resolve(new ResolveContext($baseUri, $routeValues, false, '', RouteParameters::createEmpty()));
self::assertSame('/custom/uri/pattern', (string)$actualResult);
-
- // reset router configuration for following tests
- $this->router->setRoutesConfiguration(null);
}
}
diff --git a/Neos.Flow/Tests/Functional/Mvc/UriBuilderTest.php b/Neos.Flow/Tests/Functional/Mvc/UriBuilderTest.php
index 397a976613..97cbcc1e30 100644
--- a/Neos.Flow/Tests/Functional/Mvc/UriBuilderTest.php
+++ b/Neos.Flow/Tests/Functional/Mvc/UriBuilderTest.php
@@ -126,7 +126,7 @@ public function whenLinkingToSameHostTheUrlIsAsExpectedNotContainingDoubleSlashe
*/
public function whenLinkingToRootOfSameHostTheUrlContainsASingleSlash()
{
- // NOTE: the route part handler here does not really match; as we link to the the route
+ // NOTE: the route part handler here does not really match; as we link to the route
// registered in "registerAbsoluteRoute()".
$this->registerSingleRoute(UriBuilderSetDomainRoutePartHandler::class);
// NOTE: the registered route is PREPENDED to the existing list; so we need to register the absolute route LAST as it should match FIRST.
diff --git a/Neos.Flow/Tests/Functional/Security/AuthenticationTest.php b/Neos.Flow/Tests/Functional/Security/AuthenticationTest.php
index 9d283088c4..7b54050948 100644
--- a/Neos.Flow/Tests/Functional/Security/AuthenticationTest.php
+++ b/Neos.Flow/Tests/Functional/Security/AuthenticationTest.php
@@ -12,7 +12,6 @@
*/
use GuzzleHttp\Psr7\Uri;
-use Neos\Flow\Mvc\Routing\Route;
use Neos\Flow\Security\AccountFactory;
use Neos\Flow\Security\AccountRepository;
use Neos\Flow\Tests\FunctionalTestCase;
@@ -56,57 +55,57 @@ protected function setUp(): void
$accountRepository->add($account3);
$this->persistenceManager->persistAll();
- $route = new Route();
- $route->setName('Functional Test - Security::Restricted');
- $route->setUriPattern('test/security/restricted(/{@action})');
- $route->setDefaults([
- '@package' => 'Neos.Flow',
- '@subpackage' => 'Tests\Functional\Security\Fixtures',
- '@controller' => 'Restricted',
- '@action' => 'public',
- '@format' =>'html'
- ]);
- $route->setAppendExceedingArguments(true);
- $this->router->addRoute($route);
-
- $route2 = new Route();
- $route2->setName('Functional Test - Security::Authentication');
- $route2->setUriPattern('test/security/authentication(/{@action})');
- $route2->setDefaults([
- '@package' => 'Neos.Flow',
- '@subpackage' => 'Tests\Functional\Security\Fixtures',
- '@controller' => 'Authentication',
- '@action' => 'authenticate',
- '@format' => 'html'
- ]);
- $route2->setAppendExceedingArguments(true);
- $this->router->addRoute($route2);
-
- $route3 = new Route();
- $route3->setName('Functional Test - Security::HttpBasicAuthentication');
- $route3->setUriPattern('test/security/authentication/httpbasic(/{@action})');
- $route3->setDefaults([
- '@package' => 'Neos.Flow',
- '@subpackage' => 'Tests\Functional\Security\Fixtures',
- '@controller' => 'HttpBasicTest',
- '@action' => 'authenticate',
- '@format' => 'html'
- ]);
- $route3->setAppendExceedingArguments(true);
- $this->router->addRoute($route3);
-
- $route4 = new Route();
- $route4->setName('Functional Test - Security::UsernamePasswordAuthentication');
- $route4->setUriPattern('test/security/authentication/usernamepassword(/{@action})');
- $route4->setDefaults([
- '@package' => 'Neos.Flow',
- '@subpackage' => 'Tests\Functional\Security\Fixtures',
- '@controller' => 'UsernamePasswordTest',
- '@action' => 'authenticate',
- '@format' => 'html'
- ]);
- $route4->setAppendExceedingArguments(true);
- $this->router->addRoute($route4);
+ $this->registerRoute(
+ 'Functional Test - Security::Restricted',
+ 'test/security/restricted(/{@action})',
+ [
+ '@package' => 'Neos.Flow',
+ '@subpackage' => 'Tests\Functional\Security\Fixtures',
+ '@controller' => 'Restricted',
+ '@action' => 'public',
+ '@format' =>'html'
+ ],
+ true
+ );
+
+ $this->registerRoute(
+ 'Functional Test - Security::Authentication',
+ 'test/security/authentication(/{@action})',
+ [
+ '@package' => 'Neos.Flow',
+ '@subpackage' => 'Tests\Functional\Security\Fixtures',
+ '@controller' => 'Authentication',
+ '@action' => 'authenticate',
+ '@format' => 'html'
+ ],
+ true
+ );
+
+ $this->registerRoute(
+ 'Functional Test - Security::HttpBasicAuthentication',
+ 'test/security/authentication/httpbasic(/{@action})',
+ [
+ '@package' => 'Neos.Flow',
+ '@subpackage' => 'Tests\Functional\Security\Fixtures',
+ '@controller' => 'HttpBasicTest',
+ '@action' => 'authenticate',
+ '@format' => 'html'
+ ],
+ true
+ );
+
+ $this->registerRoute(
+ 'Functional Test - Security::UsernamePasswordAuthentication',
+ 'test/security/authentication/usernamepassword(/{@action})',
+ [
+ '@package' => 'Neos.Flow',
+ '@subpackage' => 'Tests\Functional\Security\Fixtures',
+ '@controller' => 'UsernamePasswordTest',
+ '@action' => 'authenticate',
+ '@format' => 'html'
+ ],
+ true
+ );
$this->serverRequestFactory = $this->objectManager->get(ServerRequestFactoryInterface::class);
}
diff --git a/Neos.Flow/Tests/Functional/Session/SessionManagementTest.php b/Neos.Flow/Tests/Functional/Session/SessionManagementTest.php
index 726850b1aa..8f309970c7 100644
--- a/Neos.Flow/Tests/Functional/Session/SessionManagementTest.php
+++ b/Neos.Flow/Tests/Functional/Session/SessionManagementTest.php
@@ -11,7 +11,6 @@
* source code.
*/
-use Neos\Flow\Mvc\Routing\Route;
use Neos\Flow\Tests\FunctionalTestCase;
use Neos\Flow\Session;
@@ -24,17 +23,17 @@ protected function setUp(): void
{
parent::setUp();
- $route = new Route();
- $route->setName('Functional Test - Session::SessionTest');
- $route->setUriPattern('test/session(/{@action})');
- $route->setDefaults([
- '@package' => 'Neos.Flow',
- '@subpackage' => 'Tests\Functional\Session\Fixtures',
- '@controller' => 'SessionTest',
- '@action' => 'sessionStart',
- '@format' =>'html'
- ]);
- $this->router->addRoute($route);
+ $this->registerRoute(
+ 'Functional Test - Session::SessionTest',
+ 'test/session(/{@action})',
+ [
+ '@package' => 'Neos.Flow',
+ '@subpackage' => 'Tests\Functional\Session\Fixtures',
+ '@controller' => 'SessionTest',
+ '@action' => 'sessionStart',
+ '@format' =>'html'
+ ]
+ );
}
/**
diff --git a/Neos.Flow/Tests/FunctionalTestCase.php b/Neos.Flow/Tests/FunctionalTestCase.php
index 6af2923449..64b7347b82 100644
--- a/Neos.Flow/Tests/FunctionalTestCase.php
+++ b/Neos.Flow/Tests/FunctionalTestCase.php
@@ -14,6 +14,7 @@
use Neos\Flow\Configuration\ConfigurationManager;
use Neos\Flow\Core\Bootstrap;
use Neos\Flow\Annotations as Flow;
+use Neos\Flow\Mvc\Routing\TestingRoutesProvider;
use Neos\Flow\Security\Authentication\TokenAndProviderFactory;
use Neos\Http\Factories\ServerRequestFactory;
use Neos\Http\Factories\UriFactory;
@@ -263,6 +264,7 @@ protected function tearDown(): void
}
self::$bootstrap->getObjectManager()->forgetInstance(\Neos\Flow\Http\Client\InternalRequestEngine::class);
+ self::$bootstrap->getObjectManager()->get(TestingRoutesProvider::class)->reset();
self::$bootstrap->getObjectManager()->forgetInstance(\Neos\Flow\Persistence\Aspect\PersistenceMagicAspect::class);
$this->inject(self::$bootstrap->getObjectManager()->get(\Neos\Flow\ResourceManagement\ResourceRepository::class), 'addedResources', new \SplObjectStorage());
$this->inject(self::$bootstrap->getObjectManager()->get(\Neos\Flow\ResourceManagement\ResourceRepository::class), 'removedResources', new \SplObjectStorage());
@@ -369,7 +371,10 @@ protected function registerRoute($name, $uriPattern, array $defaults, $appendExc
if ($httpMethods !== null) {
$route->setHttpMethods($httpMethods);
}
- $this->router->addRoute($route);
+
+ $testingRoutesProvider = $this->objectManager->get(TestingRoutesProvider::class);
+ $testingRoutesProvider->addRoute($route);
+
return $route;
}
@@ -430,7 +435,6 @@ protected function setupHttp()
$this->browser = new \Neos\Flow\Http\Client\Browser();
$this->browser->setRequestEngine(new \Neos\Flow\Http\Client\InternalRequestEngine());
$this->router = $this->browser->getRequestEngine()->getRouter();
- $this->router->setRoutesConfiguration(null);
$serverRequestFactory = new ServerRequestFactory(new UriFactory());
$request = $serverRequestFactory->createServerRequest('GET', 'http://localhost/neos/flow/test');
diff --git a/Neos.Flow/Tests/Unit/Mvc/Routing/ConfigurationRoutesProviderTest.php b/Neos.Flow/Tests/Unit/Mvc/Routing/ConfigurationRoutesProviderTest.php
new file mode 100644
index 0000000000..08651da9ad
--- /dev/null
+++ b/Neos.Flow/Tests/Unit/Mvc/Routing/ConfigurationRoutesProviderTest.php
@@ -0,0 +1,77 @@
+createMock(ConfigurationManager::class);
+ $mockConfigurationManager->expects($this->never())->method('getConfiguration');
+ $configurationRoutesProvider = new Routing\ConfigurationRoutesProvider($mockConfigurationManager);
+ $this->assertInstanceOf(Routing\ConfigurationRoutesProvider::class, $configurationRoutesProvider);
+ }
+
+ /**
+ * @test
+ */
+ public function configurationFomConfigurationManagerIsHandled(): void
+ {
+ $configuration = [
+ [
+ 'name' => 'Route 1',
+ 'uriPattern' => 'route1/{@package}/{@controller}/{@action}(.{@format})',
+ 'defaults' => ['@format' => 'html']
+ ],
+ [
+ 'name' => 'Route 2',
+ 'uriPattern' => 'route2/{@package}/{@controller}/{@action}(.{@format})',
+ 'defaults' => ['@format' => 'html'],
+ 'appendExceedingArguments' => true,
+ 'cache' => ['lifetime' => 10000, 'tags' => ['foo', 'bar']]
+ ],
+ ];
+
+ $mockConfigurationManager = $this->createMock(ConfigurationManager::class);
+ $mockConfigurationManager->expects($this->once())->method('getConfiguration')->with(ConfigurationManager::CONFIGURATION_TYPE_ROUTES)->willReturn($configuration);
+
+ $expectedRoute1 = new Route();
+ $expectedRoute1->setName('Route 1');
+ $expectedRoute1->setUriPattern('route1/{@package}/{@controller}/{@action}(.{@format})');
+ $expectedRoute1->setDefaults(['@format' => 'html']);
+
+ $expectedRoute2 = new Route();
+ $expectedRoute2->setName('Route 2');
+ $expectedRoute2->setUriPattern('route2/{@package}/{@controller}/{@action}(.{@format})');
+ $expectedRoute2->setDefaults(['@format' => 'html']);
+ $expectedRoute2->setCacheLifetime(Routing\Dto\RouteLifetime::fromInt(10000));
+ $expectedRoute2->setCacheTags(Routing\Dto\RouteTags::createFromArray(['foo', 'bar']));
+ $expectedRoute2->setAppendExceedingArguments(true);
+
+ $expectedRoutes = Routes::create($expectedRoute1, $expectedRoute2);
+
+ $configurationRoutesProvider = new Routing\ConfigurationRoutesProvider($mockConfigurationManager);
+ $this->assertEquals($expectedRoutes, $configurationRoutesProvider->getRoutes());
+ }
+}
diff --git a/Neos.Flow/Tests/Unit/Mvc/Routing/RouterTest.php b/Neos.Flow/Tests/Unit/Mvc/Routing/RouterTest.php
index 3102cc8247..a793bf623b 100644
--- a/Neos.Flow/Tests/Unit/Mvc/Routing/RouterTest.php
+++ b/Neos.Flow/Tests/Unit/Mvc/Routing/RouterTest.php
@@ -11,9 +11,6 @@
* source code.
*/
-use GuzzleHttp\Psr7\Uri;
-use Neos\Flow\Configuration\ConfigurationManager;
-use Neos\Flow\Mvc\Exception\InvalidRouteSetupException;
use Neos\Flow\Mvc\Exception\NoMatchingRouteException;
use Neos\Flow\Mvc\Routing\Dto\RouteLifetime;
use Neos\Flow\Mvc\Routing\Dto\RouteParameters;
@@ -25,6 +22,8 @@
use Neos\Flow\Mvc\Routing\Router;
use Neos\Flow\Mvc\Routing\RouterCachingService;
use Neos\Flow\Mvc\ActionRequest;
+use Neos\Flow\Mvc\Routing\Routes;
+use Neos\Flow\Mvc\Routing\RoutesProviderInterface;
use Neos\Flow\Tests\UnitTestCase;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\UriInterface;
@@ -73,6 +72,10 @@ protected function setUp(): void
{
$this->router = $this->getAccessibleMock(Router::class, ['dummy']);
+ $mockRoutesProvider = $this->createMock(RoutesProviderInterface::class);
+ $mockRoutesProvider->method('getRoutes')->willReturn(Routes::empty());
+ $this->inject($this->router, 'routesProvider', $mockRoutesProvider);
+
$this->mockSystemLogger = $this->createMock(LoggerInterface::class);
$this->inject($this->router, 'logger', $this->mockSystemLogger);
@@ -99,101 +102,13 @@ protected function setUp(): void
$this->mockActionRequest = $this->getMockBuilder(ActionRequest::class)->disableOriginalConstructor()->getMock();
}
- /**
- * @test
- */
- public function resolveCallsCreateRoutesFromConfiguration()
- {
- /** @var Router|\PHPUnit\Framework\MockObject\MockObject $router */
- $router = $this->getAccessibleMock(Router::class, ['createRoutesFromConfiguration']);
- $this->inject($router, 'routerCachingService', $this->mockRouterCachingService);
- $this->inject($router, 'logger', $this->mockSystemLogger);
-
- // not saying anything, but seems better than to expect the exception we'd get otherwise
- /** @var Route|\PHPUnit\Framework\MockObject\MockObject $mockRoute */
- $mockRoute = $this->createMock(Route::class);
- $mockRoute->expects(self::once())->method('resolves')->willReturn(true);
- $mockRoute->expects(self::atLeastOnce())->method('getResolvedUriConstraints')->willReturn(UriConstraints::create());
-
- $this->inject($router, 'routes', [$mockRoute]);
-
- // this we actually want to know
- $router->expects(self::once())->method('createRoutesFromConfiguration');
- $router->resolve(new ResolveContext($this->mockBaseUri, [], false, '', RouteParameters::createEmpty()));
- }
-
- /**
- * @test
- */
- public function createRoutesFromConfigurationParsesTheGivenConfigurationAndBuildsRouteObjectsFromIt()
- {
- $routesConfiguration = [];
- $routesConfiguration['route1']['uriPattern'] = 'number1';
- $routesConfiguration['route2']['uriPattern'] = 'number2';
- $routesConfiguration['route3'] = [
- 'name' => 'route3',
- 'defaults' => ['foodefault'],
- 'routeParts' => ['fooroutepart'],
- 'uriPattern' => 'number3',
- 'toLowerCase' => false,
- 'appendExceedingArguments' => true,
- 'httpMethods' => ['POST', 'PUT']
- ];
-
- $this->router->setRoutesConfiguration($routesConfiguration);
- $this->router->_call('createRoutesFromConfiguration');
-
- /** @var Route[] $createdRoutes */
- $createdRoutes = $this->router->_get('routes');
-
- self::assertEquals('number1', $createdRoutes[0]->getUriPattern());
- self::assertTrue($createdRoutes[0]->isLowerCase());
- self::assertFalse($createdRoutes[0]->getAppendExceedingArguments());
- self::assertEquals('number2', $createdRoutes[1]->getUriPattern());
- self::assertFalse($createdRoutes[1]->hasHttpMethodConstraints());
- self::assertEquals([], $createdRoutes[1]->getHttpMethods());
- self::assertEquals('route3', $createdRoutes[2]->getName());
- self::assertEquals(['foodefault'], $createdRoutes[2]->getDefaults());
- self::assertEquals(['fooroutepart'], $createdRoutes[2]->getRoutePartsConfiguration());
- self::assertEquals('number3', $createdRoutes[2]->getUriPattern());
- self::assertFalse($createdRoutes[2]->isLowerCase());
- self::assertTrue($createdRoutes[2]->getAppendExceedingArguments());
- self::assertTrue($createdRoutes[2]->hasHttpMethodConstraints());
- self::assertEquals(['POST', 'PUT'], $createdRoutes[2]->getHttpMethods());
- }
-
- /**
- * @test
- */
- public function createRoutesFromConfigurationThrowsExceptionIfOnlySomeRoutesWithTheSameUriPatternHaveHttpMethodConstraints()
- {
- $this->expectException(InvalidRouteSetupException::class);
- $routesConfiguration = [
- [
- 'uriPattern' => 'somePattern'
- ],
- [
- 'uriPattern' => 'somePattern',
- 'httpMethods' => ['POST', 'PUT']
- ],
- ];
- shuffle($routesConfiguration);
- $this->router->setRoutesConfiguration($routesConfiguration);
- $this->router->_call('createRoutesFromConfiguration');
- }
-
/**
* @test
*/
public function resolveIteratesOverTheRegisteredRoutesAndReturnsTheResolvedUriConstraintsIfAny()
{
- /** @var Router|\PHPUnit\Framework\MockObject\MockObject $router */
- $router = $this->getAccessibleMock(Router::class, ['createRoutesFromConfiguration']);
- $this->inject($router, 'routerCachingService', $this->mockRouterCachingService);
- $this->inject($router, 'logger', $this->mockSystemLogger);
$routeValues = ['foo' => 'bar'];
$resolveContext = new ResolveContext($this->mockBaseUri, $routeValues, false, '', RouteParameters::createEmpty());
-
$route1 = $this->getMockBuilder(Route::class)->disableOriginalConstructor()->setMethods(['resolves'])->getMock();
$route1->expects(self::once())->method('resolves')->with($resolveContext)->willReturn(false);
@@ -204,12 +119,12 @@ public function resolveIteratesOverTheRegisteredRoutesAndReturnsTheResolvedUriCo
$route3 = $this->getMockBuilder(Route::class)->disableOriginalConstructor()->setMethods(['resolves'])->getMock();
$route3->expects(self::never())->method('resolves');
- $mockRoutes = [$route1, $route2, $route3];
+ $mockRoutesProvider = $this->createMock(RoutesProviderInterface::class);
+ $mockRoutesProvider->expects($this->once())->method("getRoutes")->willReturn(Routes::create($route1, $route2, $route3));
+ $this->inject($this->router, 'routesProvider', $mockRoutesProvider);
- $router->expects(self::once())->method('createRoutesFromConfiguration');
- $router->_set('routes', $mockRoutes);
+ $resolvedUri = $this->router->resolve($resolveContext);
- $resolvedUri = $router->resolve($resolveContext);
self::assertSame('/route2', $resolvedUri->getPath());
}
@@ -219,10 +134,6 @@ public function resolveIteratesOverTheRegisteredRoutesAndReturnsTheResolvedUriCo
public function resolveThrowsExceptionIfNoMatchingRouteWasFound()
{
$this->expectException(NoMatchingRouteException::class);
- /** @var Router|\PHPUnit\Framework\MockObject\MockObject $router */
- $router = $this->getAccessibleMock(Router::class, ['createRoutesFromConfiguration']);
- $this->inject($router, 'routerCachingService', $this->mockRouterCachingService);
- $this->inject($router, 'logger', $this->mockSystemLogger);
$route1 = $this->createMock(Route::class);
$route1->expects(self::once())->method('resolves')->willReturn(false);
@@ -230,11 +141,11 @@ public function resolveThrowsExceptionIfNoMatchingRouteWasFound()
$route2 = $this->createMock(Route::class);
$route2->expects(self::once())->method('resolves')->willReturn(false);
- $mockRoutes = [$route1, $route2];
-
- $router->_set('routes', $mockRoutes);
+ $mockRoutesProvider = $this->createMock(RoutesProviderInterface::class);
+ $mockRoutesProvider->expects($this->once())->method("getRoutes")->willReturn(Routes::create($route1, $route2));
+ $this->inject($this->router, 'routesProvider', $mockRoutesProvider);
- $router->resolve(new ResolveContext($this->mockBaseUri, [], false, '', RouteParameters::createEmpty()));
+ $this->router->resolve(new ResolveContext($this->mockBaseUri, [], false, '', RouteParameters::createEmpty()));
}
/**
@@ -250,12 +161,6 @@ public function getLastResolvedRouteReturnsNullByDefault()
*/
public function resolveSetsLastResolvedRoute()
{
- /** @var Router|\PHPUnit\Framework\MockObject\MockObject $router */
- $router = $this->getAccessibleMock(Router::class, ['createRoutesFromConfiguration']);
- $this->inject($router, 'routerCachingService', $this->mockRouterCachingService);
- $this->inject($router, 'logger', $this->mockSystemLogger);
-
-
$routeValues = ['some' => 'route values'];
$resolveContext = new ResolveContext($this->mockBaseUri, $routeValues, false, '', RouteParameters::createEmpty());
$mockRoute1 = $this->getMockBuilder(Route::class)->getMock();
@@ -264,11 +169,13 @@ public function resolveSetsLastResolvedRoute()
$mockRoute2->expects(self::once())->method('resolves')->with($resolveContext)->willReturn(true);
$mockRoute2->method('getResolvedUriConstraints')->willReturn(UriConstraints::create());
- $router->_set('routes', [$mockRoute1, $mockRoute2]);
+ $mockRoutesProvider = $this->createMock(RoutesProviderInterface::class);
+ $mockRoutesProvider->expects($this->once())->method("getRoutes")->willReturn(Routes::create($mockRoute1, $mockRoute2));
+ $this->inject($this->router, 'routesProvider', $mockRoutesProvider);
- $router->resolve($resolveContext);
+ $this->router->resolve($resolveContext);
- self::assertSame($mockRoute2, $router->getLastResolvedRoute());
+ self::assertSame($mockRoute2, $this->router->getLastResolvedRoute());
}
/**
@@ -276,22 +183,20 @@ public function resolveSetsLastResolvedRoute()
*/
public function resolveReturnsCachedResolvedUriIfFoundInCache()
{
- /** @var Router|\PHPUnit\Framework\MockObject\MockObject $router */
- $router = $this->getAccessibleMock(Router::class, ['createRoutesFromConfiguration']);
- $this->inject($router, 'routerCachingService', $this->mockRouterCachingService);
- $this->inject($router, 'logger', $this->mockSystemLogger);
-
$routeValues = ['some' => 'route values'];
$mockCachedResolvedUriConstraints = UriConstraints::create()->withPath('cached/path');
$resolveContext = new ResolveContext($this->mockBaseUri, $routeValues, false, '', RouteParameters::createEmpty());
- $mockRouterCachingService = $this->getMockBuilder(RouterCachingService::class)->getMock();
- $mockRouterCachingService->method('getCachedResolvedUriConstraints')->with($resolveContext)->willReturn($mockCachedResolvedUriConstraints);
- $router->_set('routerCachingService', $mockRouterCachingService);
+ $mockRouterCachingService = $this->createMock(RouterCachingService::class);
+ $mockRouterCachingService->expects($this->once())->method('getCachedResolvedUriConstraints')->with($resolveContext)->willReturn($mockCachedResolvedUriConstraints);
+ $this->inject($this->router, 'routerCachingService', $mockRouterCachingService);
- $router->expects(self::never())->method('createRoutesFromConfiguration');
- self::assertSame('/cached/path', (string)$router->resolve($resolveContext));
+ $mockRoutesProvider = $this->createMock(RoutesProviderInterface::class);
+ $mockRoutesProvider->expects($this->never())->method("getRoutes");
+ $this->inject($this->router, 'routesProvider', $mockRoutesProvider);
+
+ self::assertSame('/cached/path', (string)$this->router->resolve($resolveContext));
}
/**
@@ -299,11 +204,6 @@ public function resolveReturnsCachedResolvedUriIfFoundInCache()
*/
public function resolveStoresResolvedUriPathInCacheIfNotFoundInCache()
{
- /** @var Router|\PHPUnit\Framework\MockObject\MockObject $router */
- $router = $this->getAccessibleMock(Router::class, ['createRoutesFromConfiguration']);
- $this->inject($router, 'routerCachingService', $this->mockRouterCachingService);
- $this->inject($router, 'logger', $this->mockSystemLogger);
-
$routeValues = ['some' => 'route values'];
$mockResolvedUriConstraints = UriConstraints::create()->withPath('resolved/path');
@@ -315,10 +215,16 @@ public function resolveStoresResolvedUriPathInCacheIfNotFoundInCache()
$mockRoute2->expects(self::once())->method('resolves')->with($resolveContext)->willReturn(true);
$mockRoute2->expects(self::atLeastOnce())->method('getResolvedUriConstraints')->willReturn($mockResolvedUriConstraints);
- $router->_set('routes', [$mockRoute1, $mockRoute2]);
+ $mockRoutesProvider = $this->createMock(RoutesProviderInterface::class);
+ $mockRoutesProvider->expects($this->once())->method("getRoutes")->willReturn(Routes::create($mockRoute1, $mockRoute2));
+ $this->inject($this->router, 'routesProvider', $mockRoutesProvider);
+
+ $mockRouterCachingService = $this->createMock(RouterCachingService::class);
+ $mockRouterCachingService->expects(self::once())->method('getCachedResolvedUriConstraints')->with($resolveContext)->willReturn(false);
+ $mockRouterCachingService->expects(self::once())->method('storeResolvedUriConstraints')->with($resolveContext, $mockResolvedUriConstraints, null, null);
+ $this->inject($this->router, 'routerCachingService', $mockRouterCachingService);
- $this->mockRouterCachingService->expects(self::once())->method('storeResolvedUriConstraints')->with($resolveContext, $mockResolvedUriConstraints, null, null);
- self::assertSame('/resolved/path', (string)$router->resolve($resolveContext));
+ self::assertSame('/resolved/path', (string)$this->router->resolve($resolveContext));
}
/**
@@ -326,11 +232,6 @@ public function resolveStoresResolvedUriPathInCacheIfNotFoundInCache()
*/
public function resolveStoresResolvedUriPathInCacheIfNotFoundInCachWithTagsAndCacheLifetime()
{
- /** @var Router|\PHPUnit\Framework\MockObject\MockObject $router */
- $router = $this->getAccessibleMock(Router::class, ['createRoutesFromConfiguration']);
- $this->inject($router, 'routerCachingService', $this->mockRouterCachingService);
- $this->inject($router, 'logger', $this->mockSystemLogger);
-
$routeValues = ['some' => 'route values'];
$mockResolvedUriConstraints = UriConstraints::create()->withPath('resolved/path');
@@ -345,10 +246,17 @@ public function resolveStoresResolvedUriPathInCacheIfNotFoundInCachWithTagsAndCa
$mockRoute2->expects(self::atLeastOnce())->method('getResolvedUriConstraints')->willReturn($mockResolvedUriConstraints);
$mockRoute2->expects(self::atLeastOnce())->method('getResolvedTags')->willReturn($routeTags);
$mockRoute2->expects(self::atLeastOnce())->method('getResolvedLifetime')->willReturn($routeLifetime);
- $router->_set('routes', [$mockRoute1, $mockRoute2]);
- $this->mockRouterCachingService->expects(self::once())->method('storeResolvedUriConstraints')->with($resolveContext, $mockResolvedUriConstraints, $routeTags, $routeLifetime);
- self::assertSame('/resolved/path', (string)$router->resolve($resolveContext));
+ $mockRoutesProvider = $this->createMock(RoutesProviderInterface::class);
+ $mockRoutesProvider->expects($this->once())->method("getRoutes")->willReturn(Routes::create($mockRoute1, $mockRoute2));
+ $this->inject($this->router, 'routesProvider', $mockRoutesProvider);
+
+ $mockRouterCachingService = $this->createMock(RouterCachingService::class);
+ $mockRouterCachingService->expects($this->once())->method('getCachedResolvedUriConstraints')->with($resolveContext)->willReturn(false);
+ $mockRouterCachingService->expects($this->once())->method('storeResolvedUriConstraints')->with($resolveContext, $mockResolvedUriConstraints)->willReturn(false);
+ $this->inject($this->router, 'routerCachingService', $mockRouterCachingService);
+
+ self::assertSame('/resolved/path', (string)$this->router->resolve($resolveContext));
}
/**
@@ -356,20 +264,14 @@ public function resolveStoresResolvedUriPathInCacheIfNotFoundInCachWithTagsAndCa
*/
public function routeReturnsCachedMatchResultsIfFoundInCache()
{
- /** @var Router|\PHPUnit\Framework\MockObject\MockObject $router */
- $router = $this->getAccessibleMock(Router::class, ['createRoutesFromConfiguration']);
- $this->inject($router, 'logger', $this->mockSystemLogger);
-
$routeContext = new RouteContext($this->mockHttpRequest, RouteParameters::createEmpty());
$cachedMatchResults = ['some' => 'cached results'];
- $mockRouterCachingService = $this->getMockBuilder(RouterCachingService::class)->getMock();
- $mockRouterCachingService->expects(self::once())->method('getCachedMatchResults')->with($routeContext)->willReturn($cachedMatchResults);
- $this->inject($router, 'routerCachingService', $mockRouterCachingService);
-
- $router->expects(self::never())->method('createRoutesFromConfiguration');
+ $mockRouterCachingService = $this->createMock(RouterCachingService::class);
+ $mockRouterCachingService->method('getCachedMatchResults')->with($routeContext)->willReturn($cachedMatchResults);
+ $this->inject($this->router, 'routerCachingService', $mockRouterCachingService);
- self::assertSame($cachedMatchResults, $router->route($routeContext));
+ self::assertSame($cachedMatchResults, $this->router->route($routeContext));
}
/**
@@ -377,11 +279,6 @@ public function routeReturnsCachedMatchResultsIfFoundInCache()
*/
public function routeStoresMatchResultsInCacheIfNotFoundInCache()
{
- /** @var Router|\PHPUnit\Framework\MockObject\MockObject $router */
- $router = $this->getAccessibleMock(Router::class, ['createRoutesFromConfiguration']);
- $this->inject($router, 'routerCachingService', $this->mockRouterCachingService);
- $this->inject($router, 'logger', $this->mockSystemLogger);
-
$matchResults = ['some' => 'match results'];
$routeContext = new RouteContext($this->mockHttpRequest, RouteParameters::createEmpty());
@@ -391,11 +288,16 @@ public function routeStoresMatchResultsInCacheIfNotFoundInCache()
$mockRoute2->expects(self::once())->method('matches')->with($routeContext)->willReturn(true);
$mockRoute2->expects(self::once())->method('getMatchResults')->willReturn($matchResults);
- $router->_set('routes', [$mockRoute1, $mockRoute2]);
+ $mockRoutesProvider = $this->createMock(RoutesProviderInterface::class);
+ $mockRoutesProvider->expects(self::once())->method("getRoutes")->willReturn(Routes::create($mockRoute1, $mockRoute2));
+ $this->inject($this->router, 'routesProvider', $mockRoutesProvider);
- $this->mockRouterCachingService->expects(self::once())->method('storeMatchResults')->with($routeContext, $matchResults, null, null);
+ $mockRouterCachingService = $this->createMock(RouterCachingService::class);
+ $mockRouterCachingService->expects(self::once())->method('getCachedMatchResults')->with($routeContext)->willReturn(false);
+ $mockRouterCachingService->expects(self::once())->method('storeMatchResults')->with($routeContext, $matchResults, null, null);
+ $this->inject($this->router, 'routerCachingService', $mockRouterCachingService);
- self::assertSame($matchResults, $router->route($routeContext));
+ self::assertSame($matchResults, $this->router->route($routeContext));
}
/**
@@ -403,11 +305,6 @@ public function routeStoresMatchResultsInCacheIfNotFoundInCache()
*/
public function routeStoresMatchResultsInCacheIfNotFoundInCacheWithTagsAndCacheLifetime()
{
- /** @var Router|\PHPUnit\Framework\MockObject\MockObject $router */
- $router = $this->getAccessibleMock(Router::class, ['createRoutesFromConfiguration']);
- $this->inject($router, 'routerCachingService', $this->mockRouterCachingService);
- $this->inject($router, 'logger', $this->mockSystemLogger);
-
$matchResults = ['some' => 'match results'];
$routeContext = new RouteContext($this->mockHttpRequest, RouteParameters::createEmpty());
$routeTags = RouteTags::createFromArray(['foo', 'bar']);
@@ -421,11 +318,16 @@ public function routeStoresMatchResultsInCacheIfNotFoundInCacheWithTagsAndCacheL
$mockRoute2->expects(self::once())->method('getMatchedTags')->willReturn($routeTags);
$mockRoute2->expects(self::once())->method('getMatchedLifetime')->willReturn($routeLifetime);
- $router->_set('routes', [$mockRoute1, $mockRoute2]);
+ $mockRoutesProvider = $this->createMock(RoutesProviderInterface::class);
+ $mockRoutesProvider->expects(self::once())->method("getRoutes")->willReturn(Routes::create($mockRoute1, $mockRoute2));
+ $this->inject($this->router, 'routesProvider', $mockRoutesProvider);
- $this->mockRouterCachingService->expects(self::once())->method('storeMatchResults')->with($routeContext, $matchResults, $routeTags, $routeLifetime);
+ $mockRouterCachingService = $this->createMock(RouterCachingService::class);
+ $mockRouterCachingService->expects(self::once())->method('getCachedMatchResults')->with($routeContext)->willReturn(false);
+ $mockRouterCachingService->expects(self::once())->method('storeMatchResults')->with($routeContext, $matchResults, $routeTags, $routeLifetime);
+ $this->inject($this->router, 'routerCachingService', $mockRouterCachingService);
- self::assertSame($matchResults, $router->route($routeContext));
+ self::assertSame($matchResults, $this->router->route($routeContext));
}
/**
@@ -441,11 +343,6 @@ public function getLastMatchedRouteReturnsNullByDefault()
*/
public function routeSetsLastMatchedRoute()
{
- /** @var Router|\PHPUnit\Framework\MockObject\MockObject $router */
- $router = $this->getAccessibleMock(Router::class, ['createRoutesFromConfiguration']);
- $this->inject($router, 'routerCachingService', $this->mockRouterCachingService);
- $this->inject($router, 'logger', $this->mockSystemLogger);
-
$routeContext = new RouteContext($this->mockHttpRequest, RouteParameters::createEmpty());
$mockRoute1 = $this->getMockBuilder(Route::class)->getMock();
@@ -454,85 +351,12 @@ public function routeSetsLastMatchedRoute()
$mockRoute2->expects(self::once())->method('matches')->with($routeContext)->willReturn(true);
$mockRoute2->expects(self::once())->method('getMatchResults')->willReturn([]);
- $router->_set('routes', [$mockRoute1, $mockRoute2]);
+ $mockRoutesProvider = $this->createMock(RoutesProviderInterface::class);
+ $mockRoutesProvider->expects($this->once())->method("getRoutes")->willReturn(Routes::create($mockRoute1, $mockRoute2));
+ $this->inject($this->router, 'routesProvider', $mockRoutesProvider);
- $router->route($routeContext);
+ $this->router->route($routeContext);
- self::assertSame($mockRoute2, $router->getLastMatchedRoute());
- }
-
- /**
- * @test
- */
- public function routeLoadsRoutesConfigurationFromConfigurationManagerIfNotSetExplicitly()
- {
- /** @var Router|\PHPUnit\Framework\MockObject\MockObject $router */
- $router = $this->getAccessibleMock(Router::class, ['dummy']);
- $this->inject($router, 'routerCachingService', $this->mockRouterCachingService);
- $this->inject($router, 'logger', $this->mockSystemLogger);
-
- $uri = new Uri('http://localhost/');
- $this->mockHttpRequest->expects(self::any())->method('getUri')->willReturn($uri);
-
- $routesConfiguration = [
- [
- 'uriPattern' => 'some/uri/pattern',
- ],
- [
- 'uriPattern' => 'some/other/uri/pattern',
- ],
- ];
-
- /** @var ConfigurationManager|\PHPUnit\Framework\MockObject\MockObject $mockConfigurationManager */
- $mockConfigurationManager = $this->getMockBuilder(ConfigurationManager::class)->disableOriginalConstructor()->getMock();
- $mockConfigurationManager->expects(self::once())->method('getConfiguration')->with(ConfigurationManager::CONFIGURATION_TYPE_ROUTES)->willReturn($routesConfiguration);
- $this->inject($router, 'configurationManager', $mockConfigurationManager);
-
- try {
- $router->route(new RouteContext($this->mockHttpRequest, RouteParameters::createEmpty()));
- } catch (NoMatchingRouteException $exception) {
- }
-
- $routes = $router->getRoutes();
- $firstRoute = reset($routes);
- self::assertSame('some/uri/pattern', $firstRoute->getUriPattern());
- }
-
- /**
- * @test
- */
- public function routeDoesNotLoadRoutesConfigurationFromConfigurationManagerIfItsSetExplicitly()
- {
- /** @var Router|\PHPUnit\Framework\MockObject\MockObject $router */
- $router = $this->getAccessibleMock(Router::class, ['dummy']);
- $this->inject($router, 'routerCachingService', $this->mockRouterCachingService);
- $this->inject($router, 'logger', $this->mockSystemLogger);
-
- $uri = new Uri('http://localhost/');
- $this->mockHttpRequest->expects(self::any())->method('getUri')->willReturn($uri);
-
- $routesConfiguration = [
- [
- 'uriPattern' => 'some/uri/pattern',
- ],
- [
- 'uriPattern' => 'some/other/uri/pattern',
- ],
- ];
-
- /** @var ConfigurationManager|\PHPUnit\Framework\MockObject\MockObject $mockConfigurationManager */
- $mockConfigurationManager = $this->getMockBuilder(ConfigurationManager::class)->disableOriginalConstructor()->getMock();
- $mockConfigurationManager->expects(self::never())->method('getConfiguration');
- $this->inject($router, 'configurationManager', $mockConfigurationManager);
-
- $router->setRoutesConfiguration($routesConfiguration);
- try {
- $router->route(new RouteContext($this->mockHttpRequest, RouteParameters::createEmpty()));
- } catch (NoMatchingRouteException $exception) {
- }
-
- $routes = $router->getRoutes();
- $firstRoute = reset($routes);
- self::assertSame('some/uri/pattern', $firstRoute->getUriPattern());
+ self::assertSame($mockRoute2, $this->router->getLastMatchedRoute());
}
}
diff --git a/Neos.Flow/Tests/Unit/Mvc/Routing/RoutesTest.php b/Neos.Flow/Tests/Unit/Mvc/Routing/RoutesTest.php
new file mode 100644
index 0000000000..86bc766926
--- /dev/null
+++ b/Neos.Flow/Tests/Unit/Mvc/Routing/RoutesTest.php
@@ -0,0 +1,166 @@
+assertSame([], iterator_to_array($routes));
+ }
+
+ /**
+ * @test
+ */
+ public function fromConfigurationWorksAsExpected(): void
+ {
+ $route1 = new Route();
+ $route1->setName('Route 1');
+ $route1->setUriPattern('route1/{@package}/{@controller}/{@action}(.{@format})');
+ $route1->setDefaults(['@format' => 'html']);
+
+ $route2 = new Route();
+ $route2->setName('Route 2');
+ $route2->setDefaults(['@format' => 'html']);
+ $route2->setUriPattern('route2/{@package}/{@controller}/{@action}(.{@format})');
+ $route2->setLowerCase(false);
+ $route2->setAppendExceedingArguments(true);
+ $route2->setRoutePartsConfiguration(
+ [
+ '@controller' => [
+ 'handler' => 'MyRoutePartHandler'
+ ]
+ ]
+ );
+ $route2->setHttpMethods(['PUT']);
+ $route2->setCacheTags(Routing\Dto\RouteTags::createFromArray(['foo', 'bar']));
+ $route2->setCacheLifetime(Routing\Dto\RouteLifetime::fromInt(10000));
+
+ $configuration = [
+ [
+ 'name' => 'Route 1',
+ 'uriPattern' => 'route1/{@package}/{@controller}/{@action}(.{@format})',
+ 'defaults' => ['@format' => 'html']
+ ],
+ [
+ 'name' => 'Route 2',
+ 'defaults' => ['@format' => 'html'],
+ 'uriPattern' => 'route2/{@package}/{@controller}/{@action}(.{@format})',
+ 'toLowerCase' => false,
+ 'appendExceedingArguments' => true,
+ 'routeParts' => [
+ '@controller' => [
+ 'handler' => 'MyRoutePartHandler'
+ ]
+ ],
+ 'httpMethods' => ['PUT'],
+ 'cache' => [
+ 'lifetime' => 10000,
+ 'tags' => ['foo', 'bar']
+ ],
+ ],
+ ];
+
+ $routes = Routes::fromConfiguration($configuration);
+
+ $this->assertEquals(
+ [$route1, $route2],
+ iterator_to_array($routes)
+ );
+ }
+
+ /**
+ * @test
+ */
+ public function mergeRoutes(): void
+ {
+ $route1 = new Route();
+ $route1->setName("Route 1");
+
+ $route2 = new Route();
+ $route2->setName("Route 2");
+
+ $routes = Routes::create($route1)->merge(Routes::create($route2));
+
+ $this->assertSame([$route1, $route2], iterator_to_array($routes));
+ }
+
+ /**
+ * @test
+ */
+ public function createRoutesFromConfigurationThrowsExceptionIfOnlySomeRoutesWithTheSameUriPatternHaveHttpMethodConstraints()
+ {
+ // multiple routes with the uriPattern and "httpMethods" option
+ $this->expectException(InvalidRouteSetupException::class);
+ $routesConfiguration = [
+ [
+ 'uriPattern' => 'somePattern'
+ ],
+ [
+ 'uriPattern' => 'somePattern',
+ 'httpMethods' => ['POST', 'PUT']
+ ],
+ ];
+ shuffle($routesConfiguration);
+ Routes::fromConfiguration($routesConfiguration);
+ }
+
+ /**
+ * @test
+ */
+ public function createRoutesFromConfigurationParsesTheGivenConfigurationAndBuildsRouteObjectsFromIt()
+ {
+ $routesConfiguration = [];
+ $routesConfiguration['route1']['uriPattern'] = 'number1';
+ $routesConfiguration['route2']['uriPattern'] = 'number2';
+ $routesConfiguration['route3'] = [
+ 'name' => 'route3',
+ 'defaults' => ['foodefault'],
+ 'routeParts' => ['fooroutepart'],
+ 'uriPattern' => 'number3',
+ 'toLowerCase' => false,
+ 'appendExceedingArguments' => true,
+ 'httpMethods' => ['POST', 'PUT']
+ ];
+
+ /** @var Route[] $createdRoutes */
+ $createdRoutes = iterator_to_array(Routes::fromConfiguration($routesConfiguration));
+
+ self::assertEquals('number1', $createdRoutes[0]->getUriPattern());
+ self::assertTrue($createdRoutes[0]->isLowerCase());
+ self::assertFalse($createdRoutes[0]->getAppendExceedingArguments());
+ self::assertEquals('number2', $createdRoutes[1]->getUriPattern());
+ self::assertFalse($createdRoutes[1]->hasHttpMethodConstraints());
+ self::assertEquals([], $createdRoutes[1]->getHttpMethods());
+ self::assertEquals('route3', $createdRoutes[2]->getName());
+ self::assertEquals(['foodefault'], $createdRoutes[2]->getDefaults());
+ self::assertEquals(['fooroutepart'], $createdRoutes[2]->getRoutePartsConfiguration());
+ self::assertEquals('number3', $createdRoutes[2]->getUriPattern());
+ self::assertFalse($createdRoutes[2]->isLowerCase());
+ self::assertTrue($createdRoutes[2]->getAppendExceedingArguments());
+ self::assertTrue($createdRoutes[2]->hasHttpMethodConstraints());
+ self::assertEquals(['POST', 'PUT'], $createdRoutes[2]->getHttpMethods());
+ }
+}
diff --git a/Neos.Flow/Tests/Unit/Mvc/Routing/RoutingMiddlewareTest.php b/Neos.Flow/Tests/Unit/Mvc/Routing/RoutingMiddlewareTest.php
index e7f8a58e3e..273cd38085 100644
--- a/Neos.Flow/Tests/Unit/Mvc/Routing/RoutingMiddlewareTest.php
+++ b/Neos.Flow/Tests/Unit/Mvc/Routing/RoutingMiddlewareTest.php
@@ -12,11 +12,12 @@
*/
use GuzzleHttp\Psr7\Response;
-use Neos\Flow\Configuration\ConfigurationManager;
use Neos\Flow\Http\ServerRequestAttributes;
use Neos\Flow\Mvc\Routing\Dto\RouteParameters;
use Neos\Flow\Mvc\Routing\Dto\RouteContext;
use Neos\Flow\Mvc\Routing\Router;
+use Neos\Flow\Mvc\Routing\Routes;
+use Neos\Flow\Mvc\Routing\RoutesProviderInterface;
use Neos\Flow\Mvc\Routing\RoutingMiddleware;
use Neos\Flow\Tests\UnitTestCase;
use Psr\Http\Message\ServerRequestInterface;
@@ -38,11 +39,6 @@ class RoutingMiddlewareTest extends UnitTestCase
*/
protected $mockRouter;
- /**
- * @var ConfigurationManager|\PHPUnit\Framework\MockObject\MockObject
- */
- protected $mockConfigurationManager;
-
/**
* @var RequestHandlerInterface|\PHPUnit\Framework\MockObject\MockObject
*/
@@ -66,9 +62,10 @@ protected function setUp(): void
{
$this->routingMiddleware = new RoutingMiddleware();
- $this->mockRouter = $this->getMockBuilder(Router::class)->getMock();
- $this->mockConfigurationManager = $this->getMockBuilder(ConfigurationManager::class)->disableOriginalConstructor()->getMock();
- $this->inject($this->mockRouter, 'configurationManager', $this->mockConfigurationManager);
+ $this->mockRouter = $this->createMock(Router::class);
+ $mockRoutesProvider = $this->createMock(RoutesProviderInterface::class);
+ $mockRoutesProvider->method('getRoutes')->willReturn(Routes::empty());
+ $this->inject($this->mockRouter, 'routesProvider', $mockRoutesProvider);
$this->inject($this->routingMiddleware, 'router', $this->mockRouter);
diff --git a/Neos.FluidAdaptor/Tests/Functional/Core/WidgetTest.php b/Neos.FluidAdaptor/Tests/Functional/Core/WidgetTest.php
index 93dcbc4813..e6367dd320 100644
--- a/Neos.FluidAdaptor/Tests/Functional/Core/WidgetTest.php
+++ b/Neos.FluidAdaptor/Tests/Functional/Core/WidgetTest.php
@@ -11,7 +11,6 @@
* source code.
*/
-use Neos\Flow\Mvc\Routing\Route;
use Neos\Flow\Tests\FunctionalTestCase;
/**
@@ -26,17 +25,17 @@ protected function setUp(): void
{
parent::setUp();
- $route = new Route();
- $route->setName('WidgetTest');
- $route->setUriPattern('test/widget/{@controller}(/{@action})');
- $route->setDefaults([
- '@package' => 'Neos.FluidAdaptor',
- '@subpackage' => 'Tests\Functional\Core\Fixtures',
- '@action' => 'index',
- '@format' => 'html'
- ]);
- $route->setAppendExceedingArguments(true);
- $this->router->addRoute($route);
+ $this->registerRoute(
+ 'WidgetTest',
+ 'test/widget/{@controller}(/{@action})',
+ [
+ '@package' => 'Neos.FluidAdaptor',
+ '@subpackage' => 'Tests\Functional\Core\Fixtures',
+ '@action' => 'index',
+ '@format' => 'html'
+ ],
+ true
+ );
}
/**
diff --git a/Neos.FluidAdaptor/Tests/Functional/Form/FormObjectsTest.php b/Neos.FluidAdaptor/Tests/Functional/Form/FormObjectsTest.php
index 518f646d26..48eb7ed61f 100644
--- a/Neos.FluidAdaptor/Tests/Functional/Form/FormObjectsTest.php
+++ b/Neos.FluidAdaptor/Tests/Functional/Form/FormObjectsTest.php
@@ -11,7 +11,6 @@
* source code.
*/
-use Neos\Flow\Mvc\Routing\Route;
/**
* Testcase for Standalone View
@@ -37,17 +36,18 @@ protected function setUp(): void
{
parent::setUp();
- $route = new Route();
- $route->setUriPattern('test/fluid/formobjects(/{@action})');
- $route->setDefaults([
- '@package' => 'Neos.FluidAdaptor',
- '@subpackage' => 'Tests\Functional\Form\Fixtures',
- '@controller' => 'Form',
- '@action' => 'index',
- '@format' => 'html'
- ]);
- $route->setAppendExceedingArguments(true);
- $this->router->addRoute($route);
+ $this->registerRoute(
+ 'Form Test Route',
+ 'test/fluid/formobjects(/{@action})',
+ [
+ '@package' => 'Neos.FluidAdaptor',
+ '@subpackage' => 'Tests\Functional\Form\Fixtures',
+ '@controller' => 'Form',
+ '@action' => 'index',
+ '@format' => 'html'
+ ],
+ true
+ );
}
/**