diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d26232d7c4..156c09764d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -152,9 +152,16 @@ jobs: user: 'root' password: 'neos' dbname: 'flow_functional_testing' + + # see Neos\Flow\Tests\Functional\Mvc\RoutingTest mvc: routes: - 'Neos.Flow': TRUE + "Neos.Flow:TestingAttributes": + providerFactory: Neos\Flow\Mvc\Routing\AttributeRoutesProviderFactory + providerOptions: + classNames: + - Neos\Flow\Tests\Functional\Mvc\Fixtures\Controller\*Controller + "Neos.Flow": true EOF echo "Running in context '$FLOW_CONTEXT'" ./flow configuration:show @@ -196,9 +203,16 @@ jobs: charset: 'utf8' defaultTableOptions: charset: 'utf8' + + # see Neos\Flow\Tests\Functional\Mvc\RoutingTest mvc: routes: - 'Neos.Flow': TRUE + "Neos.Flow:TestingAttributes": + providerFactory: Neos\Flow\Mvc\Routing\AttributeRoutesProviderFactory + providerOptions: + classNames: + - Neos\Flow\Tests\Functional\Mvc\Fixtures\Controller\*Controller + "Neos.Flow": true EOF - name: Run unit tests (PGSQL) diff --git a/Neos.Flow/Classes/Mvc/Routing/AttributeRoutesProvider.php b/Neos.Flow/Classes/Mvc/Routing/AttributeRoutesProvider.php index 039215da9c..13158df81b 100644 --- a/Neos.Flow/Classes/Mvc/Routing/AttributeRoutesProvider.php +++ b/Neos.Flow/Classes/Mvc/Routing/AttributeRoutesProvider.php @@ -152,13 +152,13 @@ public static function compileRoutesConfiguration(ObjectManagerInterface $object 'uriPattern' => $annotation->uriPattern, 'httpMethods' => $annotation->httpMethods, 'defaults' => Arrays::arrayMergeRecursiveOverrule( - [ + array_filter([ '@package' => $controllerPackageKey, '@subpackage' => $subPackage, '@controller' => $controller, '@action' => $action, '@format' => 'html' - ], + ], fn ($value) => $value !== null), $annotation->defaults ?? [] ) ]; diff --git a/Neos.Flow/Tests/Functional/Mvc/Fixtures/Controller/RoutingAnnotationTestBController.php b/Neos.Flow/Tests/Functional/Mvc/Fixtures/Controller/RoutingAnnotationTestBController.php new file mode 100644 index 0000000000..8fd3ae3891 --- /dev/null +++ b/Neos.Flow/Tests/Functional/Mvc/Fixtures/Controller/RoutingAnnotationTestBController.php @@ -0,0 +1,29 @@ +serverRequestFactory = $this->objectManager->get(ServerRequestFactoryInterface::class); + $routeSettings = $this->objectManager->get(ConfigurationManager::class) + ->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, 'Neos.Flow.mvc.routes'); + if ( - ($this->objectManager->get(ConfigurationManager::class) - ->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, 'Neos.Flow.mvc.routes')['Neos.Flow'] ?? false) !== true + ($routeSettings['Neos.Flow'] ?? false) !== true + || !is_array($routeSettings['Neos.Flow:TestingAttributes'] ?? null) ) { - 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.')); + self::markTestSkipped(<<<'EOF' + In this distribution the Neos.Flow or Flow\Annotation routes are not included into the global configuration and thus cannot be tested: + + Neos: + Flow: + mvc: + routes: + "Neos.Flow:TestingAttributes": + providerFactory: Neos\Flow\Mvc\Routing\AttributeRoutesProviderFactory + providerOptions: + classNames: + - Neos\Flow\Tests\Functional\Mvc\Fixtures\Controller\*Controller + "Neos.Flow": true + EOF); } } @@ -98,6 +115,19 @@ public function httpMethodsAreRespectedForPostRequests() self::assertEquals('second', $actionRequest->getControllerActionName()); } + /** + * @test + */ + public function routeToControllerWithAnnotatedAction() + { + $requestUri = 'http://localhost/neos/flow/test/annotation'; + $request = $this->serverRequestFactory->createServerRequest('GET', new Uri($requestUri)); + $matchResults = $this->router->route(new RouteContext($request, RouteParameters::createEmpty())); + $actionRequest = $this->createActionRequest($request, $matchResults); + self::assertEquals(RoutingAnnotationTestBController::class, $actionRequest->getControllerObjectName()); + self::assertEquals('annotated', $actionRequest->getControllerActionName()); + } + /** * Data provider for routeTests() * @@ -360,6 +390,24 @@ public function routerInitializesRoutesIfNotInjectedExplicitly() self::assertSame('/neos/flow/test/http/foo', (string)$actualResult); } + /** + * @test + */ + public function routerMatchesRouteFromAnnotation() + { + $routeValues = [ + '@package' => 'Neos.Flow', + '@subpackage' => 'Tests\Functional\Mvc\Fixtures', + '@controller' => 'RoutingAnnotationTestB', + '@action' => 'annotated', + '@format' => 'html' + ]; + $baseUri = new Uri('http://localhost'); + $actualResult = $this->router->resolve(new ResolveContext($baseUri, $routeValues, false, '', RouteParameters::createEmpty())); + + self::assertSame('/neos/flow/test/annotation', (string)$actualResult); + } + /** * @test */ diff --git a/Neos.Flow/Tests/Unit/Mvc/Routing/AttributeRoutesProviderTest.php b/Neos.Flow/Tests/Unit/Mvc/Routing/AttributeRoutesProviderTest.php index 5daf788efc..c8bc6e70f8 100644 --- a/Neos.Flow/Tests/Unit/Mvc/Routing/AttributeRoutesProviderTest.php +++ b/Neos.Flow/Tests/Unit/Mvc/Routing/AttributeRoutesProviderTest.php @@ -110,7 +110,6 @@ class ExampleController extends \Neos\Flow\Mvc\Controller\ActionController { $expectedRoute1->setUriPattern('my/path'); $expectedRoute1->setDefaults([ '@package' => 'Vendor.Example', - '@subpackage' => null, '@controller' => 'Example', '@action' => 'special', '@format' => 'html', @@ -121,7 +120,6 @@ class ExampleController extends \Neos\Flow\Mvc\Controller\ActionController { $expectedRoute2->setUriPattern('my/other/path'); $expectedRoute2->setDefaults([ '@package' => 'Vendor.Example', - '@subpackage' => null, '@controller' => 'Example', '@action' => 'special', '@format' => 'html',