Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/9.0' into 4549-separateReference…
Browse files Browse the repository at this point in the history
…sAndProperties
  • Loading branch information
mhsdesign committed Mar 18, 2024
2 parents 47433d0 + 117c052 commit 5013a77
Show file tree
Hide file tree
Showing 811 changed files with 20,194 additions and 18,329 deletions.
39 changes: 27 additions & 12 deletions .composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@
"provide": {
},
"scripts": {
"lint:phpcs-psr12": "../../bin/phpcs --colors --standard=PSR12 ./Neos.ContentGraph.DoctrineDbalAdapter/src ./Neos.ContentGraph.PostgreSQLAdapter/src ./Neos.ContentRepository.BehavioralTests/Classes ./Neos.ContentRepository.TestSuite/Classes ./Neos.ContentRepository.Core/Classes ./Neos.Neos/Classes",
"lint:phpcs": [
"@lint:phpcs-psr12 --exclude=Generic.Files.LineLength,PSR1.Files.SideEffects"
],
"lint:phpcs": "../../bin/phpcs --colors",
"lint:phpcs:fix": "../../bin/phpcbf --colors",
"lint:phpstan": "../../bin/phpstan analyse",
"lint:phpstan-generate-baseline": "../../bin/phpstan analyse --generate-baseline",
"lint:distributionintegrity": "[ -d 'Neos.ContentRepository' ] && { echo 'Package Neos.ContentRepository should not exist.' 1>&2; exit 1; } || exit 0;",
Expand All @@ -29,31 +27,48 @@
"../../bin/phpunit --colors --stop-on-failure -c ../../Build/BuildEssentials/PhpUnit/UnitTests.xml Neos.ContentRepository.Core/Tests/Unit",
"../../bin/phpunit --colors --stop-on-failure -c ../../Build/BuildEssentials/PhpUnit/UnitTests.xml Neos.ContentRepositoryRegistry/Tests/Unit"
],
"test:parallel": [
"FLOW_CONTEXT=Testing/Behat ../../bin/paratest --debug -v --functional --group parallel --processes 2 --colors --stop-on-failure -c ../../Build/BuildEssentials/PhpUnit/FunctionalTests.xml Neos.ContentRepository.BehavioralTests/Tests/Functional/Feature/WorkspacePublication/WorkspaceWritingDuringPublication.php",
"FLOW_CONTEXT=Testing/Behat ../../bin/paratest --debug -v --functional --group parallel --processes 2 --colors --stop-on-failure -c ../../Build/BuildEssentials/PhpUnit/FunctionalTests.xml Neos.ContentRepository.BehavioralTests/Tests/Functional/Feature/WorkspacePublication/WorkspaceWritingDuringPublication.php",
"FLOW_CONTEXT=Testing/Behat ../../bin/paratest --debug -v --functional --group parallel --processes 2 --colors --stop-on-failure -c ../../Build/BuildEssentials/PhpUnit/FunctionalTests.xml Neos.ContentRepository.BehavioralTests/Tests/Functional/Feature/WorkspacePublication/WorkspaceWritingDuringPublication.php"
],
"test:functional": [
"../../bin/phpunit --colors --stop-on-failure -c ../../Build/BuildEssentials/PhpUnit/FunctionalTests.xml Neos.ContentRepository.Core/Tests/Functional"
],
"test:behat-cli": "../../bin/behat -f progress --strict --no-interaction",
"test:behavioral": [
"@test:behat-cli -c Neos.ContentRepository.BehavioralTests/Tests/Behavior/behat.yml.dist",
"@test:behat-cli -c Neos.ContentGraph.DoctrineDbalAdapter/Tests/Behavior/behat.yml.dist",
"../../flow doctrine:migrate --quiet; ../../flow cr:setup",
"@test:behat-cli -c Neos.Neos/Tests/Behavior/behat.yml",
"@test:behat-cli -c Neos.ContentRepository.LegacyNodeMigration/Tests/Behavior/behat.yml.dist",
"@test:behat-cli -c Neos.TimeableNodeVisibility/Tests/Behavior/behat.yml.dist"
"@test:behat-cli -c Neos.ContentRepository.Export/Tests/Behavior/behat.yml.dist",
"@test:behat-cli -c Neos.TimeableNodeVisibility/Tests/Behavior/behat.yml.dist",
"../../flow doctrine:migrate --quiet; ../../flow cr:setup",
"@test:behat-cli -c Neos.Neos/Tests/Behavior/behat.yml"
],
"test:behavioral:sync": [
"@putenv CATCHUPTRIGGER_ENABLE_SYNCHRONOUS_OPTION=1",
"@test:behavioral"
],
"test:behavioral:stop-on-failure": [
"@test:behat-cli -vvv --stop-on-failure -c Neos.ContentRepository.BehavioralTests/Tests/Behavior/behat.yml.dist",
"@test:behat-cli -vvv --stop-on-failure -c Neos.ContentGraph.DoctrineDbalAdapter/Tests/Behavior/behat.yml.dist",
"../../flow doctrine:migrate --quiet; ../../flow cr:setup",
"@test:behat-cli -vvv --stop-on-failure -c Neos.Neos/Tests/Behavior/behat.yml",
"@test:behat-cli -vvv --stop-on-failure -c Neos.ContentRepository.LegacyNodeMigration/Tests/Behavior/behat.yml.dist",
"@test:behat-cli -vvv --stop-on-failure -c Neos.TimeableNodeVisibility/Tests/Behavior/behat.yml.dist"
"@test:behat-cli -vvv --stop-on-failure -c Neos.ContentRepository.Export/Tests/Behavior/behat.yml.dist",
"@test:behat-cli -vvv --stop-on-failure -c Neos.TimeableNodeVisibility/Tests/Behavior/behat.yml.dist",
"../../flow doctrine:migrate --quiet; ../../flow cr:setup",
"@test:behat-cli -vvv --stop-on-failure -c Neos.Neos/Tests/Behavior/behat.yml"
],
"test:behavioral:stop-on-failure:sync": [
"@putenv CATCHUPTRIGGER_ENABLE_SYNCHRONOUS_OPTION=1",
"@test:behavioral:stop-on-failure"
],
"test": [
"@test:unit",
"@test:functional",
"@test:behavioral"
]
"@test:behavioral",
"@test:parallel"
],
"build:composer-json": "php ../../Build/BuildEssentials/ComposerManifestMerger.php"
},
"autoload": {
},
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ jobs:
- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v2
timeout-minutes: 30
with:
path: |
~/.cache/composer
Expand Down Expand Up @@ -248,7 +249,7 @@ jobs:
# DEBUG MODE: ALTERNATIVELY, comment in the following lines to dump the DB.
# do not exit the script if the tests break; as we want to upload the database dumps afterwards.
set +e
CATCHUPTRIGGER_ENABLE_SYNCHRONOUS_OPTION=1 composer test:behavioral:stop-on-failure
composer test:behavioral:stop-on-failure:sync
retVal=$?
# automatically search for race conditions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
use Neos\ContentRepository\BehavioralTests\TestSuite\Behavior\GherkinPyStringNodeBasedNodeTypeManagerFactory;
use Neos\ContentRepository\BehavioralTests\TestSuite\Behavior\GherkinTableNodeBasedContentDimensionSourceFactory;
use Neos\ContentRepository\Core\ContentRepository;
use Neos\ContentRepository\Core\Factory\ContentRepositoryId;
use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceFactoryInterface;
use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceInterface;
use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId;
use Neos\ContentRepository\TestSuite\Behavior\Features\Bootstrap\CRTestSuiteTrait;
use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@
use Doctrine\DBAL\Exception\InvalidArgumentException;
use Neos\ContentGraph\DoctrineDbalAdapter\DoctrineDbalContentGraphProjectionFactory;
use Neos\ContentGraph\DoctrineDbalAdapter\DoctrineDbalProjectionIntegrityViolationDetectionRunnerFactory;
use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\NodeFactory;
use Neos\ContentGraph\DoctrineDbalAdapter\Tests\Behavior\Features\Bootstrap\Helpers\TestingNodeAggregateId;
use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint;
use Neos\ContentRepository\Core\SharedModel\Id\UuidFactory;
use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId;
use Neos\ContentRepository\Core\Feature\SubtreeTagging\Dto\SubtreeTag;
use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId;
use Neos\ContentGraph\DoctrineDbalAdapter\Tests\Behavior\Features\Bootstrap\Helpers\TestingNodeAggregateId;
use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId;
use Neos\ContentRepository\TestSuite\Behavior\Features\Bootstrap\CRTestSuiteRuntimeVariables;
use Neos\ContentRepositoryRegistry\DoctrineDbalClient\DoctrineDbalClient;
use Neos\Error\Messages\Error;
Expand Down Expand Up @@ -64,53 +65,24 @@ public function setupDbalGraphAdapterIntegrityViolationTrait()
}

