From 08193796b7ecf810b39b32dd34c17553b2f9e29f Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Sun, 20 Oct 2024 14:11:36 +0200 Subject: [PATCH 1/5] TASK: Introduce full behat test for FrontendNodeController --- .../Bootstrap/Features/NodeCreation.php | 2 +- .../Classes/Domain/Service/FusionService.php | 12 ++ .../Features/Bootstrap/DispatcherTrait.php | 103 ++++++++++++++++ .../Features/Bootstrap/FeatureContext.php | 1 + .../DefaultFusionRendering.feature | 113 ++++++++++++++++++ 5 files changed, 230 insertions(+), 1 deletion(-) create mode 100644 Neos.Neos/Tests/Behavior/Features/Bootstrap/DispatcherTrait.php create mode 100644 Neos.Neos/Tests/Behavior/Features/FrontendNodeController/DefaultFusionRendering.feature diff --git a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/Features/NodeCreation.php b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/Features/NodeCreation.php index d20ebdab535..5f4a1b8c699 100644 --- a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/Features/NodeCreation.php +++ b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/Features/NodeCreation.php @@ -205,7 +205,7 @@ public function theFollowingCreateNodeAggregateWithNodeCommandsAreExecuted(Table if (isset($row['tetheredDescendantNodeAggregateIds'])) { $command = $command->withTetheredDescendantNodeAggregateIds(NodeAggregateIdsByNodePaths::fromJsonString($row['tetheredDescendantNodeAggregateIds'])); } - if (isset($row['nodeName'])) { + if (!empty($row['nodeName'])) { $command = $command->withNodeName(NodeName::fromString($row['nodeName'])); } $this->currentContentRepository->handle($command); diff --git a/Neos.Neos/Classes/Domain/Service/FusionService.php b/Neos.Neos/Classes/Domain/Service/FusionService.php index 528b8315a31..9573ef9befe 100644 --- a/Neos.Neos/Classes/Domain/Service/FusionService.php +++ b/Neos.Neos/Classes/Domain/Service/FusionService.php @@ -44,6 +44,16 @@ class FusionService */ protected $fusionConfigurationCache; + private ?FusionSourceCodeCollection $additionalFusionSourceCode = null; + + /** + * @deprecated fixme!!! + */ + public function unsafeSetAdditionalFusionSourceCodeToThisSingleton(string $additionalFusionSourceCode) + { + $this->additionalFusionSourceCode = FusionSourceCodeCollection::fromString($additionalFusionSourceCode); + } + public function createFusionConfigurationFromSite(Site $site): FusionConfiguration { return $this->fusionConfigurationCache->cacheFusionConfigurationBySite($site, function () use ($site) { @@ -56,6 +66,8 @@ public function createFusionConfigurationFromSite(Site $site): FusionConfigurati ) ->union( FusionSourceCodeCollection::tryFromPackageRootFusion($siteResourcesPackageKey) + )->union( + $this->additionalFusionSourceCode ?? FusionSourceCodeCollection::empty() ) ); }); diff --git a/Neos.Neos/Tests/Behavior/Features/Bootstrap/DispatcherTrait.php b/Neos.Neos/Tests/Behavior/Features/Bootstrap/DispatcherTrait.php new file mode 100644 index 00000000000..56a39fa4e9e --- /dev/null +++ b/Neos.Neos/Tests/Behavior/Features/Bootstrap/DispatcherTrait.php @@ -0,0 +1,103 @@ + $className + * + * @return T + */ + abstract private function getObject(string $className): object; + + /** + * @BeforeScenario + */ + public function setupDispatcherTest(): void + { + $this->getObject(ContentCache::class)->flush(); + $this->response = null; + } + + /** + * @When the sites Fusion code is: + */ + public function iHaveTheFollowingFusionCodeForTheSite(PyStringNode $fusionCode) + { + $this->getObject( + FusionService::class + )->unsafeSetAdditionalFusionSourceCodeToThisSingleton( + $fusionCode->getRaw() + ); + // $fakeFusionService = new class ($original) extends \Neos\Neos\Domain\Service\FusionService + // { + // public function __construct( + // private \Neos\Neos\Domain\Service\FusionService $original, + // private \Neos\Fusion\Core\FusionSourceCode $additionalFusion + // ) { + // } + // public function createFusionConfigurationFromSite(\Neos\Neos\Domain\Model\Site $site): \Neos\Fusion\Core\FusionConfiguration + // { + // $this->original->createFusionConfigurationFromSite($site)-> ... doest work + // } + // }; + } + + /** + * @When I dispatch the following request :requestUri + */ + public function iDispatchTheFollowingRequest(string $requestUri) + { + $httpRequest = $this->getObject(ServerRequestFactoryInterface::class)->createServerRequest('GET', $requestUri); + + $this->response = $this->getObject(\Neos\Flow\Http\Middleware\MiddlewaresChain::class)->handle( + $httpRequest + ); + } + + /** + * @Then I expect the following response header: + */ + public function iExpectTheFollowingResponseHeader(PyStringNode $expectedResult): void + { + Assert::assertNotNull($this->response); + Assert::assertSame($expectedResult->getRaw(), $this->response->getBody()->getContents()); + } + + /** + * @Then I expect the following response: + */ + public function iExpectTheFollowingResponse(PyStringNode $expectedResult): void + { + Assert::assertNotNull($this->response); + Assert::assertEquals($expectedResult->getRaw(), str_replace("\r\n", "\n", Message::toString($this->response))); + } +} diff --git a/Neos.Neos/Tests/Behavior/Features/Bootstrap/FeatureContext.php b/Neos.Neos/Tests/Behavior/Features/Bootstrap/FeatureContext.php index 9d06ce491eb..b02048f437e 100644 --- a/Neos.Neos/Tests/Behavior/Features/Bootstrap/FeatureContext.php +++ b/Neos.Neos/Tests/Behavior/Features/Bootstrap/FeatureContext.php @@ -39,6 +39,7 @@ class FeatureContext implements BehatContext use CRBehavioralTestsSubjectProvider; use RoutingTrait; use MigrationsTrait; + use DispatcherTrait; use FusionTrait; use ContentCacheTrait; diff --git a/Neos.Neos/Tests/Behavior/Features/FrontendNodeController/DefaultFusionRendering.feature b/Neos.Neos/Tests/Behavior/Features/FrontendNodeController/DefaultFusionRendering.feature new file mode 100644 index 00000000000..cb7689bf7cb --- /dev/null +++ b/Neos.Neos/Tests/Behavior/Features/FrontendNodeController/DefaultFusionRendering.feature @@ -0,0 +1,113 @@ +@flowEntities +Feature: Test the default Fusion rendering for a request + Background: + Given using no content dimensions + And using the following node types: + """yaml + 'Neos.ContentRepository:Root': {} + 'Neos.Neos:ContentCollection': {} + 'Neos.Neos:Content': {} + 'Neos.Neos:Sites': + superTypes: + 'Neos.ContentRepository:Root': true + 'Neos.Neos:Document': + properties: + title: + type: string + uriPathSegment: + type: string + 'Neos.Neos:Site': + superTypes: + 'Neos.Neos:Document': true + childNodes: + main: + type: 'Neos.Neos:ContentCollection' + 'Neos.Neos:Test.DocumentType': + superTypes: + 'Neos.Neos:Document': true + childNodes: + main: + type: 'Neos.Neos:ContentCollection' + 'Neos.Neos:Test.ContentType': + superTypes: + 'Neos.Neos:Content': true + properties: + text: + type: string + """ + And using identifier "default", I define a content repository + And I am in content repository "default" + When the command CreateRootWorkspace is executed with payload: + | Key | Value | + | workspaceName | "live" | + | newContentStreamId | "cs-identifier" | + And I am in workspace "live" and dimension space point {} + And the command CreateRootNodeAggregateWithNode is executed with payload: + | Key | Value | + | nodeAggregateId | "root" | + | nodeTypeName | "Neos.Neos:Sites" | + And the following CreateNodeAggregateWithNode commands are executed: + | nodeAggregateId | parentNodeAggregateId | nodeTypeName | initialPropertyValues | tetheredDescendantNodeAggregateIds | nodeName | + | a | root | Neos.Neos:Site | {"title": "Node a"} | {} | a | + | a1 | a | Neos.Neos:Test.DocumentType | {"uriPathSegment": "a1", "title": "Node a1"} | {"main": "a-tetherton" } | | + | a1a1 | a-tetherton | Neos.Neos:Test.ContentType | {"text": "my first text"} | {} | | + | a1a2 | a-tetherton | Neos.Neos:Test.ContentType | {"text": "my second text"} | {} | | + And A site exists for node name "a" and domain "http://localhost" + And the sites configuration is: + """yaml + Neos: + Neos: + sites: + 'a': + preset: default + uriPathSuffix: '' + contentDimensions: + resolver: + factoryClassName: Neos\Neos\FrontendRouting\DimensionResolution\Resolver\NoopResolverFactory + """ + + Scenario: Default output + And the sites Fusion code is: + """fusion + prototype(Neos.Neos:Test.DocumentType) < prototype(Neos.Neos:Page) { + body { + content = Neos.Fusion:Component { + renderer = afx` + {String.chr(10)}title: {node.properties.title} + {String.chr(10)}children: + {String.chr(10)} + ` + } + } + } + prototype(Neos.Neos:Test.ContentType) < prototype(Neos.Neos:ContentComponent) { + text = Neos.Neos:Editable { + property = 'text' + } + + renderer = afx` + [{props.text}] + ` + } + """ + + When I dispatch the following request "/a1" + Then I expect the following response: + """ + HTTP/1.1 200 OK + Content-Type: text/html + X-Flow-Powered: Flow/dev Neos/dev + Content-Length: 486 + + + + Node a1 + title: Node a1 + children:
[my first text][my second text]
+ + """ From 58fceb8aa61a3029f2cd21807fcaaf6ced665b4f Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Mon, 21 Oct 2024 11:24:14 +0200 Subject: [PATCH 2/5] WIP --- .../Tests/Behavior/Features/Bootstrap/DispatcherTrait.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Neos.Neos/Tests/Behavior/Features/Bootstrap/DispatcherTrait.php b/Neos.Neos/Tests/Behavior/Features/Bootstrap/DispatcherTrait.php index 56a39fa4e9e..fa9a6d68f0e 100644 --- a/Neos.Neos/Tests/Behavior/Features/Bootstrap/DispatcherTrait.php +++ b/Neos.Neos/Tests/Behavior/Features/Bootstrap/DispatcherTrait.php @@ -69,6 +69,11 @@ public function iHaveTheFollowingFusionCodeForTheSite(PyStringNode $fusionCode) // $this->original->createFusionConfigurationFromSite($site)-> ... doest work // } // }; + + // doesnt work as the packages base path cannot change ... we would need to create an actual package in /Packages as rescanPackages() will be invoked + // vfsStream::setup('packages'); + // $this->getObject(\Neos\Flow\Package\PackageManager::class)->createPackage('Vendor.Site', [], 'vfs://packages/'); + // file_put_contents('resource://Vendor.Site/Private/Fusion/Root.fusion', $fusionCode->getRaw()); } /** From 7f509682079d538233b64b13a12ef8cb07db5513 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Tue, 22 Oct 2024 10:50:20 +0200 Subject: [PATCH 3/5] WIP: Introduce `FusionAutoIncludeHandler` to be mocked during testing --- .../Core/FusionSourceCodeCollection.php | 6 --- .../Service/FusionAutoIncludeHandler.php | 15 +++++++ .../Classes/Domain/Service/FusionService.php | 27 +++++------- .../Service/FusionSourceCodeFactory.php | 12 ++---- .../ResourceFusionAutoIncludeHandler.php | 22 ++++++++++ .../TestingFusionAutoIncludeHandler.php | 43 +++++++++++++++++++ Neos.Neos/Configuration/Objects.yaml | 3 ++ Neos.Neos/Configuration/Testing/Objects.yaml | 2 + .../Features/Bootstrap/DispatcherTrait.php | 36 +++++++++++++--- .../Features/Bootstrap/RoutingTrait.php | 5 ++- .../DefaultFusionRendering.feature | 4 +- 11 files changed, 134 insertions(+), 41 deletions(-) create mode 100644 Neos.Neos/Classes/Domain/Service/FusionAutoIncludeHandler.php create mode 100644 Neos.Neos/Classes/Domain/Service/ResourceFusionAutoIncludeHandler.php create mode 100644 Neos.Neos/Classes/Testing/TestingFusionAutoIncludeHandler.php create mode 100644 Neos.Neos/Configuration/Testing/Objects.yaml diff --git a/Neos.Fusion/Classes/Core/FusionSourceCodeCollection.php b/Neos.Fusion/Classes/Core/FusionSourceCodeCollection.php index 54218f62f23..7b04aa1c5dd 100644 --- a/Neos.Fusion/Classes/Core/FusionSourceCodeCollection.php +++ b/Neos.Fusion/Classes/Core/FusionSourceCodeCollection.php @@ -52,12 +52,6 @@ public static function tryFromFilePath(string $filePath): self return self::fromFilePath($filePath); } - public static function tryFromPackageRootFusion(string $packageKey): self - { - $fusionPathAndFilename = sprintf('resource://%s/Private/Fusion/Root.fusion', $packageKey); - return self::tryFromFilePath($fusionPathAndFilename); - } - public static function empty(): self { return new self(); diff --git a/Neos.Neos/Classes/Domain/Service/FusionAutoIncludeHandler.php b/Neos.Neos/Classes/Domain/Service/FusionAutoIncludeHandler.php new file mode 100644 index 00000000000..b167eff1bdf --- /dev/null +++ b/Neos.Neos/Classes/Domain/Service/FusionAutoIncludeHandler.php @@ -0,0 +1,15 @@ +additionalFusionSourceCode = FusionSourceCodeCollection::fromString($additionalFusionSourceCode); - } + protected $fusionAutoIncludeHandler; public function createFusionConfigurationFromSite(Site $site): FusionConfiguration { return $this->fusionConfigurationCache->cacheFusionConfigurationBySite($site, function () use ($site) { $siteResourcesPackageKey = $site->getSiteResourcesPackageKey(); - return $this->fusionParser->parseFromSource( - $this->fusionSourceCodeFactory->createFromNodeTypeDefinitions($site->getConfiguration()->contentRepositoryId) - ->union( - $this->fusionSourceCodeFactory->createFromAutoIncludes() - ) - ->union( - FusionSourceCodeCollection::tryFromPackageRootFusion($siteResourcesPackageKey) - )->union( - $this->additionalFusionSourceCode ?? FusionSourceCodeCollection::empty() - ) + $this->fusionAutoIncludeHandler->loadFusionFromPackage( + $siteResourcesPackageKey, + $this->fusionSourceCodeFactory->createFromNodeTypeDefinitions($site->getConfiguration()->contentRepositoryId) + ->union( + $this->fusionSourceCodeFactory->createFromAutoIncludes() + ) + ) ); }); } diff --git a/Neos.Neos/Classes/Domain/Service/FusionSourceCodeFactory.php b/Neos.Neos/Classes/Domain/Service/FusionSourceCodeFactory.php index 948994053cb..657d2ef94ff 100644 --- a/Neos.Neos/Classes/Domain/Service/FusionSourceCodeFactory.php +++ b/Neos.Neos/Classes/Domain/Service/FusionSourceCodeFactory.php @@ -36,6 +36,9 @@ class FusionSourceCodeFactory #[Flow\InjectConfiguration("fusion.autoInclude")] protected array $autoIncludeConfiguration = []; + #[Flow\Inject] + protected FusionAutoIncludeHandler $fusionAutoIncludeHandler; + #[Flow\Inject] protected ContentRepositoryRegistry $contentRepositoryRegistry; @@ -50,19 +53,12 @@ public function createFromAutoIncludes(): FusionSourceCodeCollection $sourcecode = FusionSourceCodeCollection::empty(); foreach (array_keys($this->packageManager->getAvailablePackages()) as $packageKey) { if (isset($this->autoIncludeConfiguration[$packageKey]) && $this->autoIncludeConfiguration[$packageKey] === true) { - $sourcecode = $sourcecode->union( - FusionSourceCodeCollection::tryFromPackageRootFusion($packageKey) - ); + $sourcecode = $this->fusionAutoIncludeHandler->loadFusionFromPackage($packageKey, $sourcecode); } } return $sourcecode; } - public function createFromSite(Site $site): FusionSourceCodeCollection - { - return FusionSourceCodeCollection::tryFromPackageRootFusion($site->getSiteResourcesPackageKey()); - } - /** * Generate Fusion prototype definitions for all node types * diff --git a/Neos.Neos/Classes/Domain/Service/ResourceFusionAutoIncludeHandler.php b/Neos.Neos/Classes/Domain/Service/ResourceFusionAutoIncludeHandler.php new file mode 100644 index 00000000000..38365f9ea68 --- /dev/null +++ b/Neos.Neos/Classes/Domain/Service/ResourceFusionAutoIncludeHandler.php @@ -0,0 +1,22 @@ +union( + FusionSourceCodeCollection::tryFromFilePath(sprintf('resource://%s/Private/Fusion/Root.fusion', $packageKey)) + ); + } +} diff --git a/Neos.Neos/Classes/Testing/TestingFusionAutoIncludeHandler.php b/Neos.Neos/Classes/Testing/TestingFusionAutoIncludeHandler.php new file mode 100644 index 00000000000..356f1aa318b --- /dev/null +++ b/Neos.Neos/Classes/Testing/TestingFusionAutoIncludeHandler.php @@ -0,0 +1,43 @@ +overrideHandler = $overrideHandler; + } + + public function resetOverride(): void + { + $this->overrideHandler = null; + } + + public function loadFusionFromPackage(string $packageKey, FusionSourceCodeCollection $sourceCodeCollection): FusionSourceCodeCollection + { + if ($this->overrideHandler !== null) { + return $this->overrideHandler->loadFusionFromPackage($packageKey, $sourceCodeCollection); + } else { + return $this->resourceFusionAutoIncludeHandler->loadFusionFromPackage($packageKey, $sourceCodeCollection); + } + } +} diff --git a/Neos.Neos/Configuration/Objects.yaml b/Neos.Neos/Configuration/Objects.yaml index be5cd60dd91..20da5dd98aa 100644 --- a/Neos.Neos/Configuration/Objects.yaml +++ b/Neos.Neos/Configuration/Objects.yaml @@ -20,6 +20,9 @@ Neos\Neos\Domain\Service\FusionConfigurationCache: 2: setting: "Neos.Neos.fusion.enableObjectTreeCache" +Neos\Neos\Domain\Service\FusionAutoIncludeHandler: + className: Neos\Neos\Domain\Service\ResourceFusionAutoIncludeHandler + Neos\Fusion\Core\Cache\RuntimeContentCache: properties: serializer: diff --git a/Neos.Neos/Configuration/Testing/Objects.yaml b/Neos.Neos/Configuration/Testing/Objects.yaml new file mode 100644 index 00000000000..faa9e83523a --- /dev/null +++ b/Neos.Neos/Configuration/Testing/Objects.yaml @@ -0,0 +1,2 @@ +Neos\Neos\Domain\Service\FusionAutoIncludeHandler: + className: Neos\Neos\Testing\TestingFusionAutoIncludeHandler diff --git a/Neos.Neos/Tests/Behavior/Features/Bootstrap/DispatcherTrait.php b/Neos.Neos/Tests/Behavior/Features/Bootstrap/DispatcherTrait.php index fa9a6d68f0e..9293d79559d 100644 --- a/Neos.Neos/Tests/Behavior/Features/Bootstrap/DispatcherTrait.php +++ b/Neos.Neos/Tests/Behavior/Features/Bootstrap/DispatcherTrait.php @@ -44,18 +44,42 @@ abstract private function getObject(string $className): object; public function setupDispatcherTest(): void { $this->getObject(ContentCache::class)->flush(); + $this->getObject(\Neos\Neos\Testing\TestingFusionAutoIncludeHandler::class)->resetOverride(); $this->response = null; } /** - * @When the sites Fusion code is: + * @When the Fusion code for package :package is: */ - public function iHaveTheFollowingFusionCodeForTheSite(PyStringNode $fusionCode) + public function iHaveTheFollowingFusionCodeForTheSite(PyStringNode $fusionCode, string $package) { - $this->getObject( - FusionService::class - )->unsafeSetAdditionalFusionSourceCodeToThisSingleton( - $fusionCode->getRaw() + $this->getObject(\Neos\Neos\Testing\TestingFusionAutoIncludeHandler::class)->overrideHandler( + new class ($package, $fusionCode->getRaw(), $this->getObject(\Neos\Neos\Domain\Service\ResourceFusionAutoIncludeHandler::class)) implements \Neos\Neos\Domain\Service\FusionAutoIncludeHandler + { + public function __construct( + private string $package, + private string $fusionCode, + private \Neos\Neos\Domain\Service\ResourceFusionAutoIncludeHandler $defaultHandler, + ) { + } + + public function loadFusionFromPackage( + string $packageKey, + \Neos\Fusion\Core\FusionSourceCodeCollection $sourceCodeCollection + ): \Neos\Fusion\Core\FusionSourceCodeCollection { + if ($packageKey === $this->package) { + return $sourceCodeCollection->union( + \Neos\Fusion\Core\FusionSourceCodeCollection::fromString( + $this->fusionCode + ) + ); + } elseif (in_array($packageKey, ['Neos.Neos', 'Neos.Fusion'])) { + return $this->defaultHandler->loadFusionFromPackage($packageKey, $sourceCodeCollection); + } else { + return $sourceCodeCollection; + } + } + } ); // $fakeFusionService = new class ($original) extends \Neos\Neos\Domain\Service\FusionService // { diff --git a/Neos.Neos/Tests/Behavior/Features/Bootstrap/RoutingTrait.php b/Neos.Neos/Tests/Behavior/Features/Bootstrap/RoutingTrait.php index 3eb2dc1a93a..f5232d55a10 100644 --- a/Neos.Neos/Tests/Behavior/Features/Bootstrap/RoutingTrait.php +++ b/Neos.Neos/Tests/Behavior/Features/Bootstrap/RoutingTrait.php @@ -82,14 +82,15 @@ abstract private function getObject(string $className): object; /** * @Given A site exists for node name :nodeName * @Given A site exists for node name :nodeName and domain :domain + * @Given A site exists for node name :nodeName and domain :domain and package :package */ - public function theSiteExists(string $nodeName, string $domain = null): void + public function theSiteExists(string $nodeName, string $domain = null, string $package = null): void { $siteRepository = $this->getObject(SiteRepository::class); $persistenceManager = $this->getObject(PersistenceManagerInterface::class); $site = new Site($nodeName); - $site->setSiteResourcesPackageKey('Neos.Neos'); + $site->setSiteResourcesPackageKey($package ?: 'Neos.Neos'); $site->setState(Site::STATE_ONLINE); $siteRepository->add($site); diff --git a/Neos.Neos/Tests/Behavior/Features/FrontendNodeController/DefaultFusionRendering.feature b/Neos.Neos/Tests/Behavior/Features/FrontendNodeController/DefaultFusionRendering.feature index cb7689bf7cb..8e2d8dfcd12 100644 --- a/Neos.Neos/Tests/Behavior/Features/FrontendNodeController/DefaultFusionRendering.feature +++ b/Neos.Neos/Tests/Behavior/Features/FrontendNodeController/DefaultFusionRendering.feature @@ -52,7 +52,7 @@ Feature: Test the default Fusion rendering for a request | a1 | a | Neos.Neos:Test.DocumentType | {"uriPathSegment": "a1", "title": "Node a1"} | {"main": "a-tetherton" } | | | a1a1 | a-tetherton | Neos.Neos:Test.ContentType | {"text": "my first text"} | {} | | | a1a2 | a-tetherton | Neos.Neos:Test.ContentType | {"text": "my second text"} | {} | | - And A site exists for node name "a" and domain "http://localhost" + And A site exists for node name "a" and domain "http://localhost" and package "Vendor.Site" And the sites configuration is: """yaml Neos: @@ -67,7 +67,7 @@ Feature: Test the default Fusion rendering for a request """ Scenario: Default output - And the sites Fusion code is: + And the Fusion code for package "Vendor.Site" is: """fusion prototype(Neos.Neos:Test.DocumentType) < prototype(Neos.Neos:Page) { body { From 6b218f233828d97b655be6d9d59ecef52bf41d8e Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Sat, 26 Oct 2024 10:33:33 +0200 Subject: [PATCH 4/5] TASK: Simplify TestingFusionAutoIncludeHandler --- .../TestingFusionAutoIncludeHandler.php | 37 +++-- .../Features/Bootstrap/DispatcherTrait.php | 132 ------------------ .../Features/Bootstrap/FeatureContext.php | 2 +- .../Bootstrap/FrontendNodeControllerTrait.php | 92 ++++++++++++ 4 files changed, 120 insertions(+), 143 deletions(-) delete mode 100644 Neos.Neos/Tests/Behavior/Features/Bootstrap/DispatcherTrait.php create mode 100644 Neos.Neos/Tests/Behavior/Features/Bootstrap/FrontendNodeControllerTrait.php diff --git a/Neos.Neos/Classes/Testing/TestingFusionAutoIncludeHandler.php b/Neos.Neos/Classes/Testing/TestingFusionAutoIncludeHandler.php index 356f1aa318b..94e2dc76cb3 100644 --- a/Neos.Neos/Classes/Testing/TestingFusionAutoIncludeHandler.php +++ b/Neos.Neos/Classes/Testing/TestingFusionAutoIncludeHandler.php @@ -18,26 +18,43 @@ class TestingFusionAutoIncludeHandler implements FusionAutoIncludeHandler /** * @Flow\Inject */ - protected ResourceFusionAutoIncludeHandler $resourceFusionAutoIncludeHandler; + protected ResourceFusionAutoIncludeHandler $defaultHandler; - private ?FusionAutoIncludeHandler $overrideHandler = null; + /** + * @var array + */ + private array $overriddenIncludes = []; + + public function setIncludeFusionPackage(string $packageKey): void + { + $this->overriddenIncludes[$packageKey] = true; + } - public function overrideHandler(FusionAutoIncludeHandler $overrideHandler): void + public function setFusionForPackage(string $packageKey, FusionSourceCodeCollection $packageFusionSource): void { - $this->overrideHandler = $overrideHandler; + $this->overriddenIncludes[$packageKey] = $packageFusionSource; } - public function resetOverride(): void + public function reset(): void { - $this->overrideHandler = null; + $this->overriddenIncludes = []; } + /** + * If no override is set via {@see setIncludeFusionPackage} or {@see setFusionForPackage} we load all the fusion via the default implementation + */ public function loadFusionFromPackage(string $packageKey, FusionSourceCodeCollection $sourceCodeCollection): FusionSourceCodeCollection { - if ($this->overrideHandler !== null) { - return $this->overrideHandler->loadFusionFromPackage($packageKey, $sourceCodeCollection); - } else { - return $this->resourceFusionAutoIncludeHandler->loadFusionFromPackage($packageKey, $sourceCodeCollection); + if ($this->overriddenIncludes === []) { + return $this->defaultHandler->loadFusionFromPackage($packageKey, $sourceCodeCollection); + } + $override = $this->overriddenIncludes[$packageKey] ?? null; + if ($override === null) { + return $sourceCodeCollection; + } + if ($override === true) { + return $this->defaultHandler->loadFusionFromPackage($packageKey, $sourceCodeCollection); } + return $sourceCodeCollection->union($override); } } diff --git a/Neos.Neos/Tests/Behavior/Features/Bootstrap/DispatcherTrait.php b/Neos.Neos/Tests/Behavior/Features/Bootstrap/DispatcherTrait.php deleted file mode 100644 index 9293d79559d..00000000000 --- a/Neos.Neos/Tests/Behavior/Features/Bootstrap/DispatcherTrait.php +++ /dev/null @@ -1,132 +0,0 @@ - $className - * - * @return T - */ - abstract private function getObject(string $className): object; - - /** - * @BeforeScenario - */ - public function setupDispatcherTest(): void - { - $this->getObject(ContentCache::class)->flush(); - $this->getObject(\Neos\Neos\Testing\TestingFusionAutoIncludeHandler::class)->resetOverride(); - $this->response = null; - } - - /** - * @When the Fusion code for package :package is: - */ - public function iHaveTheFollowingFusionCodeForTheSite(PyStringNode $fusionCode, string $package) - { - $this->getObject(\Neos\Neos\Testing\TestingFusionAutoIncludeHandler::class)->overrideHandler( - new class ($package, $fusionCode->getRaw(), $this->getObject(\Neos\Neos\Domain\Service\ResourceFusionAutoIncludeHandler::class)) implements \Neos\Neos\Domain\Service\FusionAutoIncludeHandler - { - public function __construct( - private string $package, - private string $fusionCode, - private \Neos\Neos\Domain\Service\ResourceFusionAutoIncludeHandler $defaultHandler, - ) { - } - - public function loadFusionFromPackage( - string $packageKey, - \Neos\Fusion\Core\FusionSourceCodeCollection $sourceCodeCollection - ): \Neos\Fusion\Core\FusionSourceCodeCollection { - if ($packageKey === $this->package) { - return $sourceCodeCollection->union( - \Neos\Fusion\Core\FusionSourceCodeCollection::fromString( - $this->fusionCode - ) - ); - } elseif (in_array($packageKey, ['Neos.Neos', 'Neos.Fusion'])) { - return $this->defaultHandler->loadFusionFromPackage($packageKey, $sourceCodeCollection); - } else { - return $sourceCodeCollection; - } - } - } - ); - // $fakeFusionService = new class ($original) extends \Neos\Neos\Domain\Service\FusionService - // { - // public function __construct( - // private \Neos\Neos\Domain\Service\FusionService $original, - // private \Neos\Fusion\Core\FusionSourceCode $additionalFusion - // ) { - // } - // public function createFusionConfigurationFromSite(\Neos\Neos\Domain\Model\Site $site): \Neos\Fusion\Core\FusionConfiguration - // { - // $this->original->createFusionConfigurationFromSite($site)-> ... doest work - // } - // }; - - // doesnt work as the packages base path cannot change ... we would need to create an actual package in /Packages as rescanPackages() will be invoked - // vfsStream::setup('packages'); - // $this->getObject(\Neos\Flow\Package\PackageManager::class)->createPackage('Vendor.Site', [], 'vfs://packages/'); - // file_put_contents('resource://Vendor.Site/Private/Fusion/Root.fusion', $fusionCode->getRaw()); - } - - /** - * @When I dispatch the following request :requestUri - */ - public function iDispatchTheFollowingRequest(string $requestUri) - { - $httpRequest = $this->getObject(ServerRequestFactoryInterface::class)->createServerRequest('GET', $requestUri); - - $this->response = $this->getObject(\Neos\Flow\Http\Middleware\MiddlewaresChain::class)->handle( - $httpRequest - ); - } - - /** - * @Then I expect the following response header: - */ - public function iExpectTheFollowingResponseHeader(PyStringNode $expectedResult): void - { - Assert::assertNotNull($this->response); - Assert::assertSame($expectedResult->getRaw(), $this->response->getBody()->getContents()); - } - - /** - * @Then I expect the following response: - */ - public function iExpectTheFollowingResponse(PyStringNode $expectedResult): void - { - Assert::assertNotNull($this->response); - Assert::assertEquals($expectedResult->getRaw(), str_replace("\r\n", "\n", Message::toString($this->response))); - } -} diff --git a/Neos.Neos/Tests/Behavior/Features/Bootstrap/FeatureContext.php b/Neos.Neos/Tests/Behavior/Features/Bootstrap/FeatureContext.php index b02048f437e..fce5b7a3278 100644 --- a/Neos.Neos/Tests/Behavior/Features/Bootstrap/FeatureContext.php +++ b/Neos.Neos/Tests/Behavior/Features/Bootstrap/FeatureContext.php @@ -39,7 +39,7 @@ class FeatureContext implements BehatContext use CRBehavioralTestsSubjectProvider; use RoutingTrait; use MigrationsTrait; - use DispatcherTrait; + use FrontendNodeControllerTrait; use FusionTrait; use ContentCacheTrait; diff --git a/Neos.Neos/Tests/Behavior/Features/Bootstrap/FrontendNodeControllerTrait.php b/Neos.Neos/Tests/Behavior/Features/Bootstrap/FrontendNodeControllerTrait.php new file mode 100644 index 00000000000..982262f17d2 --- /dev/null +++ b/Neos.Neos/Tests/Behavior/Features/Bootstrap/FrontendNodeControllerTrait.php @@ -0,0 +1,92 @@ + $className + * + * @return T + */ + abstract private function getObject(string $className): object; + + /** + * @BeforeScenario + */ + public function setupFrontendNodeControllerTrait(): void + { + $this->getObject(ContentCache::class)->flush(); + $this->getObject(\Neos\Neos\Testing\TestingFusionAutoIncludeHandler::class)->reset(); + $this->frontendNodeControllerResponse = null; + } + + /** + * @When the Fusion code for package :package is: + */ + public function iHaveTheFollowingFusionCodeForTheSite(PyStringNode $fusionCode, string $package) + { + $testingFusionHandler = $this->getObject(\Neos\Neos\Testing\TestingFusionAutoIncludeHandler::class); + $testingFusionHandler->setFusionForPackage($package, \Neos\Fusion\Core\FusionSourceCodeCollection::fromString($fusionCode->getRaw())); + } + + /** + * @When I dispatch the following request :requestUri + */ + public function iDispatchTheFollowingRequest(string $requestUri) + { + $testingFusionHandler = $this->getObject(\Neos\Neos\Testing\TestingFusionAutoIncludeHandler::class); + $testingFusionHandler->setIncludeFusionPackage('Neos.Fusion'); + $testingFusionHandler->setIncludeFusionPackage('Neos.Neos'); + + $httpRequest = $this->getObject(ServerRequestFactoryInterface::class)->createServerRequest('GET', $requestUri); + + $this->frontendNodeControllerResponse = $this->getObject(\Neos\Flow\Http\Middleware\MiddlewaresChain::class)->handle( + $httpRequest + ); + } + + /** + * @Then I expect the following response header: + */ + public function iExpectTheFollowingResponseHeader(PyStringNode $expectedResult): void + { + Assert::assertNotNull($this->frontendNodeControllerResponse); + Assert::assertSame($expectedResult->getRaw(), $this->frontendNodeControllerResponse->getBody()->getContents()); + } + + /** + * @Then I expect the following response: + */ + public function iExpectTheFollowingResponse(PyStringNode $expectedResult): void + { + Assert::assertNotNull($this->frontendNodeControllerResponse); + Assert::assertEquals($expectedResult->getRaw(), str_replace("\r\n", "\n", Message::toString($this->frontendNodeControllerResponse))); + } +} From 3b38dff7a6f12a2a94e6ef062f496b265c10b39b Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Fri, 8 Nov 2024 16:04:07 +0100 Subject: [PATCH 5/5] TASK: Reintroduce methods and prefer to deprecate them :) --- Neos.Fusion/Classes/Core/FusionSourceCodeCollection.php | 9 +++++++++ .../Classes/Domain/Service/FusionSourceCodeFactory.php | 8 ++++++++ 2 files changed, 17 insertions(+) diff --git a/Neos.Fusion/Classes/Core/FusionSourceCodeCollection.php b/Neos.Fusion/Classes/Core/FusionSourceCodeCollection.php index 00eacaa5b04..c1d4c809330 100644 --- a/Neos.Fusion/Classes/Core/FusionSourceCodeCollection.php +++ b/Neos.Fusion/Classes/Core/FusionSourceCodeCollection.php @@ -52,6 +52,15 @@ public static function tryFromFilePath(string $filePath): self return self::fromFilePath($filePath); } + /** + * @deprecated with Neos 9, remove me :) + */ + public static function tryFromPackageRootFusion(string $packageKey): self + { + $fusionPathAndFilename = sprintf('resource://%s/Private/Fusion/Root.fusion', $packageKey); + return self::tryFromFilePath($fusionPathAndFilename); + } + public static function empty(): self { return new self(); diff --git a/Neos.Neos/Classes/Domain/Service/FusionSourceCodeFactory.php b/Neos.Neos/Classes/Domain/Service/FusionSourceCodeFactory.php index 657d2ef94ff..e8766ba3e5a 100644 --- a/Neos.Neos/Classes/Domain/Service/FusionSourceCodeFactory.php +++ b/Neos.Neos/Classes/Domain/Service/FusionSourceCodeFactory.php @@ -59,6 +59,14 @@ public function createFromAutoIncludes(): FusionSourceCodeCollection return $sourcecode; } + /** + * @deprecated with Neos 9 - YAGNI from the start :) + */ + public function createFromSite(Site $site): FusionSourceCodeCollection + { + return FusionSourceCodeCollection::tryFromPackageRootFusion($site->getSiteResourcesPackageKey()); + } + /** * Generate Fusion prototype definitions for all node types *