From 80527723d933a1095f8891ed2cb87a1116fb7b93 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Fri, 28 Jun 2024 21:30:47 +0200 Subject: [PATCH 1/4] FEATURE: WorkspaceName with reference for unused contentStream --- .../src/ContentGraphFactory.php | 6 +++++- .../src/ContentHyperGraphFactory.php | 6 +++++- .../Classes/CommandHandlingDependencies.php | 2 +- .../Classes/ContentGraphFactoryInterface.php | 3 --- .../Classes/ContentGraphFinder.php | 12 ------------ .../SharedModel/Workspace/WorkspaceName.php | 18 ++++++++++++++++++ .../Bootstrap/CRTestSuiteRuntimeVariables.php | 10 +--------- .../Features/Bootstrap/CRTestSuiteTrait.php | 1 - 8 files changed, 30 insertions(+), 28 deletions(-) diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentGraphFactory.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentGraphFactory.php index 2599353780a..367fd11f87d 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentGraphFactory.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentGraphFactory.php @@ -40,6 +40,10 @@ public function __construct( public function buildForWorkspace(WorkspaceName $workspaceName): ContentGraph { + if ($workspaceName->isReferencingUnusedContentStream()) { + return $this->buildForWorkspaceAndContentStream($workspaceName, $workspaceName->getReferencingUnusedContentStreamId()); + } + // FIXME: Should be part of this projection, this is forbidden $tableName = strtolower(sprintf( 'cr_%s_p_%s', @@ -71,7 +75,7 @@ public function buildForWorkspace(WorkspaceName $workspaceName): ContentGraph return $this->buildForWorkspaceAndContentStream($workspaceName, ContentStreamId::fromString($currentContentStreamId)); } - public function buildForWorkspaceAndContentStream(WorkspaceName $workspaceName, ContentStreamId $contentStreamId): ContentGraph + private function buildForWorkspaceAndContentStream(WorkspaceName $workspaceName, ContentStreamId $contentStreamId): ContentGraph { return new ContentGraph($this->dbal, $this->nodeFactory, $this->contentRepositoryId, $this->nodeTypeManager, $this->tableNames, $workspaceName, $contentStreamId); } diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperGraphFactory.php b/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperGraphFactory.php index 55b8b529a80..fa2cb3f0623 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperGraphFactory.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperGraphFactory.php @@ -31,6 +31,10 @@ public function __construct( public function buildForWorkspace(WorkspaceName $workspaceName): ContentGraphInterface { + if ($workspaceName->isReferencingUnusedContentStream()) { + return $this->buildForWorkspaceAndContentStream($workspaceName, $workspaceName->getReferencingUnusedContentStreamId()); + } + // FIXME: Should be part of this projection, this is forbidden $tableName = strtolower(sprintf( 'cr_%s_p_%s', @@ -55,7 +59,7 @@ public function buildForWorkspace(WorkspaceName $workspaceName): ContentGraphInt return $this->buildForWorkspaceAndContentStream($workspaceName, ContentStreamId::fromString($row['currentcontentstreamid'])); } - public function buildForWorkspaceAndContentStream(WorkspaceName $workspaceName, ContentStreamId $contentStreamId): ContentGraphInterface + private function buildForWorkspaceAndContentStream(WorkspaceName $workspaceName, ContentStreamId $contentStreamId): ContentGraphInterface { return new ContentHyperGraph($this->dbal, $this->nodeFactory, $this->contentRepositoryId, $this->nodeTypeManager, $this->tableNamePrefix, $workspaceName, $contentStreamId); } diff --git a/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php b/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php index c0b5270cc37..53a5c282b5c 100644 --- a/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php +++ b/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php @@ -83,7 +83,7 @@ public function overrideContentStreamId(WorkspaceName $workspaceName, ContentStr throw new \RuntimeException('Contentstream override for this workspace already in effect, nesting not allowed.', 1715170938); } - $contentGraph = $this->contentRepository->projectionState(ContentGraphFinder::class)->getByWorkspaceNameAndContentStreamId($workspaceName, $contentStreamId); + $contentGraph = $this->contentRepository->getContentGraph(WorkspaceName::createReferenceForUnusedContentStream($contentStreamId)); $this->overridenContentGraphInstances[$workspaceName->value] = $contentGraph; try { diff --git a/Neos.ContentRepository.Core/Classes/ContentGraphFactoryInterface.php b/Neos.ContentRepository.Core/Classes/ContentGraphFactoryInterface.php index 2a766579751..eafba61bb26 100644 --- a/Neos.ContentRepository.Core/Classes/ContentGraphFactoryInterface.php +++ b/Neos.ContentRepository.Core/Classes/ContentGraphFactoryInterface.php @@ -16,7 +16,6 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphInterface; use Neos\ContentRepository\Core\SharedModel\Exception\WorkspaceDoesNotExist; -use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; /** @@ -30,6 +29,4 @@ interface ContentGraphFactoryInterface * @throws WorkspaceDoesNotExist if the workspace does not exist */ public function buildForWorkspace(WorkspaceName $workspaceName): ContentGraphInterface; - - public function buildForWorkspaceAndContentStream(WorkspaceName $workspaceName, ContentStreamId $contentStreamId): ContentGraphInterface; } diff --git a/Neos.ContentRepository.Core/Classes/ContentGraphFinder.php b/Neos.ContentRepository.Core/Classes/ContentGraphFinder.php index 8244c2e0640..1cf9cf7812a 100644 --- a/Neos.ContentRepository.Core/Classes/ContentGraphFinder.php +++ b/Neos.ContentRepository.Core/Classes/ContentGraphFinder.php @@ -67,16 +67,4 @@ public function forgetInstances(): void { $this->contentGraphInstances = []; } - - /** - * For testing we allow getting an instance set by both parameters, effectively overriding the relationship at will - * - * @param WorkspaceName $workspaceName - * @param ContentStreamId $contentStreamId - * @internal Only for testing - */ - public function getByWorkspaceNameAndContentStreamId(WorkspaceName $workspaceName, ContentStreamId $contentStreamId): ContentGraphInterface - { - return $this->contentGraphFactory->buildForWorkspaceAndContentStream($workspaceName, $contentStreamId); - } } diff --git a/Neos.ContentRepository.Core/Classes/SharedModel/Workspace/WorkspaceName.php b/Neos.ContentRepository.Core/Classes/SharedModel/Workspace/WorkspaceName.php index 37ac2fc8c24..f9fe6784b82 100644 --- a/Neos.ContentRepository.Core/Classes/SharedModel/Workspace/WorkspaceName.php +++ b/Neos.ContentRepository.Core/Classes/SharedModel/Workspace/WorkspaceName.php @@ -48,6 +48,11 @@ public static function fromString(string $value): self return self::instance($value); } + public static function createReferenceForUnusedContentStream(ContentStreamId $contentStreamId): self + { + return self::instance('cs:' . $contentStreamId->value); + } + public static function forLive(): self { return self::instance(self::WORKSPACE_NAME_LIVE); @@ -92,6 +97,19 @@ public function isLive(): bool return $this->value === self::WORKSPACE_NAME_LIVE; } + /** + * @phpstan-assert-if-true ContentStreamId $this->getReferencingUnusedContentStreamId() + */ + public function isReferencingUnusedContentStream(): bool + { + return str_starts_with($this->value, 'cs:'); + } + + public function getReferencingUnusedContentStreamId(): ?ContentStreamId + { + return $this->isReferencingUnusedContentStream() ? ContentStreamId::fromString(substr($this->value, 3)) : null; + } + public function jsonSerialize(): string { return $this->value; diff --git a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteRuntimeVariables.php b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteRuntimeVariables.php index f5c2204d01d..81cc13a6133 100644 --- a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteRuntimeVariables.php +++ b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteRuntimeVariables.php @@ -37,8 +37,6 @@ trait CRTestSuiteRuntimeVariables { protected ?ContentRepository $currentContentRepository = null; - protected ?ContentStreamId $currentContentStreamId = null; - protected ?WorkspaceName $currentWorkspaceName = null; protected ?DimensionSpacePoint $currentDimensionSpacePoint = null; @@ -92,7 +90,7 @@ public function theCurrentDateAndTimeIs(string $timestamp): void */ public function iAmInContentStream(string $contentStreamId): void { - $this->currentContentStreamId = ContentStreamId::fromString($contentStreamId); + $this->currentWorkspaceName = WorkspaceName::createReferenceForUnusedContentStream(ContentStreamId::fromString($contentStreamId)); } /** @@ -101,7 +99,6 @@ public function iAmInContentStream(string $contentStreamId): void public function iAmInWorkspace(string $workspaceName): void { $this->currentWorkspaceName = WorkspaceName::fromString($workspaceName); - $this->currentContentStreamId = null; } /** @@ -147,11 +144,6 @@ public function getCurrentSubgraph(): ContentSubgraphInterface { $contentGraphFinder = $this->currentContentRepository->projectionState(ContentGraphFinder::class); $contentGraphFinder->forgetInstances(); - if (isset($this->currentContentStreamId)) { - // This must still be supported for low level tests, e.g. for content stream forking - return $contentGraphFinder->getByWorkspaceNameAndContentStreamId($this->currentWorkspaceName, $this->currentContentStreamId)->getSubgraph($this->currentDimensionSpacePoint, $this->currentVisibilityConstraints); - } - return $contentGraphFinder->getByWorkspaceName($this->currentWorkspaceName)->getSubgraph( $this->currentDimensionSpacePoint, $this->currentVisibilityConstraints diff --git a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php index 057edaa23b6..193215f7125 100644 --- a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php +++ b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php @@ -97,7 +97,6 @@ public function beforeEventSourcedScenarioDispatcher(BeforeScenarioScope $scope) $this->currentVisibilityConstraints = VisibilityConstraints::frontend(); $this->currentDimensionSpacePoint = null; $this->currentRootNodeAggregateId = null; - $this->currentContentStreamId = null; $this->currentWorkspaceName = null; $this->currentNodeAggregate = null; $this->currentNode = null; From c7099ab5de8e00bdaef1155b9e663dbb5d474d20 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Fri, 28 Jun 2024 21:45:58 +0200 Subject: [PATCH 2/4] TASK: Remove deprecated usage `$node->subgraphIdentity->contentStreamId` --- .../Bootstrap/Helpers/NodeDiscriminator.php | 7 +++-- .../Bootstrap/Helpers/NodeDiscriminators.php | 8 ------ .../Features/Bootstrap/ProjectedNodeTrait.php | 27 ++++++++++++------- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/Helpers/NodeDiscriminator.php b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/Helpers/NodeDiscriminator.php index 005e5464e4d..043282d1e0d 100644 --- a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/Helpers/NodeDiscriminator.php +++ b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/Helpers/NodeDiscriminator.php @@ -14,6 +14,7 @@ namespace Neos\ContentRepository\TestSuite\Behavior\Features\Bootstrap\Helpers; +use Neos\ContentRepository\Core\ContentRepository; use Neos\ContentRepository\Core\DimensionSpace\OriginDimensionSpacePoint; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; @@ -47,10 +48,12 @@ public static function fromShorthand(string $shorthand): self ); } - public static function fromNode(Node $node): self + public static function fromNode(Node $node, ContentRepository $contentRepository): self { + // todo call ContentGraphFinder::forgetInstances ??? + $contentStreamOfNode = $contentRepository->getContentGraph($node->workspaceName)->getContentStreamId(); return new self( - $node->subgraphIdentity->contentStreamId, + $contentStreamOfNode, $node->aggregateId, $node->originDimensionSpacePoint ); diff --git a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/Helpers/NodeDiscriminators.php b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/Helpers/NodeDiscriminators.php index 2bedcbce70e..07924d1de4a 100644 --- a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/Helpers/NodeDiscriminators.php +++ b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/Helpers/NodeDiscriminators.php @@ -53,14 +53,6 @@ public static function fromArray(array $array): self )); } - public static function fromNodes(Nodes $nodes): self - { - return new self(...array_map( - fn (Node $node): NodeDiscriminator => NodeDiscriminator::fromNode($node), - iterator_to_array($nodes) - )); - } - public function equal(self $other): bool { return $this->discriminators == $other->discriminators; diff --git a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/ProjectedNodeTrait.php b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/ProjectedNodeTrait.php index b227c5660b6..f89d3015040 100644 --- a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/ProjectedNodeTrait.php +++ b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/ProjectedNodeTrait.php @@ -110,7 +110,7 @@ public function iExpectNodeAggregateIdToLeadToNode( $this->initializeCurrentNodeFromContentSubgraph(function (ContentSubgraphInterface $subgraph) use ($nodeAggregateId, $expectedDiscriminator) { $currentNode = $subgraph->findNodeById($nodeAggregateId); Assert::assertNotNull($currentNode, 'No node could be found by node aggregate id "' . $nodeAggregateId->value . '" in content subgraph "' . $this->currentDimensionSpacePoint->toJson() . '@' . $this->currentWorkspaceName->value . '"'); - $actualDiscriminator = NodeDiscriminator::fromNode($currentNode); + $actualDiscriminator = NodeDiscriminator::fromNode($currentNode, $this->currentContentRepository); Assert::assertTrue($expectedDiscriminator->equals($actualDiscriminator), 'Node discriminators do not match. Expected was ' . json_encode($expectedDiscriminator) . ' , given was ' . json_encode($actualDiscriminator)); return $currentNode; }); @@ -147,7 +147,7 @@ public function iExpectPathToLeadToNode(string $serializedNodePath, string $seri $this->initializeCurrentNodeFromContentSubgraph(function (ContentSubgraphInterface $subgraph) use ($nodePath, $expectedDiscriminator) { $currentNode = $subgraph->findNodeByPath($nodePath, $this->getRootNodeAggregateId()); Assert::assertNotNull($currentNode, 'No node could be found by node path "' . $nodePath->serializeToString() . '" in content subgraph "' . $this->currentDimensionSpacePoint->toJson() . '@' . $this->currentWorkspaceName->value . '"'); - $actualDiscriminator = NodeDiscriminator::fromNode($currentNode); + $actualDiscriminator = NodeDiscriminator::fromNode($currentNode, $this->currentContentRepository); Assert::assertTrue($expectedDiscriminator->equals($actualDiscriminator), 'Node discriminators do not match. Expected was ' . json_encode($expectedDiscriminator) . ' , given was ' . json_encode($actualDiscriminator)); return $currentNode; }); @@ -479,7 +479,7 @@ private function assertReferencesMatch(TableNode $expectedReferencesTable, Refer $actualReferences[$index]->name->value ); $expectedReferenceDiscriminator = NodeDiscriminator::fromShorthand($row['Node']); - $actualReferenceDiscriminator = NodeDiscriminator::fromNode($actualReferences[$index]->node); + $actualReferenceDiscriminator = NodeDiscriminator::fromNode($actualReferences[$index]->node, $this->currentContentRepository); Assert::assertTrue( $expectedReferenceDiscriminator->equals($actualReferenceDiscriminator), 'Reference discriminator does not match.' @@ -553,12 +553,12 @@ public function iExpectThisNodeToBeTheChildOfNode(string $serializedParentNodeDi $parent = $subgraph->findParentNode($currentNode->aggregateId); Assert::assertInstanceOf(Node::class, $parent, 'Parent not found.'); - $actualParentDiscriminator = NodeDiscriminator::fromNode($parent); + $actualParentDiscriminator = NodeDiscriminator::fromNode($parent, $this->currentContentRepository); Assert::assertTrue($expectedParentDiscriminator->equals($actualParentDiscriminator), 'Parent discriminator does not match. Expected was ' . json_encode($expectedParentDiscriminator) . ', given was ' . json_encode($actualParentDiscriminator)); - $expectedChildDiscriminator = NodeDiscriminator::fromNode($currentNode); + $expectedChildDiscriminator = NodeDiscriminator::fromNode($currentNode, $this->currentContentRepository); $child = $subgraph->findNodeByPath($currentNode->name, $parent->aggregateId); - $actualChildDiscriminator = NodeDiscriminator::fromNode($child); + $actualChildDiscriminator = NodeDiscriminator::fromNode($child, $this->currentContentRepository); Assert::assertTrue($expectedChildDiscriminator->equals($actualChildDiscriminator), 'Child discriminator does not match. Expected was ' . json_encode($expectedChildDiscriminator) . ', given was ' . json_encode($actualChildDiscriminator)); }); } @@ -596,7 +596,10 @@ public function iExpectThisNodeToHaveTheFollowingChildNodes(TableNode $expectedC Assert::assertTrue($expectedNodeName->equals($actualNodeName), 'ContentSubgraph::findChildNodes: Node name in index ' . $index . ' does not match. Expected: "' . $expectedNodeName->value . '" Actual: "' . $actualNodeName->value . '"'); if (isset($row['NodeDiscriminator'])) { $expectedNodeDiscriminator = NodeDiscriminator::fromShorthand($row['NodeDiscriminator']); - $actualNodeDiscriminator = NodeDiscriminator::fromNode($actualChildNodes[$index]); + $actualNodeDiscriminator = NodeDiscriminator::fromNode( + $actualChildNodes[$index], + $this->currentContentRepository + ); Assert::assertTrue($expectedNodeDiscriminator->equals($actualNodeDiscriminator), 'ContentSubgraph::findChildNodes: Node discriminator in index ' . $index . ' does not match. Expected: ' . json_encode($expectedNodeDiscriminator->jsonSerialize()) . ' Actual: ' . json_encode($actualNodeDiscriminator)); } } @@ -635,7 +638,10 @@ public function iExpectThisNodeToHaveTheFollowingPrecedingSiblings(TableNode $ex Assert::assertCount(count($expectedPrecedingSiblingsTable->getHash()), $actualSiblings, 'ContentSubgraph::findPrecedingSiblingNodes: Sibling count does not match'); foreach ($expectedPrecedingSiblingsTable->getHash() as $index => $row) { $expectedNodeDiscriminator = NodeDiscriminator::fromShorthand($row['NodeDiscriminator']); - $actualNodeDiscriminator = NodeDiscriminator::fromNode($actualSiblings[$index]); + $actualNodeDiscriminator = NodeDiscriminator::fromNode( + $actualSiblings[$index], + $this->currentContentRepository + ); Assert::assertTrue($expectedNodeDiscriminator->equals($actualNodeDiscriminator), 'ContentSubgraph::findPrecedingSiblingNodes: Node discriminator in index ' . $index . ' does not match. Expected: ' . json_encode($expectedNodeDiscriminator) . ' Actual: ' . json_encode($actualNodeDiscriminator)); } }); @@ -672,7 +678,10 @@ public function iExpectThisNodeToHaveTheFollowingSucceedingSiblings(TableNode $e Assert::assertCount(count($expectedSucceedingSiblingsTable->getHash()), $actualSiblings, 'ContentSubgraph::findSucceedingSiblingNodes: Sibling count does not match'); foreach ($expectedSucceedingSiblingsTable->getHash() as $index => $row) { $expectedNodeDiscriminator = NodeDiscriminator::fromShorthand($row['NodeDiscriminator']); - $actualNodeDiscriminator = NodeDiscriminator::fromNode($actualSiblings[$index]); + $actualNodeDiscriminator = NodeDiscriminator::fromNode( + $actualSiblings[$index], + $this->currentContentRepository + ); Assert::assertTrue($expectedNodeDiscriminator->equals($actualNodeDiscriminator), 'ContentSubgraph::findSucceedingSiblingNodes: Node discriminator in index ' . $index . ' does not match. Expected: ' . json_encode($expectedNodeDiscriminator) . ' Actual: ' . json_encode($actualNodeDiscriminator)); } }); From b8d48c4eecb26d35b2a26c144db9e83b162be7ce Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Fri, 28 Jun 2024 22:09:31 +0200 Subject: [PATCH 3/4] TASK: Fix obsolete declaration of `And I am in content stream` followup to https://github.com/neos/neos-development-collection/pull/5162 --- Neos.Neos/Tests/Behavior/Features/Fusion/ConvertUris.feature | 1 - Neos.Neos/Tests/Behavior/Features/Fusion/FlowQuery.feature | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Neos.Neos/Tests/Behavior/Features/Fusion/ConvertUris.feature b/Neos.Neos/Tests/Behavior/Features/Fusion/ConvertUris.feature index 4aee9e82b50..a9266914f39 100644 --- a/Neos.Neos/Tests/Behavior/Features/Fusion/ConvertUris.feature +++ b/Neos.Neos/Tests/Behavior/Features/Fusion/ConvertUris.feature @@ -35,7 +35,6 @@ Feature: Tests for the "Neos.Neos:ConvertUris" Fusion prototype | Key | Value | | nodeAggregateId | "root" | | nodeTypeName | "Neos.Neos:Sites" | - And I am in content stream "cs-identifier" and dimension space point {} And the following CreateNodeAggregateWithNode commands are executed: | nodeAggregateId | parentNodeAggregateId | nodeTypeName | initialPropertyValues | nodeName | | a | root | Neos.Neos:Site | {"title": "Node a"} | a | diff --git a/Neos.Neos/Tests/Behavior/Features/Fusion/FlowQuery.feature b/Neos.Neos/Tests/Behavior/Features/Fusion/FlowQuery.feature index 6e1c2effe20..bd76b9e096c 100644 --- a/Neos.Neos/Tests/Behavior/Features/Fusion/FlowQuery.feature +++ b/Neos.Neos/Tests/Behavior/Features/Fusion/FlowQuery.feature @@ -46,12 +46,11 @@ Feature: Tests for the "Neos.ContentRepository" Flow Query methods. | Key | Value | | workspaceName | "live" | | newContentStreamId | "cs-identifier" | - And I am in workspace "live" + 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 I am in content stream "cs-identifier" and dimension space point {} And the following CreateNodeAggregateWithNode commands are executed: | nodeAggregateId | parentNodeAggregateId | nodeTypeName | initialPropertyValues | nodeName | | a | root | Neos.Neos:Site | {"title": "Node a"} | a | From 10011fb587aab06da50e8d58321cdec9deffab39 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Sat, 29 Jun 2024 10:10:07 +0200 Subject: [PATCH 4/4] WIP: Assert that write side does not operate on fake workspace names --- .../Classes/CommandHandlingDependencies.php | 4 ++++ .../Classes/Feature/WorkspaceCommandHandler.php | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php b/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php index 53a5c282b5c..0763a5dcade 100644 --- a/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php +++ b/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php @@ -65,6 +65,10 @@ public function getContentGraph(WorkspaceName $workspaceName): ContentGraphInter return $this->overridenContentGraphInstances[$workspaceName->value]; } + if ($workspaceName->isReferencingUnusedContentStream()) { + throw new \RuntimeException(sprintf('Expected actual workspace name. Got a workspace name referencing an unused content stream: "%s" instead.', $workspaceName->getReferencingUnusedContentStreamId()->value), 1719648458); + } + return $this->contentRepository->getContentGraph($workspaceName); } diff --git a/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php b/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php index 1e96149f95f..1a03137b377 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php +++ b/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php @@ -900,6 +900,10 @@ private function handleChangeWorkspaceOwner( private function requireWorkspaceToNotExist(WorkspaceName $workspaceName, CommandHandlingDependencies $commandHandlingDependencies): void { + if ($workspaceName->isReferencingUnusedContentStream()) { + throw new \RuntimeException(sprintf('Expected actual workspace name. Got a workspace name referencing an unused content stream: "%s" instead.', $workspaceName->getReferencingUnusedContentStreamId()->value), 1719648458); + } + try { $commandHandlingDependencies->getContentGraph($workspaceName); } catch (WorkspaceDoesNotExist) { @@ -918,6 +922,10 @@ private function requireWorkspaceToNotExist(WorkspaceName $workspaceName, Comman */ private function requireWorkspace(WorkspaceName $workspaceName, WorkspaceFinder $workspaceFinder): Workspace { + if ($workspaceName->isReferencingUnusedContentStream()) { + throw new \RuntimeException(sprintf('Expected actual workspace name. Got a workspace name referencing an unused content stream: "%s" instead.', $workspaceName->getReferencingUnusedContentStreamId()->value), 1719648458); + } + $workspace = $workspaceFinder->findOneByName($workspaceName); if (is_null($workspace)) { throw WorkspaceDoesNotExist::butWasSupposedTo($workspaceName);