/**
* @When /^I remove the following restriction relation:$/
* @When /^I remove the following subtree tag:$/
* @param TableNode $payloadTable
* @throws DBALException
* @throws InvalidArgumentException
*/
public function iRemoveTheFollowingRestrictionRelation(TableNode $payloadTable): void
{
$dataset = $this->transformPayloadTableToDataset($payloadTable);
$record = $this->transformDatasetToRestrictionRelationRecord($dataset);

$this->dbalClient->getConnection()->delete(
$this->getTableNamePrefix() . '_restrictionrelation',
$record
);
}

/**
* @When /^I detach the following restriction relation from its origin:$/
* @param TableNode $payloadTable
* @throws DBALException
*/
public function iDetachTheFollowingRestrictionRelationFromItsOrigin(TableNode $payloadTable): void
{
$dataset = $this->transformPayloadTableToDataset($payloadTable);
$record = $this->transformDatasetToRestrictionRelationRecord($dataset);
$this->dbalClient->getConnection()->update(
$this->getTableNamePrefix() . '_restrictionrelation',
[
'originnodeaggregateid' => (string)TestingNodeAggregateId::nonExistent()
],
$record
);
}

/**
* @When /^I detach the following restriction relation from its target:$/
* @param TableNode $payloadTable
* @throws DBALException
*/
public function iDetachTheFollowingRestrictionRelationFromItsTarget(TableNode $payloadTable): void
public function iRemoveTheFollowingSubtreeTag(TableNode $payloadTable): void
{
$dataset = $this->transformPayloadTableToDataset($payloadTable);
$record = $this->transformDatasetToRestrictionRelationRecord($dataset);
$subtreeTagToRemove = SubtreeTag::fromString($dataset['subtreeTag']);
$record = $this->transformDatasetToHierarchyRelationRecord($dataset);
$subtreeTags = NodeFactory::extractNodeTagsFromJson($record['subtreetags']);
if (!$subtreeTags->contain($subtreeTagToRemove)) {
throw new \RuntimeException(sprintf('Failed to remove subtree tag "%s" because that tag is not set', $subtreeTagToRemove->value), 1708618267);
}
$this->dbalClient->getConnection()->update(
$this->getTableNamePrefix() . '_restrictionrelation',
$this->getTableNamePrefix() . '_hierarchyrelation',
[
'affectednodeaggregateid' => (string)TestingNodeAggregateId::nonExistent()
'subtreetags' => json_encode($subtreeTags->without($subtreeTagToRemove), JSON_THROW_ON_ERROR | JSON_FORCE_OBJECT),
],
$record
);
Expand Down Expand Up @@ -234,87 +206,83 @@ private function transformDatasetToReferenceRelationRecord(array $dataset): arra
{
return [
'name' => $dataset['referenceName'],
'nodeanchorpoint' => $this->findRelationAnchorPointByIds(
'nodeanchorpoint' => $this->findHierarchyRelationByIds(
ContentStreamId::fromString($dataset['contentStreamId']),
DimensionSpacePoint::fromArray($dataset['dimensionSpacePoint']),
NodeAggregateId::fromString($dataset['sourceNodeAggregateId'])
),
)['childnodeanchor'],
'destinationnodeaggregateid' => $dataset['destinationNodeAggregateId']
];
}

private function transformDatasetToRestrictionRelationRecord(array $dataset): array
{
$dimensionSpacePoint = DimensionSpacePoint::fromArray($dataset['dimensionSpacePoint']);

return [
'contentstreamid' => $dataset['contentStreamId'],
'dimensionspacepointhash' => $dimensionSpacePoint->hash,
'originnodeaggregateid' => $dataset['originNodeAggregateId'],
'affectednodeaggregateid' => $dataset['affectedNodeAggregateId'],
];
}

private function transformDatasetToHierarchyRelationRecord(array $dataset): array
{
$dimensionSpacePoint = DimensionSpacePoint::fromArray($dataset['dimensionSpacePoint']);
$parentNodeAggregateId = TestingNodeAggregateId::fromString($dataset['parentNodeAggregateId']);
$childAggregateId = TestingNodeAggregateId::fromString($dataset['childNodeAggregateId']);

$parentHierarchyRelation = $parentNodeAggregateId->isNonExistent()
? null
: $this->findHierarchyRelationByIds(
ContentStreamId::fromString($dataset['contentStreamId']),
$dimensionSpacePoint,
NodeAggregateId::fromString($dataset['parentNodeAggregateId'])
);

$childHierarchyRelation = $childAggregateId->isNonExistent()
? null
: $this->findHierarchyRelationByIds(
ContentStreamId::fromString($dataset['contentStreamId']),
$dimensionSpacePoint,
NodeAggregateId::fromString($dataset['childNodeAggregateId'])
);

return [
'contentstreamid' => $dataset['contentStreamId'],
'dimensionspacepoint' => $dimensionSpacePoint->toJson(),
'dimensionspacepointhash' => $dimensionSpacePoint->hash,
'parentnodeanchor' => $parentNodeAggregateId->isNonExistent()
? 9999999
: $this->findRelationAnchorPointByIds(
ContentStreamId::fromString($dataset['contentStreamId']),
$dimensionSpacePoint,
NodeAggregateId::fromString($dataset['parentNodeAggregateId'])
),
'childnodeanchor' => $childAggregateId->isNonExistent()
? 8888888
: $this->findRelationAnchorPointByIds(
ContentStreamId::fromString($dataset['contentStreamId']),
$dimensionSpacePoint,
NodeAggregateId::fromString($dataset['childNodeAggregateId'])
),
'position' => $dataset['position'] ?? 0
'parentnodeanchor' => $parentHierarchyRelation !== null ? $parentHierarchyRelation['childnodeanchor'] : 9999999,
'childnodeanchor' => $childHierarchyRelation !== null ? $childHierarchyRelation['childnodeanchor'] : 8888888,
'position' => $dataset['position'] ?? $parentHierarchyRelation !== null ? $parentHierarchyRelation['position'] : 0,
'subtreetags' => $parentHierarchyRelation !== null ? $parentHierarchyRelation['subtreetags'] : '{}',
];
}

private function findRelationAnchorPointByDataset(array $dataset): int
{
$dimensionSpacePoint = DimensionSpacePoint::fromArray($dataset['originDimensionSpacePoint'] ?? $dataset['dimensionSpacePoint']);

return $this->findRelationAnchorPointByIds(
return $this->findHierarchyRelationByIds(
ContentStreamId::fromString($dataset['contentStreamId']),
$dimensionSpacePoint,
NodeAggregateId::fromString($dataset['nodeAggregateId'] ?? $dataset['childNodeAggregateId'])
);
)['childnodeanchor'];
}

private function findRelationAnchorPointByIds(
private function findHierarchyRelationByIds(
ContentStreamId $contentStreamId,
DimensionSpacePoint $dimensionSpacePoint,
NodeAggregateId $nodeAggregateId
): int {
): array {
$nodeRecord = $this->dbalClient->getConnection()->executeQuery(
'SELECT n.relationanchorpoint
FROM ' . $this->getTableNamePrefix() . '_node n
INNER JOIN ' . $this->getTableNamePrefix() . '_hierarchyrelation h
ON n.relationanchorpoint = h.childnodeanchor
WHERE n.nodeaggregateid = :nodeAggregateId
AND h.contentstreamid = :contentStreamId
AND h.dimensionspacepointhash = :dimensionSpacePointHash',
'SELECT h.*
FROM ' . $this->getTableNamePrefix() . '_node n
INNER JOIN ' . $this->getTableNamePrefix() . '_hierarchyrelation h
ON n.relationanchorpoint = h.childnodeanchor
WHERE n.nodeaggregateid = :nodeAggregateId
AND h.contentstreamid = :contentStreamId
AND h.dimensionspacepointhash = :dimensionSpacePointHash',
[
'contentStreamId' => $contentStreamId->value,
'dimensionSpacePointHash' => $dimensionSpacePoint->hash,
'nodeAggregateId' => $nodeAggregateId->value
]
)->fetchAssociative();
if ($nodeRecord === false) {
throw new \InvalidArgumentException(sprintf('Failed to find hierarchy relation for content stream "%s", dimension space point "%s" and node aggregate id "%s"', $contentStreamId->value, $dimensionSpacePoint->hash, $nodeAggregateId->value), 1708617712);
}

return $nodeRecord['relationanchorpoint'];
return $nodeRecord;
}

private function transformPayloadTableToDataset(TableNode $payloadTable): array
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ Feature: Run integrity violation detection regarding hierarchy relations and nod
| workspaceDescription | "The live workspace" |
| newContentStreamId | "cs-identifier" |
And the graph projection is fully up to date
And I am in the active content stream of workspace "live" and dimension space point {}
And the command CreateRootNodeAggregateWithNode is executed with payload:
| Key | Value |
| contentStreamId | "cs-identifier" |
| nodeAggregateId | "lady-eleonode-rootford" |
| nodeTypeName | "Neos.ContentRepository:Root" |
And the event NodeAggregateWithNodeWasCreated was published with payload:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ Feature: Run integrity violation detection regarding parent relations
| workspaceDescription | "The live workspace" |
| newContentStreamId | "cs-identifier" |
And the graph projection is fully up to date
And I am in the active content stream of workspace "live" and dimension space point {"language":"de"}
And the command CreateRootNodeAggregateWithNode is executed with payload:
| Key | Value |
| contentStreamId | "cs-identifier" |
| nodeAggregateId | "lady-eleonode-rootford" |
| nodeTypeName | "Neos.ContentRepository:Root" |
And the event NodeAggregateWithNodeWasCreated was published with payload:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ Feature: Run integrity violation detection regarding reference relations
| workspaceDescription | "The live workspace" |
| newContentStreamId | "cs-identifier" |
And the graph projection is fully up to date
And I am in the active content stream of workspace "live" and dimension space point {"language":"de"}
And the command CreateRootNodeAggregateWithNode is executed with payload:
| Key | Value |
| contentStreamId | "cs-identifier" |
| nodeAggregateId | "lady-eleonode-rootford" |
| nodeTypeName | "Neos.ContentRepository:Root" |
And the event NodeAggregateWithNodeWasCreated was published with payload:
Expand All @@ -51,7 +51,6 @@ Feature: Run integrity violation detection regarding reference relations
Scenario: Detach a reference relation from its source
When the command SetNodeReferences is executed with payload:
| Key | Value |
| contentStreamId | "cs-identifier" |
| sourceOriginDimensionSpacePoint | {"language":"de"} |
| sourceNodeAggregateId | "source-nodandaise" |
| referenceName | "referenceProperty" |
Expand Down
Loading

0 comments on commit 5013a77

Please sign in to comment.