From 63eed53bfbba181c45edae0370ca8839bf136ff0 Mon Sep 17 00:00:00 2001 From: "v.scharf" Date: Thu, 9 Jul 2026 14:46:46 +0200 Subject: [PATCH] delete unused steps --- tests/acceptance/bootstrap/CliContext.php | 20 --- tests/acceptance/bootstrap/FeatureContext.php | 47 ----- .../bootstrap/FilesVersionsContext.php | 1 - tests/acceptance/bootstrap/OCSContext.php | 56 ------ .../bootstrap/PublicWebDavContext.php | 80 --------- tests/acceptance/bootstrap/Sharing.php | 12 -- .../acceptance/bootstrap/SharingNgContext.php | 1 - tests/acceptance/bootstrap/SpacesContext.php | 88 ---------- tests/acceptance/bootstrap/WebDav.php | 124 -------------- .../bootstrap/WebDavLockingContext.php | 39 ----- .../bootstrap/WebDavPropertiesContext.php | 161 ------------------ tests/acceptance/scripts/find-unused-steps.sh | 89 +++++++++- 12 files changed, 81 insertions(+), 637 deletions(-) diff --git a/tests/acceptance/bootstrap/CliContext.php b/tests/acceptance/bootstrap/CliContext.php index 7a9dcf7ee8..0178e9a162 100644 --- a/tests/acceptance/bootstrap/CliContext.php +++ b/tests/acceptance/bootstrap/CliContext.php @@ -1017,26 +1017,6 @@ class CliContext implements Context { sleep(1); } - /** - * - * @param string $space - * - * @return void - */ - #[When('the administrator deletes the project space :space on the POSIX filesystem')] - public function theAdministratorDeletesSpace(string $space): void { - $projectsStoragePath = $this->getProjectsStoragePath(); - $spaceId = $this->spacesContext->getSpaceIdByName($this->featureContext->getAdminUsername(), $space); - $spaceId = explode('$', $spaceId)[1]; - - $body = [ - "command" => "rm -r $projectsStoragePath/$spaceId", - "raw" => true - ]; - $this->featureContext->setResponse(CliHelper::runCommand($body)); - sleep(1); - } - /** * * @param string $attribute diff --git a/tests/acceptance/bootstrap/FeatureContext.php b/tests/acceptance/bootstrap/FeatureContext.php index c5769a549d..82746fc549 100644 --- a/tests/acceptance/bootstrap/FeatureContext.php +++ b/tests/acceptance/bootstrap/FeatureContext.php @@ -1341,34 +1341,6 @@ class FeatureContext extends BehatVariablesContext { $this->setResponse($this->sendingToWithDirectUrl($user, $verb, $endpoint)); } - /** - * - * @param string $method - * @param string $url - * @param string $password - * - * @return void - */ - #[When('the public sends HTTP method :method to URL :url with password :password')] - public function thePublicSendsHttpMethodToUrlWithPassword(string $method, string $url, string $password): void { - $password = $this->getActualPassword($password); - $token = $this->shareNgGetLastCreatedLinkShareToken(); - $fullUrl = $this->getBaseUrl() . $url; - $headers = [ - 'Public-Token' => $token - ]; - $this->setResponse( - HttpRequestHelper::sendRequest( - $fullUrl, - $this->getStepLineRef(), - $method, - "public", - $password, - $headers - ) - ); - } - /** * * @param string $user @@ -1440,25 +1412,6 @@ class FeatureContext extends BehatVariablesContext { $this->setResponse($this->sendingToWithDirectUrl($user, $method, $davPath, $content)); } - /** - * - * @param string $user - * @param string $verb - * @param string $url - * @param string $password - * - * @return void - */ - #[When('user :user sends HTTP method :verb to URL :url with password :password')] - public function userSendsHTTPMethodToUrlWithPassword( - string $user, - string $verb, - string $url, - string $password - ): void { - $this->setResponse($this->sendingToWithDirectUrl($user, $verb, $url, null, $password)); - } - /** * @param string $user * @param string $verb diff --git a/tests/acceptance/bootstrap/FilesVersionsContext.php b/tests/acceptance/bootstrap/FilesVersionsContext.php index 3fb8a1c9fe..69ab146580 100644 --- a/tests/acceptance/bootstrap/FilesVersionsContext.php +++ b/tests/acceptance/bootstrap/FilesVersionsContext.php @@ -535,7 +535,6 @@ class FilesVersionsContext implements Context { * * @return void */ - #[When('user :user gets the number of versions of file :file from space :space')] #[When('user :user tries to get the number of versions of file :file from space :space')] public function userGetsTheNumberOfVersionsOfFileFromSpace(string $user, string $file, string $space): void { $fileId = $this->spacesContext->getFileId($user, $space, $file); diff --git a/tests/acceptance/bootstrap/OCSContext.php b/tests/acceptance/bootstrap/OCSContext.php index 801e2abe0d..95b01d2bc7 100644 --- a/tests/acceptance/bootstrap/OCSContext.php +++ b/tests/acceptance/bootstrap/OCSContext.php @@ -239,30 +239,6 @@ class OCSContext implements Context { } } - /** - * - * @param string $statusCode1 - * @param string $statusCode2 - * - * @return void - * @throws Exception - */ - #[Then('the OCS status code should be :statusCode1 or :statusCode2')] - public function theOcsStatusCodeShouldBeOr(string $statusCode1, string $statusCode2): void { - $statusCodes = [$statusCode1,$statusCode1]; - $response = $this->featureContext->getResponse(); - $responseStatusCode = $this->getOCSResponseStatusCode( - $response - ); - Assert::assertContainsEquals( - $responseStatusCode, - $statusCodes, - "OCS status code is not any of the expected values " - . \implode(",", $statusCodes) . " got " . $responseStatusCode - ); - $this->featureContext->emptyLastOCSStatusCodesArray(); - } - /** * Check the text in an OCS status message * @@ -272,7 +248,6 @@ class OCSContext implements Context { * @return void */ #[Then('the OCS status message should be :statusMessage')] - #[Then('the OCS status message should be :statusMessage in language :language')] public function theOCSStatusMessageShouldBe(string $statusMessage, ?string $language = null): void { $language = TranslationHelper::getLanguage($language); $statusMessage = $this->getActualStatusMessage($statusMessage, $language); @@ -288,37 +263,6 @@ class OCSContext implements Context { ); } - /** - * Check the text in an OCS status message. - * Use this step form if the expected text contains double quotes, - * single quotes and other content that theOCSStatusMessageShouldBe() - * cannot handle. - * - * After the step, write the expected text in PyString form like: - * - * """ - * File "abc.txt" can't be shared due to reason "xyz" - * """ - * - * @param PyStringNode $statusMessage - * - * @return void - */ - #[Then('the OCS status message should be:')] - public function theOCSStatusMessageShouldBePyString( - PyStringNode $statusMessage - ): void { - Assert::assertEquals( - $statusMessage->getRaw(), - $this->getOCSResponseStatusMessage( - $this->featureContext->getResponse() - ), - 'Unexpected OCS status message: "' . $this->getOCSResponseStatusMessage( - $this->featureContext->getResponse() - ) . '" in response' - ); - } - /** * Parses the xml answer to get ocs response which doesn't match with * http one in v1 of the api. diff --git a/tests/acceptance/bootstrap/PublicWebDavContext.php b/tests/acceptance/bootstrap/PublicWebDavContext.php index a528561928..1f786d58df 100644 --- a/tests/acceptance/bootstrap/PublicWebDavContext.php +++ b/tests/acceptance/bootstrap/PublicWebDavContext.php @@ -66,7 +66,6 @@ class PublicWebDavContext implements Context { * * @return void */ - #[When('the public downloads the last public link shared file using the public WebDAV API')] #[When('the public tries to download the last public link shared file using the public WebDAV API')] public function downloadPublicFile(): void { $response = $this->downloadPublicFileWithRange(""); @@ -500,19 +499,6 @@ class PublicWebDavContext implements Context { $this->featureContext->pushToLastStatusCodesArrays(); } - /** - * - * @param string $filename target file name - * @param string $body content to upload - * - * @return void - */ - #[Given('the public has uploaded file :filename with content :body')] - public function thePublicHasUploadedFileWithContent(string $filename, string $body): void { - $response = $this->publicUploadContent($filename, '', $body); - $this->featureContext->theHTTPStatusCodeShouldBe([201, 204], "", $response); - } - /** * * @param string $password @@ -548,7 +534,6 @@ class PublicWebDavContext implements Context { * @return void */ #[Then('the public should not be able to download file :path from inside the last public link shared folder using the public WebDAV API without a password')] - #[Then('the public download of file :path from inside the last public link shared folder using the public WebDAV API should fail with HTTP status code :expectedHttpCode')] public function shouldNotBeAbleToDownloadFileInsidePublicSharedFolder( string $path, string $expectedHttpCode = "401" @@ -977,45 +962,6 @@ class PublicWebDavContext implements Context { $this->featureContext->setResponse($this->publicCreatesFolderUsingPassword($destination, '')); } - /** - * - * @param string $foldername - * @param string $password - * - * @return void - */ - #[Then('the public should be able to create folder :foldername in the last public link shared folder using the new public WebDAV API with password :password')] - public function publicShouldBeAbleToCreateFolderWithPassword( - string $foldername, - string $password - ): void { - $response = $this->publicCreatesFolderUsingPassword($foldername, $password); - $this->featureContext->theHTTPStatusCodeShouldBe(201, "", $response); - } - - /** - * - * @param string $foldername - * @param string $password - * @param string $expectedHttpCode - * - * @return void - */ - #[Then('the public creation of folder :foldername in the last public link shared folder using the new public WebDAV API with password :password should fail with HTTP status code :expectedHttpCode')] - public function publicCreationOfFolderWithPasswordShouldFail( - string $foldername, - string $password, - string $expectedHttpCode - ): void { - $response = $this->publicCreatesFolderUsingPassword($foldername, $password); - $this->featureContext->theHTTPStatusCodeShouldBe( - $expectedHttpCode, - "creation of $foldername in the last publicly shared folder should have failed with code " . - $expectedHttpCode, - $response - ); - } - /** * * @param string $fileName @@ -1047,32 +993,6 @@ class PublicWebDavContext implements Context { ); } - /** - * - * @param string $fileName - * @param string $mtime - * - * @return void - * @throws Exception - */ - #[Then('the mtime of file :fileName in the last shared public link using the WebDAV API should not be :mtime')] - public function theMtimeOfFileInTheLastSharedPublicLinkUsingTheWebdavApiShouldNotBe( - string $fileName, - string $mtime - ): void { - $token = $this->featureContext->getLastCreatedPublicShareToken(); - $baseUrl = $this->featureContext->getBaseUrl(); - Assert::assertNotEquals( - $mtime, - WebDavHelper::getMtimeOfFileInPublicLinkShare( - $baseUrl, - $fileName, - $token, - $this->featureContext->getStepLineRef() - ) - ); - } - /** * Uploads a file through the public WebDAV API and sets the response in FeatureContext * diff --git a/tests/acceptance/bootstrap/Sharing.php b/tests/acceptance/bootstrap/Sharing.php index 9eaeb9236d..88bb466eb0 100755 --- a/tests/acceptance/bootstrap/Sharing.php +++ b/tests/acceptance/bootstrap/Sharing.php @@ -1266,18 +1266,6 @@ trait Sharing { $this->pushToLastStatusCodesArrays(); } - /** - * - * @param string $user - * - * @return void - */ - #[Given('user :user has deleted the last share')] - public function userHasDeletedLastShareUsingTheSharingApi(string $user): void { - $response = $this->deleteLastShareUsingSharingApi($user); - $this->theHTTPStatusCodeShouldBeBetween(200, 299, $response); - } - /** * @param string $user * @param string $shareType user|group|link diff --git a/tests/acceptance/bootstrap/SharingNgContext.php b/tests/acceptance/bootstrap/SharingNgContext.php index da5415d5e7..5d9b2c5b9b 100644 --- a/tests/acceptance/bootstrap/SharingNgContext.php +++ b/tests/acceptance/bootstrap/SharingNgContext.php @@ -1196,7 +1196,6 @@ class SharingNgContext implements Context { * @throws JsonException * @throws GuzzleException */ - #[When('user :user removes own access from space :space using root endpoint of the Graph API')] #[When('user :user tries to remove own access from space :space using root endpoint of the Graph API')] public function userRemovesOwnAccessFromSpaceUsingGraphAPI( string $user, diff --git a/tests/acceptance/bootstrap/SpacesContext.php b/tests/acceptance/bootstrap/SpacesContext.php index 9e6130a678..a5ffe52877 100644 --- a/tests/acceptance/bootstrap/SpacesContext.php +++ b/tests/acceptance/bootstrap/SpacesContext.php @@ -2650,25 +2650,6 @@ class SpacesContext implements Context { ); } - /** - * - * @param string $user - * @param string $spaceName - * @param TableNode $table - * - * @return void - * @throws GuzzleException - */ - #[Given('user :user has created a share inside of space :spaceName with settings:')] - public function userHasSharedTheFollowingEntityInsideOfSpace( - string $user, - string $spaceName, - TableNode $table - ): void { - $response = $this->createShareResource($user, $spaceName, $table); - $this->featureContext->theHTTPStatusCodeShouldBe(200, "", $response); - } - /** * * @param string $user @@ -2819,53 +2800,6 @@ class SpacesContext implements Context { ); } - /** - * - * @param string $user - * @param string $spaceName - * @param TableNode $table - * - * @return void - * @throws GuzzleException - */ - #[Given('user :user has created a public link share inside of space :spaceName with settings:')] - public function userHasCreatedPublicLinkToEntityInsideOfSpaceRequest( - string $user, - string $spaceName, - TableNode $table - ): void { - $response = $this->createPublicLinkToEntityInsideOfSpaceRequest($user, $spaceName, $table); - - $this->featureContext->theHTTPStatusCodeShouldBe( - 200, - "Expected response status code should be 200", - $response - ); - } - - /** - * - * @param string $user - * @param string $spaceName - * @param string $recipient - * - * @return void - * @throws GuzzleException - */ - #[Given('user :user has unshared a space :spaceName shared with :recipient')] - public function userHasUnsharedASpaceSharedWith( - string $user, - string $spaceName, - string $recipient - ): void { - $response = $this->sendUnshareSpaceRequest($user, $spaceName, $recipient); - $this->featureContext->theHTTPStatusCodeShouldBe( - 200, - "Expected response status code should be 200", - $response - ); - } - /** * @param string $user * @param string $spaceName @@ -3159,28 +3093,6 @@ class SpacesContext implements Context { ); } - /** - * - * @param string $user - * @param string $spaceName - * - * @return void - * @throws GuzzleException - */ - #[Given('user :user has restored a disabled space :spaceName')] - public function userHasRestoredSpaceRequest( - string $user, - string $spaceName - ): void { - $response = $this->restoreSpace($user, $spaceName); - $expectedHTTPStatus = "200"; - $this->featureContext->theHTTPStatusCodeShouldBe( - $expectedHTTPStatus, - "Expected response status code should be $expectedHTTPStatus", - $response - ); - } - /** * @param string $user * @param string $spaceName diff --git a/tests/acceptance/bootstrap/WebDav.php b/tests/acceptance/bootstrap/WebDav.php index 2e14367fd8..3f3667ad0a 100644 --- a/tests/acceptance/bootstrap/WebDav.php +++ b/tests/acceptance/bootstrap/WebDav.php @@ -1880,27 +1880,6 @@ trait WebDav { $this->checkTheHTTPStatusCodeOfResponsesOnEachEndpoint($statusCodes); } - /** - * - * @param string $ocStatusCodes a comma-separated string of expected HTTP status codes when running on OpenCloud - * @param string $revaStatusCodes a comma-separated string of expected HTTP status codes when running on reva - * - * @return void - * @throws Exception - */ - #[Then('the HTTP status code of responses on each endpoint should be :ocStatusCodes on OpenCloud or :revaStatusCodes on reva')] - public function theHTTPStatusCodeOfResponsesOnEachEndpointShouldBeOcReva( - string $ocStatusCodes, - string $revaStatusCodes - ): void { - if (OcHelper::isTestingOnReva()) { - $expectedStatusCodes = $revaStatusCodes; - } else { - $expectedStatusCodes = $ocStatusCodes; - } - $this->checkTheHTTPStatusCodeOfResponsesOnEachEndpoint($expectedStatusCodes); - } - /** * * @param string $statusCodes @@ -3199,109 +3178,6 @@ trait WebDav { return $this->moveNewDavChunkToFinalFile($user, $id, $dest, $headers); } - /** - * - * @param string $user - * @param string $id - * @param string $type "asynchronously" or empty - * @param string $dest - * - * @return void - */ - #[When('/^user "([^"]*)" moves new chunk file with id "([^"]*)"\\s?(asynchronously|) to "([^"]*)" using the WebDAV API$/')] - public function userMovesNewChunkFileWithIdToMychunkedfile( - string $user, - string $id, - string $type, - string $dest - ): void { - $this->setResponse($this->userMoveNewChunkFileWithIdToMychunkedfile($user, $id, $type, $dest)); - } - - /** - * @param string $user - * @param string $id - * @param string $type "asynchronously" or empty - * @param string $dest - * @param int $size - * - * @return ResponseInterface - */ - public function userMoveNewChunkFileWithIdToMychunkedfileWithSize( - string $user, - string $id, - string $type, - string $dest, - int $size - ): ResponseInterface { - $headers = ['OC-Total-Length' => $size]; - if ($type === "asynchronously") { - $headers['OC-LazyOps'] = 'true'; - } - return $this->moveNewDavChunkToFinalFile( - $user, - $id, - $dest, - $headers - ); - } - - /** - * @param string $user - * @param string $id - * @param string $type "asynchronously" or empty - * @param string $dest - * @param string $checksum - * - * @return ResponseInterface - */ - public function userMoveNewChunkFileWithIdToMychunkedfileWithChecksum( - string $user, - string $id, - string $type, - string $dest, - string $checksum - ): ResponseInterface { - $headers = ['OC-Checksum' => $checksum]; - if ($type === "asynchronously") { - $headers['OC-LazyOps'] = 'true'; - } - return $this->moveNewDavChunkToFinalFile( - $user, - $id, - $dest, - $headers - ); - } - - /** - * - * @param string $user - * @param string $id - * @param string $type "asynchronously" or empty - * @param string $dest - * @param string $checksum - * - * @return void - */ - #[Given('/^user "([^"]*)" has moved new chunk file with id "([^"]*)"\\s?(asynchronously|) to "([^"]*)" with checksum "([^"]*)"')] - public function userHasMovedNewChunkFileWithIdToMychunkedfileWithChecksum( - string $user, - string $id, - string $type, - string $dest, - string $checksum - ): void { - $response = $this->userMoveNewChunkFileWithIdToMychunkedfileWithChecksum( - $user, - $id, - $type, - $dest, - $checksum - ); - $this->theHTTPStatusCodeShouldBe("201", "", $response); - } - /** * Move chunked new DAV file to final file * diff --git a/tests/acceptance/bootstrap/WebDavLockingContext.php b/tests/acceptance/bootstrap/WebDavLockingContext.php index 6604e77d9f..f5fb43624b 100644 --- a/tests/acceptance/bootstrap/WebDavLockingContext.php +++ b/tests/acceptance/bootstrap/WebDavLockingContext.php @@ -628,45 +628,6 @@ class WebDavLockingContext implements Context { } } - /** - * - * @param string $user - * @param string $itemToUnlock - * @param string $lockOwner - * @param string $itemToUseLockOf - * @param boolean $public - * - * @return void - * @throws Exception|GuzzleException - */ - #[Given('user :user has unlocked file :itemToUnlock with the last created lock of file :itemToUseLockOf of user :lockOwner using the WebDAV API')] - public function hasUnlockItemWithTheLastCreatedLock( - string $user, - string $itemToUnlock, - string $lockOwner, - string $itemToUseLockOf, - bool $public = false - ) { - $lockCount = $this->countLockOfResources($user, $itemToUnlock); - - $response = $this->unlockItemWithLastLockOfUserAndItemUsingWebDavAPI( - $user, - $itemToUnlock, - $lockOwner, - $itemToUseLockOf, - $public - ); - $this->featureContext->theHTTPStatusCodeShouldBe(204, "", $response); - - $lockCountAfterUnlock = $this->countLockOfResources($user, $itemToUnlock); - - Assert::assertEquals( - $lockCount - 1, - $lockCountAfterUnlock, - "Expected $lockCount lock(s) for '$itemToUnlock' but found '$lockCount'" - ); - } - /** * @param string $user * @param string $itemToUnlock diff --git a/tests/acceptance/bootstrap/WebDavPropertiesContext.php b/tests/acceptance/bootstrap/WebDavPropertiesContext.php index 5ad5f3ec48..3bc0ec09db 100644 --- a/tests/acceptance/bootstrap/WebDavPropertiesContext.php +++ b/tests/acceptance/bootstrap/WebDavPropertiesContext.php @@ -140,25 +140,6 @@ class WebDavPropertiesContext implements Context { $this->featureContext->pushToLastStatusCodesArrays(); } - /** - * - * @param string $path - * @param TableNode|null $propertiesTable - * - * @return void - * @throws Exception - */ - #[When('/^the user gets the following properties of (?:file|folder|entry) "([^"]*)" using the WebDAV API$/')] - public function theUserGetsPropertiesOfFolder(string $path, TableNode $propertiesTable) { - $response = $this->getPropertiesOfFolder( - $this->featureContext->getCurrentUser(), - $path, - null, - $propertiesTable - ); - $this->featureContext->setResponse($response); - } - /** * * @param string $username @@ -413,35 +394,6 @@ class WebDavPropertiesContext implements Context { $this->featureContext->theHTTPStatusCodeShouldBe(207, "", $response); } - /** - * - * @param string $user user id who sets the property - * @param string $propertyName name of property in Clark notation - * @param string $namespace namespace in the form of "x1='http://whatever.org/ns'" - * @param string $path path on which to set properties to - * @param string $propertyValue property value - * - * @return void - * @throws Exception - */ - #[Given('/^user "([^"]*)" has set property "([^"]*)" with namespace "([^"]*)" of (?:file|folder|entry) "([^"]*)" to "([^"]*)"$/')] - public function userHasSetPropertyWithNamespaceOfEntryTo( - string $user, - string $propertyName, - string $namespace, - string $path, - string $propertyValue - ): void { - $response = $this->setResourceProperty( - $user, - $propertyName, - $path, - $propertyValue, - $namespace - ); - $this->featureContext->theHTTPStatusCodeShouldBe(207, "", $response); - } - /** * * @param string $propertyName @@ -615,29 +567,6 @@ class WebDavPropertiesContext implements Context { ); } - /** - * - * @param string $key - * @param string $expectedValue - * @param string $altExpectedValue - * - * @return void - * @throws Exception - */ - #[Then('the single response should contain a property :key with value :value or with value :altValue')] - public function theSingleResponseShouldContainAPropertyWithValueAndAlternative( - string $key, - string $expectedValue, - string $altExpectedValue - ): void { - $this->checkResponseContainsAPropertyWithValue( - $this->featureContext->getResponse(), - $key, - $expectedValue, - $altExpectedValue - ); - } - /** * @param ResponseInterface $response * @param string $key @@ -884,31 +813,6 @@ class WebDavPropertiesContext implements Context { ); } - /** - * - * @param string $xpath - * @param string $path - * @param string $pattern - * - * @return void - * @throws Exception - */ - #[Then('/^as a public the lock discovery property "([^"]*)" of the (?:file|folder|entry) "([^"]*)" should match "([^"]*)"$/')] - public function publicGetsThePropertiesOfFolderAndAssertValueOfItemInResponseRegExp( - string $xpath, - string $path, - string $pattern - ): void { - $propertiesTable = new TableNode([['propertyName'],['d:lockdiscovery']]); - $response = $this->getPropertiesOfEntryFromLastLinkShare($path, $propertiesTable); - $this->featureContext->theHTTPStatusCodeShouldBe('207', "", $response); - $this->assertXpathValueMatchesPattern( - HttpRequestHelper::getResponseXml($response, __METHOD__), - $xpath, - $pattern - ); - } - /** * * @param string $expectedHref @@ -1021,55 +925,6 @@ class WebDavPropertiesContext implements Context { ); } - /** - * - * @param string|null $user - * @param string $xpath - * @param string $path - * @param string $pattern - * - * @return void - * @throws Exception - */ - #[Then('/^as user "([^"]*)" the lock discovery property "([^"]*)" of the (?:file|folder|entry) "([^"]*)" should match "([^"]*)"$/')] - public function userGetsPropertiesOfFolderAndAssertValueOfItemInResponseToUserRegExp( - string $user, - string $xpath, - string $path, - string $pattern - ): void { - $propertiesTable = new TableNode([['propertyName'],['d:lockdiscovery']]); - $response = $this->getPropertiesOfFolder( - $user, - $path, - null, - $propertiesTable - ); - $this->featureContext->theHTTPStatusCodeShouldBe('207', '', $response); - $this->assertXpathValueMatchesPattern( - HttpRequestHelper::getResponseXml($response, __METHOD__), - $xpath, - $pattern, - $user - ); - } - - /** - * - * @param string $xpath - * - * @return void - * @throws Exception - */ - #[Then('the item :xpath in the response should not exist')] - public function assertItemInResponseDoesNotExist(string $xpath): void { - $xmlPart = HttpRequestHelper::getResponseXml($this->featureContext->getResponse())->xpath($xpath); - Assert::assertFalse( - isset($xmlPart[0]), - "Found item with xpath \"$xpath\" but it should not exist" - ); - } - /** * * @param string $user @@ -1227,22 +1082,6 @@ class WebDavPropertiesContext implements Context { return $xmlObject; } - /** - * - * @param string $user - * @param string $path - * - * @return void - * @throws Exception - */ - #[When('user :user stores etag of element :path using the WebDAV API')] - public function userStoresEtagOfElement(string $user, string $path): void { - $this->storeEtagOfElement( - $user, - $path - ); - } - /** * * @param string $user diff --git a/tests/acceptance/scripts/find-unused-steps.sh b/tests/acceptance/scripts/find-unused-steps.sh index 7da57ca6d3..5b9b11f5a2 100755 --- a/tests/acceptance/scripts/find-unused-steps.sh +++ b/tests/acceptance/scripts/find-unused-steps.sh @@ -47,6 +47,19 @@ foreach (glob($bootstrapDir . '/*.php') as $file) { } $stepLineRegex = '/^\s*(Given|When|Then|And|But)\s+(.*)$/'; +$tableRowRegex = '/^\s*\|(.*)\|\s*$/'; + +/** + * Splits a Gherkin table row into trimmed cell values. + * + * @param string $row + * + * @return string[] + */ +function splitTableRow(string $row): array { + return array_map('trim', explode('|', trim($row, "| \t"))); +} + $uniqueTexts = []; $featureFiles = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($featuresDir, FilesystemIterator::SKIP_DOTS) @@ -55,10 +68,75 @@ foreach ($featureFiles as $fileInfo) { if ($fileInfo->getExtension() !== 'feature') { continue; } - foreach (file($fileInfo->getPathname()) as $line) { - if (preg_match($stepLineRegex, rtrim($line, "\n"), $m)) { - $uniqueTexts[rtrim($m[2])] = true; + $lines = file($fileInfo->getPathname()); + + // pendingOutlineSteps holds raw "" step texts belonging to the + // Scenario Outline currently being parsed, waiting to be substituted once + // their Examples: table(s) are found. + $pendingOutlineSteps = []; + $inOutline = false; + + $i = 0; + $count = count($lines); + while ($i < $count) { + $line = rtrim($lines[$i], "\n"); + + if (preg_match('/^\s*Scenario Outline\s*:/i', $line)) { + $inOutline = true; + $pendingOutlineSteps = []; + $i++; + continue; } + + if (preg_match('/^\s*(Scenario\s*:|Scenario Outline\s*:|Feature\s*:)/i', $line) && !preg_match('/^\s*Scenario Outline\s*:/i', $line)) { + // A plain Scenario (or a new Feature) ends the current outline context. + $inOutline = false; + $pendingOutlineSteps = []; + } + + if (preg_match($stepLineRegex, $line, $m)) { + $text = rtrim($m[2]); + if ($inOutline && strpos($text, '<') !== false) { + $pendingOutlineSteps[] = $text; + } else { + $uniqueTexts[$text] = true; + } + $i++; + continue; + } + + if ($inOutline && preg_match('/^\s*Examples\s*:/i', $line)) { + $i++; + // skip blank/tag lines before the header row + while ($i < $count && trim($lines[$i]) === '') { + $i++; + } + if ($i >= $count || !preg_match($tableRowRegex, rtrim($lines[$i], "\n"), $hm)) { + continue; + } + $header = splitTableRow($hm[1]); + $i++; + while ($i < $count && preg_match($tableRowRegex, rtrim($lines[$i], "\n"), $rm)) { + $row = splitTableRow($rm[1]); + $values = count($header) === count($row) ? array_combine($header, $row) : false; + if ($values !== false) { + foreach ($pendingOutlineSteps as $template) { + $substituted = preg_replace_callback( + '/<([^>]+)>/', + function ($mm) use ($values) { + return $values[$mm[1]] ?? $mm[0]; + }, + $template + ); + $uniqueTexts[$substituted] = true; + } + } + $i++; + } + continue; + } + + $i++; } } $uniqueTexts = array_keys($uniqueTexts); @@ -94,9 +172,4 @@ echo "Found " . count($unused) . " potentially unused step definitions:\n\n"; foreach ($unused as $u) { echo "{$u['file']}:{$u['line']} [{$u['keyword']}] {$u['pattern']}\n"; } - -if (count($unused) > 0) { - echo "\nNote: a step may be flagged here but still be in use if it's called\n"; - echo "programmatically from other PHP context code rather than from a .feature file.\n"; -} PHP