diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..157ff0c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea +vendor/ +composer.lock diff --git a/Tests/Behavior/Bootstrap/FusionRenderingTrait.php b/Tests/Behavior/Bootstrap/FusionRenderingTrait.php index c93e658..0379a81 100644 --- a/Tests/Behavior/Bootstrap/FusionRenderingTrait.php +++ b/Tests/Behavior/Bootstrap/FusionRenderingTrait.php @@ -27,11 +27,15 @@ use Sandstorm\E2ETestTools\FusionRenderingResult; use Symfony\Component\DomCrawler\Crawler; +require_once(__DIR__ . "/PersistentResourceTrait.php"); + /** * This trait is only useful in NEOS applications; not in Symfony projects. */ trait FusionRenderingTrait { + use PersistentResourceTrait; + abstract public function getObjectManager(): ObjectManagerInterface; private string $sitePackageKey; @@ -43,6 +47,7 @@ public function setupFusionRendering(string $sitePackageKey) } $this->sitePackageKey = $sitePackageKey; + $this->PersistentResourceTrait_setupServices($this->getObjectManager()); } /** @@ -357,6 +362,7 @@ public function iHaveTheFollowingNodes($table) throw new \Exception(sprintf('Could not get parent node with path %s to create node %s', $parentPath, $path)); } + $persistenceManager = $this->objectManager->get(PersistenceManagerInterface::class); $node = $parentNode->createNode($name, $nodeType, $identifier); if (isset($row['Properties']) && $row['Properties'] !== '') { @@ -365,7 +371,15 @@ public function iHaveTheFollowingNodes($table) throw new \Exception(sprintf('Error decoding json value "%s": %d', $row['Properties'], json_last_error())); } foreach ($properties as $propertyName => $propertyValue) { - $node->setProperty($propertyName, $propertyValue); + if (is_array($propertyValue) && isset($propertyValue['__flow_object_type'])) { + $instance = $persistenceManager->getObjectByIdentifier( + $propertyValue['__identifier'], + $propertyValue['__flow_object_type'], + true); + $node->setProperty($propertyName, $instance); + } else { + $node->setProperty($propertyName, $propertyValue); + } } } @@ -377,7 +391,7 @@ public function iHaveTheFollowingNodes($table) } // Make sure we do not use cached instances - $this->objectManager->get(PersistenceManagerInterface::class)->persistAll(); + $persistenceManager->persistAll(); $this->resetNodeInstances(); } } diff --git a/Tests/Behavior/Bootstrap/PersistentResourceTrait.php b/Tests/Behavior/Bootstrap/PersistentResourceTrait.php new file mode 100644 index 0000000..2e8215c --- /dev/null +++ b/Tests/Behavior/Bootstrap/PersistentResourceTrait.php @@ -0,0 +1,61 @@ +<?php + +namespace Sandstorm\E2ETestTools\Tests\Behavior\Bootstrap; + +use Behat\Gherkin\Node\PyStringNode; +use Neos\Flow\Core\Bootstrap; +use Neos\Flow\ObjectManagement\ObjectManagerInterface; +use Neos\Flow\Persistence\PersistenceManagerInterface; +use Neos\Flow\ResourceManagement\ResourceManager; +use Neos\Media\Domain\Model\Document; +use Neos\Media\Domain\Repository\AssetRepository; +use Neos\Utility\ObjectAccess; + +trait PersistentResourceTrait +{ + /** + * @var AssetRepository + */ + private AssetRepository $PersistentResourceTrait_assetRepository; + + /** + * @var ResourceManager + */ + private ResourceManager $PersistentResourceTrait_resourceManager; + + /** + * @var PersistenceManagerInterface + */ + private PersistenceManagerInterface $PersistentResourceTrait_persistenceManager; + + /** + * @var Bootstrap + */ + private Bootstrap $PersistentResourceTrait_bootstrap; + + public function PersistentResourceTrait_setupServices(ObjectManagerInterface $objectManager): void + { + $this->PersistentResourceTrait_assetRepository = $objectManager->get(AssetRepository::class); + $this->PersistentResourceTrait_resourceManager = $objectManager->get(ResourceManager::class); + $this->PersistentResourceTrait_persistenceManager = $objectManager->get(PersistenceManagerInterface::class); + $this->PersistentResourceTrait_bootstrap = $objectManager->get(Bootstrap::class); + } + + /** + * @Given I have a textual persistent resource :uuid named :filename with the following content: + * @throws Exception failure while storing the resource + */ + public function iHaveATextualPersistentResourceWithTheFollowingContent(string $uuid, string $filename, PyStringNode $content): void + { + $resource = $this->PersistentResourceTrait_resourceManager->importResourceFromContent( + $content->getRaw(), + $filename); + $document = new Document($resource); + ObjectAccess::setProperty($document, 'Persistence_Object_Identifier', $uuid, true); + $this->PersistentResourceTrait_assetRepository->add($document); + $this->PersistentResourceTrait_persistenceManager->persistAll(); + + $flowContext = $this->PersistentResourceTrait_bootstrap->getContext(); + exec("FLOW_CONTEXT=$flowContext ./flow resource:publish", $output, $resultCode); + } +} diff --git a/Tests/Behavior/Examples/persistentResources.feature b/Tests/Behavior/Examples/persistentResources.feature new file mode 100644 index 0000000..be5dc14 --- /dev/null +++ b/Tests/Behavior/Examples/persistentResources.feature @@ -0,0 +1,30 @@ +@playwright +@fixtures +Feature: Persistent Resources + + In this example we assume there is a content unit JavaScriptWidget which allows the editor to select a + JavaScript file from the persistent resources. This widget is then loaded and executed. + Also the JavaScriptWidget generates div-tags with given IDs as anchors for the script. + + Hints for the test setup: + + While developing this feature I had trouble loading my persistent resource. This was due to some split-brain + behavior due to a duplicate flow configuration. During the execution of the steps the active FLOW_CONTEXT is + "Testing/Behat". During the fetch of the page and resource it has been "Development/Behat". The persistent + resource was not found since the storage settings (ie the storage- and the target-path) did not match. + + Scenario: JavaScript widget loads and executes + Given I have a site for Site Node "website" + And I have a textual persistent resource "74d819f0-0bf4-44df-ae36-0c7639c1afcc" named "my-widget.js" with the following content: + """ + document.getElementById('my-container-1').appendChild(document.createTextNode('Hello Container 1!')); + document.getElementById('my-container-2').appendChild(document.createTextNode('Hello Container 2!')); + """ + And I have the following nodes: + | Path | Node Type | Properties | HiddenInIndex | + | /sites | unstructured | [] | false | + | /sites/website | Neos.Neos:Document | {"uriPathSegment":"website","title":"Website","privacyPage":"b9d32958-9bc0-4502-bdd2-274b54f1777e"} | false | + | /sites/website/main/node-2ph9cgxvafhxe | My.Cool:JavaScriptWidget | {"javaScriptSourceFile":{"__flow_object_type": "Neos\\Media\\Domain\\Model\\Document","__identifier": "74d819f0-0bf4-44df-ae36-0c7639c1afcc"},"anchorElementIds":"my-container-1,my-container-2"} | false | + When I access the URI path "/" + Then there should be the text "Hello Container 1!" on the page + And there should be the text "Hello Container 2!" on the page