|
1 | 1 | <?php |
2 | 2 |
|
| 3 | +declare(strict_types=1); |
| 4 | + |
3 | 5 | use Behat\Behat\Context\Context; |
4 | 6 | use Behat\Gherkin\Node\PyStringNode; |
| 7 | +use Composer\InstalledVersions; |
5 | 8 | use Flowpack\DecoupledContentStore\Command\ContentReleaseValidationCommandController; |
6 | 9 | use Flowpack\DecoupledContentStore\ContentReleaseManager; |
7 | 10 | use Flowpack\DecoupledContentStore\Core\ConcurrentBuildLockService; |
8 | 11 | use Flowpack\DecoupledContentStore\Core\Domain\ValueObject\ContentReleaseIdentifier; |
9 | 12 | use Flowpack\DecoupledContentStore\Core\Domain\ValueObject\PrunnerJobId; |
10 | 13 | use Flowpack\DecoupledContentStore\Core\Domain\ValueObject\RedisInstanceIdentifier; |
11 | | -use Flowpack\DecoupledContentStore\Exception as DecoupledContentStoreException; |
12 | | -use Flowpack\DecoupledContentStore\QuickPublish\Dto\NodeIdentifiers; |
13 | | -use Flowpack\DecoupledContentStore\QuickPublish\Infrastructure\RedisReleaseCopyService; |
14 | | -use Flowpack\DecoupledContentStore\QuickPublish\QuickPublishNodeEnumerator; |
15 | | -use Flowpack\DecoupledContentStore\Core\RedisKeyService; |
16 | 14 | use Flowpack\DecoupledContentStore\Core\Infrastructure\ContentReleaseLogger; |
17 | 15 | use Flowpack\DecoupledContentStore\Core\Infrastructure\RedisClientManager; |
| 16 | +use Flowpack\DecoupledContentStore\Core\RedisKeyService; |
| 17 | +use Flowpack\DecoupledContentStore\Exception as DecoupledContentStoreException; |
18 | 18 | use Flowpack\DecoupledContentStore\IncrementalContentReleaseHandler; |
19 | 19 | use Flowpack\DecoupledContentStore\NodeEnumeration\Domain\Repository\RedisEnumerationRepository; |
20 | 20 | use Flowpack\DecoupledContentStore\NodeEnumeration\Domain\Service\NodeContextCombinator; |
|
32 | 32 | use Flowpack\DecoupledContentStore\NodeRendering\ProcessEvents\RenderingQueueFilledEvent; |
33 | 33 | use Flowpack\DecoupledContentStore\NodeRendering\Render\CustomFusionView; |
34 | 34 | use Flowpack\DecoupledContentStore\PrepareContentRelease\Infrastructure\RedisContentReleaseService; |
| 35 | +use Flowpack\DecoupledContentStore\QuickPublish\Dto\NodeIdentifiers; |
| 36 | +use Flowpack\DecoupledContentStore\QuickPublish\Infrastructure\RedisReleaseCopyService; |
| 37 | +use Flowpack\DecoupledContentStore\QuickPublish\QuickPublishNodeEnumerator; |
35 | 38 | use Flowpack\DecoupledContentStore\Tests\Behavior\Fixtures\StubPrunnerApiService; |
36 | | -use Neos\Behat\Tests\Behat\FlowContextTrait; |
| 39 | +use Neos\Behat\FlowBootstrapTrait; |
| 40 | +use Neos\Behat\FlowEntitiesTrait; |
37 | 41 | use Neos\ContentRepository\Domain\Model\NodeInterface; |
38 | 42 | use Neos\ContentRepository\Domain\Repository\WorkspaceRepository; |
39 | 43 | use Neos\ContentRepository\Domain\Service\NodeTypeManager; |
40 | 44 | use Neos\ContentRepository\Tests\Behavior\Features\Bootstrap\NodeOperationsTrait; |
| 45 | +use Neos\Flow\Mvc\ActionRequest; |
41 | 46 | use Neos\Flow\ObjectManagement\ObjectManagerInterface; |
42 | 47 | use Neos\Flow\Persistence\PersistenceManagerInterface; |
43 | | -use Neos\Flow\Tests\Behavior\Features\Bootstrap\SecurityOperationsTrait; |
| 48 | +use Neos\Flow\Security\Account; |
| 49 | +use Neos\Flow\Security\Authentication\AuthenticationProviderManager; |
| 50 | +use Neos\Flow\Security\Authentication\Provider\TestingProvider; |
| 51 | +use Neos\Flow\Security\Authentication\TokenAndProviderFactoryInterface; |
| 52 | +use Neos\Flow\Security\Authentication\TokenInterface; |
| 53 | +use Neos\Flow\Security\Context as SecurityContext; |
| 54 | +use Neos\Flow\Security\Policy\PolicyService; |
44 | 55 | use Neos\Neos\Domain\Model\Domain; |
45 | 56 | use Neos\Neos\Domain\Model\Site; |
46 | 57 | use Neos\Neos\Domain\Repository\DomainRepository; |
|
49 | 60 | use Neos\Utility\Arrays; |
50 | 61 | use Neos\Utility\ObjectAccess; |
51 | 62 | use PHPUnit\Framework\Assert; |
| 63 | +use Psr\Http\Message\ServerRequestFactoryInterface; |
52 | 64 | use Symfony\Component\Console\Output\BufferedOutput; |
53 | 65 | use Symfony\Component\Yaml\Yaml; |
54 | 66 |
|
55 | | -require_once __DIR__ . '/../../../../../../Packages/Application/Neos.Behat/Tests/Behat/FlowContextTrait.php'; |
56 | | -require_once |
57 | | - __DIR__ |
58 | | - . '/../../../../../../Packages/Application/Neos.ContentRepository/Tests/Behavior/Features/Bootstrap/NodeOperationsTrait.php'; |
59 | | -require_once |
60 | | - __DIR__ |
61 | | - . '/../../../../../../Packages/Framework/Neos.Flow/Tests/Behavior/Features/Bootstrap/SecurityOperationsTrait.php'; |
| 67 | +// The content repository keeps its step definitions in a directory no autoloader knows about, so the file has to be |
| 68 | +// included by hand. Composer knows where the package was installed, which holds wherever this package itself sits - |
| 69 | +// inside a Neos installation as well as in a checkout of its own. |
| 70 | +require_once InstalledVersions::getInstallPath('neos/content-repository') |
| 71 | + . '/Tests/Behavior/Features/Bootstrap/NodeOperationsTrait.php'; |
62 | 72 |
|
63 | 73 | /** |
64 | 74 | * Features context |
65 | 75 | */ |
66 | 76 | class FeatureContext implements Context |
67 | 77 | { |
68 | | - use FlowContextTrait; |
69 | | - use SecurityOperationsTrait; |
| 78 | + use FlowBootstrapTrait; |
| 79 | + use FlowEntitiesTrait; |
70 | 80 | use NodeOperationsTrait; |
71 | 81 |
|
| 82 | + /** |
| 83 | + * The step definitions of the content repository run their steps in a sub process where this is TRUE, which none |
| 84 | + * of the features here ask for. |
| 85 | + */ |
72 | 86 | protected $isolated = false; |
73 | 87 |
|
74 | 88 | /** |
75 | 89 | * @var ObjectManagerInterface |
76 | 90 | */ |
77 | 91 | protected $objectManager; |
78 | 92 |
|
| 93 | + private SecurityContext $securityContext; |
| 94 | + private ActionRequest $securityActionRequest; |
| 95 | + private AuthenticationProviderManager $authenticationManager; |
| 96 | + private TestingProvider $testingProvider; |
| 97 | + private PolicyService $policyService; |
| 98 | + |
79 | 99 | private ?InterruptibleProcessRuntime $renderOrchestratorProcess; |
80 | 100 | private ?InterruptibleProcessRuntimeEventInterface $renderOrchestratorProcessLastEvent; |
81 | 101 | private StubPrunnerApiService $stubPrunnerApiService; |
82 | 102 | private BufferedOutput $renderOrchestratorProcessBufferedOutput; |
83 | 103 |
|
84 | 104 | public function __construct() |
85 | 105 | { |
86 | | - if (self::$bootstrap === null) { |
87 | | - self::$bootstrap = $this->initializeFlow(); |
88 | | - } |
89 | | - $this->objectManager = self::$bootstrap->getObjectManager(); |
| 106 | + $this->objectManager = self::bootstrapFlow()->getObjectManager(); |
90 | 107 | $this->setupSecurity(); |
91 | 108 |
|
92 | 109 | // for testing, we use Private/EndToEndTestFusion as fusion folder to load. |
@@ -116,6 +133,63 @@ public function getObjectManager(): ObjectManagerInterface |
116 | 133 | return $this->objectManager; |
117 | 134 | } |
118 | 135 |
|
| 136 | + /** |
| 137 | + * Persist any changes - part of what the content repository's step definitions expect from their context. |
| 138 | + */ |
| 139 | + public function persistAll(): void |
| 140 | + { |
| 141 | + $persistenceManager = $this->getObject(PersistenceManagerInterface::class); |
| 142 | + $persistenceManager->persistAll(); |
| 143 | + $persistenceManager->clearState(); |
| 144 | + |
| 145 | + // roles are read through the policy service, which holds on to them across a database reset |
| 146 | + $this->policyService->reset(); |
| 147 | + } |
| 148 | + |
| 149 | + /** |
| 150 | + * The authentication a scenario gets through "I am authenticated with role" needs a security context which has |
| 151 | + * a request, and a TestingProvider to hand the account to. |
| 152 | + */ |
| 153 | + private function setupSecurity(): void |
| 154 | + { |
| 155 | + $this->policyService = $this->getObject(PolicyService::class); |
| 156 | + $this->authenticationManager = $this->getObject(AuthenticationProviderManager::class); |
| 157 | + |
| 158 | + // asking for the providers is what builds them, and with them the singleton TestingProvider |
| 159 | + $providers = $this->getObject(TokenAndProviderFactoryInterface::class)->getProviders(); |
| 160 | + $this->testingProvider = $providers['TestingProvider']; |
| 161 | + |
| 162 | + $httpRequest = $this->getObject(ServerRequestFactoryInterface::class) |
| 163 | + ->createServerRequest('GET', 'http://localhost/'); |
| 164 | + $this->securityActionRequest = ActionRequest::fromHttpRequest($httpRequest); |
| 165 | + |
| 166 | + $this->securityContext = $this->getObject(SecurityContext::class); |
| 167 | + $this->securityContext->clearContext(); |
| 168 | + $this->securityContext->setRequest($this->securityActionRequest); |
| 169 | + } |
| 170 | + |
| 171 | + /** |
| 172 | + * @Given /^I am authenticated with role "([^"]*)"$/ |
| 173 | + */ |
| 174 | + public function iAmAuthenticatedWithRole(string $roleIdentifier): void |
| 175 | + { |
| 176 | + $roles = []; |
| 177 | + foreach (Arrays::trimExplode(',', $roleIdentifier) as $roleName) { |
| 178 | + $roles[] = $this->policyService->getRole($roleName); |
| 179 | + } |
| 180 | + |
| 181 | + $account = new Account(); |
| 182 | + $account->setAccountIdentifier('TestAccount'); |
| 183 | + $account->setRoles($roles); |
| 184 | + |
| 185 | + $this->testingProvider->setAuthenticationStatus(TokenInterface::AUTHENTICATION_SUCCESSFUL); |
| 186 | + $this->testingProvider->setAccount($account); |
| 187 | + |
| 188 | + $this->securityContext->clearContext(); |
| 189 | + $this->securityContext->setRequest($this->securityActionRequest); |
| 190 | + $this->authenticationManager->authenticate(); |
| 191 | + } |
| 192 | + |
119 | 193 | /** |
120 | 194 | * @BeforeScenario @resetRedis |
121 | 195 | */ |
@@ -331,7 +405,7 @@ public function theEnumerationContainsNode($contentReleaseIdentifier, $expectedC |
331 | 405 | } )() |
332 | 406 | ); |
333 | 407 |
|
334 | | - Assert::assertCount($expectedCount, $enumerationAsArray); |
| 408 | + Assert::assertCount((int)$expectedCount, $enumerationAsArray); |
335 | 409 | } |
336 | 410 |
|
337 | 411 | /** |
@@ -488,7 +562,7 @@ public function duringRenderingOfContentReleaseSomeErrorsOccured($contentRelease |
488 | 562 | $contentReleaseIdentifier = ContentReleaseIdentifier::fromString($contentReleaseIdentifier); |
489 | 563 | $redisRenderingErrorManager = $this->getObjectManager()->get(RedisRenderingErrorManager::class); |
490 | 564 | $renderingErrors = $redisRenderingErrorManager->getRenderingErrors($contentReleaseIdentifier); |
491 | | - Assert::assertCount($expectedNumberOfErrors, $renderingErrors); |
| 565 | + Assert::assertCount((int)$expectedNumberOfErrors, $renderingErrors); |
492 | 566 | } |
493 | 567 |
|
494 | 568 | private const DEFAULT_NODETYPES_CONFIG = <<<EOF |
|
0 commit comments