Skip to content

Commit

Permalink
Merge pull request #5320 from neos/4191-nodeTypeChange
Browse files Browse the repository at this point in the history
!!! 4191 - Adjust and test node type change behavior
  • Loading branch information
nezaniel authored Oct 24, 2024
2 parents ab88f04 + b410ab3 commit 6597802
Show file tree
Hide file tree
Showing 30 changed files with 1,883 additions and 779 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ public function findIngoingHierarchyRelationsForNode(
}

/**
* @return array<string, HierarchyRelation> indexed by the dimension space point hash: ['<dimensionSpacePointHash>' => HierarchyRelation, ...]
* @return array<int, HierarchyRelation>
*/
public function findOutgoingHierarchyRelationsForNode(
NodeRelationAnchorPoint $parentAnchorPoint,
Expand Down Expand Up @@ -461,7 +461,7 @@ public function findOutgoingHierarchyRelationsForNode(
}
$relations = [];
foreach ($rows as $row) {
$relations[(string)$row['dimensionspacepointhash']] = $this->mapRawDataToHierarchyRelation($row);
$relations[] = $this->mapRawDataToHierarchyRelation($row);
}
return $relations;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,17 @@ Feature: Remove NodeAggregate
And I expect node aggregate identifier "nodingers-cat" and node path "pet" to lead to node cs-identifier;nodingers-cat;{}
And I expect this node to have no references
And I expect node aggregate identifier "nodingers-kitten" and node path "pet/kitten" to lead to no node

Scenario: Remove a node aggregate with descendants and expect all of them to be gone
When the following CreateNodeAggregateWithNode commands are executed:
| nodeAggregateId | nodeTypeName | parentNodeAggregateId | nodeName |
| nody-mc-nodeface | Neos.ContentRepository.Testing:Document | sir-david-nodenborough | child |
| younger-mc-nodeface | Neos.ContentRepository.Testing:Document | sir-david-nodenborough | younger-child |
When the command RemoveNodeAggregate is executed with payload:
| Key | Value |
| nodeAggregateId | "sir-david-nodenborough" |
| nodeVariantSelectionStrategy | "allVariants" |

Then I expect node aggregate identifier "sir-david-nodenborough" and node path "document" to lead to no node
And I expect node aggregate identifier "nody-mc-nodeface" and node path "document/child" to lead to no node
And I expect node aggregate identifier "younger-mc-nodeface" and node path "document/younger-child" to lead to no node
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
@contentrepository @adapters=DoctrineDBAL
Feature: Change node aggregate type - basic error cases

As a user of the CR I want to change the type of a node aggregate.

Background:
Given using the following content dimensions:
| Identifier | Values | Generalizations |
| language | de, gsw | gsw->de |
And using the following node types:
"""yaml
'Neos.ContentRepository.Testing:AnotherRoot':
superTypes:
'Neos.ContentRepository:Root': true
'Neos.ContentRepository.Testing:Tethered': []
'Neos.ContentRepository.Testing:Simple': []
'Neos.ContentRepository.Testing:AbstractNode':
abstract: true
'Neos.ContentRepository.Testing:ParentNodeType':
childNodes:
tethered:
type: 'Neos.ContentRepository.Testing:Tethered'
constraints:
nodeTypes:
'*': TRUE
'Neos.ContentRepository.Testing:NodeTypeB': false
constraints:
nodeTypes:
'*': TRUE
'Neos.ContentRepository.Testing:NodeTypeB': false
'Neos.ContentRepository.Testing:GrandParentNodeType':
childNodes:
tethered:
type: 'Neos.ContentRepository.Testing:ParentNodeType'
'Neos.ContentRepository.Testing:ChildOfNodeTypeA': []
'Neos.ContentRepository.Testing:ChildOfNodeTypeB': []
'Neos.ContentRepository.Testing:NodeTypeA':
childNodes:
childOfTypeA:
type: 'Neos.ContentRepository.Testing:ChildOfNodeTypeA'
properties:
text:
type: string
defaultValue: 'text'
'Neos.ContentRepository.Testing:NodeTypeB':
childNodes:
childOfTypeB:
type: 'Neos.ContentRepository.Testing:ChildOfNodeTypeB'
properties:
otherText:
type: string
defaultValue: 'otherText'
"""
And using identifier "default", I define a content repository
And I am in content repository "default"
And the command CreateRootWorkspace is executed with payload:
| Key | Value |
| workspaceName | "live" |
| newContentStreamId | "cs-identifier" |
And I am in workspace "live" and dimension space point {"language":"de"}
And the command CreateRootNodeAggregateWithNode is executed with payload:
| Key | Value |
| nodeAggregateId | "lady-eleonode-rootford" |
| nodeTypeName | "Neos.ContentRepository:Root" |
And the following CreateNodeAggregateWithNode commands are executed:
| nodeAggregateId | nodeName | parentNodeAggregateId | nodeTypeName | tetheredDescendantNodeAggregateIds |
| sir-david-nodenborough | parent | lady-eleonode-rootford | Neos.ContentRepository.Testing:ParentNodeType | {"tethered": "nodewyn-tetherton"} |
| nody-mc-nodeface | null | sir-david-nodenborough | Neos.ContentRepository.Testing:Simple | {} |
| nodimus-prime | null | nodewyn-tetherton | Neos.ContentRepository.Testing:Simple | {} |

Scenario: Try to change the node aggregate type in a workspace that currently does not exist
When the command ChangeNodeAggregateType is executed with payload and exceptions are caught:
| Key | Value |
| workspaceName | "non-existing" |
| nodeAggregateId | "sir-david-nodenborough" |
| newNodeTypeName | "Neos.ContentRepository.Testing:ChildOfNodeTypeA" |
| strategy | "happypath" |
Then the last command should have thrown an exception of type "WorkspaceDoesNotExist"

Scenario: Try to change the node aggregate type in a workspace whose content stream is closed
When the command CloseContentStream is executed with payload:
| Key | Value |
| contentStreamId | "cs-identifier" |
And the command ChangeNodeAggregateType is executed with payload and exceptions are caught:
| Key | Value |
| workspaceName | "live" |
| nodeAggregateId | "sir-david-nodenborough" |
| newNodeTypeName | "Neos.ContentRepository.Testing:ChildOfNodeTypeA" |
| strategy | "happypath" |
Then the last command should have thrown an exception of type "ContentStreamIsClosed"

Scenario: Try to change the type on a non-existing node aggregate
When the command ChangeNodeAggregateType is executed with payload and exceptions are caught:
| Key | Value |
| nodeAggregateId | "non-existing" |
| newNodeTypeName | "Neos.ContentRepository.Testing:ChildOfNodeTypeA" |
| strategy | "happypath" |
Then the last command should have thrown an exception of type "NodeAggregateCurrentlyDoesNotExist"

Scenario: Try to change the type of a root node aggregate:
When the command ChangeNodeAggregateType is executed with payload and exceptions are caught:
| Key | Value |
| nodeAggregateId | "lady-eleonode-rootford" |
| newNodeTypeName | "Neos.ContentRepository.Testing:AnotherRoot" |
| strategy | "happypath" |
Then the last command should have thrown an exception of type "NodeAggregateIsRoot"

Scenario: Try to change the type of a tethered node aggregate:
When the command ChangeNodeAggregateType is executed with payload and exceptions are caught:
| Key | Value |
| nodeAggregateId | "nodewyn-tetherton" |
| newNodeTypeName | "Neos.ContentRepository.Testing:ParentNodeType" |
| strategy | "happypath" |
Then the last command should have thrown an exception of type "NodeAggregateIsTethered"

Scenario: Try to change a node aggregate to a non existing type
When the command ChangeNodeAggregateType is executed with payload and exceptions are caught:
| Key | Value |
| nodeAggregateId | "sir-david-nodenborough" |
| newNodeTypeName | "Neos.ContentRepository.Testing:Undefined" |
| strategy | "happypath" |
Then the last command should have thrown an exception of type "NodeTypeNotFound"

Scenario: Try to change node aggregate to a root type:
When the command ChangeNodeAggregateType is executed with payload and exceptions are caught:
| Key | Value |
| nodeAggregateId | "sir-david-nodenborough" |
| newNodeTypeName | "Neos.ContentRepository.Testing:AnotherRoot" |
| strategy | "happypath" |
Then the last command should have thrown an exception of type "NodeTypeIsOfTypeRoot"

Scenario: Try to change a node aggregate to an abstract type
When the command ChangeNodeAggregateType is executed with payload and exceptions are caught:
| Key | Value |
| nodeAggregateId | "sir-david-nodenborough" |
| newNodeTypeName | "Neos.ContentRepository.Testing:AbstractNode" |
| strategy | "happypath" |
Then the last command should have thrown an exception of type "NodeTypeIsAbstract"

Scenario: Try to change to a node type disallowed by the parent node
When the command ChangeNodeAggregateType is executed with payload and exceptions are caught:
| Key | Value |
| nodeAggregateId | "nody-mc-nodeface" |
| newNodeTypeName | "Neos.ContentRepository.Testing:NodeTypeB" |
| strategy | "happypath" |
Then the last command should have thrown an exception of type "NodeConstraintException"

Scenario: Try to change to a node type disallowed by the parent node in a variant
When the command MoveNodeAggregate is executed with payload:
| Key | Value |
| nodeAggregateId | "nody-mc-nodeface" |
| dimensionSpacePoint | {"language": "gsw"} |
| newParentNodeAggregateId | "lady-eleonode-rootford" |
| newSucceedingSiblingNodeAggregateId | null |
| relationDistributionStrategy | "scatter" |
And the command ChangeNodeAggregateType is executed with payload and exceptions are caught:
| Key | Value |
| nodeAggregateId | "nody-mc-nodeface" |
| newNodeTypeName | "Neos.ContentRepository.Testing:NodeTypeB" |
| strategy | "happypath" |
Then the last command should have thrown an exception of type "NodeConstraintException"

Scenario: Try to change to a node type that is not allowed by the grand parent aggregate inside a tethered parent aggregate

When the command ChangeNodeAggregateType is executed with payload and exceptions are caught:
| Key | Value |
| nodeAggregateId | "nodimus-prime" |
| newNodeTypeName | "Neos.ContentRepository.Testing:NodeTypeB" |
| strategy | "happypath" |
Then the last command should have thrown an exception of type "NodeConstraintException"

Scenario: Try to change to a node type that is not allowed by the grand parent aggregate inside a tethered parent aggregate in a variant
When the command MoveNodeAggregate is executed with payload:
| Key | Value |
| nodeAggregateId | "nodimus-prime" |
| dimensionSpacePoint | {"language": "gsw"} |
| newParentNodeAggregateId | "lady-eleonode-rootford" |
| newSucceedingSiblingNodeAggregateId | null |
| relationDistributionStrategy | "scatter" |
And the command ChangeNodeAggregateType is executed with payload and exceptions are caught:
| Key | Value |
| nodeAggregateId | "nodimus-prime" |
| newNodeTypeName | "Neos.ContentRepository.Testing:NodeTypeB" |
| strategy | "happypath" |
Then the last command should have thrown an exception of type "NodeConstraintException"

Scenario: Try to change a node to a type with a tethered node declaration, whose name is already occupied by a non-tethered node
When the following CreateNodeAggregateWithNode commands are executed:
| nodeAggregateId | nodeName | parentNodeAggregateId | nodeTypeName |
| oddnode-tetherton | tethered | nody-mc-nodeface | Neos.ContentRepository.Testing:Simple |
And the command ChangeNodeAggregateType is executed with payload and exceptions are caught:
| Key | Value |
| nodeAggregateId | "nody-mc-nodeface" |
| newNodeTypeName | "Neos.ContentRepository.Testing:ParentNodeType" |
| strategy | "happypath" |
Then the last command should have thrown an exception of type "NodeAggregateIsUntethered"

Scenario: Try to change a node to a type with a descendant tethered node declaration, whose name is already occupied by a non-tethered node (recursive case)
When the following CreateNodeAggregateWithNode commands are executed:
| nodeAggregateId | nodeName | parentNodeAggregateId | nodeTypeName |
| oddnode-tetherton | tethered | nodewyn-tetherton | Neos.ContentRepository.Testing:Simple |
And the command ChangeNodeAggregateType is executed with payload and exceptions are caught:
| Key | Value |
| nodeAggregateId | "sir-david-nodenborough" |
| newNodeTypeName | "Neos.ContentRepository.Testing:GrandParentNodeType" |
| strategy | "happypath" |
Then the last command should have thrown an exception of type "NodeAggregateIsUntethered"
Loading

0 comments on commit 6597802

Please sign in to comment.