Skip to content

Commit

Permalink
Merge pull request #14 from sandstorm/feature/12-support-for-textual-…
Browse files Browse the repository at this point in the history
…persistent-resources

Feature/12 support for textual persistent resources
  • Loading branch information
christoph-daehne authored Jun 27, 2022
2 parents 6dc9677 + 2c296a4 commit 0076f74
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.idea
vendor/
composer.lock
18 changes: 16 additions & 2 deletions Tests/Behavior/Bootstrap/FusionRenderingTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -43,6 +47,7 @@ public function setupFusionRendering(string $sitePackageKey)
}

$this->sitePackageKey = $sitePackageKey;
$this->PersistentResourceTrait_setupServices($this->getObjectManager());
}

/**
Expand Down Expand Up @@ -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'] !== '') {
Expand All @@ -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);
}
}
}

Expand All @@ -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();
}
}
Expand Down
61 changes: 61 additions & 0 deletions Tests/Behavior/Bootstrap/PersistentResourceTrait.php
Original file line number Diff line number Diff line change
@@ -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);
}
}
30 changes: 30 additions & 0 deletions Tests/Behavior/Examples/persistentResources.feature
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 0076f74

Please sign in to comment.