Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Content Repository Test Suite #4455

Merged
merged 39 commits into from
Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
0454bf0
Introduce test support suite package
Jul 13, 2023
93da115
Declare test suite package in distribution
Jul 13, 2023
ace0152
Rename test suite package
Jul 13, 2023
9d747cf
Fix namespace
Jul 13, 2023
6658ba4
Add autoloading to test suite
Jul 13, 2023
7bdd4e8
Merge branch '9.0' into testSuite
Jul 31, 2023
3ea1df2
Merge branch '9.0' into testSuite
Aug 1, 2023
bf16879
Extract feature traits to TestSuite package
Aug 1, 2023
6e86c07
Introduce the test suite to linting
Aug 1, 2023
9f0cbe2
WIP: Adjust test suite
Aug 17, 2023
7176e5a
Adjust NodeTraversal tests
Aug 17, 2023
80653e5
Adjust NodeTypeChange tests
Aug 17, 2023
f6be389
Adjust final test cases
Aug 17, 2023
86071fd
Clean up stuff
Aug 17, 2023
b79dcb4
Merge branch '9.0' into testSuite
Aug 17, 2023
b16bde1
Pacify linter
Aug 17, 2023
d614486
(hopefully) Increase readability of tests
Aug 18, 2023
ce3589d
Further separate tests from CR registry
Aug 18, 2023
9934739
Run tests only on one graph adapter
Aug 18, 2023
4e87058
Extract CurrentSubgraphTrait
Aug 18, 2023
673a6e3
Move test helpers / bootstrap traits to respective packages
Aug 18, 2023
087a0a6
Adjust behavioral tests to registry architecture
Aug 19, 2023
c52215f
Make CRRegistrySubjectProvider work for 3rd party applications
Aug 19, 2023
86e020a
Pacify linter
Aug 19, 2023
cec6451
Require behat and phpunit
Aug 20, 2023
d2f90b8
Adjust DBAL adapter tests
Aug 20, 2023
8bdd842
Revert obsolete changes on ContentRepositoryRegistry::buildFactory
Aug 20, 2023
8e63465
Clean up higher level feature contexts
Aug 20, 2023
f0720dd
run CR setup before cleanup
Aug 25, 2023
c51663d
Remove implicit dependency from TestSuite to BehavioralTests
Aug 25, 2023
3d0a7eb
properly name reset method and correct nodeTypeManager::getNodeTypes …
Aug 25, 2023
a182756
Adjust DoctrineDBAL adapter and Neos test suites
Aug 25, 2023
fb4714a
Adjust Neos.Neos behavioral tests
Aug 25, 2023
d7fea93
Fix typo
Aug 26, 2023
373d253
Merge branch '9.0' into testSuite
Aug 26, 2023
b3e6431
Move test suite helpers to test folders to avoid autoloading in non-t…
Aug 29, 2023
e12ebe4
Move BT helpers
Aug 29, 2023
d994260
Revert "Move BT helpers"
Aug 29, 2023
b11cbe4
Revert "Move test suite helpers to test folders to avoid autoloading …
Aug 29, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"suggest": {
},
"scripts": {
"lint:phpcs-psr12": "../../bin/phpcs --colors --standard=PSR12 ./Neos.ContentGraph.DoctrineDbalAdapter/src ./Neos.ContentGraph.PostgreSQLAdapter/src ./Neos.ContentRepository.BehavioralTests/Classes ./Neos.ContentRepository.Core/Classes ./Neos.Neos/Classes",
"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"
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,152 +12,79 @@
*/

require_once(__DIR__ . '/../../../../../../Application/Neos.Behat/Tests/Behat/FlowContextTrait.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/NodeOperationsTrait.php');
require_once(__DIR__ . '/../../../../../../Framework/Neos.Flow/Tests/Behavior/Features/Bootstrap/IsolatedBehatStepsTrait.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/Features/ContentStreamForking.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/Features/NodeCopying.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/Features/NodeCreation.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/Features/NodeDisabling.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/Features/NodeModification.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/Features/NodeMove.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/Features/NodeReferencing.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/Features/NodeRemoval.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/Features/NodeRenaming.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/Features/NodeTypeChange.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/Features/NodeVariation.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/Features/WorkspaceCreation.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/Features/WorkspaceDiscarding.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/Features/WorkspacePublishing.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/CurrentSubgraphTrait.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/CurrentUserTrait.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/CurrentDateTimeTrait.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/GenericCommandExecutionAndEventPublication.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/NodeTraversalTrait.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/ProjectedNodeAggregateTrait.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/ProjectedNodeTrait.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/EventSourcedTrait.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/MigrationsTrait.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/NodeOperationsTrait.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Security/Tests/Behavior/Features/Bootstrap/NodeAuthorizationTrait.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/StructureAdjustmentsTrait.php');
require_once(__DIR__ . '/ProjectionIntegrityViolationDetectionTrait.php');
require_once(__DIR__ . '/../../../../../Neos.ContentRepository.Core/Tests/Behavior/Features/Bootstrap/EventSourcedTrait.php');

use Behat\Behat\Context\Context as BehatContext;
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
use Neos\Behat\Tests\Behat\FlowContextTrait;
use Neos\ContentGraph\DoctrineDbalAdapter\Tests\Behavior\Features\Bootstrap\ProjectionIntegrityViolationDetectionTrait;
use Neos\ContentRepository\BehavioralTests\Tests\Functional\BehatTestHelper;
use Neos\ContentRepository\BehavioralTests\TestSuite\Behavior\CRBehavioralTestsSubjectProvider;
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\Infrastructure\DbalClientInterface;
use Neos\ContentRepository\Core\Tests\Behavior\Features\Bootstrap\Helpers\ContentRepositoryInternalsFactory;
use Neos\ContentRepository\Core\Tests\Behavior\Features\Bootstrap\Helpers\FakeClockFactory;
use Neos\ContentRepository\Core\Tests\Behavior\Features\Bootstrap\Helpers\FakeUserIdProviderFactory;
use Neos\ContentRepository\Core\Tests\Behavior\Features\Bootstrap\NodeOperationsTrait;
use Neos\ContentRepository\Core\Tests\Behavior\Features\Helper\ContentGraphs;
use Neos\ContentRepository\TestSuite\Behavior\Features\Bootstrap\CRTestSuiteTrait;
use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry;
use Neos\Flow\Configuration\ConfigurationManager;
use Neos\Flow\ObjectManagement\ObjectManagerInterface;
use Neos\Flow\Tests\Behavior\Features\Bootstrap\IsolatedBehatStepsTrait;
use Neos\Flow\Utility\Environment;

/**
* Features context
*/
class FeatureContext implements \Behat\Behat\Context\Context
class FeatureContext implements BehatContext
{
use FlowContextTrait;
use IsolatedBehatStepsTrait;
use ProjectionIntegrityViolationDetectionTrait;
use Neos\ContentRepository\Core\Tests\Behavior\Features\Bootstrap\EventSourcedTrait;
use NodeOperationsTrait;
use CRTestSuiteTrait;
use CRBehavioralTestsSubjectProvider;

protected string $behatTestHelperObjectName = BehatTestHelper::class;

protected ?ContentRepositoryRegistry $contentRepositoryRegistry = null;
protected ContentRepositoryRegistry $contentRepositoryRegistry;

public function __construct()
{
if (self::$bootstrap === null) {
self::$bootstrap = $this->initializeFlow();
}
$this->objectManager = self::$bootstrap->getObjectManager();
$this->setupEventSourcedTrait();
$this->setupDbalGraphAdapterIntegrityViolationTrait();
}
$this->contentRepositoryRegistry = $this->objectManager->get(ContentRepositoryRegistry::class);

/**
* @return ObjectManagerInterface
*/
protected function getObjectManager(): ObjectManagerInterface
{
return $this->objectManager;
$this->setupCRTestSuiteTrait();
$this->setupDbalGraphAdapterIntegrityViolationTrait();
}

/**
* @return Environment
* @BeforeScenario
*/
protected function getEnvironment()
public function resetContentRepositoryComponents(BeforeScenarioScope $scope): void
{
return $this->objectManager->get(Environment::class);
}

protected function initCleanContentRepository(array $adapterKeys): void
{
$this->logToRaceConditionTracker(['msg' => 'initCleanContentRepository']);

$configurationManager = $this->getObjectManager()->get(ConfigurationManager::class);
$registrySettings = $configurationManager->getConfiguration(
ConfigurationManager::CONFIGURATION_TYPE_SETTINGS,
'Neos.ContentRepositoryRegistry'
);

unset($registrySettings['presets'][$this->contentRepositoryId->value]['projections']['Neos.ContentGraph.PostgreSQLAdapter:Hypergraph']);
$registrySettings['presets'][$this->contentRepositoryId->value]['userIdProvider']['factoryObjectName'] = FakeUserIdProviderFactory::class;
$registrySettings['presets'][$this->contentRepositoryId->value]['clock']['factoryObjectName'] = FakeClockFactory::class;

$this->contentRepositoryRegistry = new ContentRepositoryRegistry(
$registrySettings,
$this->getObjectManager()
);


$this->contentRepository = $this->contentRepositoryRegistry->get($this->contentRepositoryId);
// Big performance optimization: only run the setup once - DRAMATICALLY reduces test time
if ($this->alwaysRunContentRepositorySetup || !self::$wasContentRepositorySetupCalled) {
$this->contentRepository->setUp();
self::$wasContentRepositorySetupCalled = true;
}
$this->contentRepositoryInternals = $this->contentRepositoryRegistry->buildService(
$this->contentRepositoryId,
new ContentRepositoryInternalsFactory()
);

$availableContentGraphs = [];
$availableContentGraphs['DoctrineDBAL'] = $this->contentRepository->getContentGraph();

if (count($availableContentGraphs) === 0) {
throw new \RuntimeException('No content graph active during testing. Please set one in settings in activeContentGraphs');
}
$this->availableContentGraphs = new ContentGraphs($availableContentGraphs);
GherkinTableNodeBasedContentDimensionSourceFactory::reset();
GherkinPyStringNodeBasedNodeTypeManagerFactory::reset();
}

protected function getContentRepositoryService(
ContentRepositoryId $contentRepositoryId,
ContentRepositoryServiceFactoryInterface $factory
): ContentRepositoryServiceInterface {
/** @var ContentRepositoryRegistry $contentRepositoryRegistry */
$contentRepositoryRegistry = $this->contentRepositoryRegistry
?: $this->objectManager->get(ContentRepositoryRegistry::class);

return $contentRepositoryRegistry->buildService(
$contentRepositoryId,
return $this->contentRepositoryRegistry->buildService(
$this->currentContentRepository->id,
$factory
);
}

protected function getDbalClient(): DbalClientInterface
{
return $this->dbalClient;
protected function createContentRepository(
ContentRepositoryId $contentRepositoryId
): ContentRepository {
$this->contentRepositoryRegistry->resetFactoryInstance($contentRepositoryId);
$contentRepository = $this->contentRepositoryRegistry->get($contentRepositoryId);
GherkinTableNodeBasedContentDimensionSourceFactory::reset();
GherkinPyStringNodeBasedNodeTypeManagerFactory::reset();

return $contentRepository;
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
<?php declare(strict_types=1);
namespace Neos\ContentRepository\Core\Tests\Behavior\Features\Helper;
<?php

/*
* This file is part of the Neos.ContentRepository package.
* This file is part of the Neos.ContentGraph.DoctrineDbalAdapter package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
Expand All @@ -11,6 +10,10 @@
* source code.
*/

declare(strict_types=1);

namespace Neos\ContentGraph\DoctrineDbalAdapter\Tests\Behavior\Features\Bootstrap\Helpers;

/**
* The testing node aggregate identifier value object
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
<?php
declare(strict_types=1);

namespace Neos\ContentGraph\DoctrineDbalAdapter\Tests\Behavior\Features\Bootstrap;

/*
* This file is part of the Neos.ContentGraph.DoctrineDbalAdapter package.
Expand All @@ -13,17 +10,20 @@
* source code.
*/

declare(strict_types=1);

namespace Neos\ContentGraph\DoctrineDbalAdapter\Tests\Behavior\Features\Bootstrap;

use Behat\Gherkin\Node\TableNode;
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Exception\InvalidArgumentException;
use Neos\ContentGraph\DoctrineDbalAdapter\DoctrineDbalContentGraphProjectionFactory;
use Neos\ContentGraph\DoctrineDbalAdapter\DoctrineDbalProjectionIntegrityViolationDetectionRunnerFactory;
use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint;
use Neos\ContentRepository\Core\Factory\ContentRepositoryId;
use Neos\ContentRepository\Core\Infrastructure\DbalClientInterface;
use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId;
use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId;
use Neos\ContentRepository\Core\Tests\Behavior\Features\Helper\TestingNodeAggregateId;
use Neos\ContentGraph\DoctrineDbalAdapter\Tests\Behavior\Features\Bootstrap\Helpers\TestingNodeAggregateId;
use Neos\ContentRepository\TestSuite\Behavior\Features\Bootstrap\CRTestSuiteRuntimeVariables;
use Neos\ContentRepositoryRegistry\Infrastructure\DbalClient;
use Neos\Error\Messages\Error;
use Neos\Error\Messages\Result;
Expand All @@ -35,16 +35,16 @@
*/
trait ProjectionIntegrityViolationDetectionTrait
{
use CRTestSuiteRuntimeVariables;

private DbalClient $dbalClient;

protected Result $lastIntegrityViolationDetectionResult;

abstract protected function getContentRepositoryId(): ContentRepositoryId;

protected function getTableNamePrefix(): string
{
return DoctrineDbalContentGraphProjectionFactory::graphProjectionTableNamePrefix(
$this->getContentRepositoryId()
$this->currentContentRepository->id
);
}

Expand Down Expand Up @@ -108,7 +108,6 @@ public function iDetachTheFollowingRestrictionRelationFromItsTarget(TableNode $p

/**
* @When /^I add the following hierarchy relation:$/
* @param TableNode $payloadTable
* @throws DBALException
*/
public function iAddTheFollowingHierarchyRelation(TableNode $payloadTable): void
Expand Down Expand Up @@ -303,7 +302,7 @@ private function transformPayloadTableToDataset(TableNode $payloadTable): array
*/
public function iRunIntegrityViolationDetection(): void
{
$projectionIntegrityViolationDetectionRunner = $this->getContentRepositoryService($this->getContentRepositoryId(), new DoctrineDbalProjectionIntegrityViolationDetectionRunnerFactory($this->dbalClient));
$projectionIntegrityViolationDetectionRunner = $this->getContentRepositoryService(new DoctrineDbalProjectionIntegrityViolationDetectionRunnerFactory($this->dbalClient));
$this->lastIntegrityViolationDetectionResult = $projectionIntegrityViolationDetectionRunner->run();
}

Expand Down Expand Up @@ -334,6 +333,4 @@ public function iExpectIntegrityViolationDetectionResultErrorNumberNToHaveCodeX(
$error->getCode()
);
}

abstract protected function getDbalClient(): DbalClientInterface;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ Feature: Run integrity violation detection regarding hierarchy relations and nod
As a user of the CR I want to know whether there are nodes or hierarchy relations with invalid hashes or parents / children

Background:
Given I have the following content dimensions:
Given using the following content dimensions:
| Identifier | Values | Generalizations |
| language | de, gsw, fr | gsw->de |
And I have the following NodeTypes configuration:
"""
And using the following node types:
"""yaml
'Neos.ContentRepository:Root': []
'Neos.ContentRepository.Testing:Document': []
"""
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" |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ Feature: Run integrity violation detection regarding parent relations
As a user of the CR I want to know whether there are nodes that have multiple parents per subgraph

Background:
Given I have the following content dimensions:
Given using the following content dimensions:
| Identifier | Values | Generalizations |
| language | de, gsw, fr | gsw->de |
And I have the following NodeTypes configuration:
"""
And using the following node types:
"""yaml
'Neos.ContentRepository:Root': []
'Neos.ContentRepository.Testing:Document': []
"""
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" |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@ Feature: Run integrity violation detection regarding reference relations
As a user of the CR I want to know whether there are disconnected reference relations

Background:
Given I have the following content dimensions:
Given using the following content dimensions:
| Identifier | Values | Generalizations |
| language | de, gsw, fr | gsw->de |
And I have the following NodeTypes configuration:
"""
And using the following node types:
"""yaml
'Neos.ContentRepository:Root': []
'Neos.ContentRepository.Testing:Document':
properties:
referenceProperty:
type: reference
"""
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" |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ Feature: Run integrity violation detection regarding restriction relations
As a user of the CR I want to know whether there are nodes with restriction relations missing from their ancestors

Background:
Given I have the following content dimensions:
Given using the following content dimensions:
| Identifier | Values | Generalizations |
| language | de, gsw, fr | gsw->de |
And I have the following NodeTypes configuration:
"""
And using the following node types:
"""yaml
'Neos.ContentRepository:Root': []
'Neos.ContentRepository.Testing:Document': []
"""
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" |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ Feature: Run integrity violation detection regarding restriction relations
As a user of the CR I want to know whether there are nodes with restriction relations missing from their ancestors

Background:
Given I have the following content dimensions:
Given using the following content dimensions:
| Identifier | Values | Generalizations |
| language | de, gsw, fr | gsw->de |
And I have the following NodeTypes configuration:
"""
And using the following node types:
"""yaml
'Neos.ContentRepository:Root': []
'Neos.ContentRepository.Testing:Document': []
"""
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" |
Expand Down
Loading