From cd371cc9ebd111cc64776ef1b04f9a1acd8aa6e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Noco=C5=84?= Date: Thu, 31 Mar 2022 16:33:05 +0200 Subject: [PATCH] [Behat] Divided Query Controller tests into setup and execution (#297) --- .github/workflows/browser-tests.yaml | 3 +- .../Context/QueryControllerContext.php | 305 +----------------- .../QueryController/query_controller.feature | 199 +----------- .../Features/QueryController/setup.feature | 101 ++++++ .../Resources/config/feature_contexts.yml | 5 +- .../EzPublishCoreBundle/behat_suites.yml | 14 +- phpstan-baseline.neon | 5 - 7 files changed, 130 insertions(+), 502 deletions(-) create mode 100644 eZ/Bundle/EzPublishCoreBundle/Features/QueryController/setup.feature diff --git a/.github/workflows/browser-tests.yaml b/.github/workflows/browser-tests.yaml index d2403c450c..797e0c7bd4 100644 --- a/.github/workflows/browser-tests.yaml +++ b/.github/workflows/browser-tests.yaml @@ -14,6 +14,7 @@ jobs: with: project-edition: 'oss' project-version: '^3.3.x-dev' - test-suite: '--mode=standard --profile=core --tags=~@broken' + test-setup-phase-1: '--mode=standard --profile=core --suite=setup' + test-suite: "--mode=standard --profile=core --tags='~@broken&&~@setup'" secrets: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} diff --git a/eZ/Bundle/EzPublishCoreBundle/Features/Context/QueryControllerContext.php b/eZ/Bundle/EzPublishCoreBundle/Features/Context/QueryControllerContext.php index cffdc80ede..bb21773509 100644 --- a/eZ/Bundle/EzPublishCoreBundle/Features/Context/QueryControllerContext.php +++ b/eZ/Bundle/EzPublishCoreBundle/Features/Context/QueryControllerContext.php @@ -6,233 +6,11 @@ */ namespace eZ\Bundle\EzPublishCoreBundle\Features\Context; -use Behat\Behat\Context\Context; -use Behat\Behat\Hook\Scope\BeforeScenarioScope; -use Behat\Gherkin\Node\PyStringNode; use Behat\MinkExtension\Context\RawMinkContext; -use eZ\Publish\API\Repository\Repository; -use eZ\Publish\API\Repository\Values\Content\Content; use PHPUnit\Framework\Assert; -use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\Yaml\Yaml; -class QueryControllerContext extends RawMinkContext implements Context +class QueryControllerContext extends RawMinkContext { - /** @var YamlConfigurationContext */ - private $configurationContext; - - /** - * Content item matched by the view configuration. - * - * @var \eZ\Publish\API\Repository\Values\Content\Content - */ - private $matchedContent; - - public function __construct(Repository $repository) - { - $this->repository = $repository; - } - - /** @BeforeScenario */ - public function gatherContexts(BeforeScenarioScope $scope) - { - $environment = $scope->getEnvironment(); - - $this->configurationContext = $environment->getContext( - 'eZ\Bundle\EzPublishCoreBundle\Features\Context\YamlConfigurationContext' - ); - } - - /** - * @Given /^the following content view configuration block:$/ - */ - public function addContentViewConfigurationBlock(PyStringNode $string) - { - $configurationBlock = array_merge( - Yaml::parse($string), - [ - 'template' => '@eZBehat/tests/dump.html.twig', - 'match' => [ - 'Id\Content' => $this->matchedContent->id, - ], - ] - ); - - $configurationBlockName = 'behat_query_controller_' . $this->matchedContent->id; - - $configuration = [ - 'ezplatform' => [ - 'system' => [ - 'default' => [ - 'content_view' => [ - 'full' => [ - $configurationBlockName => $configurationBlock, - ], - ], - ], - ], - ], - ]; - - $this->configurationContext->addConfiguration($configuration); - } - - /** - * @Given /^the following content view configuration block with paging action:$/ - */ - public function addContentViewConfigurationBlockWithPagingAction(PyStringNode $string) - { - $configurationBlock = array_merge( - Yaml::parse($string), - [ - 'template' => '@eZBehat/tests/dump.html.twig', - 'match' => [ - 'Id\Content' => $this->matchedContent->id, - ], - ] - ); - - $configurationBlockName = 'behat_paging_query_controller_' . $this->matchedContent->id; - - $configuration = [ - 'ezplatform' => [ - 'system' => [ - 'default' => [ - 'content_view' => [ - 'full' => [ - $configurationBlockName => $configurationBlock, - ], - ], - ], - ], - ], - ]; - - $this->configurationContext->addConfiguration($configuration); - } - - /** - * @Given /^a content item that matches the view configuration block below$/ - */ - public function aContentItemThatMatchesTheViewConfigurationBlockBelow() - { - $this->matchedContent = $this->repository->sudo(function (Repository $repository) { - return $this->createFolder($repository); - }); - } - - /** - * @Given :arg1 contents are created to test paging - */ - public function contentsAreCreatedToTestPaging2($numberOfContents) - { - for ($i = 0; $i < $numberOfContents; ++$i) { - $this->repository->sudo(function (Repository $repository) { - return $this->createFolder($repository); - }); - } - } - - /** - * @return \eZ\Publish\API\Repository\Values\Content\Content - */ - private function createFolder(Repository $repository) - { - $contentService = $repository->getContentService(); - $contentTypeService = $repository->getContentTypeService(); - $locationService = $repository->getLocationService(); - - $struct = $contentService->newContentCreateStruct( - $contentTypeService->loadContentTypeByIdentifier('folder'), - 'eng-GB' - ); - - $struct->setField('name', uniqid('Query Controller BDD ', true)); - - $contentDraft = $contentService->createContent( - $struct, - [$locationService->newLocationCreateStruct(2)] - ); - $contentService->publishVersion($contentDraft->versionInfo); - - return $contentService->loadContent($contentDraft->id); - } - - /** - * @Given /^a LocationChildren QueryType defined in "([^"]*)":$/ - */ - public function createPhpFile($phpFilePath, PyStringNode $phpFileContents) - { - $fs = new Filesystem(); - $fs->mkdir(\dirname($phpFilePath)); - $fs->dumpFile($phpFilePath, $phpFileContents); - if ($this->configurationContext->isSymfonyCacheClearRequired()) { - $this->configurationContext->clearSymfonyCache(); - } - } - - /** - * @When /^I view a content matched by the view configuration above$/ - */ - public function visitMatchedContent() - { - $urlAliasService = $this->repository->getURLAliasService(); - $urlAlias = $urlAliasService->reverseLookup( - $this->repository->getLocationService()->loadLocation( - $this->matchedContent->contentInfo->mainLocationId - ) - ); - - $this->visitPath($urlAlias->path); - - if ($this->getSession()->getStatusCode() !== 200) { - $page = $this->getSession()->getPage(); - $exceptionElements = $page->findAll('xpath', "//div[@class='text-exception']/h1"); - $exceptionStackTraceItems = $page->findAll('xpath', "//ol[@id='traces-0']/li"); - if (\count($exceptionElements) > 0) { - $exceptionElement = $exceptionElements[0]; - $exceptionLines = [$exceptionElement->getText(), '']; - - foreach ($exceptionStackTraceItems as $stackTraceItem) { - $html = $stackTraceItem->getHtml(); - $html = substr($html, 0, strpos($html, '', '->', $html); - $exceptionLines[] = trim($html); - } - $message = 'An exception occurred during rendering:' . implode("\n", $exceptionLines); - Assert::assertTrue(false, $message); - } - } - $this->assertSession()->statusCodeEquals(200); - } - - /** - * @Then /^the viewed content's main location id is mapped to the parentLocationId QueryType parameter$/ - */ - public function theViewedContentSMainLocationIdIsMappedToTheParentLocationIdQueryTypeParameter() - { - // not sure how to assert that - } - - /** - * @Then /^a LocationChildren Query is built from the LocationChildren QueryType$/ - */ - public function aLocationChildrenQueryIsBuiltFromTheLocationChildrenQueryType() - { - // not sure how to assert that either - } - - /** - * @Given /^a Location Search is executed with the LocationChildren Query$/ - */ - public function aLocationSearchIsExecutedWithTheLocationChildrenQuery() - { - // still not sure... - } - /** * @Given /^the Query results are assigned to the "([^"]*)" twig variable$/ */ @@ -254,87 +32,6 @@ public function theQueryResultsAssignedToTheTwigVariableIsAObject($twigVariableN Assert::assertEquals($className, $variableTypes[$twigVariableName], "The $twigVariableName twig variable does not have $className type"); } - /** - * @Given /^the following template defined in "([^"]*)":$/ - */ - public function createTemplateFile($tplFilePath, PyStringNode $tplFileContents) - { - $fs = new Filesystem(); - $fs->mkdir(\dirname($tplFilePath)); - $fs->dumpFile($tplFilePath, $tplFileContents); - } - - /** - * @Given the following content view configuration block with paging action and the template set above: - */ - public function theFollowingContentViewConfigurationBlockWithPagingActionAndTheTemplateSetAbove(PyStringNode $string) - { - $configurationBlock = array_merge( - Yaml::parse($string), - [ - 'match' => [ - 'Id\Content' => $this->matchedContent->id, - ], - ] - ); - - $configurationBlockName = 'behat_paging_query_controller_' . $this->matchedContent->id; - - $configuration = [ - 'ezplatform' => [ - 'system' => [ - 'default' => [ - 'content_view' => [ - 'full' => [ - $configurationBlockName => $configurationBlock, - ], - ], - ], - ], - ], - ]; - - $this->configurationContext->addConfiguration($configuration); - } - - /** - * @When I view a content matched by the view configuration above on page :arg1 with the :arg2 parameter - */ - public function iViewAContentMatchedByTheViewConfigurationAboveOnPageWithTheParameter($pageNumber, $pageParam) - { - $urlAliasService = $this->repository->getURLAliasService(); - $urlAlias = $urlAliasService->reverseLookup( - $this->repository->getLocationService()->loadLocation( - $this->matchedContent->contentInfo->mainLocationId - ) - ); - - $this->visitPath($urlAlias->path . "?$pageParam=$pageNumber"); - - if ($this->getSession()->getStatusCode() !== 200) { - $page = $this->getSession()->getPage(); - $exceptionElements = $page->findAll('xpath', "//div[@class='text-exception']/h1"); - $exceptionStackTraceItems = $page->findAll('xpath', "//ol[@id='traces-0']/li"); - if (\count($exceptionElements) > 0) { - $exceptionElement = $exceptionElements[0]; - $exceptionLines = [$exceptionElement->getText(), '']; - - foreach ($exceptionStackTraceItems as $stackTraceItem) { - $html = $stackTraceItem->getHtml(); - $html = substr($html, 0, strpos($html, '', '->', $html); - $exceptionLines[] = trim($html); - } - $message = 'An exception occurred during rendering:' . implode("\n", $exceptionLines); - Assert::assertTrue(false, $message); - } - } - $this->assertSession()->statusCodeEquals(200); - } - /** * @Then the Query results assigned to the twig variable is a Pagerfanta object and has limit :arg1 and selected page :arg2 */ diff --git a/eZ/Bundle/EzPublishCoreBundle/Features/QueryController/query_controller.feature b/eZ/Bundle/EzPublishCoreBundle/Features/QueryController/query_controller.feature index ac904b0b4f..cf24ab542b 100644 --- a/eZ/Bundle/EzPublishCoreBundle/Features/QueryController/query_controller.feature +++ b/eZ/Bundle/EzPublishCoreBundle/Features/QueryController/query_controller.feature @@ -4,196 +4,23 @@ Feature: Query controller I want to run repository queries from content views Scenario: A content view can be configured to run and render a query - Given a content item that matches the view configuration block below - And the following content view configuration block: - """ - controller: ez_query:locationQueryAction - params: - query: - query_type: 'LocationChildren' - parameters: - parentLocationId: 2 - assign_results_to: 'children' - """ - And a LocationChildren QueryType defined in "src/QueryType/LocationChildrenQueryType.php": - """ - new ParentLocationId($parameters['parentLocationId']), - ]); - } - - public function getSupportedParameters() - { - return ['parentLocationId']; - } - - public static function getName() - { - return 'LocationChildren'; - } - } - """ - When I view a content matched by the view configuration above - Then the viewed content's main location id is mapped to the parentLocationId QueryType parameter - Then a LocationChildren Query is built from the LocationChildren QueryType - And a Location Search is executed with the LocationChildren Query + When I go to "QueryControllerContainer/QueryControllerItem1" And the Query results are assigned to the "children" twig variable Scenario: A content view can be configured to run and render a query and return a PagerFanta Object - Given a content item that matches the view configuration block below - And the following content view configuration block with paging action: - """ - controller: ez_query:pagingQueryAction - params: - query: - query_type: 'LocationChildren' - parameters: - parentLocationId: 2 - assign_results_to: 'children' - """ - And a LocationChildren QueryType defined in "src/QueryType/LocationChildrenQueryType.php": - """ - new ParentLocationId($parameters['parentLocationId']), - ]); - } - - public function getSupportedParameters() - { - return ['parentLocationId']; - } - - public static function getName() - { - return 'LocationChildren'; - } - } - """ - When I view a content matched by the view configuration above - Then the Query results assigned to the "children" twig variable is a "eZ\Publish\Core\Pagination\Pagerfanta\Pagerfanta" object + When I go to "QueryControllerContainer/QueryControllerItem2" + Then the Query results assigned to the "children" twig variable is a "eZ\Publish\Core\Pagination\Pagerfanta\Pagerfanta" object Scenario: A content view can be configured to run and render a query return a PagerFanta Object and set limit and page name - Given a content item that matches the view configuration block below - And the following template defined in "templates/tests.html.twig": - """ -
{{ children.currentPage }}
-
{{ children.maxPerPage }}
- """ - And the following content view configuration block with paging action and the template set above: - """ - controller: ez_query:pagingQueryAction - template: tests.html.twig - params: - query: - query_type: 'LocationChildren' - parameters: - parentLocationId: 2 - limit: 1 - assign_results_to: 'children' - """ - And a LocationChildren QueryType defined in "src/QueryType/LocationChildrenQueryType.php": - """ - new ParentLocationId($parameters['parentLocationId']), - ]); - } - - public function getSupportedParameters() - { - return ['parentLocationId']; - } - - public static function getName() - { - return 'LocationChildren'; - } - } - """ - When I view a content matched by the view configuration above - Then the Query results assigned to the twig variable is a Pagerfanta object and has limit "1" and selected page "1" + When I go to "QueryControllerContainer/QueryControllerItem3" + Then the Query results assigned to the twig variable is a Pagerfanta object and has limit "1" and selected page "1" + @APIUser:admin Scenario: A content view can be configured to run and render a query and set a specific page - Given a content item that matches the view configuration block below - And "3" contents are created to test paging - And the following template defined in "templates/tests.html.twig": - """ -
{{ children.currentPage }}
-
{{ children.maxPerPage }}
- """ - And the following content view configuration block with paging action and the template set above: - """ - controller: ez_query:pagingQueryAction - template: tests.html.twig - params: - query: - query_type: 'LocationChildren' - parameters: - parentLocationId: 2 - limit: 1 - page_param: p - assign_results_to: 'children' - """ - And a LocationChildren QueryType defined in "src/QueryType/LocationChildrenQueryType.php": - """ - new ParentLocationId($parameters['parentLocationId']), - ]); - } - - public function getSupportedParameters() - { - return ['parentLocationId']; - } - - public static function getName() - { - return 'LocationChildren'; - } - } - """ - When I view a content matched by the view configuration above on page "2" with the "p" parameter - Then the Query results assigned to the twig variable is a Pagerfanta object and has limit "1" and selected page "2" + Given I create "Folder" Content items in root in "eng-GB" + | short_name | + | TestPaginationItem1 | + | TestPaginationItem2 | + | TestPaginationItem3 | + When I go to "QueryControllerContainer/QueryControllerItem4?p=2" + Then the Query results assigned to the twig variable is a Pagerfanta object and has limit "1" and selected page "2" diff --git a/eZ/Bundle/EzPublishCoreBundle/Features/QueryController/setup.feature b/eZ/Bundle/EzPublishCoreBundle/Features/QueryController/setup.feature new file mode 100644 index 0000000000..be1f1569d0 --- /dev/null +++ b/eZ/Bundle/EzPublishCoreBundle/Features/QueryController/setup.feature @@ -0,0 +1,101 @@ +@setup +Feature: Query controller + In order to simplify listing items from the repository + As a developer + I want to run repository queries from content views + + @APIUser:admin + Scenario: Set up Query Controller tests + Given I create "Folder" Content items in root in "eng-GB" + | name | short_name | + | QueryControllerContainer | QueryControllerContainer | + And I create "Folder" Content items in "QueryControllerContainer" in "eng-GB" + | name | short_name | + | QueryControllerItem1 | QueryControllerItem1 | + | QueryControllerItem2 | QueryControllerItem2 | + | QueryControllerItem3 | QueryControllerItem3 | + | QueryControllerItem4 | QueryControllerItem4 | + And I append configuration to "default" siteaccess under "content_view.full" key + """ + query_controller_item_1: + template: "@eZBehat/tests/dump.html.twig" + match: + Id\Location: "%location_id(QueryControllerContainer/QueryControllerItem1)%" + controller: ez_query:locationQueryAction + params: + query: + query_type: 'LocationChildren' + parameters: + parentLocationId: 2 + assign_results_to: 'children' + query_controller_item_2: + template: "@eZBehat/tests/dump.html.twig" + match: + Id\Location: "%location_id(QueryControllerContainer/QueryControllerItem2)%" + controller: ez_query:pagingQueryAction + params: + query: + query_type: 'LocationChildren' + parameters: + parentLocationId: 2 + assign_results_to: 'children' + query_controller_item_3: + template: tests.html.twig + match: + Id\Location: "%location_id(QueryControllerContainer/QueryControllerItem3)%" + controller: ez_query:pagingQueryAction + params: + query: + query_type: 'LocationChildren' + parameters: + parentLocationId: 2 + limit: 1 + assign_results_to: 'children' + query_controller_item_4: + template: tests.html.twig + match: + Id\Location: "%location_id(QueryControllerContainer/QueryControllerItem4)%" + controller: ez_query:pagingQueryAction + params: + query: + query_type: 'LocationChildren' + parameters: + parentLocationId: 2 + page_param: p + limit: 1 + assign_results_to: 'children' + """ + And I create a file "src/QueryType/LocationChildrenQueryType.php" with contents + """ + new ParentLocationId($parameters['parentLocationId']), + ]); + } + + public function getSupportedParameters() + { + return ['parentLocationId']; + } + + public static function getName() + { + return 'LocationChildren'; + } + } + """ + And I create a file "templates/tests.html.twig" with contents + """ +
{{ children.currentPage }}
+
{{ children.maxPerPage }}
+ """ diff --git a/eZ/Bundle/EzPublishCoreBundle/Resources/config/feature_contexts.yml b/eZ/Bundle/EzPublishCoreBundle/Resources/config/feature_contexts.yml index 3c3deb155c..47331ea777 100644 --- a/eZ/Bundle/EzPublishCoreBundle/Resources/config/feature_contexts.yml +++ b/eZ/Bundle/EzPublishCoreBundle/Resources/config/feature_contexts.yml @@ -16,10 +16,7 @@ services: arguments: $kernel: '@kernel' - eZ\Bundle\EzPublishCoreBundle\Features\Context\QueryControllerContext: - public: true - arguments: - $repository: '@ezpublish.api.repository' + eZ\Bundle\EzPublishCoreBundle\Features\Context\QueryControllerContext: ~ eZ\Bundle\EzPublishCoreBundle\Features\Context\ContentTypeContext: public: true diff --git a/eZ/Bundle/EzPublishCoreBundle/behat_suites.yml b/eZ/Bundle/EzPublishCoreBundle/behat_suites.yml index 075ca91586..dc867a253d 100644 --- a/eZ/Bundle/EzPublishCoreBundle/behat_suites.yml +++ b/eZ/Bundle/EzPublishCoreBundle/behat_suites.yml @@ -17,7 +17,17 @@ core: - eZ\Bundle\EzPublishCoreBundle\Features\Context\ExceptionContext query_controller: paths: - - vendor/ezsystems/ezplatform-kernel/eZ/Bundle/EzPublishCoreBundle/Features/QueryController + - vendor/ezsystems/ezplatform-kernel/eZ/Bundle/EzPublishCoreBundle/Features/QueryController/query_controller.feature contexts: + - Behat\MinkExtension\Context\MinkContext - eZ\Bundle\EzPublishCoreBundle\Features\Context\QueryControllerContext - - eZ\Bundle\EzPublishCoreBundle\Features\Context\YamlConfigurationContext + - EzSystems\Behat\API\Context\ContentContext + - EzSystems\Behat\API\Context\TestContext + setup: + paths: + - vendor/ezsystems/ezplatform-kernel/eZ/Bundle/EzPublishCoreBundle/Features/QueryController/setup.feature + contexts: + - EzSystems\Behat\API\Context\ContentContext + - EzSystems\Behat\API\Context\TestContext + - EzSystems\Behat\Core\Context\ConfigurationContext + - EzSystems\Behat\Core\Context\FileContext diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index bf4bff99e4..60a2b473e7 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -55,11 +55,6 @@ parameters: count: 1 path: eZ/Bundle/EzPublishCoreBundle/Features/Context/ContentTypeContext.php - - - message: "#^Access to an undefined property eZ\\\\Bundle\\\\EzPublishCoreBundle\\\\Features\\\\Context\\\\QueryControllerContext\\:\\:\\$repository\\.$#" - count: 7 - path: eZ/Bundle/EzPublishCoreBundle/Features/Context/QueryControllerContext.php - - message: "#^Method eZ\\\\Bundle\\\\EzPublishCoreBundle\\\\Features\\\\Context\\\\UserContext\\:\\:ensureUserExists\\(\\) invoked with 2 parameters, 3\\-4 required\\.$#" count: 1