diff --git a/build/integration/behat.php b/build/integration/behat.php new file mode 100644 index 0000000000000..d44c32b3b3761 --- /dev/null +++ b/build/integration/behat.php @@ -0,0 +1,105 @@ + ['admin', 'admin'], + 'regular_user_password' => 123456, +]; + +/** + * Contexts shared by the main feature suites (default, comments, dav, files). + */ +$commonContexts = static function (Suite $suite, string $mainContext) use ($baseUrl, $ocsUrl, $adminArgs): Suite { + return $suite + ->addContext($mainContext, ['baseUrl' => $ocsUrl] + $adminArgs) + ->addContext('CommentsContext', ['baseUrl' => $baseUrl]) + ->addContext('TagsContext', ['baseUrl' => $baseUrl]) + ->addContext('CardDavContext', ['baseUrl' => $baseUrl]) + ->addContext('CalDavContext', ['baseUrl' => $baseUrl]) + ->addContext('ChecksumsContext', ['baseUrl' => $baseUrl]) + ->addContext('CommandLineContext', ['baseUrl' => $baseUrl, 'ocPath' => '../../']); +}; + +/** + * Suite with a single context that is configured with the OCS base URL and admin credentials. + */ +$ocsSuite = static function (string $name, string $path, string $context) use ($ocsUrl, $adminArgs): Suite { + return (new Suite($name)) + ->withPaths('%paths.base%/' . $path) + ->addContext($context, ['baseUrl' => $ocsUrl] + $adminArgs); +}; + +/** + * Suite with a single context that is configured with the plain base URL and admin credentials. + */ +$plainSuite = static function (string $name, string $path, string $context) use ($baseUrl, $adminArgs): Suite { + return (new Suite($name)) + ->withPaths('%paths.base%/' . $path) + ->addContext($context, ['baseUrl' => $baseUrl] + $adminArgs); +}; + +$profile = (new Profile('default', [ + 'autoload' => [ + '' => '%paths.base%/features/bootstrap', + ], +])) + ->withExtension(new Extension(PHPUnitAssertionsExtension::class)) + ->withFormatter((new JUnitFormatter())->withOutputPath('%paths.base%/output')) + ->withFormatter((new PrettyFormatter())->withOutputStyles(['comment' => ['bright-blue']])) + ->withSuite($commonContexts((new Suite('default'))->withPaths('%paths.base%/features'), 'FeatureContext')) + ->withSuite($commonContexts((new Suite('comments'))->withPaths('%paths.base%/comments_features'), 'FeatureContext')) + ->withSuite( + $commonContexts((new Suite('dav'))->withPaths('%paths.base%/dav_features'), 'DavFeatureContext') + ->addContext('PrincipalPropertySearchContext', ['baseUrl' => $baseUrl]) + ) + ->withSuite( + (new Suite('encryption')) + ->withPaths('%paths.base%/encryption_features') + ->addContext('FeatureContext', ['baseUrl' => $ocsUrl] + $adminArgs) + ->addContext('CommandLineContext', ['baseUrl' => $baseUrl, 'ocPath' => '../../']) + ) + ->withSuite($ocsSuite('federation', 'federation_features', 'FederationContext')) + ->withSuite( + $commonContexts((new Suite('files'))->withPaths('%paths.base%/files_features'), 'FeatureContext') + ->addContext('MetadataContext', ['baseUrl' => $baseUrl] + $adminArgs) + ) + ->withSuite($plainSuite('files_conversion', 'file_conversions', 'ConversionsContext')) + ->withSuite($plainSuite('files_reminders', 'files_reminders', 'FilesRemindersContext')) + ->withSuite($ocsSuite('capabilities', 'capabilities_features', 'CapabilitiesContext')) + ->withSuite($ocsSuite('collaboration', 'collaboration_features', 'CollaborationContext')) + ->withSuite($ocsSuite('sharees', 'sharees_features', 'ShareesContext')) + ->withSuite($ocsSuite('sharing', 'sharing_features', 'SharingContext')->addContext('TalkContext')) + ->withSuite($ocsSuite('videoverification', 'videoverification_features', 'SharingContext')->addContext('TalkContext')) + ->withSuite( + (new Suite('guests')) + ->withPaths('%paths.base%/guests_features') + ->addContext('GuestsContext') + ->addContext('SharingContext', ['baseUrl' => $ocsUrl] + $adminArgs) + ) + ->withSuite($ocsSuite('setup', 'setup_features', 'SetupContext')) + ->withSuite($plainSuite('filesdrop', 'filesdrop_features', 'FilesDropContext')) + ->withSuite($plainSuite('ldap', 'ldap_features', 'LDAPContext')) + ->withSuite($plainSuite('openldap_numerical', 'openldap_numerical_features', 'LDAPContext')) + ->withSuite($plainSuite('openldap', 'openldap_features', 'LDAPContext')) + ->withSuite($plainSuite('ratelimiting', 'ratelimiting_features', 'RateLimitingContext')) + ->withSuite($plainSuite('routing', 'routing_features', 'RoutingContext')) + ->withSuite($plainSuite('theming', 'theming_features', 'FeatureContext')); + +return (new Config())->withProfile($profile); diff --git a/build/integration/config/behat.yml b/build/integration/config/behat.yml deleted file mode 100644 index 6071badadb089..0000000000000 --- a/build/integration/config/behat.yml +++ /dev/null @@ -1,299 +0,0 @@ -# SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors -# SPDX-FileCopyrightText: 2015-2016 ownCloud, Inc. -# SPDX-License-Identifier: AGPL-3.0-only -default: - autoload: - '': "%paths.base%/../features/bootstrap" - formatters: - junit: - output_path: '%paths.base%/../output' - pretty: - output_styles: - comment: [ 'bright-blue' ] - suites: - default: - paths: - - "%paths.base%/../features" - contexts: - - FeatureContext: - baseUrl: http://localhost:8080/ocs/ - admin: - - admin - - admin - regular_user_password: 123456 - - CommentsContext: - baseUrl: http://localhost:8080 - - TagsContext: - baseUrl: http://localhost:8080 - - CardDavContext: - baseUrl: http://localhost:8080 - - CalDavContext: - baseUrl: http://localhost:8080 - - ChecksumsContext: - baseUrl: http://localhost:8080 - - CommandLineContext: - baseUrl: http://localhost:8080 - ocPath: ../../ - comments: - paths: - - "%paths.base%/../comments_features" - contexts: - - FeatureContext: - baseUrl: http://localhost:8080/ocs/ - admin: - - admin - - admin - regular_user_password: 123456 - - CommentsContext: - baseUrl: http://localhost:8080 - - TagsContext: - baseUrl: http://localhost:8080 - - CardDavContext: - baseUrl: http://localhost:8080 - - CalDavContext: - baseUrl: http://localhost:8080 - - ChecksumsContext: - baseUrl: http://localhost:8080 - - CommandLineContext: - baseUrl: http://localhost:8080 - ocPath: ../../ - dav: - paths: - - "%paths.base%/../dav_features" - contexts: - - DavFeatureContext: - baseUrl: http://localhost:8080/ocs/ - admin: - - admin - - admin - regular_user_password: 123456 - - CommentsContext: - baseUrl: http://localhost:8080 - - TagsContext: - baseUrl: http://localhost:8080 - - CardDavContext: - baseUrl: http://localhost:8080 - - CalDavContext: - baseUrl: http://localhost:8080 - - ChecksumsContext: - baseUrl: http://localhost:8080 - - CommandLineContext: - baseUrl: http://localhost:8080 - ocPath: ../../ - - PrincipalPropertySearchContext: - baseUrl: http://localhost:8080 - encryption: - paths: - - "%paths.base%/../encryption_features" - contexts: - - FeatureContext: - baseUrl: http://localhost:8080/ocs/ - admin: - - admin - - admin - regular_user_password: 123456 - - CommandLineContext: - baseUrl: http://localhost:8080 - ocPath: ../../ - federation: - paths: - - "%paths.base%/../federation_features" - contexts: - - FederationContext: - baseUrl: http://localhost:8080/ocs/ - admin: - - admin - - admin - regular_user_password: 123456 - files: - paths: - - "%paths.base%/../files_features" - contexts: - - FeatureContext: - baseUrl: http://localhost:8080/ocs/ - admin: - - admin - - admin - regular_user_password: 123456 - - CommentsContext: - baseUrl: http://localhost:8080 - - TagsContext: - baseUrl: http://localhost:8080 - - CardDavContext: - baseUrl: http://localhost:8080 - - CalDavContext: - baseUrl: http://localhost:8080 - - ChecksumsContext: - baseUrl: http://localhost:8080 - - CommandLineContext: - baseUrl: http://localhost:8080 - ocPath: ../../ - - MetadataContext: - baseUrl: http://localhost:8080 - admin: - - admin - - admin - regular_user_password: 123456 - files_conversion: - paths: - - "%paths.base%/../file_conversions" - contexts: - - ConversionsContext: - baseUrl: http://localhost:8080 - admin: - - admin - - admin - regular_user_password: 123456 - files_reminders: - paths: - - "%paths.base%/../files_reminders" - contexts: - - FilesRemindersContext: - baseUrl: http://localhost:8080 - admin: - - admin - - admin - regular_user_password: 123456 - capabilities: - paths: - - "%paths.base%/../capabilities_features" - contexts: - - CapabilitiesContext: - baseUrl: http://localhost:8080/ocs/ - admin: - - admin - - admin - regular_user_password: 123456 - collaboration: - paths: - - "%paths.base%/../collaboration_features" - contexts: - - CollaborationContext: - baseUrl: http://localhost:8080/ocs/ - admin: - - admin - - admin - regular_user_password: 123456 - sharees: - paths: - - "%paths.base%/../sharees_features" - contexts: - - ShareesContext: - baseUrl: http://localhost:8080/ocs/ - admin: - - admin - - admin - regular_user_password: 123456 - sharing: - paths: - - "%paths.base%/../sharing_features" - contexts: - - SharingContext: - baseUrl: http://localhost:8080/ocs/ - admin: - - admin - - admin - regular_user_password: 123456 - - TalkContext - videoverification: - paths: - - "%paths.base%/../videoverification_features" - contexts: - - SharingContext: - baseUrl: http://localhost:8080/ocs/ - admin: - - admin - - admin - regular_user_password: 123456 - - TalkContext - guests: - paths: - - "%paths.base%/../guests_features" - contexts: - - GuestsContext - - SharingContext: - baseUrl: http://localhost:8080/ocs/ - admin: - - admin - - admin - regular_user_password: 123456 - setup: - paths: - - "%paths.base%/../setup_features" - contexts: - - SetupContext: - baseUrl: http://localhost:8080/ocs/ - admin: - - admin - - admin - regular_user_password: 123456 - filesdrop: - paths: - - "%paths.base%/../filesdrop_features" - contexts: - - FilesDropContext: - baseUrl: http://localhost:8080 - admin: - - admin - - admin - regular_user_password: 123456 - ldap: - paths: - - "%paths.base%/../ldap_features" - contexts: - - LDAPContext: - baseUrl: http://localhost:8080 - admin: - - admin - - admin - regular_user_password: 123456 - openldap_numerical: - paths: - - "%paths.base%/../openldap_numerical_features" - contexts: - - LDAPContext: - baseUrl: http://localhost:8080 - admin: - - admin - - admin - regular_user_password: 123456 - openldap: - paths: - - "%paths.base%/../openldap_features" - contexts: - - LDAPContext: - baseUrl: http://localhost:8080 - admin: - - admin - - admin - regular_user_password: 123456 - ratelimiting: - paths: - - "%paths.base%/../ratelimiting_features" - contexts: - - RateLimitingContext: - baseUrl: http://localhost:8080 - admin: - - admin - - admin - regular_user_password: 123456 - routing: - paths: - - "%paths.base%/../routing_features" - contexts: - - RoutingContext: - baseUrl: http://localhost:8080 - admin: - - admin - - admin - regular_user_password: 123456 - theming: - paths: - - "%paths.base%/../theming_features" - contexts: - - FeatureContext: - baseUrl: http://localhost:8080 - admin: - - admin - - admin - regular_user_password: 123456 diff --git a/build/integration/features/bootstrap/Activity.php b/build/integration/features/bootstrap/Activity.php index 4172776304d0f..e323f25eedddb 100644 --- a/build/integration/features/bootstrap/Activity.php +++ b/build/integration/features/bootstrap/Activity.php @@ -8,15 +8,16 @@ */ use Behat\Gherkin\Node\TableNode; +use Behat\Step\Then; use PHPUnit\Framework\Assert; trait Activity { use BasicStructure; /** - * @Then last activity should be * @param TableNode $activity */ + #[Then('last activity should be')] public function lastActivityIs(TableNode $activity): void { $this->sendRequestForJSON('GET', '/apps/activity/api/v2/activity'); $this->theHTTPStatusCodeShouldBe('200'); diff --git a/build/integration/features/bootstrap/AppConfiguration.php b/build/integration/features/bootstrap/AppConfiguration.php index 1313e3421072d..94986ee18242b 100644 --- a/build/integration/features/bootstrap/AppConfiguration.php +++ b/build/integration/features/bootstrap/AppConfiguration.php @@ -8,6 +8,9 @@ use Behat\Behat\Hook\Scope\AfterScenarioScope; use Behat\Behat\Hook\Scope\BeforeScenarioScope; use Behat\Gherkin\Node\TableNode; +use Behat\Hook\AfterScenario; +use Behat\Hook\BeforeScenario; +use Behat\Step\Given; use PHPUnit\Framework\Assert; use Psr\Http\Message\ResponseInterface; @@ -26,11 +29,11 @@ abstract public function theOCSStatusCodeShouldBe($statusCode); abstract public function theHTTPStatusCodeShouldBe($statusCode); /** - * @Given /^parameter "([^"]*)" of app "([^"]*)" is set to "([^"]*)"$/ * @param string $parameter * @param string $app * @param string $value */ + #[Given('/^parameter "([^"]*)" of app "([^"]*)" is set to "([^"]*)"$/')] public function serverParameterIsSetTo($parameter, $app, $value) { $user = $this->currentUser; $this->currentUser = 'admin'; @@ -86,12 +89,11 @@ protected function setStatusTestingApp($enabled) { abstract protected function resetAppConfigs(); /** - * @BeforeScenario - * * Enable the testing app before the first scenario of the feature and * reset the configs before each scenario * @param BeforeScenarioScope $event */ + #[BeforeScenario] public function prepareParameters(BeforeScenarioScope $event) { $user = $this->currentUser; $this->currentUser = 'admin'; @@ -107,11 +109,10 @@ public function prepareParameters(BeforeScenarioScope $event) { } /** - * @AfterScenario - * * Reset the values after the last scenario of the feature and disable the testing app * @param AfterScenarioScope $event */ + #[AfterScenario] public function undoChangingParameters(AfterScenarioScope $event) { $scenarios = $event->getFeature()->getScenarios(); if ($event->getScenario() === end($scenarios)) { diff --git a/build/integration/features/bootstrap/Auth.php b/build/integration/features/bootstrap/Auth.php index a3f549769f2dc..f0f8ebdfa4afa 100644 --- a/build/integration/features/bootstrap/Auth.php +++ b/build/integration/features/bootstrap/Auth.php @@ -5,6 +5,9 @@ * SPDX-FileCopyrightText: 2016 ownCloud, Inc. * SPDX-License-Identifier: AGPL-3.0-or-later */ +use Behat\Hook\BeforeScenario; +use Behat\Step\Given; +use Behat\Step\When; use GuzzleHttp\Client; use GuzzleHttp\Cookie\CookieJar; use GuzzleHttp\Exception\ClientException; @@ -22,16 +25,14 @@ trait Auth { /** @var string */ private $responseXml; - /** @BeforeScenario */ + #[BeforeScenario] public function setUpScenario() { $this->client = new Client(); $this->responseXml = ''; $this->cookieJar = new CookieJar(); } - /** - * @When requesting :url with :method - */ + #[When('requesting :url with :method')] public function requestingWith($url, $method) { $this->sendRequest($url, $method); } @@ -61,9 +62,7 @@ private function sendRequest($url, $method, $authHeader = null, $useCookies = fa } } - /** - * @When the CSRF token is extracted from the previous response - */ + #[When('the CSRF token is extracted from the previous response')] public function theCsrfTokenIsExtractedFromThePreviousResponse() { $this->requestToken = substr(preg_replace('/(.*)data-requesttoken="(.*)">(.*)/sm', '\2', $this->response->getBody()->getContents()), 0, 89); } @@ -101,9 +100,7 @@ private function createClientToken($loginViaWeb = true) { return json_decode($this->response->getBody()->getContents()); } - /** - * @Given a new restricted client token is added - */ + #[Given('a new restricted client token is added')] public function aNewRestrictedClientTokenIsAdded() { $tokenObj = $this->createClientToken(); $newCreatedTokenId = $tokenObj->deviceToken->id; @@ -126,85 +123,80 @@ public function aNewRestrictedClientTokenIsAdded() { $this->restrictedClientToken = $tokenObj->token; } - /** - * @Given a new unrestricted client token is added - */ + #[Given('a new unrestricted client token is added')] public function aNewUnrestrictedClientTokenIsAdded() { $this->unrestrictedClientToken = $this->createClientToken()->token; } - /** - * @When a new unrestricted client token is added using restricted basic token auth - */ + #[When('a new unrestricted client token is added using restricted basic token auth')] public function aNewUnrestrictedClientTokenIsAddedUsingRestrictedBasicTokenAuth() { $this->createClientToken(false); } /** - * @When requesting :url with :method using basic auth * * @param string $url * @param string $method */ + #[When('requesting :url with :method using basic auth')] public function requestingWithBasicAuth($url, $method) { $this->sendRequest($url, $method, 'basic ' . base64_encode('user0:123456')); } /** - * @When requesting :url with :method using unrestricted basic token auth * * @param string $url * @param string $method */ + #[When('requesting :url with :method using unrestricted basic token auth')] public function requestingWithUnrestrictedBasicTokenAuth($url, $method) { $this->sendRequest($url, $method, 'basic ' . base64_encode('user0:' . $this->unrestrictedClientToken), true); } /** - * @When requesting :url with :method using restricted basic token auth * * @param string $url * @param string $method */ + #[When('requesting :url with :method using restricted basic token auth')] public function requestingWithRestrictedBasicTokenAuth($url, $method) { $this->sendRequest($url, $method, 'basic ' . base64_encode('user0:' . $this->restrictedClientToken), true); } /** - * @When requesting :url with :method using an unrestricted client token * * @param string $url * @param string $method */ + #[When('requesting :url with :method using an unrestricted client token')] public function requestingWithUsingAnUnrestrictedClientToken($url, $method) { $this->sendRequest($url, $method, 'Bearer ' . $this->unrestrictedClientToken); } /** - * @When requesting :url with :method using a restricted client token * * @param string $url * @param string $method */ + #[When('requesting :url with :method using a restricted client token')] public function requestingWithUsingARestrictedClientToken($url, $method) { $this->sendRequest($url, $method, 'Bearer ' . $this->restrictedClientToken); } /** - * @When requesting :url with :method using browser session * * @param string $url * @param string $method */ + #[When('requesting :url with :method using browser session')] public function requestingWithBrowserSession($url, $method) { $this->sendRequest($url, $method, null, true); } /** - * @Given a new browser session is started - * * @param bool $remember */ + #[Given('a new browser session is started')] public function aNewBrowserSessionIsStarted($remember = false) { $baseUrl = substr($this->baseUrl, 0, -5); $loginUrl = $baseUrl . '/login'; @@ -234,23 +226,17 @@ public function aNewBrowserSessionIsStarted($remember = false) { $this->extracRequestTokenFromResponse($response); } - /** - * @Given a new remembered browser session is started - */ + #[Given('a new remembered browser session is started')] public function aNewRememberedBrowserSessionIsStarted() { $this->aNewBrowserSessionIsStarted(true); } - /** - * @Given the cookie jar is reset - */ + #[Given('the cookie jar is reset')] public function theCookieJarIsReset() { $this->cookieJar = new CookieJar(); } - /** - * @When the session cookie expires - */ + #[When('the session cookie expires')] public function whenTheSessionCookieExpires() { $this->cookieJar->clearSessionCookies(); } diff --git a/build/integration/features/bootstrap/Avatar.php b/build/integration/features/bootstrap/Avatar.php index e3ebde513a7d0..b29784277dcae 100644 --- a/build/integration/features/bootstrap/Avatar.php +++ b/build/integration/features/bootstrap/Avatar.php @@ -4,6 +4,9 @@ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ +use Behat\Hook\AfterScenario; +use Behat\Step\Then; +use Behat\Step\When; use PHPUnit\Framework\Assert; require __DIR__ . '/autoload.php'; @@ -12,7 +15,7 @@ trait Avatar { /** @var string * */ private $lastAvatar; - /** @AfterScenario **/ + #[AfterScenario] public function cleanupLastAvatar() { $this->lastAvatar = null; } @@ -28,22 +31,22 @@ private function getLastAvatar() { } /** - * @When user :user gets avatar for user :userAvatar * * @param string $user * @param string $userAvatar */ + #[When('user :user gets avatar for user :userAvatar')] public function userGetsAvatarForUser(string $user, string $userAvatar) { $this->userGetsAvatarForUserWithSize($user, $userAvatar, '128'); } /** - * @When user :user gets avatar for user :userAvatar with size :size * * @param string $user * @param string $userAvatar * @param string $size */ + #[When('user :user gets avatar for user :userAvatar with size :size')] public function userGetsAvatarForUserWithSize(string $user, string $userAvatar, string $size) { $this->asAn($user); $this->sendingToDirectUrl('GET', '/index.php/avatar/' . $userAvatar . '/' . $size); @@ -53,11 +56,11 @@ public function userGetsAvatarForUserWithSize(string $user, string $userAvatar, } /** - * @When user :user gets avatar for guest :guestAvatar * * @param string $user * @param string $guestAvatar */ + #[When('user :user gets avatar for guest :guestAvatar')] public function userGetsAvatarForGuest(string $user, string $guestAvatar) { $this->asAn($user); $this->sendingToDirectUrl('GET', '/index.php/avatar/guest/' . $guestAvatar . '/128'); @@ -67,10 +70,9 @@ public function userGetsAvatarForGuest(string $user, string $guestAvatar) { } /** - * @When logged in user posts avatar from file :source - * * @param string $source */ + #[When('logged in user posts avatar from file :source')] public function loggedInUserPostsAvatarFromFile(string $source) { $file = \GuzzleHttp\Psr7\Utils::streamFor(fopen($source, 'r')); @@ -87,28 +89,24 @@ public function loggedInUserPostsAvatarFromFile(string $source) { } /** - * @When logged in user posts avatar from internal path :path - * * @param string $path */ + #[When('logged in user posts avatar from internal path :path')] public function loggedInUserPostsAvatarFromInternalPath(string $path) { $this->sendingAToWithRequesttoken('POST', '/index.php/avatar?path=' . $path); $this->theHTTPStatusCodeShouldBe('200'); } - /** - * @When logged in user deletes the user avatar - */ + #[When('logged in user deletes the user avatar')] public function loggedInUserDeletesTheUserAvatar() { $this->sendingAToWithRequesttoken('DELETE', '/index.php/avatar'); $this->theHTTPStatusCodeShouldBe('200'); } /** - * @Then last avatar is a square of size :size - * * @param string size */ + #[Then('last avatar is a square of size :size')] public function lastAvatarIsASquareOfSize(string $size) { [$width, $height] = getimagesizefromstring($this->lastAvatar); @@ -116,28 +114,24 @@ public function lastAvatarIsASquareOfSize(string $size) { Assert::assertEquals($size, $width); } - /** - * @Then last avatar is not a square - */ + #[Then('last avatar is not a square')] public function lastAvatarIsNotASquare() { [$width, $height] = getimagesizefromstring($this->lastAvatar); Assert::assertNotEquals($width, $height, 'Expected avatar to not be a square'); } - /** - * @Then last avatar is not a single color - */ + #[Then('last avatar is not a single color')] public function lastAvatarIsNotASingleColor() { Assert::assertEquals(null, $this->getColorFromLastAvatar()); } /** - * @Then last avatar is a single :color color * * @param string $color * @param string $size */ + #[Then('last avatar is a single :color color')] public function lastAvatarIsASingleColor(string $color) { $expectedColor = $this->hexStringToRgbColor($color); $colorFromLastAvatar = $this->getColorFromLastAvatar(); diff --git a/build/integration/features/bootstrap/BasicStructure.php b/build/integration/features/bootstrap/BasicStructure.php index 4a30fa720e7f3..3609f5a1ec463 100644 --- a/build/integration/features/bootstrap/BasicStructure.php +++ b/build/integration/features/bootstrap/BasicStructure.php @@ -6,6 +6,13 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ use Behat\Gherkin\Node\TableNode; +use Behat\Hook\AfterScenario; +use Behat\Hook\AfterSuite; +use Behat\Hook\BeforeScenario; +use Behat\Hook\BeforeSuite; +use Behat\Step\Given; +use Behat\Step\Then; +use Behat\Step\When; use GuzzleHttp\Client; use GuzzleHttp\Cookie\CookieJar; use GuzzleHttp\Exception\ClientException; @@ -72,9 +79,7 @@ public function __construct($baseUrl, $admin, $regular_user_password) { } } - /** - * @BeforeScenario - */ + #[BeforeScenario] public function resetAuthState(): void { $this->currentUser = ''; $this->currentServer = 'LOCAL'; @@ -84,24 +89,20 @@ public function resetAuthState(): void { $this->cookieJar = new CookieJar(); } - /** - * @Given /^using api version "(\d+)"$/ - */ + #[Given('/^using api version "(\d+)"$/')] public function usingApiVersion(int $version): void { $this->apiVersion = (int)$version; } - /** - * @Given /^As an "([^"]*)"$/ - */ + #[Given('/^As an "([^"]*)"$/')] public function asAn(string $user): void { $this->currentUser = $user; } /** - * @Given /^Using server "(LOCAL|REMOTE)"$/ * @return string Previous used server */ + #[Given('/^Using server "(LOCAL|REMOTE)"$/')] public function usingServer(string $server): string { $previousServer = $this->currentServer; if ($server === 'LOCAL') { @@ -115,9 +116,7 @@ public function usingServer(string $server): string { } } - /** - * @When /^sending "([^"]*)" to "([^"]*)"$/ - */ + #[When('/^sending "([^"]*)" to "([^"]*)"$/')] public function sendingTo(string $verb, string $url): void { $this->sendingToWith($verb, $url, null); } @@ -153,9 +152,7 @@ public function simplifyArray(array $arrayOfArrays): array { return $a; } - /** - * @When /^sending "([^"]*)" to "([^"]*)" with$/ - */ + #[When('/^sending "([^"]*)" to "([^"]*)" with$/')] public function sendingToWith(string $verb, string $url, ?TableNode $body): void { $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php" . $url; $client = new Client(); @@ -218,10 +215,10 @@ protected function sendRequestForJSON(string $verb, string $url, TableNode|array } /** - * @When /^sending "([^"]*)" with exact url to "([^"]*)"$/ * @param string $verb * @param string $url */ + #[When('/^sending "([^"]*)" with exact url to "([^"]*)"$/')] public function sendingToDirectUrl($verb, $url) { $this->sendingToWithDirectUrl($verb, $url, null); } @@ -254,25 +251,25 @@ public function isExpectedUrl($possibleUrl, $finalPart) { } /** - * @Then /^the OCS status code should be "([^"]*)"$/ * @param int $statusCode */ + #[Then('/^the OCS status code should be "([^"]*)"$/')] public function theOCSStatusCodeShouldBe($statusCode) { Assert::assertEquals($statusCode, $this->getOCSResponseCode($this->response)); } /** - * @Then /^the HTTP status code should be "([^"]*)"$/ * @param int $statusCode */ + #[Then('/^the HTTP status code should be "([^"]*)"$/')] public function theHTTPStatusCodeShouldBe($statusCode) { Assert::assertEquals($statusCode, $this->response->getStatusCode()); } /** - * @Then /^the Content-Type should be "([^"]*)"$/ * @param string $contentType */ + #[Then('/^the Content-Type should be "([^"]*)"$/')] public function theContentTypeShouldbe($contentType) { Assert::assertEquals($contentType, $this->response->getHeader('Content-Type')[0]); } @@ -285,9 +282,9 @@ private function extracRequestTokenFromResponse(ResponseInterface $response) { } /** - * @Given Logging in using web as :user * @param string $user */ + #[Given('Logging in using web as :user')] public function loggingInUsingWebAs($user) { $baseUrl = substr($this->baseUrl, 0, -5); $loginUrl = $baseUrl . '/index.php/login'; @@ -322,11 +319,11 @@ public function loggingInUsingWebAs($user) { } /** - * @When Sending a :method to :url with requesttoken * @param string $method * @param string $url * @param TableNode|array|null $body */ + #[When('Sending a :method to :url with requesttoken')] public function sendingAToWithRequesttoken($method, $url, $body = null) { $baseUrl = substr($this->baseUrl, 0, -5); @@ -357,10 +354,10 @@ public function sendingAToWithRequesttoken($method, $url, $body = null) { } /** - * @When Sending a :method to :url without requesttoken * @param string $method * @param string $url */ + #[When('Sending a :method to :url without requesttoken')] public function sendingAToWithoutRequesttoken($method, $url) { $baseUrl = substr($this->baseUrl, 0, -5); @@ -385,11 +382,11 @@ public static function removeFile($path, $filename) { } /** - * @Given User :user modifies text of :filename with text :text * @param string $user * @param string $filename * @param string $text */ + #[Given('User :user modifies text of :filename with text :text')] public function modifyTextOfFile($user, $filename, $text) { self::removeFile($this->getDataDirectory() . "/$user/files", "$filename"); file_put_contents($this->getDataDirectory() . "/$user/files" . "$filename", "$text"); @@ -417,11 +414,11 @@ private function getDataDirectory() { } /** - * @Given file :filename is created :times times in :user user data * @param string $filename * @param string $times * @param string $user */ + #[Given('file :filename is created :times times in :user user data')] public function fileIsCreatedTimesInUserData($filename, $times, $user) { for ($i = 0; $i < $times; $i++) { file_put_contents($this->getDataDirectory() . "/$user/files" . "$filename-$i", "content-$i"); @@ -442,41 +439,37 @@ public function createFileWithText($name, $text) { } /** - * @Given file :filename of size :size is created in local storage * @param string $filename * @param string $size */ + #[Given('file :filename of size :size is created in local storage')] public function fileIsCreatedInLocalStorageWithSize($filename, $size) { $this->createFileSpecificSize("local_storage/$filename", $size); } /** - * @Given file :filename with text :text is created in local storage * @param string $filename * @param string $text */ + #[Given('file :filename with text :text is created in local storage')] public function fileIsCreatedInLocalStorageWithText($filename, $text) { $this->createFileWithText("local_storage/$filename", $text); } /** - * @When Sleep for :seconds seconds * @param int $seconds */ + #[When('Sleep for :seconds seconds')] public function sleepForSeconds($seconds) { sleep((int)$seconds); } - /** - * @BeforeSuite - */ + #[BeforeSuite] public static function createPHPUnitConfiguration(): void { (new \PHPUnit\TextUI\Configuration\Builder())->build([]); } - /** - * @BeforeSuite - */ + #[BeforeSuite] public static function addFilesToSkeleton() { for ($i = 0; $i < 5; $i++) { file_put_contents('../../core/skeleton/' . 'textfile' . "$i" . '.txt', "Nextcloud test text file\n"); @@ -494,9 +487,7 @@ public static function addFilesToSkeleton() { file_put_contents('../../core/skeleton/PARENT/CHILD/' . 'child.txt', "Nextcloud test text file\n"); } - /** - * @AfterSuite - */ + #[AfterSuite] public static function removeFilesFromSkeleton() { for ($i = 0; $i < 5; $i++) { self::removeFile('../../core/skeleton/', 'textfile' . "$i" . '.txt'); @@ -514,9 +505,7 @@ public static function removeFilesFromSkeleton() { } } - /** - * @BeforeScenario @local_storage - */ + #[BeforeScenario('@local_storage')] public static function removeFilesFromLocalStorageBefore() { $dir = './work/local_storage/'; $di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS); @@ -526,9 +515,7 @@ public static function removeFilesFromLocalStorageBefore() { } } - /** - * @AfterScenario @local_storage - */ + #[AfterScenario('@local_storage')] public static function removeFilesFromLocalStorageAfter() { $dir = './work/local_storage/'; $di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS); @@ -538,18 +525,16 @@ public static function removeFilesFromLocalStorageAfter() { } } - /** - * @Given /^cookies are reset$/ - */ + #[Given('/^cookies are reset$/')] public function cookiesAreReset() { $this->cookieJar = new CookieJar(); } /** - * @Then The following headers should be set * @param TableNode $table * @throws \Exception */ + #[Then('The following headers should be set')] public function theFollowingHeadersShouldBeSet(TableNode $table) { foreach ($table->getTable() as $header) { $headerName = $header[0]; diff --git a/build/integration/features/bootstrap/CalDavContext.php b/build/integration/features/bootstrap/CalDavContext.php index 3d99040075162..679765bffe7bc 100644 --- a/build/integration/features/bootstrap/CalDavContext.php +++ b/build/integration/features/bootstrap/CalDavContext.php @@ -7,6 +7,11 @@ */ require __DIR__ . '/autoload.php'; +use Behat\Hook\AfterScenario; +use Behat\Hook\BeforeScenario; +use Behat\Step\Given; +use Behat\Step\Then; +use Behat\Step\When; use GuzzleHttp\Client; use GuzzleHttp\Exception\GuzzleException; use Psr\Http\Message\ResponseInterface; @@ -32,13 +37,13 @@ public function __construct( } } - /** @BeforeScenario */ + #[BeforeScenario] public function setUpScenario() { $this->client = new Client(); $this->responseXml = ''; } - /** @AfterScenario */ + #[AfterScenario] public function afterScenario() { foreach (['MyCalendar', 'MyCalendar2'] as $calendarName) { try { @@ -54,7 +59,7 @@ public function afterScenario() { } } - /** @AfterScenario @caldav-delegation */ + #[AfterScenario('@caldav-delegation')] public function afterDelegationScenario() { foreach (['calendar-proxy-read', 'calendar-proxy-write'] as $proxyType) { try { @@ -77,11 +82,11 @@ public function afterDelegationScenario() { } /** - * @When :user requests calendar :calendar on the endpoint :endpoint * @param string $user * @param string $calendar * @param string $endpoint */ + #[When(':user requests calendar :calendar on the endpoint :endpoint')] public function requestsCalendar($user, $calendar, $endpoint) { $davUrl = $this->baseUrl . $endpoint . $calendar; @@ -102,9 +107,7 @@ public function requestsCalendar($user, $calendar, $endpoint) { } } - /** - * @When :user requests principal :principal on the endpoint :endpoint - */ + #[When(':user requests principal :principal on the endpoint :endpoint')] public function requestsPrincipal(string $user, string $principal, string $endpoint): void { $davUrl = $this->baseUrl . $endpoint . $principal; @@ -131,9 +134,9 @@ public function requestsPrincipal(string $user, string $principal, string $endpo } /** - * @Then The CalDAV response should contain a property :key * @throws \Exception */ + #[Then('The CalDAV response should contain a property :key')] public function theCaldavResponseShouldContainAProperty(string $key): void { /** @var \Sabre\DAV\Xml\Response\MultiStatus $multiStatus */ $multiStatus = $this->responseXml['value']; @@ -160,9 +163,9 @@ public function theCaldavResponseShouldContainAProperty(string $key): void { } /** - * @Then The CalDAV response should contain a property :key with a href value :value * @throws \Exception */ + #[Then('The CalDAV response should contain a property :key with a href value :value')] public function theCaldavResponseShouldContainAPropertyWithHrefValue( string $key, string $value, @@ -191,9 +194,9 @@ public function theCaldavResponseShouldContainAPropertyWithHrefValue( } /** - * @Then The CalDAV response should contain an href :href * @throws \Exception */ + #[Then('The CalDAV response should contain an href :href')] public function theCaldavResponseShouldContainAnHref(string $href): void { /** @var \Sabre\DAV\Xml\Response\MultiStatus $multiStatus */ $multiStatus = $this->responseXml['value']; @@ -211,9 +214,9 @@ public function theCaldavResponseShouldContainAnHref(string $href): void { } /** - * @Then The CalDAV response should be multi status * @throws \Exception */ + #[Then('The CalDAV response should be multi status')] public function theCaldavResponseShouldBeMultiStatus(): void { if ($this->response->getStatusCode() !== 207) { throw new \Exception( @@ -236,10 +239,10 @@ public function theCaldavResponseShouldBeMultiStatus(): void { } /** - * @Then The CalDAV HTTP status code should be :code * @param int $code * @throws \Exception */ + #[Then('The CalDAV HTTP status code should be :code')] public function theCaldavHttpStatusCodeShouldBe($code) { if ((int)$code !== $this->response->getStatusCode()) { throw new \Exception( @@ -260,10 +263,10 @@ public function theCaldavHttpStatusCodeShouldBe($code) { } /** - * @Then The exception is :message * @param string $message * @throws \Exception */ + #[Then('The exception is :message')] public function theExceptionIs($message) { $result = $this->responseXml['value'][0]['value']; @@ -279,10 +282,10 @@ public function theExceptionIs($message) { } /** - * @Then The error message is :message * @param string $message * @throws \Exception */ + #[Then('The error message is :message')] public function theErrorMessageIs($message) { $result = $this->responseXml['value'][1]['value']; @@ -298,10 +301,10 @@ public function theErrorMessageIs($message) { } /** - * @Given :user creates a calendar named :name * @param string $user * @param string $name */ + #[Given(':user creates a calendar named :name')] public function createsACalendarNamed($user, $name) { $davUrl = $this->baseUrl . '/remote.php/dav/calendars/' . $user . '/' . $name; $password = ($user === 'admin') ? 'admin' : '123456'; @@ -320,11 +323,11 @@ public function createsACalendarNamed($user, $name) { } /** - * @Then :user publicly shares the calendar named :name * * @param string $user * @param string $name */ + #[Then(':user publicly shares the calendar named :name')] public function publiclySharesTheCalendarNamed($user, $name) { $davUrl = $this->baseUrl . '/remote.php/dav/calendars/' . $user . '/' . $name; $password = ($user === 'admin') ? 'admin' : '123456'; @@ -346,10 +349,9 @@ public function publiclySharesTheCalendarNamed($user, $name) { } /** - * @Then There should be :amount calendars in the response body - * * @param string $amount */ + #[Then('There should be :amount calendars in the response body')] public function t($amount) { $jsonEncoded = json_encode($this->responseXml); $arrayElement = json_decode($jsonEncoded, true); @@ -365,9 +367,7 @@ public function t($amount) { } } - /** - * @When :user sends a create calendar request to :calendar on the endpoint :endpoint - */ + #[When(':user sends a create calendar request to :calendar on the endpoint :endpoint')] public function sendsCreateCalendarRequest(string $user, string $calendar, string $endpoint) { $davUrl = $this->baseUrl . $endpoint . $calendar; $password = ($user === 'admin') ? 'admin' : '123456'; @@ -389,9 +389,7 @@ public function sendsCreateCalendarRequest(string $user, string $calendar, strin } } - /** - * @Given :user updates property :key to href :value of principal :principal on the endpoint :endpoint - */ + #[Given(':user updates property :key to href :value of principal :principal on the endpoint :endpoint')] public function updatesHrefPropertyOfPrincipal( string $user, string $key, diff --git a/build/integration/features/bootstrap/CapabilitiesContext.php b/build/integration/features/bootstrap/CapabilitiesContext.php index 460d480158802..ce2f30955effb 100644 --- a/build/integration/features/bootstrap/CapabilitiesContext.php +++ b/build/integration/features/bootstrap/CapabilitiesContext.php @@ -6,7 +6,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ use Behat\Behat\Context\Context; -use Behat\Behat\Context\SnippetAcceptingContext; +use Behat\Step\Then; use PHPUnit\Framework\Assert; require __DIR__ . '/autoload.php'; @@ -14,14 +14,14 @@ /** * Capabilities context. */ -class CapabilitiesContext implements Context, SnippetAcceptingContext { +class CapabilitiesContext implements Context { use BasicStructure; use AppConfiguration; /** - * @Then /^fields of capabilities match with$/ * @param \Behat\Gherkin\Node\TableNode|null $formData */ + #[Then('/^fields of capabilities match with$/')] public function checkCapabilitiesResponse(\Behat\Gherkin\Node\TableNode $formData) { $capabilitiesXML = simplexml_load_string($this->response->getBody()); Assert::assertNotFalse($capabilitiesXML, 'Failed to fetch capabilities'); diff --git a/build/integration/features/bootstrap/CardDavContext.php b/build/integration/features/bootstrap/CardDavContext.php index 030bf86509e03..a8d757cbfcf87 100644 --- a/build/integration/features/bootstrap/CardDavContext.php +++ b/build/integration/features/bootstrap/CardDavContext.php @@ -7,6 +7,11 @@ */ require __DIR__ . '/autoload.php'; +use Behat\Hook\AfterScenario; +use Behat\Hook\BeforeScenario; +use Behat\Step\Given; +use Behat\Step\Then; +use Behat\Step\When; use GuzzleHttp\Client; use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp\Message\ResponseInterface; @@ -29,13 +34,13 @@ public function __construct( } } - /** @BeforeScenario */ + #[BeforeScenario] public function setUpScenario() { $this->client = new Client(); $this->responseXml = ''; } - /** @AfterScenario */ + #[AfterScenario] public function afterScenario() { $davUrl = $this->baseUrl . '/remote.php/dav/addressbooks/users/admin/MyAddressbook'; try { @@ -53,13 +58,13 @@ public function afterScenario() { } /** - * @When :user requests addressbook :addressBook with statuscode :statusCode on the endpoint :endpoint * @param string $user * @param string $addressBook * @param int $statusCode * @param string $endpoint * @throws \Exception */ + #[When(':user requests addressbook :addressBook with statuscode :statusCode on the endpoint :endpoint')] public function requestsAddressbookWithStatuscodeOnTheEndpoint($user, $addressBook, $statusCode, $endpoint) { $davUrl = $this->baseUrl . $endpoint . $addressBook; @@ -98,12 +103,12 @@ public function requestsAddressbookWithStatuscodeOnTheEndpoint($user, $addressBo } /** - * @Given :user creates an addressbook named :addressBook with statuscode :statusCode * @param string $user * @param string $addressBook * @param int $statusCode * @throws \Exception */ + #[Given(':user creates an addressbook named :addressBook with statuscode :statusCode')] public function createsAnAddressbookNamedWithStatuscode($user, $addressBook, $statusCode) { $davUrl = $this->baseUrl . '/remote.php/dav/addressbooks/users/' . $user . '/' . $addressBook; $password = ($user === 'admin') ? 'admin' : '123456'; @@ -144,10 +149,10 @@ public function createsAnAddressbookNamedWithStatuscode($user, $addressBook, $st } /** - * @When The CardDAV exception is :message * @param string $message * @throws \Exception */ + #[When('The CardDAV exception is :message')] public function theCarddavExceptionIs($message) { $result = $this->responseXml['value'][0]['value']; @@ -163,10 +168,10 @@ public function theCarddavExceptionIs($message) { } /** - * @When The CardDAV error message is :arg1 * @param string $message * @throws \Exception */ + #[When('The CardDAV error message is :arg1')] public function theCarddavErrorMessageIs($message) { $result = $this->responseXml['value'][1]['value']; @@ -181,9 +186,7 @@ public function theCarddavErrorMessageIs($message) { } } - /** - * @Given :user uploads the contact :fileName to the addressbook :addressbook - */ + #[Given(':user uploads the contact :fileName to the addressbook :addressbook')] public function uploadsTheContactToTheAddressbook($user, $fileName, $addressBook) { $davUrl = $this->baseUrl . '/remote.php/dav/addressbooks/users/' . $user . '/' . $addressBook . '/' . $fileName; $password = ($user === 'admin') ? 'admin' : '123456'; @@ -214,9 +217,7 @@ public function uploadsTheContactToTheAddressbook($user, $fileName, $addressBook } } - /** - * @When Exporting the picture of contact :fileName from addressbook :addressBook as user :user - */ + #[When('Exporting the picture of contact :fileName from addressbook :addressBook as user :user')] public function whenExportingThePictureOfContactFromAddressbookAsUser($fileName, $addressBook, $user) { $davUrl = $this->baseUrl . '/remote.php/dav/addressbooks/users/' . $user . '/' . $addressBook . '/' . $fileName . '?photo=true'; $password = ($user === 'admin') ? 'admin' : '123456'; @@ -240,9 +241,7 @@ public function whenExportingThePictureOfContactFromAddressbookAsUser($fileName, } } - /** - * @When Downloading the contact :fileName from addressbook :addressBook as user :user - */ + #[When('Downloading the contact :fileName from addressbook :addressBook as user :user')] public function whenDownloadingTheContactFromAddressbookAsUser($fileName, $addressBook, $user) { $davUrl = $this->baseUrl . '/remote.php/dav/addressbooks/users/' . $user . '/' . $addressBook . '/' . $fileName; $password = ($user === 'admin') ? 'admin' : '123456'; @@ -267,10 +266,10 @@ public function whenDownloadingTheContactFromAddressbookAsUser($fileName, $addre } /** - * @Then The following HTTP headers should be set * @param \Behat\Gherkin\Node\TableNode $table * @throws \Exception */ + #[Then('The following HTTP headers should be set')] public function theFollowingHttpHeadersShouldBeSet(\Behat\Gherkin\Node\TableNode $table) { foreach ($table->getTable() as $header) { $headerName = $header[0]; @@ -289,9 +288,7 @@ public function theFollowingHttpHeadersShouldBeSet(\Behat\Gherkin\Node\TableNode } } - /** - * @When :user sends a create addressbook request to :addressbook on the endpoint :endpoint - */ + #[When(':user sends a create addressbook request to :addressbook on the endpoint :endpoint')] public function sendsCreateAddressbookRequest(string $user, string $addressbook, string $endpoint) { $davUrl = $this->baseUrl . $endpoint . $addressbook; $password = ($user === 'admin') ? 'admin' : '123456'; @@ -326,10 +323,10 @@ public function sendsCreateAddressbookRequest(string $user, string $addressbook, } /** - * @Then The CardDAV HTTP status code should be :code * @param int $code * @throws \Exception */ + #[Then('The CardDAV HTTP status code should be :code')] public function theCarddavHttpStatusCodeShouldBe($code) { if ((int)$code !== $this->response->getStatusCode()) { throw new \Exception( diff --git a/build/integration/features/bootstrap/ChecksumsContext.php b/build/integration/features/bootstrap/ChecksumsContext.php index 6f07c32b09d6d..e7ad30782acbb 100644 --- a/build/integration/features/bootstrap/ChecksumsContext.php +++ b/build/integration/features/bootstrap/ChecksumsContext.php @@ -7,6 +7,11 @@ */ require __DIR__ . '/autoload.php'; +use Behat\Hook\AfterScenario; +use Behat\Hook\BeforeScenario; +use Behat\Step\Given; +use Behat\Step\Then; +use Behat\Step\When; use GuzzleHttp\Client; use GuzzleHttp\Message\ResponseInterface; @@ -26,12 +31,12 @@ public function __construct( } } - /** @BeforeScenario */ + #[BeforeScenario] public function setUpScenario() { $this->client = new Client(); } - /** @AfterScenario */ + #[AfterScenario] public function tearDownScenario() { } @@ -47,12 +52,12 @@ private function getPasswordForUser($userName) { } /** - * @When user :user uploads file :source to :destination with checksum :checksum * @param string $user * @param string $source * @param string $destination * @param string $checksum */ + #[When('user :user uploads file :source to :destination with checksum :checksum')] public function userUploadsFileToWithChecksum($user, $source, $destination, $checksum) { $file = \GuzzleHttp\Psr7\Utils::streamFor(fopen($source, 'r')); try { @@ -76,10 +81,10 @@ public function userUploadsFileToWithChecksum($user, $source, $destination, $che } /** - * @Then The webdav response should have a status code :statusCode * @param int $statusCode * @throws \Exception */ + #[Then('The webdav response should have a status code :statusCode')] public function theWebdavResponseShouldHaveAStatusCode($statusCode) { if ((int)$statusCode !== $this->response->getStatusCode()) { throw new \Exception("Expected $statusCode, got " . $this->response->getStatusCode()); @@ -87,10 +92,10 @@ public function theWebdavResponseShouldHaveAStatusCode($statusCode) { } /** - * @When user :user request the checksum of :path via propfind * @param string $user * @param string $path */ + #[When('user :user request the checksum of :path via propfind')] public function userRequestTheChecksumOfViaPropfind($user, $path) { $this->response = $this->client->request( 'PROPFIND', @@ -111,10 +116,10 @@ public function userRequestTheChecksumOfViaPropfind($user, $path) { } /** - * @Then The webdav checksum should match :checksum * @param string $checksum * @throws \Exception */ + #[Then('The webdav checksum should match :checksum')] public function theWebdavChecksumShouldMatch($checksum) { $service = new Sabre\Xml\Service(); $parsed = $service->parse($this->response->getBody()->getContents()); @@ -131,10 +136,10 @@ public function theWebdavChecksumShouldMatch($checksum) { } /** - * @When user :user downloads the file :path * @param string $user * @param string $path */ + #[When('user :user downloads the file :path')] public function userDownloadsTheFile($user, $path) { $this->response = $this->client->get( $this->baseUrl . '/remote.php/webdav' . $path, @@ -148,10 +153,10 @@ public function userDownloadsTheFile($user, $path) { } /** - * @Then The header checksum should match :checksum * @param string $checksum * @throws \Exception */ + #[Then('The header checksum should match :checksum')] public function theHeaderChecksumShouldMatch($checksum) { if ($this->response->getHeader('OC-Checksum')[0] !== $checksum) { throw new \Exception("Expected $checksum, got " . $this->response->getHeader('OC-Checksum')[0]); @@ -159,11 +164,11 @@ public function theHeaderChecksumShouldMatch($checksum) { } /** - * @Given User :user copied file :source to :destination * @param string $user * @param string $source * @param string $destination */ + #[Given('User :user copied file :source to :destination')] public function userCopiedFileTo($user, $source, $destination) { $this->response = $this->client->request( 'MOVE', @@ -180,9 +185,7 @@ public function userCopiedFileTo($user, $source, $destination) { ); } - /** - * @Then The webdav checksum should be empty - */ + #[Then('The webdav checksum should be empty')] public function theWebdavChecksumShouldBeEmpty() { $service = new Sabre\Xml\Service(); $parsed = $service->parse($this->response->getBody()->getContents()); @@ -198,9 +201,7 @@ public function theWebdavChecksumShouldBeEmpty() { } } - /** - * @Then The OC-Checksum header should not be there - */ + #[Then('The OC-Checksum header should not be there')] public function theOcChecksumHeaderShouldNotBeThere() { if ($this->response->hasHeader('OC-Checksum')) { throw new \Exception('Expected no checksum header but got ' . $this->response->getHeader('OC-Checksum')[0]); diff --git a/build/integration/features/bootstrap/CollaborationContext.php b/build/integration/features/bootstrap/CollaborationContext.php index 3b17eb62b6f3a..e8c1307e4b6a4 100644 --- a/build/integration/features/bootstrap/CollaborationContext.php +++ b/build/integration/features/bootstrap/CollaborationContext.php @@ -8,6 +8,8 @@ */ use Behat\Behat\Context\Context; use Behat\Gherkin\Node\TableNode; +use Behat\Step\Given; +use Behat\Step\Then; use GuzzleHttp\Client; use PHPUnit\Framework\Assert; @@ -19,17 +21,17 @@ class CollaborationContext implements Context { use WebDav; /** - * @Then /^get autocomplete for "([^"]*)"$/ * @param TableNode|null $formData */ + #[Then('/^get autocomplete for "([^"]*)"$/')] public function getAutocompleteForUser(string $search, TableNode $formData): void { $this->getAutocompleteWithType(0, $search, $formData); } /** - * @Then /^get email autocomplete for "([^"]*)"$/ * @param TableNode|null $formData */ + #[Then('/^get email autocomplete for "([^"]*)"$/')] public function getAutocompleteForEmail(string $search, TableNode $formData): void { $this->getAutocompleteWithType(4, $search, $formData); } @@ -63,9 +65,7 @@ private function getAutocompleteWithType(int $type, string $search, TableNode $f }, $suggestions, $formData->getHash())); } - /** - * @Given /^there is a contact in an addressbook$/ - */ + #[Given('/^there is a contact in an addressbook$/')] public function thereIsAContactInAnAddressbook() { $this->usingNewDavPath(); try { @@ -115,10 +115,10 @@ protected function resetAppConfigs(): void { } /** - * @Given /^user "([^"]*)" has status "([^"]*)"$/ * @param string $user * @param string $status */ + #[Given('/^user "([^"]*)" has status "([^"]*)"$/')] public function assureUserHasStatus($user, $status) { $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/apps/user_status/api/v1/user_status/status"; $client = new Client(); @@ -175,11 +175,11 @@ public function getStatusList(string $user): ?array { } /** - * @Given /^user statuses for "([^"]*)" list "([^"]*)" with status "([^"]*)"$/ * @param string $user * @param string $statusUser * @param string $status */ + #[Given('/^user statuses for "([^"]*)" list "([^"]*)" with status "([^"]*)"$/')] public function assertStatusesList(string $user, string $statusUser, string $status): void { $statusList = $this->getStatusList($user); Assert::assertArrayHasKey('element', $statusList, 'Returned status list empty or broken'); @@ -196,9 +196,9 @@ public function assertStatusesList(string $user, string $statusUser, string $sta } /** - * @Given /^user statuses for "([^"]*)" are empty$/ * @param string $user */ + #[Given('/^user statuses for "([^"]*)" are empty$/')] public function assertStatusesEmpty(string $user): void { $statusList = $this->getStatusList($user); Assert::assertEmpty($statusList); diff --git a/build/integration/features/bootstrap/CommandLine.php b/build/integration/features/bootstrap/CommandLine.php index a91e8ca6b2530..bc432b71b794b 100644 --- a/build/integration/features/bootstrap/CommandLine.php +++ b/build/integration/features/bootstrap/CommandLine.php @@ -5,6 +5,8 @@ * SPDX-FileCopyrightText: 2016 ownCloud, Inc. * SPDX-License-Identifier: AGPL-3.0-only */ +use Behat\Step\Given; +use Behat\Step\Then; use PHPUnit\Framework\Assert; require __DIR__ . '/autoload.php'; @@ -12,17 +14,13 @@ trait CommandLine { use OccRunner; - /** - * @Given /^invoking occ with "([^"]*)"$/ - */ + #[Given('/^invoking occ with "([^"]*)"$/')] public function invokingTheCommand(string $cmd): void { $args = explode(' ', $cmd); $this->runOcc($args); } - /** - * @Given /^invoking occ with "([^"]*)" with input "([^"]+)"$/ - */ + #[Given('/^invoking occ with "([^"]*)" with input "([^"]+)"$/')] public function invokingTheCommandWith(string $cmd, string $inputString): void { $args = explode(' ', $cmd); $this->runOcc($args, $inputString); @@ -49,9 +47,7 @@ public function findExceptions(): array { return $exceptions; } - /** - * @Then /^the command was successful$/ - */ + #[Then('/^the command was successful$/')] public function theCommandWasSuccessful(): void { $exceptions = $this->findExceptions(); if ($this->lastCode !== 0) { @@ -66,18 +62,14 @@ public function theCommandWasSuccessful(): void { } } - /** - * @Then /^the command failed with exit code ([0-9]+)$/ - */ + #[Then('/^the command failed with exit code ([0-9]+)$/')] public function theCommandFailedWithExitCode($exitCode): void { if ($this->lastCode !== (int)$exitCode) { throw new \Exception('The command was expected to fail with exit code ' . $exitCode . ' but got ' . $this->lastCode); } } - /** - * @Then /^the command failed with exception text "([^"]*)"$/ - */ + #[Then('/^the command failed with exception text "([^"]*)"$/')] public function theCommandFailedWithException(string $exceptionText): void { $exceptions = $this->findExceptions(); if (empty($exceptions)) { @@ -89,23 +81,17 @@ public function theCommandFailedWithException(string $exceptionText): void { } } - /** - * @Then /^the command output contains the text "([^"]*)"$/ - */ + #[Then('/^the command output contains the text "([^"]*)"$/')] public function theCommandOutputContainsTheText(string $text): void { Assert::assertStringContainsString($text, $this->lastStdOut, 'The command did not output the expected text on stdout.'); } - /** - * @Then /^the command output does not contain the text "([^"]*)"$/ - */ + #[Then('/^the command output does not contain the text "([^"]*)"$/')] public function theCommandOutputDoesNotContainTheText(string $text): void { Assert::assertStringNotContainsString($text, $this->lastStdOut, 'The command did output the not expected text on stdout.'); } - /** - * @Then /^the command error output contains the text "([^"]*)"$/ - */ + #[Then('/^the command error output contains the text "([^"]*)"$/')] public function theCommandErrorOutputContainsTheText(string $text): void { Assert::assertStringContainsString($text, $this->lastStdErr, 'The command did not output the expected text on stderr.'); } diff --git a/build/integration/features/bootstrap/CommandLineContext.php b/build/integration/features/bootstrap/CommandLineContext.php index 8b21fcdbf7068..69cf28d4c97e8 100644 --- a/build/integration/features/bootstrap/CommandLineContext.php +++ b/build/integration/features/bootstrap/CommandLineContext.php @@ -9,6 +9,10 @@ use Behat\Behat\Context\Exception\ContextNotFoundException; use Behat\Behat\Hook\Scope\BeforeScenarioScope; +use Behat\Hook\BeforeScenario; +use Behat\Step\Given; +use Behat\Step\Then; +use Behat\Step\When; use PHPUnit\Framework\Assert; class CommandLineContext implements \Behat\Behat\Context\Context { @@ -25,21 +29,17 @@ public function __construct( $this->ocPath = rtrim($ocPath, '/') . '/'; } - /** - * @Given Maintenance mode is enabled - */ + #[Given('Maintenance mode is enabled')] public function maintenanceModeIsEnabled() { $this->runOcc(['maintenance:mode', '--on']); } - /** - * @Then Maintenance mode is disabled - */ + #[Then('Maintenance mode is disabled')] public function maintenanceModeIsDisabled() { $this->runOcc(['maintenance:mode', '--off']); } - /** @BeforeScenario */ + #[BeforeScenario] public function gatherContexts(BeforeScenarioScope $scope) { $environment = $scope->getEnvironment(); // this should really be "WebDavContext" @@ -83,9 +83,7 @@ private function findLastTransferFolderForUser($sourceUser, $targetUser) { return substr($foundPath, strlen($davPath) + 1); } - /** - * @When /^transferring ownership from "([^"]+)" to "([^"]+)"$/ - */ + #[When('/^transferring ownership from "([^"]+)" to "([^"]+)"$/')] public function transferringOwnership($user1, $user2) { if ($this->runOcc(['files:transfer-ownership', $user1, $user2]) === 0) { $this->lastTransferPath = $this->findLastTransferFolderForUser($user1, $user2); @@ -95,9 +93,7 @@ public function transferringOwnership($user1, $user2) { } } - /** - * @When /^transferring ownership of path "([^"]+)" from "([^"]+)" to "([^"]+)"$/ - */ + #[When('/^transferring ownership of path "([^"]+)" from "([^"]+)" to "([^"]+)"$/')] public function transferringOwnershipPath($path, $user1, $user2) { $path = '--path=' . $path; if ($this->runOcc(['files:transfer-ownership', $path, $user1, $user2]) === 0) { @@ -108,18 +104,14 @@ public function transferringOwnershipPath($path, $user1, $user2) { } } - /** - * @When /^using received transfer folder of "([^"]+)" as dav path$/ - */ + #[When('/^using received transfer folder of "([^"]+)" as dav path$/')] public function usingTransferFolderAsDavPath($user) { $davPath = $this->featureContext->getDavFilesPath($user); $davPath = rtrim($davPath, '/') . $this->lastTransferPath; $this->featureContext->usingDavPath($davPath); } - /** - * @Then /^transfer folder name contains "([^"]+)"$/ - */ + #[Then('/^transfer folder name contains "([^"]+)"$/')] public function transferFolderNameContains($text) { Assert::assertStringContainsString($text, $this->lastTransferPath); } diff --git a/build/integration/features/bootstrap/CommentsContext.php b/build/integration/features/bootstrap/CommentsContext.php index a3da58a705529..55d1e25b70c4a 100644 --- a/build/integration/features/bootstrap/CommentsContext.php +++ b/build/integration/features/bootstrap/CommentsContext.php @@ -5,6 +5,12 @@ * SPDX-FileCopyrightText: 2016 ownCloud, Inc. * SPDX-License-Identifier: AGPL-3.0-only */ + +use Behat\Hook\AfterScenario; +use Behat\Step\Given; +use Behat\Step\Then; +use Behat\Step\When; + require __DIR__ . '/autoload.php'; class CommentsContext implements \Behat\Behat\Context\Context { @@ -57,7 +63,7 @@ private function getValueFromNamedEntries(string $path, array $response): mixed return null; } - /** @AfterScenario */ + #[AfterScenario] public function teardownScenario() { $client = new \GuzzleHttp\Client(); try { @@ -103,13 +109,13 @@ private function getFileIdForPath($path) { } /** - * @When :user posts a comment with content :content on the file named :fileName it should return :statusCode * @param string $user * @param string $content * @param string $fileName * @param int $statusCode * @throws \Exception */ + #[When(':user posts a comment with content :content on the file named :fileName it should return :statusCode')] public function postsACommentWithContentOnTheFileNamedItShouldReturn($user, $content, $fileName, $statusCode) { $fileId = $this->getFileIdForPath($fileName); $this->fileId = (int)$fileId; @@ -140,12 +146,12 @@ public function postsACommentWithContentOnTheFileNamedItShouldReturn($user, $con } /** - * @Then As :user load all the comments of the file named :fileName it should return :statusCode * @param string $user * @param string $fileName * @param int $statusCode * @throws \Exception */ + #[Then('As :user load all the comments of the file named :fileName it should return :statusCode')] public function asLoadloadAllTheCommentsOfTheFileNamedItShouldReturn($user, $fileName, $statusCode) { $fileId = $this->getFileIdForPath($fileName); $url = $this->baseUrl . '/remote.php/dav/comments/files/' . $fileId . '/'; @@ -187,13 +193,13 @@ public function asLoadloadAllTheCommentsOfTheFileNamedItShouldReturn($user, $fil } /** - * @Given As :user sending :verb to :url with * @param string $user * @param string $verb * @param string $url * @param \Behat\Gherkin\Node\TableNode $body * @throws \Exception */ + #[Given('As :user sending :verb to :url with')] public function asUserSendingToWith($user, $verb, $url, \Behat\Gherkin\Node\TableNode $body) { $client = new \GuzzleHttp\Client(); $options = []; @@ -207,11 +213,11 @@ public function asUserSendingToWith($user, $verb, $url, \Behat\Gherkin\Node\Tabl } /** - * @Then As :user delete the created comment it should return :statusCode * @param string $user * @param int $statusCode * @throws \Exception */ + #[Then('As :user delete the created comment it should return :statusCode')] public function asDeleteTheCreatedCommentItShouldReturn($user, $statusCode) { $url = $this->baseUrl . '/remote.php/dav/comments/files/' . $this->fileId . '/' . $this->commentId; @@ -239,11 +245,11 @@ public function asDeleteTheCreatedCommentItShouldReturn($user, $statusCode) { } /** - * @Then the response should contain a property :key with value :value * @param string $key * @param string $value * @throws \Exception */ + #[Then('the response should contain a property :key with value :value')] public function theResponseShouldContainAPropertyWithValue($key, $value) { // $keys = $this->response[0]['value'][1]['value'][0]['value']; $keys = $this->getValueFromNamedEntries('{DAV:}response {DAV:}propstat {DAV:}prop', $this->response); @@ -261,10 +267,10 @@ public function theResponseShouldContainAPropertyWithValue($key, $value) { } /** - * @Then the response should contain only :number comments * @param int $number * @throws \Exception */ + #[Then('the response should contain only :number comments')] public function theResponseShouldContainOnlyComments($number) { $count = 0; if ($this->response !== null) { @@ -276,12 +282,12 @@ public function theResponseShouldContainOnlyComments($number) { } /** - * @Then As :user edit the last created comment and set text to :text it should return :statusCode * @param string $user * @param string $text * @param int $statusCode * @throws \Exception */ + #[Then('As :user edit the last created comment and set text to :text it should return :statusCode')] public function asEditTheLastCreatedCommentAndSetTextToItShouldReturn($user, $text, $statusCode) { $client = new \GuzzleHttp\Client(); $options = []; diff --git a/build/integration/features/bootstrap/ContactsMenu.php b/build/integration/features/bootstrap/ContactsMenu.php index f6bf6b9422b70..4fbaa4a7e4f5d 100644 --- a/build/integration/features/bootstrap/ContactsMenu.php +++ b/build/integration/features/bootstrap/ContactsMenu.php @@ -4,17 +4,17 @@ * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ +use Behat\Step\Then; +use Behat\Step\When; use PHPUnit\Framework\Assert; trait ContactsMenu { // BasicStructure trait is expected to be used in the class that uses this // trait. - /** - * @When /^searching for contacts matching with "([^"]*)"$/ - * * @param string $filter */ + #[When('/^searching for contacts matching with "([^"]*)"$/')] public function searchingForContactsMatchingWith(string $filter) { $url = '/index.php/contactsmenu/contacts'; @@ -25,9 +25,7 @@ public function searchingForContactsMatchingWith(string $filter) { $this->sendingAToWithRequesttoken('POST', $url); } - /** - * @Then /^the list of searched contacts has "(\d+)" contacts$/ - */ + #[Then('/^the list of searched contacts has "(\d+)" contacts$/')] public function theListOfSearchedContactsHasContacts(int $count) { $this->theHTTPStatusCodeShouldBe(200); @@ -37,11 +35,11 @@ public function theListOfSearchedContactsHasContacts(int $count) { } /** - * @Then /^searched contact "(\d+)" is named "([^"]*)"$/ * * @param int $index * @param string $expectedName */ + #[Then('/^searched contact "(\d+)" is named "([^"]*)"$/')] public function searchedContactXIsNamed(int $index, string $expectedName) { $searchedContacts = json_decode($this->response->getBody(), $asAssociativeArray = true)['contacts']; $searchedContact = $searchedContacts[$index]; diff --git a/build/integration/features/bootstrap/ConversionsContext.php b/build/integration/features/bootstrap/ConversionsContext.php index 847e5a9bec5b6..e088e0aa44e56 100644 --- a/build/integration/features/bootstrap/ConversionsContext.php +++ b/build/integration/features/bootstrap/ConversionsContext.php @@ -10,21 +10,23 @@ require __DIR__ . '/autoload.php'; use Behat\Behat\Context\Context; -use Behat\Behat\Context\SnippetAcceptingContext; use Behat\Gherkin\Node\TableNode; +use Behat\Hook\AfterScenario; +use Behat\Hook\BeforeScenario; +use Behat\Step\When; -class ConversionsContext implements Context, SnippetAcceptingContext { +class ConversionsContext implements Context { use AppConfiguration; use BasicStructure; use WebDav; - /** @BeforeScenario */ + #[BeforeScenario] public function setUpScenario() { $this->asAn('admin'); $this->setStatusTestingApp(true); } - /** @AfterScenario */ + #[AfterScenario] public function tearDownScenario() { $this->asAn('admin'); $this->setStatusTestingApp(false); @@ -33,16 +35,12 @@ public function tearDownScenario() { protected function resetAppConfigs() { } - /** - * @When /^user "([^"]*)" converts file "([^"]*)" to "([^"]*)"$/ - */ + #[When('/^user "([^"]*)" converts file "([^"]*)" to "([^"]*)"$/')] public function userConvertsTheSavedFileId(string $user, string $path, string $mime) { $this->userConvertsTheSavedFileIdTo($user, $path, $mime, null); } - /** - * @When /^user "([^"]*)" converts file "([^"]*)" to "([^"]*)" and saves it to "([^"]*)"$/ - */ + #[When('/^user "([^"]*)" converts file "([^"]*)" to "([^"]*)" and saves it to "([^"]*)"$/')] public function userConvertsTheSavedFileIdTo(string $user, string $path, string $mime, ?string $destination) { try { $fileId = $this->getFileIdForPath($user, $path); diff --git a/build/integration/features/bootstrap/DavFeatureContext.php b/build/integration/features/bootstrap/DavFeatureContext.php index 1376b320ffe66..e2739ca36d1aa 100644 --- a/build/integration/features/bootstrap/DavFeatureContext.php +++ b/build/integration/features/bootstrap/DavFeatureContext.php @@ -8,11 +8,10 @@ */ use Behat\Behat\Context\Context; -use Behat\Behat\Context\SnippetAcceptingContext; require __DIR__ . '/autoload.php'; -class DavFeatureContext implements Context, SnippetAcceptingContext { +class DavFeatureContext implements Context { use AppConfiguration; use ContactsMenu; use ExternalStorage; diff --git a/build/integration/features/bootstrap/Download.php b/build/integration/features/bootstrap/Download.php index 13f50fb860565..d90d677d46f40 100644 --- a/build/integration/features/bootstrap/Download.php +++ b/build/integration/features/bootstrap/Download.php @@ -4,6 +4,9 @@ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ +use Behat\Hook\AfterScenario; +use Behat\Step\Then; +use Behat\Step\When; use PHPUnit\Framework\Assert; use Psr\Http\Message\StreamInterface; @@ -13,14 +16,12 @@ trait Download { /** @var string * */ private $downloadedFile; - /** @AfterScenario **/ + #[AfterScenario] public function cleanupDownloadedFile() { $this->downloadedFile = null; } - /** - * @When user :user downloads zip file for entries :entries in folder :folder - */ + #[When('user :user downloads zip file for entries :entries in folder :folder')] public function userDownloadsZipFileForEntriesInFolder($user, $entries, $folder) { $folder = trim($folder, '/'); $this->asAn($user); @@ -39,9 +40,7 @@ private function getDownloadedFile() { $body->close(); } - /** - * @Then the downloaded file is a zip file - */ + #[Then('the downloaded file is a zip file')] public function theDownloadedFileIsAZipFile() { $this->getDownloadedFile(); @@ -51,9 +50,7 @@ public function theDownloadedFileIsAZipFile() { ); } - /** - * @Then the downloaded zip file is a zip32 file - */ + #[Then('the downloaded zip file is a zip32 file')] public function theDownloadedZipFileIsAZip32File() { $this->theDownloadedFileIsAZipFile(); @@ -65,9 +62,7 @@ public function theDownloadedZipFileIsAZip32File() { ); } - /** - * @Then the downloaded zip file is a zip64 file - */ + #[Then('the downloaded zip file is a zip64 file')] public function theDownloadedZipFileIsAZip64File() { $this->theDownloadedFileIsAZipFile(); @@ -79,9 +74,7 @@ public function theDownloadedZipFileIsAZip64File() { ); } - /** - * @Then the downloaded zip file contains a file named :fileName with the contents of :sourceFileName from :user data - */ + #[Then('the downloaded zip file contains a file named :fileName with the contents of :sourceFileName from :user data')] public function theDownloadedZipFileContainsAFileNamedWithTheContentsOfFromData($fileName, $sourceFileName, $user) { $fileHeaderRegExp = '/'; $fileHeaderRegExp .= "\x50\x4B\x03\x04"; // Local file header signature @@ -119,9 +112,7 @@ public function theDownloadedZipFileContainsAFileNamedWithTheContentsOfFromData( ); } - /** - * @Then the downloaded zip file contains a folder named :folderName - */ + #[Then('the downloaded zip file contains a folder named :folderName')] public function theDownloadedZipFileContainsAFolderNamed($folderName) { $folderHeaderRegExp = '/'; $folderHeaderRegExp .= "\x50\x4B\x03\x04"; // Local file header signature @@ -139,9 +130,7 @@ public function theDownloadedZipFileContainsAFolderNamed($folderName) { ); } - /** - * @Then the downloaded file has the content of :sourceFilename from :user data - */ + #[Then('the downloaded file has the content of :sourceFilename from :user data')] public function theDownloadedFileHasContentOfUserFile($sourceFilename, $user) { $this->getDownloadedFile(); $expectedFileContents = file_get_contents($this->getDataDirectory() . "/$user/files" . $sourceFilename); diff --git a/build/integration/features/bootstrap/ExternalStorage.php b/build/integration/features/bootstrap/ExternalStorage.php index 7dd39bd36db94..aef686f717b0c 100644 --- a/build/integration/features/bootstrap/ExternalStorage.php +++ b/build/integration/features/bootstrap/ExternalStorage.php @@ -5,6 +5,9 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ use Behat\Gherkin\Node\TableNode; +use Behat\Hook\AfterScenario; +use Behat\Step\Then; +use Behat\Step\When; use PHPUnit\Framework\Assert; require __DIR__ . '/autoload.php'; @@ -14,9 +17,7 @@ trait ExternalStorage { private array $lastExternalStorageData; - /** - * @AfterScenario - **/ + #[AfterScenario] public function deleteCreatedStorages(): void { foreach ($this->storageIds as $storageId) { $this->deleteStorage($storageId); @@ -44,10 +45,9 @@ private function deleteStorage(string $storageId): void { } /** - * @When logged in user creates external global storage - * * @param TableNode $fields */ + #[When('logged in user creates external global storage')] public function loggedInUserCreatesExternalGlobalStorage(TableNode $fields): void { $this->sendJsonWithRequestTokenAndBasicAuth('POST', '/index.php/apps/files_external/globalstorages', $fields); $this->theHTTPStatusCodeShouldBe('201'); @@ -58,10 +58,9 @@ public function loggedInUserCreatesExternalGlobalStorage(TableNode $fields): voi } /** - * @When logged in user updates last external userglobal storage - * * @param TableNode $fields */ + #[When('logged in user updates last external userglobal storage')] public function loggedInUserUpdatesLastExternalUserglobalStorage(TableNode $fields): void { $this->sendJsonWithRequestTokenAndBasicAuth('PUT', '/index.php/apps/files_external/userglobalstorages/' . $this->lastExternalStorageData['id'], $fields); $this->theHTTPStatusCodeShouldBe('200'); @@ -70,10 +69,9 @@ public function loggedInUserUpdatesLastExternalUserglobalStorage(TableNode $fiel } /** - * @Then fields of last external storage match with - * * @param TableNode $fields */ + #[Then('fields of last external storage match with')] public function fieldsOfLastExternalStorageMatchWith(TableNode $fields): void { foreach ($fields->getRowsHash() as $expectedField => $expectedValue) { if (!array_key_exists($expectedField, $this->lastExternalStorageData)) { diff --git a/build/integration/features/bootstrap/FeatureContext.php b/build/integration/features/bootstrap/FeatureContext.php index 65934f15427eb..eb1ce1a1e34fc 100644 --- a/build/integration/features/bootstrap/FeatureContext.php +++ b/build/integration/features/bootstrap/FeatureContext.php @@ -8,14 +8,13 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ use Behat\Behat\Context\Context; -use Behat\Behat\Context\SnippetAcceptingContext; require __DIR__ . '/autoload.php'; /** * Features context. */ -class FeatureContext implements Context, SnippetAcceptingContext { +class FeatureContext implements Context { use AppConfiguration; use OccRunner; use ContactsMenu; diff --git a/build/integration/features/bootstrap/FederationContext.php b/build/integration/features/bootstrap/FederationContext.php index eb1d2bda10cd8..3f4084eefa4bd 100644 --- a/build/integration/features/bootstrap/FederationContext.php +++ b/build/integration/features/bootstrap/FederationContext.php @@ -6,8 +6,12 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ use Behat\Behat\Context\Context; -use Behat\Behat\Context\SnippetAcceptingContext; use Behat\Gherkin\Node\TableNode; +use Behat\Hook\AfterScenario; +use Behat\Hook\BeforeScenario; +use Behat\Step\Given; +use Behat\Step\Then; +use Behat\Step\When; use PHPUnit\Framework\Assert; require __DIR__ . '/autoload.php'; @@ -15,7 +19,7 @@ /** * Federation context. */ -class FederationContext implements Context, SnippetAcceptingContext { +class FederationContext implements Context { use WebDav; use AppConfiguration; use CommandLine; @@ -27,12 +31,11 @@ class FederationContext implements Context, SnippetAcceptingContext { private $lastAcceptedRemoteShareId; /** - * @BeforeScenario - * @AfterScenario - * * The server is started also after the scenarios to ensure that it is * properly cleaned up if stopped. */ + #[BeforeScenario] + #[AfterScenario] public function startFederatedServer(): void { if (self::$phpFederatedServerPid !== '') { return; @@ -43,9 +46,7 @@ public function startFederatedServer(): void { self::$phpFederatedServerPid = exec('PHP_CLI_SERVER_WORKERS=2 php -S localhost:' . $port . ' -t ../../ >/dev/null & echo $!'); } - /** - * @BeforeScenario - */ + #[BeforeScenario] public function cleanupRemoteStorages(): void { // Ensure that dangling remote storages from previous tests will not // interfere with the current scenario. @@ -57,11 +58,11 @@ public function cleanupRemoteStorages(): void { } /** - * @Given /^User "([^"]*)" from server "(LOCAL|REMOTE)" shares "([^"]*)" with user "([^"]*)" from server "(LOCAL|REMOTE)"$/ - * - * @param 'LOCAL'|'REMOTE' $sharerServer "LOCAL" or "REMOTE" + * * + * * @param 'LOCAL'|'REMOTE' $sharerServer "LOCAL" or "REMOTE" * @param 'LOCAL'|'REMOTE' $shareeServer */ + #[Given('/^User "([^"]*)" from server "(LOCAL|REMOTE)" shares "([^"]*)" with user "([^"]*)" from server "(LOCAL|REMOTE)"$/')] public function federateSharing(string $sharerUser, string $sharerServer, string $sharerPath, string $shareeUser, string $shareeServer): void { if ($shareeServer === 'REMOTE') { $shareWith = "$shareeUser@" . substr($this->remoteBaseUrl, 0, -4); @@ -74,11 +75,11 @@ public function federateSharing(string $sharerUser, string $sharerServer, string } /** - * @Given /^User "([^"]*)" from server "(LOCAL|REMOTE)" shares "([^"]*)" with group "([^"]*)" from server "(LOCAL|REMOTE)"$/ - * - * @param 'LOCAL'|'REMOTE' $sharerServer "LOCAL" or "REMOTE" + * * + * * @param 'LOCAL'|'REMOTE' $sharerServer "LOCAL" or "REMOTE" * @param 'LOCAL'|'REMOTE' $shareeServer */ + #[Given('/^User "([^"]*)" from server "(LOCAL|REMOTE)" shares "([^"]*)" with group "([^"]*)" from server "(LOCAL|REMOTE)"$/')] public function federateGroupSharing(string $sharerUser, string $sharerServer, string $sharerPath, string $shareeGroup, string $shareeServer): void { if ($shareeServer === 'REMOTE') { $shareWith = "$shareeGroup@" . substr($this->remoteBaseUrl, 0, -4); @@ -90,9 +91,7 @@ public function federateGroupSharing(string $sharerUser, string $sharerServer, s $this->usingServer($previous); } - /** - * @Then remote share :count is returned with - */ + #[Then('remote share :count is returned with')] public function remoteShareXIsReturnedWith(int $number, TableNode $body): void { $this->theHTTPStatusCodeShouldBe('200'); $this->theOCSStatusCodeShouldBe('100'); @@ -118,9 +117,7 @@ public function remoteShareXIsReturnedWith(int $number, TableNode $body): void { } } - /** - * @When /^User "([^"]*)" from server "(LOCAL|REMOTE)" accepts last pending share$/ - */ + #[When('/^User "([^"]*)" from server "(LOCAL|REMOTE)" accepts last pending share$/')] public function acceptLastPendingShare(string $user, string $server): void { $previous = $this->usingServer($server); $this->asAn($user); @@ -137,17 +134,13 @@ public function acceptLastPendingShare(string $user, string $server): void { $this->lastAcceptedRemoteShareId = $share_id; } - /** - * @When /^user "([^"]*)" deletes last accepted remote share$/ - */ + #[When('/^user "([^"]*)" deletes last accepted remote share$/')] public function deleteLastAcceptedRemoteShare(string $user): void { $this->asAn($user); $this->sendingToWith('DELETE', '/apps/files_sharing/api/v1/remote_shares/' . $this->lastAcceptedRemoteShareId, null); } - /** - * @When /^remote server is stopped$/ - */ + #[When('/^remote server is stopped$/')] public function remoteServerIsStopped(): void { if (self::$phpFederatedServerPid === '') { return; @@ -158,9 +151,7 @@ public function remoteServerIsStopped(): void { self::$phpFederatedServerPid = ''; } - /** - * @BeforeScenario @TrustedFederation - */ + #[BeforeScenario('@TrustedFederation')] public function theServersAreTrustingEachOther(): void { $this->asAn('admin'); // Trust the remote server on the local server @@ -175,9 +166,7 @@ public function theServersAreTrustingEachOther(): void { Assert::assertTrue(($this->response->getStatusCode() === 200 || $this->response->getStatusCode() === 409)); } - /** - * @AfterScenario @TrustedFederation - */ + #[AfterScenario('@TrustedFederation')] public function theServersAreNoLongerTrustingEachOther(): void { $this->asAn('admin'); // Untrust the remote servers on the local server diff --git a/build/integration/features/bootstrap/FilesDropContext.php b/build/integration/features/bootstrap/FilesDropContext.php index 02925535bd4f6..8c585dca27225 100644 --- a/build/integration/features/bootstrap/FilesDropContext.php +++ b/build/integration/features/bootstrap/FilesDropContext.php @@ -5,17 +5,15 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ use Behat\Behat\Context\Context; -use Behat\Behat\Context\SnippetAcceptingContext; +use Behat\Step\When; use GuzzleHttp\Client; require __DIR__ . '/autoload.php'; -class FilesDropContext implements Context, SnippetAcceptingContext { +class FilesDropContext implements Context { use WebDav; - /** - * @When Dropping file :path with :content - */ + #[When('Dropping file :path with :content')] public function droppingFileWith($path, $content, $nickname = null) { $client = new Client(); $options = []; @@ -45,16 +43,12 @@ public function droppingFileWith($path, $content, $nickname = null) { } } - /** - * @When Dropping file :path with :content as :nickName - */ + #[When('Dropping file :path with :content as :nickName')] public function droppingFileWithAs($path, $content, $nickname) { $this->droppingFileWith($path, $content, $nickname); } - /** - * @When Creating folder :folder in drop - */ + #[When('Creating folder :folder in drop')] public function creatingFolderInDrop($folder, $nickname = null) { $client = new Client(); $options = []; @@ -82,9 +76,7 @@ public function creatingFolderInDrop($folder, $nickname = null) { } } - /** - * @When Creating folder :folder in drop as :nickName - */ + #[When('Creating folder :folder in drop as :nickName')] public function creatingFolderInDropWithNickname($folder, $nickname) { return $this->creatingFolderInDrop($folder, $nickname); } diff --git a/build/integration/features/bootstrap/FilesRemindersContext.php b/build/integration/features/bootstrap/FilesRemindersContext.php index 0889042c9af20..051d04f42913f 100644 --- a/build/integration/features/bootstrap/FilesRemindersContext.php +++ b/build/integration/features/bootstrap/FilesRemindersContext.php @@ -5,6 +5,8 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ use Behat\Behat\Context\Context; +use Behat\Step\Then; +use Behat\Step\When; use PHPUnit\Framework\Assert; require __DIR__ . '/autoload.php'; @@ -16,9 +18,7 @@ class FilesRemindersContext implements Context { use BasicStructure; use WebDav; - /** - * @When the user sets a reminder for :path with due date :dueDate - */ + #[When('the user sets a reminder for :path with due date :dueDate')] public function settingAReminderForFileWithDueDate($path, $dueDate) { $fileId = $this->getFileIdForPath($this->currentUser, $path); $this->sendRequestForJSON( @@ -29,9 +29,7 @@ public function settingAReminderForFileWithDueDate($path, $dueDate) { ); } - /** - * @Then the user sees the reminder for :path is set to :dueDate - */ + #[Then('the user sees the reminder for :path is set to :dueDate')] public function retrievingTheReminderForFile($path, $dueDate) { $fileId = $this->getFileIdForPath($this->currentUser, $path); $this->sendRequestForJSON( @@ -44,9 +42,7 @@ public function retrievingTheReminderForFile($path, $dueDate) { Assert::assertEquals($dueDate, $response); } - /** - * @Then the user sees the reminder for :path is not set - */ + #[Then('the user sees the reminder for :path is not set')] public function retrievingTheReminderForFileIsNotSet($path) { $fileId = $this->getFileIdForPath($this->currentUser, $path); $this->sendRequestForJSON( @@ -59,9 +55,7 @@ public function retrievingTheReminderForFileIsNotSet($path) { Assert::assertNull($response); } - /** - * @When the user removes the reminder for :path - */ + #[When('the user removes the reminder for :path')] public function removingTheReminderForFile($path) { $fileId = $this->getFileIdForPath($this->currentUser, $path); $this->sendRequestForJSON( diff --git a/build/integration/features/bootstrap/GuestsContext.php b/build/integration/features/bootstrap/GuestsContext.php index 134ab3f8b56f9..21bd1819232c8 100644 --- a/build/integration/features/bootstrap/GuestsContext.php +++ b/build/integration/features/bootstrap/GuestsContext.php @@ -7,21 +7,25 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ use Behat\Behat\Context\Context; +use Behat\Hook\AfterScenario; +use Behat\Hook\BeforeFeature; +use Behat\Hook\BeforeScenario; +use Behat\Step\Given; class GuestsContext implements Context { public const TEST_PASSWORD = '123456'; protected static $lastStdOut = null; protected static $lastCode = null; - #[\Behat\Hook\BeforeScenario('@Guests')] - #[\Behat\Hook\BeforeFeature('@Guests')] + #[BeforeScenario('@Guests')] + #[BeforeFeature('@Guests')] public static function skipTestsIfGuestsIsNotInstalled() { if (!self::isGuestsInstalled()) { throw new Exception('Guests needs to be installed to run features or scenarios tagged with @Guests'); } } - #[\Behat\Hook\AfterScenario('@Guests')] + #[AfterScenario('@Guests')] public static function disableGuests() { self::runOcc(['app:disable', 'guests']); } @@ -53,7 +57,7 @@ private static function runOcc(array $args, array $env = []): int { return self::$lastCode; } - #[\Behat\Step\Given('/^user "([^"]*)" is a guest account user$/')] + #[Given('/^user "([^"]*)" is a guest account user$/')] public function createGuestUser(string $email): void { self::runOcc([ 'user:delete', diff --git a/build/integration/features/bootstrap/LDAPContext.php b/build/integration/features/bootstrap/LDAPContext.php index 986dced77a16b..27c04e103a637 100644 --- a/build/integration/features/bootstrap/LDAPContext.php +++ b/build/integration/features/bootstrap/LDAPContext.php @@ -6,6 +6,9 @@ */ use Behat\Behat\Context\Context; use Behat\Gherkin\Node\TableNode; +use Behat\Hook\AfterScenario; +use Behat\Step\Given; +use Behat\Step\When; use PHPUnit\Framework\Assert; class LDAPContext implements Context { @@ -17,7 +20,7 @@ class LDAPContext implements Context { protected $apiUrl; - /** @AfterScenario */ + #[AfterScenario] public function teardown() { if ($this->configID === null) { return; @@ -27,17 +30,13 @@ public function teardown() { $this->sendingTo('DELETE', $this->apiUrl . '/' . $this->configID); } - /** - * @Given /^the response should contain a tag "([^"]*)"$/ - */ + #[Given('/^the response should contain a tag "([^"]*)"$/')] public function theResponseShouldContainATag($arg1) { $configID = simplexml_load_string($this->response->getBody())->data[0]->$arg1; Assert::assertInstanceOf(SimpleXMLElement::class, $configID[0]); } - /** - * @Given /^creating an LDAP configuration at "([^"]*)"$/ - */ + #[Given('/^creating an LDAP configuration at "([^"]*)"$/')] public function creatingAnLDAPConfigurationAt($apiUrl) { $this->apiUrl = $apiUrl; $this->sendingToWith('POST', $this->apiUrl, null); @@ -45,24 +44,18 @@ public function creatingAnLDAPConfigurationAt($apiUrl) { $this->configID = $configElements[0]; } - /** - * @When /^deleting the LDAP configuration$/ - */ + #[When('/^deleting the LDAP configuration$/')] public function deletingTheLDAPConfiguration() { $this->sendingToWith('DELETE', $this->apiUrl . '/' . $this->configID, null); } - /** - * @Given /^the response should contain a tag "([^"]*)" with value "([^"]*)"$/ - */ + #[Given('/^the response should contain a tag "([^"]*)" with value "([^"]*)"$/')] public function theResponseShouldContainATagWithValue($tagName, $expectedValue) { $data = simplexml_load_string($this->response->getBody())->data[0]->$tagName; Assert::assertEquals($expectedValue, $data[0]); } - /** - * @When /^getting the LDAP configuration with showPassword "([^"]*)"$/ - */ + #[When('/^getting the LDAP configuration with showPassword "([^"]*)"$/')] public function gettingTheLDAPConfigurationWithShowPassword($showPassword) { $this->sendingToWith( 'GET', @@ -71,16 +64,12 @@ public function gettingTheLDAPConfigurationWithShowPassword($showPassword) { ); } - /** - * @Given /^setting the LDAP configuration to$/ - */ + #[Given('/^setting the LDAP configuration to$/')] public function settingTheLDAPConfigurationTo(TableNode $configData) { $this->sendingToWith('PUT', $this->apiUrl . '/' . $this->configID, $configData); } - /** - * @Given /^having a valid LDAP configuration$/ - */ + #[Given('/^having a valid LDAP configuration$/')] public function havingAValidLDAPConfiguration() { $this->asAn('admin'); $this->creatingAnLDAPConfigurationAt('/apps/user_ldap/api/v1/config'); @@ -102,9 +91,9 @@ public function havingAValidLDAPConfiguration() { } /** - * @Given /^looking up details for the first result matches expectations$/ * @param TableNode $expectations */ + #[Given('/^looking up details for the first result matches expectations$/')] public function lookingUpDetailsForTheFirstResult(TableNode $expectations) { $userResultElements = simplexml_load_string($this->response->getBody())->data[0]->users[0]->element; $userResults = json_decode(json_encode($userResultElements), 1); @@ -114,9 +103,7 @@ public function lookingUpDetailsForTheFirstResult(TableNode $expectations) { $this->theRecordFieldsShouldMatch($expectations); } - /** - * @Given /^modify LDAP configuration$/ - */ + #[Given('/^modify LDAP configuration$/')] public function modifyLDAPConfiguration(TableNode $table) { $originalAsAn = $this->currentUser; $this->asAn('admin'); @@ -131,9 +118,7 @@ public function modifyLDAPConfiguration(TableNode $table) { $this->asAn($originalAsAn); } - /** - * @Given /^the "([^"]*)" result should match$/ - */ + #[Given('/^the "([^"]*)" result should match$/')] public function theGroupResultShouldMatch(string $type, TableNode $expectations) { $listReturnedElements = simplexml_load_string($this->response->getBody())->data[0]->$type[0]->element; $extractedIDsArray = json_decode(json_encode($listReturnedElements), 1); @@ -146,9 +131,7 @@ public function theGroupResultShouldMatch(string $type, TableNode $expectations) } } - /** - * @Given /^Expect ServerException on failed web login as "([^"]*)"$/ - */ + #[Given('/^Expect ServerException on failed web login as "([^"]*)"$/')] public function expectServerExceptionOnFailedWebLoginAs($login) { try { $this->loggingInUsingWebAs($login); @@ -159,9 +142,7 @@ public function expectServerExceptionOnFailedWebLoginAs($login) { Assert::assertTrue(false, 'expected Exception not received'); } - /** - * @Given /^the "([^"]*)" result should contain "([^"]*)" of$/ - */ + #[Given('/^the "([^"]*)" result should contain "([^"]*)" of$/')] public function theResultShouldContainOf($type, $expectedCount, TableNode $expectations) { $listReturnedElements = simplexml_load_string($this->response->getBody())->data[0]->$type[0]->element; $extractedIDsArray = json_decode(json_encode($listReturnedElements), 1); @@ -174,9 +155,7 @@ public function theResultShouldContainOf($type, $expectedCount, TableNode $expec Assert::assertSame((int)$expectedCount, $uidsFound); } - /** - * @Given /^the record's fields should match$/ - */ + #[Given('/^the record\'s fields should match$/')] public function theRecordFieldsShouldMatch(TableNode $expectations) { foreach ($expectations->getRowsHash() as $k => $v) { $value = (string)simplexml_load_string($this->response->getBody())->data[0]->$k; diff --git a/build/integration/features/bootstrap/Mail.php b/build/integration/features/bootstrap/Mail.php index 4c7ca6a0d27e9..3c47ae4a79fc4 100644 --- a/build/integration/features/bootstrap/Mail.php +++ b/build/integration/features/bootstrap/Mail.php @@ -4,6 +4,10 @@ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + +use Behat\Hook\AfterScenario; +use Behat\Step\Given; + trait Mail { // OccRunner trait is expected to be used in the class that uses this // trait. @@ -13,9 +17,7 @@ trait Mail { */ private $fakeSmtpServerPid; - /** - * @AfterScenario - */ + #[AfterScenario] public function killDummyMailServer() { if (!$this->fakeSmtpServerPid) { return; @@ -26,9 +28,7 @@ public function killDummyMailServer() { $this->runOcc(['config:system:delete', 'mail_smtpport']); } - /** - * @Given /^dummy mail server is listening$/ - */ + #[Given('/^dummy mail server is listening$/')] public function dummyMailServerIsListening() { // Default smtpport (25) is restricted for regular users, so the // FakeSMTP uses 2525 instead. diff --git a/build/integration/features/bootstrap/PHPUnitAssertionsExtension.php b/build/integration/features/bootstrap/PHPUnitAssertionsExtension.php new file mode 100644 index 0000000000000..e052a67eae01f --- /dev/null +++ b/build/integration/features/bootstrap/PHPUnitAssertionsExtension.php @@ -0,0 +1,51 @@ +addTag(ExceptionExtension::STRINGER_TAG, ['priority' => 50]); + $container->setDefinition(ExceptionExtension::STRINGER_TAG . '.phpunit_assertions', $stringer); + + $listener = new Definition(PHPUnitBootstrappingListener::class); + $listener->addTag(EventDispatcherExtension::SUBSCRIBER_TAG, ['priority' => -10]); + $container->setDefinition('phpunit_assertions.bootstrapping_listener', $listener); + } + + public function process(ContainerBuilder $container): void { + } +} diff --git a/build/integration/features/bootstrap/PrincipalPropertySearchContext.php b/build/integration/features/bootstrap/PrincipalPropertySearchContext.php index 95a417b03fffc..f2ede2c2baad2 100644 --- a/build/integration/features/bootstrap/PrincipalPropertySearchContext.php +++ b/build/integration/features/bootstrap/PrincipalPropertySearchContext.php @@ -8,6 +8,9 @@ require __DIR__ . '/autoload.php'; use Behat\Behat\Context\Context; +use Behat\Hook\BeforeScenario; +use Behat\Step\Then; +use Behat\Step\When; use GuzzleHttp\BodySummarizer; use GuzzleHttp\Client; use GuzzleHttp\HandlerStack; @@ -29,7 +32,7 @@ public function __construct( } } - /** @BeforeScenario */ + #[BeforeScenario] public function setUpScenario(): void { $this->client = $this->createGuzzleInstance(); } @@ -50,10 +53,10 @@ private function createGuzzleInstance(): Client { } /** - * @When searching for a principal matching :match * @param string $match * @throws \Exception */ + #[When('searching for a principal matching :match')] public function principalPropertySearch(string $match) { $davUrl = $this->baseUrl . '/remote.php/dav/'; $user = 'admin'; @@ -115,10 +118,10 @@ public function principalPropertySearch(string $match) { } /** - * @Then The search HTTP status code should be :code * @param string $code * @throws \Exception */ + #[Then('The search HTTP status code should be :code')] public function theHttpStatusCodeShouldBe(string $code): void { if ((int)$code !== $this->response->getStatusCode()) { throw new \Exception('Expected ' . (int)$code . ' got ' . $this->response->getStatusCode()); @@ -126,10 +129,10 @@ public function theHttpStatusCodeShouldBe(string $code): void { } /** - * @Then The search response should contain :needle * @param string $needle * @throws \Exception */ + #[Then('The search response should contain :needle')] public function theResponseShouldContain(string $needle): void { $body = $this->response->getBody()->getContents(); diff --git a/build/integration/features/bootstrap/Provisioning.php b/build/integration/features/bootstrap/Provisioning.php index 80322978741db..e5a71592e840d 100644 --- a/build/integration/features/bootstrap/Provisioning.php +++ b/build/integration/features/bootstrap/Provisioning.php @@ -7,6 +7,11 @@ */ use Behat\Gherkin\Node\TableNode; +use Behat\Hook\AfterScenario; +use Behat\Hook\BeforeScenario; +use Behat\Step\Given; +use Behat\Step\Then; +use Behat\Step\When; use GuzzleHttp\Client; use GuzzleHttp\Message\ResponseInterface; use PHPUnit\Framework\Assert; @@ -34,7 +39,7 @@ trait Provisioning { /** @var array */ private $createdGroups = []; - /** @AfterScenario */ + #[AfterScenario] public function restoreAppsEnabledStateAfterScenario() { $this->asAn('admin'); @@ -48,9 +53,9 @@ public function restoreAppsEnabledStateAfterScenario() { } /** - * @Given /^user "([^"]*)" exists$/ * @param string $user */ + #[Given('/^user "([^"]*)" exists$/')] public function assureUserExists($user) { try { $this->userExists($user); @@ -65,9 +70,9 @@ public function assureUserExists($user) { } /** - * @Given /^user "([^"]*)" with displayname "((?:[^"]|\\")*)" exists$/ * @param string $user */ + #[Given('/^user "([^"]*)" with displayname "((?:[^"]|\\\\")*)" exists$/')] public function assureUserWithDisplaynameExists($user, $displayname) { try { $this->userExists($user); @@ -82,9 +87,9 @@ public function assureUserWithDisplaynameExists($user, $displayname) { } /** - * @Given /^user "([^"]*)" does not exist$/ * @param string $user */ + #[Given('/^user "([^"]*)" does not exist$/')] public function userDoesNotExist($user) { try { $this->userExists($user); @@ -143,11 +148,11 @@ public function creatingTheUser($user, $displayname = '') { } /** - * @Then /^user "([^"]*)" has$/ * * @param string $user * @param TableNode|null $settings */ + #[Then('/^user "([^"]*)" has$/')] public function userHasSetting($user, $settings) { $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user"; $client = new Client(); @@ -177,9 +182,7 @@ public function userHasSetting($user, $settings) { } } - /** - * @Then /^user "([^"]*)" has the following profile data$/ - */ + #[Then('/^user "([^"]*)" has the following profile data$/')] public function userHasProfileData(string $user, ?TableNode $settings): void { $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/profile/$user"; $client = new Client(); @@ -209,11 +212,11 @@ public function userHasProfileData(string $user, ?TableNode $settings): void { } /** - * @Then /^group "([^"]*)" has$/ * * @param string $user * @param TableNode|null $settings */ + #[Then('/^group "([^"]*)" has$/')] public function groupHasSetting($group, $settings) { $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/groups/details?search=$group"; $client = new Client(); @@ -240,11 +243,11 @@ public function groupHasSetting($group, $settings) { } /** - * @Then /^user "([^"]*)" has editable fields$/ * * @param string $user * @param TableNode|null $fields */ + #[Then('/^user "([^"]*)" has editable fields$/')] public function userHasEditableFields($user, $fields) { $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/user/fields"; if ($user !== 'self') { @@ -273,11 +276,11 @@ public function userHasEditableFields($user, $fields) { } /** - * @Then /^search users by phone for region "([^"]*)" with$/ * * @param string $user * @param TableNode|null $settings */ + #[Then('/^search users by phone for region "([^"]*)" with$/')] public function searchUserByPhone($region, TableNode $searchTable) { $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/search/by-phone"; $client = new Client(); @@ -348,10 +351,10 @@ public function userExists($user) { } /** - * @Then /^check that user "([^"]*)" belongs to group "([^"]*)"$/ * @param string $user * @param string $group */ + #[Then('/^check that user "([^"]*)" belongs to group "([^"]*)"$/')] public function checkThatUserBelongsToGroup($user, $group) { $fullUrl = $this->baseUrl . "v2.php/cloud/users/$user/groups"; $client = new Client(); @@ -392,10 +395,10 @@ public function userBelongsToGroup($user, $group) { } /** - * @Given /^user "([^"]*)" belongs to group "([^"]*)"$/ * @param string $user * @param string $group */ + #[Given('/^user "([^"]*)" belongs to group "([^"]*)"$/')] public function assureUserBelongsToGroup($user, $group) { $previous_user = $this->currentUser; $this->currentUser = 'admin'; @@ -409,10 +412,10 @@ public function assureUserBelongsToGroup($user, $group) { } /** - * @Given /^user "([^"]*)" does not belong to group "([^"]*)"$/ * @param string $user * @param string $group */ + #[Given('/^user "([^"]*)" does not belong to group "([^"]*)"$/')] public function userDoesNotBelongToGroup($user, $group) { $fullUrl = $this->baseUrl . "v2.php/cloud/users/$user/groups"; $client = new Client(); @@ -432,9 +435,9 @@ public function userDoesNotBelongToGroup($user, $group) { } /** - * @When /^creating the group "([^"]*)"$/ * @param string $group */ + #[When('/^creating the group "([^"]*)"$/')] public function creatingTheGroup($group) { $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/groups"; $client = new Client(); @@ -458,9 +461,7 @@ public function creatingTheGroup($group) { } } - /** - * @When /^assure user "([^"]*)" is disabled$/ - */ + #[When('/^assure user "([^"]*)" is disabled$/')] public function assureUserIsDisabled($user) { $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user/disable"; $client = new Client(); @@ -480,9 +481,9 @@ public function assureUserIsDisabled($user) { } /** - * @When /^Deleting the user "([^"]*)"$/ * @param string $user */ + #[When('/^Deleting the user "([^"]*)"$/')] public function deletingTheUser($user) { $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user"; $client = new Client(); @@ -498,9 +499,9 @@ public function deletingTheUser($user) { } /** - * @When /^Deleting the group "([^"]*)"$/ * @param string $group */ + #[When('/^Deleting the group "([^"]*)"$/')] public function deletingTheGroup($group) { $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/groups/$group"; $client = new Client(); @@ -522,10 +523,10 @@ public function deletingTheGroup($group) { } /** - * @Given /^Add user "([^"]*)" to the group "([^"]*)"$/ * @param string $user * @param string $group */ + #[Given('/^Add user "([^"]*)" to the group "([^"]*)"$/')] public function addUserToGroup($user, $group) { $this->userExists($user); $this->groupExists($group); @@ -533,10 +534,10 @@ public function addUserToGroup($user, $group) { } /** - * @When /^User "([^"]*)" is added to the group "([^"]*)"$/ * @param string $user * @param string $group */ + #[When('/^User "([^"]*)" is added to the group "([^"]*)"$/')] public function addingUserToGroup($user, $group) { $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user/groups"; $client = new Client(); @@ -568,9 +569,9 @@ public function groupExists($group) { } /** - * @Given /^group "([^"]*)" exists$/ * @param string $group */ + #[Given('/^group "([^"]*)" exists$/')] public function assureGroupExists($group) { try { $this->groupExists($group); @@ -585,9 +586,9 @@ public function assureGroupExists($group) { } /** - * @Given /^group "([^"]*)" does not exist$/ * @param string $group */ + #[Given('/^group "([^"]*)" does not exist$/')] public function groupDoesNotExist($group) { try { $this->groupExists($group); @@ -609,10 +610,10 @@ public function groupDoesNotExist($group) { } /** - * @Given /^user "([^"]*)" is subadmin of group "([^"]*)"$/ * @param string $user * @param string $group */ + #[Given('/^user "([^"]*)" is subadmin of group "([^"]*)"$/')] public function userIsSubadminOfGroup($user, $group) { $fullUrl = $this->baseUrl . "v2.php/cloud/groups/$group/subadmins"; $client = new Client(); @@ -632,10 +633,10 @@ public function userIsSubadminOfGroup($user, $group) { } /** - * @Given /^Assure user "([^"]*)" is subadmin of group "([^"]*)"$/ * @param string $user * @param string $group */ + #[Given('/^Assure user "([^"]*)" is subadmin of group "([^"]*)"$/')] public function assureUserIsSubadminOfGroup($user, $group) { $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user/subadmins"; $client = new Client(); @@ -654,10 +655,10 @@ public function assureUserIsSubadminOfGroup($user, $group) { } /** - * @Given /^user "([^"]*)" is not a subadmin of group "([^"]*)"$/ * @param string $user * @param string $group */ + #[Given('/^user "([^"]*)" is not a subadmin of group "([^"]*)"$/')] public function userIsNotSubadminOfGroup($user, $group) { $fullUrl = $this->baseUrl . "v2.php/cloud/groups/$group/subadmins"; $client = new Client(); @@ -677,9 +678,9 @@ public function userIsNotSubadminOfGroup($user, $group) { } /** - * @Then /^users returned are$/ * @param TableNode|null $usersList */ + #[Then('/^users returned are$/')] public function theUsersShouldBe($usersList) { if ($usersList instanceof TableNode) { $users = $usersList->getRows(); @@ -690,9 +691,9 @@ public function theUsersShouldBe($usersList) { } /** - * @Then /^phone matches returned are$/ * @param TableNode|null $usersList */ + #[Then('/^phone matches returned are$/')] public function thePhoneUsersShouldBe($usersList) { if ($usersList instanceof TableNode) { $users = $usersList->getRowsHash(); @@ -703,9 +704,9 @@ public function thePhoneUsersShouldBe($usersList) { } /** - * @Then /^detailed users returned are$/ * @param TableNode|null $usersList */ + #[Then('/^detailed users returned are$/')] public function theDetailedUsersShouldBe($usersList) { if ($usersList instanceof TableNode) { $users = $usersList->getRows(); @@ -717,9 +718,9 @@ public function theDetailedUsersShouldBe($usersList) { } /** - * @Then /^groups returned are$/ * @param TableNode|null $groupsList */ + #[Then('/^groups returned are$/')] public function theGroupsShouldBe($groupsList) { if ($groupsList instanceof TableNode) { $groups = $groupsList->getRows(); @@ -730,9 +731,9 @@ public function theGroupsShouldBe($groupsList) { } /** - * @Then /^subadmin groups returned are$/ * @param TableNode|null $groupsList */ + #[Then('/^subadmin groups returned are$/')] public function theSubadminGroupsShouldBe($groupsList) { if ($groupsList instanceof TableNode) { $groups = $groupsList->getRows(); @@ -743,9 +744,9 @@ public function theSubadminGroupsShouldBe($groupsList) { } /** - * @Then /^apps returned are$/ * @param TableNode|null $appList */ + #[Then('/^apps returned are$/')] public function theAppsShouldBe($appList) { if ($appList instanceof TableNode) { $apps = $appList->getRows(); @@ -756,9 +757,9 @@ public function theAppsShouldBe($appList) { } /** - * @Then /^subadmin users returned are$/ * @param TableNode|null $groupsList */ + #[Then('/^subadmin users returned are$/')] public function theSubadminUsersShouldBe($groupsList) { $this->theSubadminGroupsShouldBe($groupsList); } @@ -824,9 +825,9 @@ public function getArrayOfSubadminsResponded($resp) { } /** - * @Given /^app "([^"]*)" enabled state will be restored once the scenario finishes$/ * @param string $app */ + #[Given('/^app "([^"]*)" enabled state will be restored once the scenario finishes$/')] public function appEnabledStateWillBeRestoredOnceTheScenarioFinishes($app) { $previousUser = $this->currentUser; $this->currentUser = 'admin'; @@ -859,9 +860,9 @@ private function getAppsWithFilter($filter) { } /** - * @Given /^app "([^"]*)" is disabled$/ * @param string $app */ + #[Given('/^app "([^"]*)" is disabled$/')] public function appIsDisabled($app) { $respondedArray = $this->getAppsWithFilter('disabled'); Assert::assertContains($app, $respondedArray); @@ -869,9 +870,9 @@ public function appIsDisabled($app) { } /** - * @Given /^app "([^"]*)" is enabled$/ * @param string $app */ + #[Given('/^app "([^"]*)" is enabled$/')] public function appIsEnabled($app) { $respondedArray = $this->getAppsWithFilter('enabled'); Assert::assertContains($app, $respondedArray); @@ -879,12 +880,11 @@ public function appIsEnabled($app) { } /** - * @Given /^app "([^"]*)" is not enabled$/ - * * Checks that the app is disabled or not installed. * * @param string $app */ + #[Given('/^app "([^"]*)" is not enabled$/')] public function appIsNotEnabled($app) { $respondedArray = $this->getAppsWithFilter('enabled'); Assert::assertNotContains($app, $respondedArray); @@ -892,9 +892,9 @@ public function appIsNotEnabled($app) { } /** - * @Then /^user "([^"]*)" is disabled$/ * @param string $user */ + #[Then('/^user "([^"]*)" is disabled$/')] public function userIsDisabled($user) { $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user"; $client = new Client(); @@ -912,9 +912,9 @@ public function userIsDisabled($user) { } /** - * @Then /^user "([^"]*)" is enabled$/ * @param string $user */ + #[Then('/^user "([^"]*)" is enabled$/')] public function userIsEnabled($user) { $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user"; $client = new Client(); @@ -932,10 +932,10 @@ public function userIsEnabled($user) { } /** - * @Given user :user has a quota of :quota * @param string $user * @param string $quota */ + #[Given('user :user has a quota of :quota')] public function userHasAQuotaOf($user, $quota) { $body = new TableNode([ 0 => ['key', 'quota'], @@ -947,9 +947,9 @@ public function userHasAQuotaOf($user, $quota) { } /** - * @Given user :user has unlimited quota * @param string $user */ + #[Given('user :user has unlimited quota')] public function userHasUnlimitedQuota($user) { $this->userHasAQuotaOf($user, 'none'); } @@ -968,10 +968,8 @@ public function getUserHome($user) { return simplexml_load_string($this->response->getBody())->data[0]->home; } - /** - * @BeforeScenario - * @AfterScenario - */ + #[BeforeScenario] + #[AfterScenario] public function cleanupUsers() { $previousServer = $this->currentServer; $this->usingServer('LOCAL'); @@ -985,10 +983,8 @@ public function cleanupUsers() { $this->usingServer($previousServer); } - /** - * @BeforeScenario - * @AfterScenario - */ + #[BeforeScenario] + #[AfterScenario] public function cleanupGroups() { $previousServer = $this->currentServer; $this->usingServer('LOCAL'); @@ -1002,9 +998,7 @@ public function cleanupGroups() { $this->usingServer($previousServer); } - /** - * @Then /^user "([^"]*)" has not$/ - */ + #[Then('/^user "([^"]*)" has not$/')] public function userHasNotSetting($user, TableNode $settings) { $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user"; $client = new Client(); diff --git a/build/integration/features/bootstrap/RateLimitingContext.php b/build/integration/features/bootstrap/RateLimitingContext.php index f649396920a5d..bc775b339ab0a 100644 --- a/build/integration/features/bootstrap/RateLimitingContext.php +++ b/build/integration/features/bootstrap/RateLimitingContext.php @@ -7,24 +7,22 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ use Behat\Behat\Context\Context; +use Behat\Hook\AfterScenario; +use Behat\Hook\BeforeScenario; class RateLimitingContext implements Context { use BasicStructure; use CommandLine; use Provisioning; - /** - * @BeforeScenario @RateLimiting - */ + #[BeforeScenario('@RateLimiting')] public function enableRateLimiting() { // Enable rate limiting for the tests. // Ratelimiting is disabled by default, so we need to enable it $this->runOcc(['config:system:set', 'ratelimit.protection.enabled', '--value', 'true', '--type', 'bool']); } - /** - * @AfterScenario @RateLimiting - */ + #[AfterScenario('@RateLimiting')] public function disableRateLimiting() { // Restore the default rate limiting configuration. // Ratelimiting is disabled by default, so we need to disable it diff --git a/build/integration/features/bootstrap/RoutingContext.php b/build/integration/features/bootstrap/RoutingContext.php index 4b346932def32..c9b6c8ad442d1 100644 --- a/build/integration/features/bootstrap/RoutingContext.php +++ b/build/integration/features/bootstrap/RoutingContext.php @@ -5,12 +5,13 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ use Behat\Behat\Context\Context; -use Behat\Behat\Context\SnippetAcceptingContext; +use Behat\Hook\AfterScenario; +use Behat\Step\Given; use PHPUnit\Framework\Assert; require __DIR__ . '/autoload.php'; -class RoutingContext implements Context, SnippetAcceptingContext { +class RoutingContext implements Context { use Provisioning; use AppConfiguration; use CommandLine; @@ -18,16 +19,12 @@ class RoutingContext implements Context, SnippetAcceptingContext { protected function resetAppConfigs(): void { } - /** - * @AfterScenario - */ + #[AfterScenario] public function deleteMemcacheSetting(): void { $this->invokingTheCommand('config:system:delete memcache.local'); } - /** - * @Given /^route "([^"]*)" of app "([^"]*)" is defined in routes.php$/ - */ + #[Given('/^route "([^"]*)" of app "([^"]*)" is defined in routes.php$/')] public function routeOfAppIsDefinedInRoutesPhP(string $route, string $app): void { $previousUser = $this->currentUser; $this->currentUser = 'admin'; diff --git a/build/integration/features/bootstrap/Search.php b/build/integration/features/bootstrap/Search.php index 49a4fe9282275..a80b83f32af9f 100644 --- a/build/integration/features/bootstrap/Search.php +++ b/build/integration/features/bootstrap/Search.php @@ -5,25 +5,26 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ use Behat\Gherkin\Node\TableNode; +use Behat\Step\Then; +use Behat\Step\When; use PHPUnit\Framework\Assert; trait Search { // BasicStructure trait is expected to be used in the class that uses this // trait. - /** - * @When /^searching for "([^"]*)"$/ * @param string $query */ + #[When('/^searching for "([^"]*)"$/')] public function searchingFor(string $query) { $this->searchForInApp($query, ''); } /** - * @When /^searching for "([^"]*)" in app "([^"]*)"$/ * @param string $query * @param string $app */ + #[When('/^searching for "([^"]*)" in app "([^"]*)"$/')] public function searchingForInApp(string $query, string $app) { $url = '/index.php/core/search'; @@ -35,9 +36,7 @@ public function searchingForInApp(string $query, string $app) { $this->sendingAToWithRequesttoken('GET', $url); } - /** - * @Then /^the list of search results has "(\d+)" results$/ - */ + #[Then('/^the list of search results has "(\d+)" results$/')] public function theListOfSearchResultsHasResults(int $count) { $this->theHTTPStatusCodeShouldBe(200); @@ -47,11 +46,11 @@ public function theListOfSearchResultsHasResults(int $count) { } /** - * @Then /^search result "(\d+)" contains$/ * * @param int $number * @param TableNode $body */ + #[Then('/^search result "(\d+)" contains$/')] public function searchResultXContains(int $number, TableNode $body) { if (!($body instanceof TableNode)) { return; diff --git a/build/integration/features/bootstrap/ShareesContext.php b/build/integration/features/bootstrap/ShareesContext.php index dcd2e9a72e32b..1e0f7fbafc532 100644 --- a/build/integration/features/bootstrap/ShareesContext.php +++ b/build/integration/features/bootstrap/ShareesContext.php @@ -8,14 +8,13 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ use Behat\Behat\Context\Context; -use Behat\Behat\Context\SnippetAcceptingContext; require __DIR__ . '/autoload.php'; /** * Features context. */ -class ShareesContext implements Context, SnippetAcceptingContext { +class ShareesContext implements Context { use Sharing; use AppConfiguration; diff --git a/build/integration/features/bootstrap/Sharing.php b/build/integration/features/bootstrap/Sharing.php index 3bc97ba0446e2..34a725b834fd1 100644 --- a/build/integration/features/bootstrap/Sharing.php +++ b/build/integration/features/bootstrap/Sharing.php @@ -6,6 +6,10 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ use Behat\Gherkin\Node\TableNode; +use Behat\Hook\BeforeScenario; +use Behat\Step\Given; +use Behat\Step\Then; +use Behat\Step\When; use GuzzleHttp\Client; use GuzzleHttp\Exception\ClientException; use OCA\Files_Sharing\MountProvider; @@ -24,9 +28,7 @@ trait Sharing { private array $storedShareData = []; private ?string $savedShareId = null; - /** - * @BeforeScenario - */ + #[BeforeScenario] public function resetSharingState(): void { $this->lastShareData = null; $this->storedShareData = []; @@ -35,9 +37,7 @@ public function resetSharingState(): void { /** @var ResponseInterface */ private $response; - /** - * @Given /^as "([^"]*)" creating a share with$/ - */ + #[Given('/^as "([^"]*)" creating a share with$/')] public function asCreatingAShareWith(string $user, ?TableNode $body): void { $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/apps/files_sharing/api/v{$this->sharingApiVersion}/shares"; $client = new Client(); @@ -76,30 +76,22 @@ public function asCreatingAShareWith(string $user, ?TableNode $body): void { $this->lastShareData = simplexml_load_string($this->response->getBody()); } - /** - * @When /^save the last share data as "([^"]*)"$/ - */ + #[When('/^save the last share data as "([^"]*)"$/')] public function saveLastShareData(string $name): void { $this->storedShareData[$name] = $this->lastShareData; } - /** - * @When /^restore the last share data from "([^"]*)"$/ - */ + #[When('/^restore the last share data from "([^"]*)"$/')] public function restoreLastShareData(string $name): void { $this->lastShareData = $this->storedShareData[$name]; } - /** - * @When /^creating a share with$/ - */ + #[When('/^creating a share with$/')] public function creatingShare(?TableNode $body): void { $this->asCreatingAShareWith($this->currentUser, $body); } - /** - * @When /^opening last share accept confirmation page$/ - */ + #[When('/^opening last share accept confirmation page$/')] public function openingLastShareAcceptConfirmationPage(): void { $share_id = $this->lastShareData->data[0]->id; $url = "/index.php/apps/files_sharing/accept/ocinternal:$share_id"; @@ -117,9 +109,7 @@ public function openingLastShareAcceptConfirmationPage(): void { } } - /** - * @When /^accepting last share via the accept endpoint with requesttoken$/ - */ + #[When('/^accepting last share via the accept endpoint with requesttoken$/')] public function acceptingLastShareViaAcceptEndpointWithRequesttoken(): void { $share_id = $this->lastShareData->data[0]->id; $url = "/index.php/apps/files_sharing/accept/ocinternal:$share_id"; @@ -143,9 +133,7 @@ public function acceptingLastShareViaAcceptEndpointWithRequesttoken(): void { } } - /** - * @When /^accepting last share via the accept endpoint$/ - */ + #[When('/^accepting last share via the accept endpoint$/')] public function acceptingLastShareViaAcceptEndpoint(): void { $this->loggingInUsingWebAs($this->currentUser); $this->openingLastShareAcceptConfirmationPage(); @@ -158,9 +146,7 @@ public function acceptingLastShareViaAcceptEndpoint(): void { $this->acceptingLastShareViaAcceptEndpointWithRequesttoken(); } - /** - * @When /^accepting last share$/ - */ + #[When('/^accepting last share$/')] public function acceptingLastShare(): void { $share_id = $this->lastShareData->data[0]->id; $url = "/apps/files_sharing/api/v{$this->sharingApiVersion}/shares/pending/$share_id"; @@ -169,9 +155,7 @@ public function acceptingLastShare(): void { $this->theHTTPStatusCodeShouldBe('200'); } - /** - * @When /^user "([^"]*)" accepts last share$/ - */ + #[When('/^user "([^"]*)" accepts last share$/')] public function userAcceptsLastShare(string $user): void { // "As userXXX" and "user userXXX accepts last share" steps are not // expected to be used in the same scenario, but restore the user just @@ -189,9 +173,7 @@ public function userAcceptsLastShare(string $user): void { $this->theHTTPStatusCodeShouldBe('200'); } - /** - * @Then /^last link share can be downloaded$/ - */ + #[Then('/^last link share can be downloaded$/')] public function lastLinkShareCanBeDownloaded(): void { if (count($this->lastShareData->data->element) > 0) { $url = $this->lastShareData->data[0]->url; @@ -202,9 +184,7 @@ public function lastLinkShareCanBeDownloaded(): void { $this->checkDownload($fullUrl, null, 'text/plain'); } - /** - * @Then /^last link share can not be downloaded with status "([^"]*)"$/ - */ + #[Then('/^last link share can not be downloaded with status "([^"]*)"$/')] public function lastLinkShareCanNotBeDownloaded(string $status): void { if (count($this->lastShareData->data->element) > 0) { $url = $this->lastShareData->data[0]->url; @@ -222,9 +202,7 @@ public function lastLinkShareCanNotBeDownloaded(string $status): void { Assert::assertNotEquals($status, $response->getStatusCode()); } - /** - * @Then /^last share can be downloaded$/ - */ + #[Then('/^last share can be downloaded$/')] public function lastShareCanBeDownloaded(): void { if (count($this->lastShareData->data->element) > 0) { $token = $this->lastShareData->data[0]->token; @@ -236,9 +214,7 @@ public function lastShareCanBeDownloaded(): void { $this->checkDownload($fullUrl, null, 'text/plain'); } - /** - * @Then /^last share with password "([^"]*)" can be downloaded$/ - */ + #[Then('/^last share with password "([^"]*)" can be downloaded$/')] public function lastShareWithPasswordCanBeDownloaded($password) { if (count($this->lastShareData->data->element) > 0) { $token = $this->lastShareData->data[0]->token; @@ -274,9 +250,7 @@ private function checkDownload($url, $auth = null, $mimeType = null) { } } - /** - * @When /^Adding expiration date to last share$/ - */ + #[When('/^Adding expiration date to last share$/')] public function addingExpirationDate() { $share_id = (string)$this->lastShareData->data[0]->id; $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/apps/files_sharing/api/v{$this->sharingApiVersion}/shares/$share_id"; @@ -294,9 +268,9 @@ public function addingExpirationDate() { } /** - * @When /^Updating last share with$/ * @param TableNode|null $body */ + #[When('/^Updating last share with$/')] public function updatingLastShare($body) { $share_id = (string)$this->lastShareData->data[0]->id; $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/apps/files_sharing/api/v{$this->sharingApiVersion}/shares/$share_id"; @@ -438,37 +412,33 @@ public function isFieldInResponse($field, $contentExpected) { } /** - * @Then /^File "([^"]*)" should be included in the response$/ - * * @param string $filename */ + #[Then('/^File "([^"]*)" should be included in the response$/')] public function checkSharedFileInResponse($filename) { Assert::assertEquals(true, $this->isFieldInResponse('file_target', "/$filename")); } /** - * @Then /^File "([^"]*)" should not be included in the response$/ - * * @param string $filename */ + #[Then('/^File "([^"]*)" should not be included in the response$/')] public function checkSharedFileNotInResponse($filename) { Assert::assertEquals(false, $this->isFieldInResponse('file_target', "/$filename")); } /** - * @Then /^User "([^"]*)" should be included in the response$/ - * * @param string $user */ + #[Then('/^User "([^"]*)" should be included in the response$/')] public function checkSharedUserInResponse($user) { Assert::assertEquals(true, $this->isFieldInResponse('share_with', "$user")); } /** - * @Then /^User "([^"]*)" should not be included in the response$/ - * * @param string $user */ + #[Then('/^User "([^"]*)" should not be included in the response$/')] public function checkSharedUserNotInResponse($user) { Assert::assertEquals(false, $this->isFieldInResponse('share_with', "$user")); } @@ -484,12 +454,12 @@ public function isUserOrGroupInSharedData($userOrGroup, $permissions = null) { } /** - * @Given /^(file|folder|entry) "([^"]*)" of user "([^"]*)" is shared with user "([^"]*)"( with permissions ([\d]*))?( view-only)?$/ * * @param string $filepath * @param string $user1 * @param string $user2 */ + #[Given('/^(file|folder|entry) "([^"]*)" of user "([^"]*)" is shared with user "([^"]*)"( with permissions ([\d]*))?( view-only)?$/')] public function assureFileIsShared($entry, $filepath, $user1, $user2, $withPerms = null, $permissions = null, $viewOnly = null) { // when view-only is set, permissions is empty string instead of null... if ($permissions === '') { @@ -517,12 +487,12 @@ public function assureFileIsShared($entry, $filepath, $user1, $user2, $withPerms } /** - * @Given /^(file|folder|entry) "([^"]*)" of user "([^"]*)" is shared with group "([^"]*)"( with permissions ([\d]*))?( view-only)?$/ * * @param string $filepath * @param string $user * @param string $group */ + #[Given('/^(file|folder|entry) "([^"]*)" of user "([^"]*)" is shared with group "([^"]*)"( with permissions ([\d]*))?( view-only)?$/')] public function assureFileIsSharedWithGroup($entry, $filepath, $user, $group, $withPerms = null, $permissions = null, $viewOnly = null) { // when view-only is set, permissions is empty string instead of null... if ($permissions === '') { @@ -549,27 +519,21 @@ public function assureFileIsSharedWithGroup($entry, $filepath, $user, $group, $w Assert::assertEquals(true, $this->isUserOrGroupInSharedData($group, $permissions)); } - /** - * @When /^Deleting last share$/ - */ + #[When('/^Deleting last share$/')] public function deletingLastShare() { $share_id = $this->lastShareData->data[0]->id; $url = "/apps/files_sharing/api/v{$this->sharingApiVersion}/shares/$share_id"; $this->sendingToWith('DELETE', $url, null); } - /** - * @When /^Getting info of last share$/ - */ + #[When('/^Getting info of last share$/')] public function gettingInfoOfLastShare() { $share_id = $this->lastShareData->data[0]->id; $url = "/apps/files_sharing/api/v{$this->sharingApiVersion}/shares/$share_id"; $this->sendingToWith('GET', $url, null); } - /** - * @Then /^last share_id is included in the answer$/ - */ + #[Then('/^last share_id is included in the answer$/')] public function checkingLastShareIDIsIncluded() { $share_id = $this->lastShareData->data[0]->id; if (!$this->isFieldInResponse('id', $share_id)) { @@ -577,9 +541,7 @@ public function checkingLastShareIDIsIncluded() { } } - /** - * @Then /^last share_id is not included in the answer$/ - */ + #[Then('/^last share_id is not included in the answer$/')] public function checkingLastShareIDIsNotIncluded() { $share_id = $this->lastShareData->data[0]->id; if ($this->isFieldInResponse('id', $share_id)) { @@ -588,9 +550,9 @@ public function checkingLastShareIDIsNotIncluded() { } /** - * @Then /^Share fields of last share match with$/ * @param TableNode|null $body */ + #[Then('/^Share fields of last share match with$/')] public function checkShareFields($body) { if ($body instanceof TableNode) { $fd = $body->getRowsHash(); @@ -611,9 +573,7 @@ public function checkShareFields($body) { } } - /** - * @Then the list of returned shares has :count shares - */ + #[Then('the list of returned shares has :count shares')] public function theListOfReturnedSharesHasShares(int $count): void { $this->theHTTPStatusCodeShouldBe('200'); $this->theOCSStatusCodeShouldBe('100'); @@ -624,11 +584,11 @@ public function theListOfReturnedSharesHasShares(int $count): void { } /** - * @Then share :count is returned with * * @param int $number * @param TableNode $body */ + #[Then('share :count is returned with')] public function shareXIsReturnedWith(int $number, TableNode $body) { $this->theHTTPStatusCodeShouldBe('200'); $this->theOCSStatusCodeShouldBe('100'); @@ -726,9 +686,7 @@ private function assertFieldIsInReturnedShare(string $field, string $contentExpe } } - /** - * @Then As :user remove all shares from the file named :fileName - */ + #[Then('As :user remove all shares from the file named :fileName')] public function asRemoveAllSharesFromTheFileNamed($user, $fileName) { $url = $this->baseUrl . "v{$this->apiVersion}.php/apps/files_sharing/api/v{$this->sharingApiVersion}/shares?format=json"; $client = new \GuzzleHttp\Client(); @@ -772,16 +730,12 @@ public function asRemoveAllSharesFromTheFileNamed($user, $fileName) { } } - /** - * @When save last share id - */ + #[When('save last share id')] public function saveLastShareId() { $this->savedShareId = ($this->lastShareData['data']['id'] ?? null); } - /** - * @Then share ids should match - */ + #[Then('share ids should match')] public function shareIdsShouldMatch() { if ($this->savedShareId !== ($this->lastShareData['data']['id'] ?? null)) { throw new \Exception('Expected the same link share to be returned'); @@ -789,9 +743,9 @@ public function shareIdsShouldMatch() { } /** - * @When /^getting sharees for$/ * @param TableNode $body */ + #[When('/^getting sharees for$/')] public function whenGettingShareesFor($body) { $url = '/apps/files_sharing/api/v1/sharees'; if ($body instanceof TableNode) { @@ -814,11 +768,11 @@ public function whenGettingShareesFor($body) { } /** - * @Then /^"([^"]*)" sharees returned (are|is empty)$/ * @param string $shareeType * @param string $isEmpty * @param TableNode|null $shareesList */ + #[Then('/^"([^"]*)" sharees returned (are|is empty)$/')] public function thenListOfSharees($shareeType, $isEmpty, $shareesList = null) { if ($isEmpty !== 'is empty') { $sharees = $shareesList->getRows(); @@ -882,9 +836,7 @@ public function getArrayOfShareesResponded(ResponseInterface $response, $shareeT return $sharees; } - /** - * @Then /^Share mounts for "([^"]*)" match$/ - */ + #[Then('/^Share mounts for "([^"]*)" match$/')] public function checkShareMounts(string $user, ?TableNode $body) { if ($body instanceof TableNode) { $fd = $body->getRows(); @@ -901,9 +853,7 @@ public function checkShareMounts(string $user, ?TableNode $body) { } } - /** - * @Then /^Share mounts for "([^"]*)" are empty$/ - */ + #[Then('/^Share mounts for "([^"]*)" are empty$/')] public function checkShareMountsEmpty(string $user) { $this->runOcc(['files:mount:list', '--output', 'json', '--cached-only', $user]); $mounts = json_decode($this->lastStdOut, true)['cached']; diff --git a/build/integration/features/bootstrap/SharingContext.php b/build/integration/features/bootstrap/SharingContext.php index de8cf286bd62b..4bf6918650eba 100644 --- a/build/integration/features/bootstrap/SharingContext.php +++ b/build/integration/features/bootstrap/SharingContext.php @@ -7,14 +7,13 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ use Behat\Behat\Context\Context; -use Behat\Behat\Context\SnippetAcceptingContext; require __DIR__ . '/autoload.php'; /** * Features context. */ -class SharingContext implements Context, SnippetAcceptingContext { +class SharingContext implements Context { use WebDav; use Trashbin; use AppConfiguration; diff --git a/build/integration/features/bootstrap/TagsContext.php b/build/integration/features/bootstrap/TagsContext.php index f9f7f0ee44143..a6b84f40a4bf3 100644 --- a/build/integration/features/bootstrap/TagsContext.php +++ b/build/integration/features/bootstrap/TagsContext.php @@ -8,6 +8,10 @@ require __DIR__ . '/autoload.php'; use Behat\Gherkin\Node\TableNode; +use Behat\Hook\AfterScenario; +use Behat\Hook\BeforeScenario; +use Behat\Step\Then; +use Behat\Step\When; use GuzzleHttp\Client; use GuzzleHttp\Message\ResponseInterface; @@ -30,12 +34,12 @@ public function __construct( } } - /** @BeforeScenario */ + #[BeforeScenario] public function setUpScenario() { $this->client = new Client(); } - /** @AfterScenario */ + #[AfterScenario] public function tearDownScenario() { $user = 'admin'; $tags = $this->requestTagsForUser($user); @@ -132,33 +136,33 @@ private function createTag($user, $type, $name, $groups = null) { } /** - * @When :user creates a :type tag with name :name * @param string $user * @param string $type * @param string $name * @throws \Exception */ + #[When(':user creates a :type tag with name :name')] public function createsATagWithName($user, $type, $name) { $this->createTag($user, $type, $name); } /** - * @When :user creates a :type tag with name :name and groups :groups * @param string $user * @param string $type * @param string $name * @param string $groups * @throws \Exception */ + #[When(':user creates a :type tag with name :name and groups :groups')] public function createsATagWithNameAndGroups($user, $type, $name, $groups) { $this->createTag($user, $type, $name, $groups); } /** - * @Then The response should have a status code :statusCode * @param int $statusCode * @throws \Exception */ + #[Then('The response should have a status code :statusCode')] public function theResponseShouldHaveAStatusCode($statusCode) { if ((int)$statusCode !== $this->response->getStatusCode()) { throw new \Exception("Expected $statusCode, got " . $this->response->getStatusCode()); @@ -233,11 +237,11 @@ private function requestTagsForUser($user, $withGroups = false) { } /** - * @Then The following tags should exist for :user * @param string $user * @param TableNode $table * @throws \Exception */ + #[Then('The following tags should exist for :user')] public function theFollowingTagsShouldExistFor($user, TableNode $table) { $tags = $this->requestTagsForUser($user); @@ -267,9 +271,7 @@ public function theFollowingTagsShouldExistFor($user, TableNode $table) { } } - /** - * @Then the user :user :can assign The :type tag with name :tagName - */ + #[Then('the user :user :can assign The :type tag with name :tagName')] public function theUserCanAssignTheTag($user, $can, $type, $tagName) { $foundTag = $this->findTag($type, $tagName, $user); if ($foundTag === null) { @@ -289,9 +291,7 @@ public function theUserCanAssignTheTag($user, $can, $type, $tagName) { } } - /** - * @Then The :type tag with name :tagName has the groups :groups - */ + #[Then('The :type tag with name :tagName has the groups :groups')] public function theTagHasGroup($type, $tagName, $groups) { $foundTag = $this->findTag($type, $tagName, 'admin', true); if ($foundTag === null) { @@ -304,11 +304,11 @@ public function theTagHasGroup($type, $tagName, $groups) { } /** - * @Then :count tags should exist for :user * @param int $count * @param string $user * @throws \Exception */ + #[Then(':count tags should exist for :user')] public function tagsShouldExistFor($count, $user) { if ((int)$count !== count($this->requestTagsForUser($user))) { throw new \Exception("Expected $count tags, got " . count($this->requestTagsForUser($user))); @@ -371,12 +371,12 @@ private function findTagIdByName($name) { } /** - * @When :user edits the tag with name :oldNmae and sets its name to :newName * @param string $user * @param string $oldName * @param string $newName * @throws \Exception */ + #[When(':user edits the tag with name :oldNmae and sets its name to :newName')] public function editsTheTagWithNameAndSetsItsNameTo($user, $oldName, $newName) { $tagId = $this->findTagIdByName($oldName); if ($tagId === 0) { @@ -408,12 +408,12 @@ public function editsTheTagWithNameAndSetsItsNameTo($user, $oldName, $newName) { } /** - * @When :user edits the tag with name :oldNmae and sets its groups to :groups * @param string $user * @param string $oldName * @param string $groups * @throws \Exception */ + #[When(':user edits the tag with name :oldNmae and sets its groups to :groups')] public function editsTheTagWithNameAndSetsItsGroupsTo($user, $oldName, $groups) { $tagId = $this->findTagIdByName($oldName); if ($tagId === 0) { @@ -445,10 +445,10 @@ public function editsTheTagWithNameAndSetsItsGroupsTo($user, $oldName, $groups) } /** - * @When :user deletes the tag with name :name * @param string $user * @param string $name */ + #[When(':user deletes the tag with name :name')] public function deletesTheTagWithName($user, $name) { $tagId = $this->findTagIdByName($name); try { @@ -495,12 +495,12 @@ private function getFileIdForPath($path, $user) { } /** - * @When /^"([^"]*)" adds the tag "([^"]*)" to "([^"]*)" (shared|owned) by "([^"]*)"$/ * @param string $taggingUser * @param string $tagName * @param string $fileName * @param string $sharingUser */ + #[When('/^"([^"]*)" adds the tag "([^"]*)" to "([^"]*)" (shared|owned) by "([^"]*)"$/')] public function addsTheTagToSharedBy($taggingUser, $tagName, $fileName, $sharedOrOwnedBy, $sharingUser) { $fileId = $this->getFileIdForPath($fileName, $sharingUser); $tagId = $this->findTagIdByName($tagName); @@ -521,12 +521,12 @@ public function addsTheTagToSharedBy($taggingUser, $tagName, $fileName, $sharedO } /** - * @Then /^"([^"]*)" (shared|owned) by "([^"]*)" has the following tags$/ * @param string $fileName * @param string $sharingUser * @param TableNode $table * @throws \Exception */ + #[Then('/^"([^"]*)" (shared|owned) by "([^"]*)" has the following tags$/')] public function sharedByHasTheFollowingTags($fileName, $sharedOrOwnedBy, $sharingUser, TableNode $table) { $loadedExpectedTags = $table->getTable(); $expectedTags = []; @@ -570,13 +570,13 @@ public function sharedByHasTheFollowingTags($fileName, $sharedOrOwnedBy, $sharin } /** - * @Then :fileName shared by :sharingUser has the following tags for :user * @param string $fileName * @param string $sharingUser * @param string $user * @param TableNode $table * @throws \Exception */ + #[Then(':fileName shared by :sharingUser has the following tags for :user')] public function sharedByHasTheFollowingTagsFor($fileName, $sharingUser, $user, TableNode $table) { $loadedExpectedTags = $table->getTable(); $expectedTags = []; @@ -628,12 +628,12 @@ public function sharedByHasTheFollowingTagsFor($fileName, $sharingUser, $user, T } /** - * @When :user removes the tag :tagName from :fileName shared by :shareUser * @param string $user * @param string $tagName * @param string $fileName * @param string $shareUser */ + #[When(':user removes the tag :tagName from :fileName shared by :shareUser')] public function removesTheTagFromSharedBy($user, $tagName, $fileName, $shareUser) { $tagId = $this->findTagIdByName($tagName); $fileId = $this->getFileIdForPath($fileName, $shareUser); diff --git a/build/integration/features/bootstrap/TalkContext.php b/build/integration/features/bootstrap/TalkContext.php index 6f351c30ccf25..a68570416cd54 100644 --- a/build/integration/features/bootstrap/TalkContext.php +++ b/build/integration/features/bootstrap/TalkContext.php @@ -5,21 +5,19 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ use Behat\Behat\Context\Context; +use Behat\Hook\AfterScenario; +use Behat\Hook\BeforeFeature; class TalkContext implements Context { - /** - * @BeforeFeature @Talk - * @BeforeScenario @Talk - */ + #[BeforeFeature('@Talk')] + #[BeforeScenario('@Talk')] public static function skipTestsIfTalkIsNotInstalled() { if (!TalkContext::isTalkInstalled()) { throw new Exception('Talk needs to be installed to run features or scenarios tagged with @Talk'); } } - /** - * @AfterScenario @Talk - */ + #[AfterScenario('@Talk')] public static function disableTalk() { TalkContext::runOcc(['app:disable', 'spreed']); } diff --git a/build/integration/features/bootstrap/Theming.php b/build/integration/features/bootstrap/Theming.php index 765f1e443cb33..22ce168cab560 100644 --- a/build/integration/features/bootstrap/Theming.php +++ b/build/integration/features/bootstrap/Theming.php @@ -4,15 +4,17 @@ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + +use Behat\Hook\AfterScenario; +use Behat\Step\When; + require __DIR__ . '/autoload.php'; trait Theming { private bool $undoAllThemingChangesAfterScenario = false; - /** - * @AfterScenario - */ + #[AfterScenario] public function undoAllThemingChanges() { if (!$this->undoAllThemingChangesAfterScenario) { return; @@ -25,11 +27,11 @@ public function undoAllThemingChanges() { } /** - * @When logged in admin uploads theming image for :key from file :source * * @param string $key * @param string $source */ + #[When('logged in admin uploads theming image for :key from file :source')] public function loggedInAdminUploadsThemingImageForFromFile(string $key, string $source) { $this->undoAllThemingChangesAfterScenario = true; diff --git a/build/integration/features/bootstrap/Trashbin.php b/build/integration/features/bootstrap/Trashbin.php index 6eec7eb0d2ba4..3a3531ba59e65 100644 --- a/build/integration/features/bootstrap/Trashbin.php +++ b/build/integration/features/bootstrap/Trashbin.php @@ -6,6 +6,8 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +use Behat\Step\Then; +use Behat\Step\When; use PHPUnit\Framework\Assert; require __DIR__ . '/autoload.php'; @@ -15,11 +17,10 @@ */ trait Trashbin { // WebDav trait is expected to be used in the class that uses this trait. - /** - * @When User :user empties trashbin * @param string $user user */ + #[When('User :user empties trashbin')] public function emptyTrashbin($user) { $client = $this->getSabreClient($user); $response = $client->request('DELETE', $this->makeSabrePath($user, 'trash', 'trashbin')); @@ -82,11 +83,11 @@ public function listTrashbinFolder($user, $path) { } /** - * @Then /^user "([^"]*)" in trash folder "([^"]*)" should have the following elements$/ * @param string $user * @param string $folder * @param \Behat\Gherkin\Node\TableNode|null $expectedElements */ + #[Then('/^user "([^"]*)" in trash folder "([^"]*)" should have the following elements$/')] public function checkTrashContents($user, $folder, $expectedElements) { $elementList = $this->listTrashbinFolder($user, $folder); $trashContent = array_filter(array_map(function (array $item) { @@ -105,11 +106,11 @@ public function checkTrashContents($user, $folder, $expectedElements) { } /** - * @Then /^as "([^"]*)" the (file|folder) "([^"]*)" exists in trash$/ * @param string $user * @param string $type * @param string $file */ + #[Then('/^as "([^"]*)" the (file|folder) "([^"]*)" exists in trash$/')] public function checkTrashContains($user, $type, $file) { $parent = dirname($file); if ($parent === '.') { @@ -127,21 +128,21 @@ public function checkTrashContains($user, $type, $file) { } /** - * @Then /^user "([^"]*)" in trash folder "([^"]*)" should have (\d+) elements?$/ * @param string $user * @param string $folder * @param \Behat\Gherkin\Node\TableNode|null $expectedElements */ + #[Then('/^user "([^"]*)" in trash folder "([^"]*)" should have (\d+) elements?$/')] public function checkTrashSize($user, $folder, $expectedCount) { $elementList = $this->listTrashbinFolder($user, $folder); Assert::assertEquals($expectedCount, count($elementList)); } /** - * @When /^user "([^"]*)" in restores "([^"]*)" from trash$/ * @param string $user * @param string $file */ + #[When('/^user "([^"]*)" in restores "([^"]*)" from trash$/')] public function restoreFromTrash($user, $file) { $file = $this->getFullTrashPath($user, $file); $url = $this->makeSabrePath($user, 'trash' . $file, 'trashbin'); diff --git a/build/integration/features/bootstrap/WebDav.php b/build/integration/features/bootstrap/WebDav.php index 2a0e5278f1597..f274782b64799 100644 --- a/build/integration/features/bootstrap/WebDav.php +++ b/build/integration/features/bootstrap/WebDav.php @@ -6,6 +6,9 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ +use Behat\Step\Given; +use Behat\Step\Then; +use Behat\Step\When; use GuzzleHttp\Client as GClient; use PHPUnit\Framework\Assert; use Psr\Http\Message\ResponseInterface; @@ -29,32 +32,24 @@ trait WebDav { /** @var string[] */ private array $parts = []; - /** - * @Given /^using dav path "([^"]*)"$/ - */ + #[Given('/^using dav path "([^"]*)"$/')] public function usingDavPath(string $davPath): void { $this->davPath = $davPath; } - /** - * @Given /^using old dav path$/ - */ + #[Given('/^using old dav path$/')] public function usingOldDavPath(): void { $this->davPath = 'remote.php/webdav'; $this->usingOldDavPath = true; } - /** - * @Given /^using new dav path$/ - */ + #[Given('/^using new dav path$/')] public function usingNewDavPath(): void { $this->davPath = 'remote.php/dav'; $this->usingOldDavPath = false; } - /** - * @Given /^using new public dav path$/ - */ + #[Given('/^using new public dav path$/')] public function usingNewPublicDavPath(): void { $this->davPath = 'public.php/dav'; $this->usingOldDavPath = false; @@ -90,11 +85,11 @@ public function makeDavRequest($user, $method, $path, $headers, $body = null, $t } /** - * @Given /^User "([^"]*)" moved (file|folder|entry) "([^"]*)" to "([^"]*)"$/ * @param string $user * @param string $fileSource * @param string $fileDestination */ + #[Given('/^User "([^"]*)" moved (file|folder|entry) "([^"]*)" to "([^"]*)"$/')] public function userMovedFile($user, $entry, $fileSource, $fileDestination) { $fullUrl = substr($this->baseUrl, 0, -4) . $this->getDavFilesPath($user); $headers['Destination'] = $fullUrl . $fileDestination; @@ -103,11 +98,11 @@ public function userMovedFile($user, $entry, $fileSource, $fileDestination) { } /** - * @When /^User "([^"]*)" moves (file|folder|entry) "([^"]*)" to "([^"]*)"$/ * @param string $user * @param string $fileSource * @param string $fileDestination */ + #[When('/^User "([^"]*)" moves (file|folder|entry) "([^"]*)" to "([^"]*)"$/')] public function userMovesFile($user, $entry, $fileSource, $fileDestination) { $fullUrl = substr($this->baseUrl, 0, -4) . $this->getDavFilesPath($user); $headers['Destination'] = $fullUrl . $fileDestination; @@ -119,11 +114,11 @@ public function userMovesFile($user, $entry, $fileSource, $fileDestination) { } /** - * @When /^User "([^"]*)" copies file "([^"]*)" to "([^"]*)"$/ * @param string $user * @param string $fileSource * @param string $fileDestination */ + #[When('/^User "([^"]*)" copies file "([^"]*)" to "([^"]*)"$/')] public function userCopiesFileTo($user, $fileSource, $fileDestination) { $fullUrl = substr($this->baseUrl, 0, -4) . $this->getDavFilesPath($user); $headers['Destination'] = $fullUrl . $fileDestination; @@ -136,19 +131,19 @@ public function userCopiesFileTo($user, $fileSource, $fileDestination) { } /** - * @When /^Downloading file "([^"]*)" with range "([^"]*)"$/ * @param string $fileSource * @param string $range */ + #[When('/^Downloading file "([^"]*)" with range "([^"]*)"$/')] public function downloadFileWithRange($fileSource, $range) { $headers['Range'] = $range; $this->response = $this->makeDavRequest($this->currentUser, 'GET', $fileSource, $headers); } /** - * @When /^Downloading last public shared file with range "([^"]*)"$/ * @param string $range */ + #[When('/^Downloading last public shared file with range "([^"]*)"$/')] public function downloadPublicFileWithRange($range) { $token = $this->lastShareData->data->token; $fullUrl = substr($this->baseUrl, 0, -4) . "public.php/dav/files/$token"; @@ -163,9 +158,9 @@ public function downloadPublicFileWithRange($range) { } /** - * @When /^Downloading last public shared file inside a folder "([^"]*)" with range "([^"]*)"$/ * @param string $range */ + #[When('/^Downloading last public shared file inside a folder "([^"]*)" with range "([^"]*)"$/')] public function downloadPublicFileInsideAFolderWithRange($path, $range) { $token = $this->lastShareData->data->token; $fullUrl = substr($this->baseUrl, 0, -4) . "public.php/dav/files/$token/$path"; @@ -181,37 +176,33 @@ public function downloadPublicFileInsideAFolderWithRange($path, $range) { } /** - * @Then /^Downloaded content should be "([^"]*)"$/ * @param string $content */ + #[Then('/^Downloaded content should be "([^"]*)"$/')] public function downloadedContentShouldBe($content) { Assert::assertEquals($content, (string)$this->response->getBody()); } /** - * @Then /^File "([^"]*)" should have prop "([^"]*):([^"]*)" equal to "([^"]*)"$/ * @param string $file * @param string $prefix * @param string $prop * @param string $value */ + #[Then('/^File "([^"]*)" should have prop "([^"]*):([^"]*)" equal to "([^"]*)"$/')] public function checkPropForFile($file, $prefix, $prop, $value) { $elementList = $this->propfindFile($this->currentUser, $file, "<$prefix:$prop/>"); $property = $elementList['/' . $this->getDavFilesPath($this->currentUser) . $file][200]["{DAV:}$prop"]; Assert::assertEquals($property, $value); } - /** - * @Then /^Image search should work$/ - */ + #[Then('/^Image search should work$/')] public function search(): void { $this->searchFile($this->currentUser); Assert::assertEquals(207, $this->response->getStatusCode()); } - /** - * @Then /^Favorite search should work$/ - */ + #[Then('/^Favorite search should work$/')] public function searchFavorite(): void { $this->searchFile( $this->currentUser, @@ -228,19 +219,17 @@ public function searchFavorite(): void { } /** - * @Then /^Downloaded content when downloading file "([^"]*)" with range "([^"]*)" should be "([^"]*)"$/ * @param string $fileSource * @param string $range * @param string $content */ + #[Then('/^Downloaded content when downloading file "([^"]*)" with range "([^"]*)" should be "([^"]*)"$/')] public function downloadedContentWhenDownloadindShouldBe($fileSource, $range, $content) { $this->downloadFileWithRange($fileSource, $range); $this->downloadedContentShouldBe($content); } - /** - * @When Downloading folder :folderName - */ + #[When('Downloading folder :folderName')] public function downloadingFolder(string $folderName) { try { $this->response = $this->makeDavRequest($this->currentUser, 'GET', $folderName, ['Accept' => 'application/zip']); @@ -249,9 +238,7 @@ public function downloadingFolder(string $folderName) { } } - /** - * @When Downloading public folder :folderName - */ + #[When('Downloading public folder :folderName')] public function downloadPublicFolder(string $folderName) { $token = $this->lastShareData->data->token; $fullUrl = substr($this->baseUrl, 0, -4) . "public.php/dav/files/$token/$folderName"; @@ -270,9 +257,9 @@ public function downloadPublicFolder(string $folderName) { } /** - * @When Downloading file :fileName * @param string $fileName */ + #[When('Downloading file :fileName')] public function downloadingFile($fileName) { try { $this->response = $this->makeDavRequest($this->currentUser, 'GET', $fileName, []); @@ -281,9 +268,7 @@ public function downloadingFile($fileName) { } } - /** - * @When Downloading public file :filename - */ + #[When('Downloading public file :filename')] public function downloadingPublicFile(string $filename) { $token = $this->lastShareData->data->token; $fullUrl = substr($this->baseUrl, 0, -4) . "public.php/dav/files/$token/$filename"; @@ -302,9 +287,7 @@ public function downloadingPublicFile(string $filename) { } } - /** - * @When Downloading public file :filename without ajax header - */ + #[When('Downloading public file :filename without ajax header')] public function downloadingPublicFileWithoutHeader(string $filename) { $token = $this->lastShareData->data->token; $fullUrl = substr($this->baseUrl, 0, -4) . "public.php/dav/files/$token/$filename"; @@ -318,10 +301,10 @@ public function downloadingPublicFileWithoutHeader(string $filename) { } /** - * @Then Downloaded content should start with :start * @param int $start * @throws \Exception */ + #[Then('Downloaded content should start with :start')] public function downloadedContentShouldStartWith($start) { if (strpos($this->response->getBody()->getContents(), $start) !== 0) { throw new \Exception( @@ -334,9 +317,7 @@ public function downloadedContentShouldStartWith($start) { } } - /** - * @When Uploading public file :filename with content :content - */ + #[When('Uploading public file :filename with content :content')] public function uploadingPublicFile(string $filename, string $content) { $token = $this->lastShareData->data->token; $fullUrl = substr($this->baseUrl, 0, -4) . "public.php/dav/files/$token/$filename"; @@ -352,12 +333,12 @@ public function uploadingPublicFile(string $filename, string $content) { } /** - * @Then /^as "([^"]*)" gets properties of (file|folder|entry) "([^"]*)" with$/ * @param string $user * @param string $elementType * @param string $path * @param \Behat\Gherkin\Node\TableNode|null $propertiesTable */ + #[Then('/^as "([^"]*)" gets properties of (file|folder|entry) "([^"]*)" with$/')] public function asGetsPropertiesOfFolderWith($user, $elementType, $path, $propertiesTable) { $properties = null; if ($propertiesTable instanceof \Behat\Gherkin\Node\TableNode) { @@ -369,12 +350,12 @@ public function asGetsPropertiesOfFolderWith($user, $elementType, $path, $proper } /** - * @Then /^as "([^"]*)" the (file|folder|entry) "([^"]*)" does not exist$/ * @param string $user * @param string $entry * @param string $path * @param \Behat\Gherkin\Node\TableNode|null $propertiesTable */ + #[Then('/^as "([^"]*)" the (file|folder|entry) "([^"]*)" does not exist$/')] public function asTheFileOrFolderDoesNotExist($user, $entry, $path) { $client = $this->getSabreClient($user); $response = $client->request('HEAD', $this->makeSabrePath($user, $path)); @@ -386,19 +367,19 @@ public function asTheFileOrFolderDoesNotExist($user, $entry, $path) { } /** - * @Then /^as "([^"]*)" the (file|folder|entry) "([^"]*)" exists$/ * @param string $user * @param string $entry * @param string $path */ + #[Then('/^as "([^"]*)" the (file|folder|entry) "([^"]*)" exists$/')] public function asTheFileOrFolderExists($user, $entry, $path) { $this->response = $this->listFolder($user, $path, 0); } /** - * @Then the response should be empty * @throws \Exception */ + #[Then('the response should be empty')] public function theResponseShouldBeEmpty(): void { $response = ($this->response instanceof ResponseInterface) ? $this->convertResponseToDavEntries() : $this->response; if ($response === []) { @@ -409,11 +390,11 @@ public function theResponseShouldBeEmpty(): void { } /** - * @Then the single response should contain a property :key with value :value * @param string $key * @param string $expectedValue * @throws \Exception */ + #[Then('the single response should contain a property :key with value :value')] public function theSingleResponseShouldContainAPropertyWithValue($key, $expectedValue) { $response = ($this->response instanceof ResponseInterface) ? $this->convertResponseToDavSingleEntry() : $this->response; if (!array_key_exists($key, $response)) { @@ -434,9 +415,7 @@ public function theSingleResponseShouldContainAPropertyWithValue($key, $expected } } - /** - * @Then the response should contain a share-types property with - */ + #[Then('the response should contain a share-types property with')] public function theResponseShouldContainAShareTypesPropertyWith($table) { $keys = $this->response; if (!array_key_exists('{http://owncloud.org/ns}share-types', $keys)) { @@ -468,10 +447,10 @@ public function theResponseShouldContainAShareTypesPropertyWith($table) { } /** - * @Then the response should contain an empty property :property * @param string $property * @throws \Exception */ + #[Then('the response should contain an empty property :property')] public function theResponseShouldContainAnEmptyProperty($property) { $properties = $this->response; if (!array_key_exists($property, $properties)) { @@ -670,10 +649,10 @@ public function getSabreClient($user) { } /** - * @Then /^user "([^"]*)" should see following elements$/ * @param string $user * @param \Behat\Gherkin\Node\TableNode|null $expectedElements */ + #[Then('/^user "([^"]*)" should see following elements$/')] public function checkElementList($user, $expectedElements) { $elementList = $this->listFolder($user, '/', 3); if ($expectedElements instanceof \Behat\Gherkin\Node\TableNode) { @@ -689,11 +668,11 @@ public function checkElementList($user, $expectedElements) { } /** - * @When User :user uploads file :source to :destination * @param string $user * @param string $source * @param string $destination */ + #[When('User :user uploads file :source to :destination')] public function userUploadsAFileTo($user, $source, $destination) { $file = \GuzzleHttp\Psr7\Utils::streamFor(fopen($source, 'r')); try { @@ -708,11 +687,11 @@ public function userUploadsAFileTo($user, $source, $destination) { } /** - * @When User :user adds a file of :bytes bytes to :destination * @param string $user * @param string $bytes * @param string $destination */ + #[When('User :user adds a file of :bytes bytes to :destination')] public function userAddsAFileTo($user, $bytes, $destination) { $filename = 'filespecificSize.txt'; $this->createFileSpecificSize($filename, $bytes); @@ -723,9 +702,7 @@ public function userAddsAFileTo($user, $bytes, $destination) { $this->checkElementList($user, $expectedElements); } - /** - * @When User :user uploads file with content :content to :destination - */ + #[When('User :user uploads file with content :content to :destination')] public function userUploadsAFileWithContentTo($user, $content, $destination) { $file = \GuzzleHttp\Psr7\Utils::streamFor($content); try { @@ -740,12 +717,12 @@ public function userUploadsAFileWithContentTo($user, $content, $destination) { } /** - * @When /^user "([^"]*)" uploads file with content "([^"]*)" and mtime "([^"]*)" to "([^"]*)"$/ * @param string $user * @param string $content * @param string $mtime * @param string $destination */ + #[When('/^user "([^"]*)" uploads file with content "([^"]*)" and mtime "([^"]*)" to "([^"]*)"$/')] public function userUploadsAFileWithContentAndMtimeTo($user, $content, $mtime, $destination) { $file = \GuzzleHttp\Psr7\Utils::streamFor($content); try { @@ -762,11 +739,11 @@ public function userUploadsAFileWithContentAndMtimeTo($user, $content, $mtime, $ * file through the versions DAV endpoint: * GET remote.php/dav/versions//versions// * - * @When /^user "([^"]*)" downloads version "([^"]*)" of file "([^"]*)"$/ * @param string $user * @param string $revision * @param string $path */ + #[When('/^user "([^"]*)" downloads version "([^"]*)" of file "([^"]*)"$/')] public function userDownloadsVersionOfFile($user, $revision, $path) { $fileId = $this->getFileIdForPath($user, $path); $versionPath = '/' . $user . '/versions/' . $fileId . '/' . $revision; @@ -780,11 +757,11 @@ public function userDownloadsVersionOfFile($user, $revision, $path) { } /** - * @When /^User "([^"]*)" deletes (file|folder) "([^"]*)"$/ * @param string $user * @param string $type * @param string $file */ + #[When('/^User "([^"]*)" deletes (file|folder) "([^"]*)"$/')] public function userDeletesFile($user, $type, $file) { try { $this->response = $this->makeDavRequest($user, 'DELETE', $file, []); @@ -798,10 +775,10 @@ public function userDeletesFile($user, $type, $file) { } /** - * @Given User :user created a folder :destination * @param string $user * @param string $destination */ + #[Given('User :user created a folder :destination')] public function userCreatedAFolder($user, $destination) { try { $destination = '/' . ltrim($destination, '/'); @@ -816,7 +793,6 @@ public function userCreatedAFolder($user, $destination) { } /** - * @Given user :user uploads bulked files :name1 with :content1 and :name2 with :content2 and :name3 with :content3 * @param string $user * @param string $name1 * @param string $content1 @@ -825,6 +801,7 @@ public function userCreatedAFolder($user, $destination) { * @param string $name3 * @param string $content3 */ + #[Given('user :user uploads bulked files :name1 with :content1 and :name2 with :content2 and :name3 with :content3')] public function userUploadsBulkedFiles($user, $name1, $content1, $name2, $content2, $name3, $content3) { $boundary = 'boundary_azertyuiop'; @@ -869,18 +846,14 @@ public function userUploadsBulkedFiles($user, $name1, $content1, $name2, $conten return $client->request('POST', substr($this->baseUrl, 0, -4) . 'remote.php/dav/bulk', $options); } - /** - * @Given user :user creates a new chunking upload with id :id - */ + #[Given('user :user creates a new chunking upload with id :id')] public function userCreatesANewChunkingUploadWithId($user, $id) { $this->parts = []; $destination = '/uploads/' . $user . '/' . $id; $this->makeDavRequest($user, 'MKCOL', $destination, [], null, 'uploads'); } - /** - * @When user :user creates a new chunking upload with id :id in the uploads folder for :uidOrToken - */ + #[When('user :user creates a new chunking upload with id :id in the uploads folder for :uidOrToken')] public function userCreatesANewChunkingUploadWithIdInFolderOf($user, $id, $uidOrToken): void { $destination = '/uploads/' . $uidOrToken . '/' . $id; try { @@ -890,18 +863,14 @@ public function userCreatesANewChunkingUploadWithIdInFolderOf($user, $id, $uidOr } } - /** - * @Given user :user uploads new chunk file :num with :data to id :id - */ + #[Given('user :user uploads new chunk file :num with :data to id :id')] public function userUploadsNewChunkFileOfWithToId($user, $num, $data, $id) { $data = \GuzzleHttp\Psr7\Utils::streamFor($data); $destination = '/uploads/' . $user . '/' . $id . '/' . $num; $this->makeDavRequest($user, 'PUT', $destination, [], $data, 'uploads'); } - /** - * @Given user :user moves new chunk file with id :id to :dest - */ + #[Given('user :user moves new chunk file with id :id to :dest')] public function userMovesNewChunkFileWithIdToMychunkedfile($user, $id, $dest) { $source = '/uploads/' . $user . '/' . $id . '/.file'; $destination = substr($this->baseUrl, 0, -4) . $this->getDavFilesPath($user) . $dest; @@ -910,9 +879,7 @@ public function userMovesNewChunkFileWithIdToMychunkedfile($user, $id, $dest) { ], null, 'uploads'); } - /** - * @Then user :user moves new chunk file with id :id to :dest with size :size - */ + #[Then('user :user moves new chunk file with id :id to :dest with size :size')] public function userMovesNewChunkFileWithIdToMychunkedfileWithSize($user, $id, $dest, $size) { $source = '/uploads/' . $user . '/' . $id . '/.file'; $destination = substr($this->baseUrl, 0, -4) . $this->getDavFilesPath($user) . $dest; @@ -927,32 +894,24 @@ public function userMovesNewChunkFileWithIdToMychunkedfileWithSize($user, $id, $ } } - /** - * @Given creating a new public chunking upload with id :id - */ + #[Given('creating a new public chunking upload with id :id')] public function creatingANewPublicChunkingUploadWithId(string $id): void { $this->makePublicUploadsDavRequest('MKCOL', '/' . $id); } - /** - * @Given uploading new public chunk file :num with :data to id :id - */ + #[Given('uploading new public chunk file :num with :data to id :id')] public function uploadingNewPublicChunkFileWithToId(string $num, string $data, string $id): void { $this->makePublicUploadsDavRequest('PUT', '/' . $id . '/' . $num, [], \GuzzleHttp\Psr7\Utils::streamFor($data)); } - /** - * @When moving new public chunk file with id :id to :dest - */ + #[When('moving new public chunk file with id :id to :dest')] public function movingNewPublicChunkFileWithIdTo(string $id, string $dest): void { $this->makePublicUploadsDavRequest('MOVE', '/' . $id . '/.file', [ 'Destination' => $this->getPublicDavFilesUrl() . $dest, ]); } - /** - * @When copying new public chunk file with id :id to :dest - */ + #[When('copying new public chunk file with id :id to :dest')] public function copyingNewPublicChunkFileWithIdTo(string $id, string $dest): void { $this->makePublicUploadsDavRequest('COPY', '/' . $id . '/.file', [ 'Destination' => $this->getPublicDavFilesUrl() . $dest, @@ -990,9 +949,7 @@ private function makePublicUploadsDavRequest(string $method, string $path, array } } - /** - * @Given user :user creates a new chunking v2 upload with id :id and destination :targetDestination - */ + #[Given('user :user creates a new chunking v2 upload with id :id and destination :targetDestination')] public function userCreatesANewChunkingv2UploadWithIdAndDestination($user, $id, $targetDestination) { $this->s3MultipartDestination = $this->getTargetDestination($user, $targetDestination); $this->newUploadId(); @@ -1010,9 +967,7 @@ public function userCreatesANewChunkingv2UploadWithIdAndDestination($user, $id, } } - /** - * @Given user :user uploads new chunk v2 file :num to id :id - */ + #[Given('user :user uploads new chunk v2 file :num to id :id')] public function userUploadsNewChunkv2FileToIdAndDestination($user, $num, $id) { $data = \GuzzleHttp\Psr7\Utils::streamFor(fopen('/tmp/part-upload-' . $num, 'r')); $destination = '/uploads/' . $user . '/' . $this->getUploadId($id) . '/' . $num; @@ -1021,9 +976,7 @@ public function userUploadsNewChunkv2FileToIdAndDestination($user, $num, $id) { ], $data, 'uploads'); } - /** - * @Given user :user moves new chunk v2 file with id :id - */ + #[Given('user :user moves new chunk v2 file with id :id')] public function userMovesNewChunkv2FileWithIdToMychunkedfileAndDestination($user, $id) { $source = '/uploads/' . $user . '/' . $this->getUploadId($id) . '/.file'; try { @@ -1051,9 +1004,7 @@ private function newUploadId() { $this->uploadId = (string)time(); } - /** - * @Given /^Downloading file "([^"]*)" as "([^"]*)"$/ - */ + #[Given('/^Downloading file "([^"]*)" as "([^"]*)"$/')] public function downloadingFileAs($fileName, $user) { try { $this->response = $this->makeDavRequest($user, 'GET', $fileName, []); @@ -1077,16 +1028,12 @@ private function encodePath($path) { return str_replace('%2F', '/', rawurlencode($path)); } - /** - * @When user :user favorites element :path - */ + #[When('user :user favorites element :path')] public function userFavoritesElement($user, $path) { $this->response = $this->changeFavStateOfAnElement($user, $path, 1, 0, null); } - /** - * @When user :user unfavorites element :path - */ + #[When('user :user unfavorites element :path')] public function userUnfavoritesElement($user, $path) { $this->response = $this->changeFavStateOfAnElement($user, $path, 0, 0, null); } @@ -1116,9 +1063,7 @@ public function changeFavStateOfAnElement($user, $path, $favOrUnfav, $folderDept return $response; } - /** - * @Given user :user stores etag of element :path - */ + #[Given('user :user stores etag of element :path')] public function userStoresEtagOfElement($user, $path) { $propertiesTable = new \Behat\Gherkin\Node\TableNode([['{DAV:}getetag']]); $this->asGetsPropertiesOfFolderWith($user, 'entry', $path, $propertiesTable); @@ -1126,27 +1071,21 @@ public function userStoresEtagOfElement($user, $path) { $this->storedETAG[$user] = $pathETAG; } - /** - * @Then etag of element :path of user :user has not changed - */ + #[Then('etag of element :path of user :user has not changed')] public function checkIfETAGHasNotChanged($path, $user) { $propertiesTable = new \Behat\Gherkin\Node\TableNode([['{DAV:}getetag']]); $this->asGetsPropertiesOfFolderWith($user, 'entry', $path, $propertiesTable); Assert::assertEquals($this->response['{DAV:}getetag'], $this->storedETAG[$user][$path]); } - /** - * @Then etag of element :path of user :user has changed - */ + #[Then('etag of element :path of user :user has changed')] public function checkIfETAGHasChanged($path, $user) { $propertiesTable = new \Behat\Gherkin\Node\TableNode([['{DAV:}getetag']]); $this->asGetsPropertiesOfFolderWith($user, 'entry', $path, $propertiesTable); Assert::assertNotEquals($this->response['{DAV:}getetag'], $this->storedETAG[$user][$path]); } - /** - * @When Connecting to dav endpoint - */ + #[When('Connecting to dav endpoint')] public function connectingToDavEndpoint() { try { $this->response = $this->makeDavRequest($this->currentUser, 'PROPFIND', '', []); @@ -1155,9 +1094,7 @@ public function connectingToDavEndpoint() { } } - /** - * @When Requesting share note on dav endpoint - */ + #[When('Requesting share note on dav endpoint')] public function requestingShareNote() { $propfind = ''; if (count($this->lastShareData->data->element) > 0) { @@ -1172,9 +1109,7 @@ public function requestingShareNote() { } } - /** - * @Then there are no duplicate headers - */ + #[Then('there are no duplicate headers')] public function thereAreNoDuplicateHeaders() { $headers = $this->response->getHeaders(); foreach ($headers as $headerName => $headerValues) { @@ -1186,11 +1121,11 @@ public function thereAreNoDuplicateHeaders() { } /** - * @Then /^user "([^"]*)" in folder "([^"]*)" should have favorited the following elements$/ * @param string $user * @param string $folder * @param \Behat\Gherkin\Node\TableNode|null $expectedElements */ + #[Then('/^user "([^"]*)" in folder "([^"]*)" should have favorited the following elements$/')] public function checkFavoritedElements($user, $folder, $expectedElements) { $elementList = $this->reportFolder($user, $folder, @@ -1209,10 +1144,10 @@ public function checkFavoritedElements($user, $folder, $expectedElements) { } /** - * @When /^User "([^"]*)" deletes everything from folder "([^"]*)"$/ * @param string $user * @param string $folder */ + #[When('/^User "([^"]*)" deletes everything from folder "([^"]*)"$/')] public function userDeletesEverythingInFolder($user, $folder) { $elementList = $this->listFolder($user, $folder, 1); $elementListKeys = array_keys($elementList); @@ -1238,27 +1173,25 @@ private function getFileIdForPath($user, $path) { } /** - * @Given /^User "([^"]*)" stores id of file "([^"]*)"$/ * @param string $user * @param string $path */ + #[Given('/^User "([^"]*)" stores id of file "([^"]*)"$/')] public function userStoresFileIdForPath($user, $path) { $this->storedFileID = $this->getFileIdForPath($user, $path); } /** - * @Given /^User "([^"]*)" checks id of file "([^"]*)"$/ * @param string $user * @param string $path */ + #[Given('/^User "([^"]*)" checks id of file "([^"]*)"$/')] public function userChecksFileIdForPath($user, $path) { $currentFileID = $this->getFileIdForPath($user, $path); Assert::assertEquals($currentFileID, $this->storedFileID); } - /** - * @Given /^user "([^"]*)" creates a file locally with "([^"]*)" x 5 MB chunks$/ - */ + #[Given('/^user "([^"]*)" creates a file locally with "([^"]*)" x 5 MB chunks$/')] public function userCreatesAFileLocallyWithChunks($arg1, $chunks) { $this->parts = []; for ($i = 1;$i <= (int)$chunks;$i++) { @@ -1268,18 +1201,14 @@ public function userCreatesAFileLocallyWithChunks($arg1, $chunks) { } } - /** - * @Given user :user creates the chunk :id with a size of :size MB - */ + #[Given('user :user creates the chunk :id with a size of :size MB')] public function userCreatesAChunk($user, $id, $size) { $randomletter = substr(str_shuffle('abcdefghijklmnopqrstuvwxyz'), 0, 1); file_put_contents('/tmp/part-upload-' . $id, str_repeat($randomletter, (int)$size * 1024 * 1024)); $this->parts[] = '/tmp/part-upload-' . $id; } - /** - * @Then /^Downloaded content should be the created file$/ - */ + #[Then('/^Downloaded content should be the created file$/')] public function downloadedContentShouldBeTheCreatedFile() { $content = ''; sort($this->parts); @@ -1289,16 +1218,12 @@ public function downloadedContentShouldBeTheCreatedFile() { Assert::assertEquals($content, (string)$this->response->getBody()); } - /** - * @Then /^the S3 multipart upload was successful with status "([^"]*)"$/ - */ + #[Then('/^the S3 multipart upload was successful with status "([^"]*)"$/')] public function theSmultipartUploadWasSuccessful($status) { Assert::assertEquals((int)$status, $this->response->getStatusCode()); } - /** - * @Then /^the upload should fail on object storage$/ - */ + #[Then('/^the upload should fail on object storage$/')] public function theUploadShouldFailOnObjectStorage() { $descriptor = [ 0 => ['pipe', 'r'], diff --git a/vendor-bin/behat/composer.json b/vendor-bin/behat/composer.json index fd91913a07ebe..6a4402d5aa8fd 100644 --- a/vendor-bin/behat/composer.json +++ b/vendor-bin/behat/composer.json @@ -6,7 +6,8 @@ "sort-packages": true }, "require-dev": { - "behat/behat": "^3.33", + "behat/behat": "^4.0", + "behat/phpunit-assertions-extension": "^1.0", "phpunit/phpunit": "^11.5" } } diff --git a/vendor-bin/behat/composer.lock b/vendor-bin/behat/composer.lock index b29fbd47a9524..46efa79eb24dc 100644 --- a/vendor-bin/behat/composer.lock +++ b/vendor-bin/behat/composer.lock @@ -4,49 +4,48 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3e75ac62494172e6796af48ae596b949", + "content-hash": "834b766d718f11ddb1b27319895342c5", "packages": [], "packages-dev": [ { "name": "behat/behat", - "version": "v3.33.0", + "version": "v4.0.0", "source": { "type": "git", "url": "https://github.com/Behat/Behat.git", - "reference": "a76fe078164e72d3183afc48224a6e8902dccaf0" + "reference": "3f65b57a8e52c7d2c45e219ecaf5900a995946bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Behat/Behat/zipball/a76fe078164e72d3183afc48224a6e8902dccaf0", - "reference": "a76fe078164e72d3183afc48224a6e8902dccaf0", + "url": "https://api.github.com/repos/Behat/Behat/zipball/3f65b57a8e52c7d2c45e219ecaf5900a995946bf", + "reference": "3f65b57a8e52c7d2c45e219ecaf5900a995946bf", "shasum": "" }, "require": { - "behat/gherkin": "^4.17.0", + "behat/gherkin": "^4.18.0", "composer-runtime-api": "^2.2", "composer/xdebug-handler": "^1.4 || ^2.0 || ^3.0", "cucumber/tag-expressions": "^11.0", "ext-mbstring": "*", - "nikic/php-parser": "^4.19.2 || ^5.2", "php": ">=8.2 <8.6", "psr/container": "^1.0 || ^2.0", - "symfony/config": "^5.4 || ^6.4 || ^7.0", - "symfony/console": "^5.4.9 || ^6.4 || ^7.0", - "symfony/dependency-injection": "^5.4 || ^6.4 || ^7.0", - "symfony/event-dispatcher": "^5.4 || ^6.4 || ^7.0", - "symfony/translation": "^5.4 || ^6.4 || ^7.0", - "symfony/yaml": "^5.4 || ^6.4 || ^7.0" + "symfony/config": "^5.4 || ^6.4 || ^7.0 || ^8.0", + "symfony/console": "^5.4.9 || ^6.4 || ^7.0 || ^8.0", + "symfony/dependency-injection": "^5.4 || ^6.4 || ^7.0 || ^8.0", + "symfony/event-dispatcher": "^5.4 || ^6.4 || ^7.0 || ^8.0", + "symfony/translation": "^5.4 || ^6.4 || ^7.0 || ^8.0", + "symfony/yaml": "^5.4 || ^6.4 || ^7.0 || ^8.0" }, "require-dev": { "opis/json-schema": "^2.5", "php-cs-fixer/shim": "^3.89", "phpstan/phpstan": "2.1.46", - "phpunit/phpunit": "^9.6", + "phpunit/phpunit": "^11.5", "rector/rector": "2.3.9", - "sebastian/diff": "^4.0", - "symfony/filesystem": "^5.4 || ^6.4 || ^7.0", + "sebastian/diff": "^6.0", + "symfony/filesystem": "^5.4 || ^6.4 || ^7.0 || ^8.0", "symfony/polyfill-php84": "^1.31", - "symfony/process": "^5.4 || ^6.4 || ^7.0" + "symfony/process": "^5.4 || ^6.4 || ^7.0 || ^8.0" }, "suggest": { "ext-dom": "Needed to output test results in JUnit format." @@ -94,7 +93,7 @@ ], "support": { "issues": "https://github.com/Behat/Behat/issues", - "source": "https://github.com/Behat/Behat/tree/v3.33.0" + "source": "https://github.com/Behat/Behat/tree/v4.0.0" }, "funding": [ { @@ -110,20 +109,20 @@ "type": "github" } ], - "time": "2026-09-07T14:37:47+00:00" + "time": "2026-09-28T16:13:53+00:00" }, { "name": "behat/gherkin", - "version": "v4.17.0", + "version": "v4.18.0", "source": { "type": "git", "url": "https://github.com/Behat/Gherkin.git", - "reference": "5c8b3149fac39b5a79942b64eeec59a5ee4001c0" + "reference": "496248b29d9d7848311a263c2d17c1860e4c7b6c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Behat/Gherkin/zipball/5c8b3149fac39b5a79942b64eeec59a5ee4001c0", - "reference": "5c8b3149fac39b5a79942b64eeec59a5ee4001c0", + "url": "https://api.github.com/repos/Behat/Gherkin/zipball/496248b29d9d7848311a263c2d17c1860e4c7b6c", + "reference": "496248b29d9d7848311a263c2d17c1860e4c7b6c", "shasum": "" }, "require": { @@ -131,11 +130,12 @@ "php": ">=8.1 <8.6" }, "require-dev": { - "cucumber/gherkin-monorepo": "dev-gherkin-v39.1.0", + "cucumber/gherkin-monorepo": "dev-gherkin-v42.0.1", "friendsofphp/php-cs-fixer": "^3.77", "mikey179/vfsstream": "^1.6", "phpstan/extension-installer": "^1", - "phpstan/phpstan": "^2", + "phpstan/phpstan": "2.2.14", + "phpstan/phpstan-deprecation-rules": "^2.0", "phpstan/phpstan-phpunit": "^2", "phpunit/phpunit": "^10.5", "symfony/yaml": "^5.4 || ^6.4 || ^7.0" @@ -177,7 +177,7 @@ ], "support": { "issues": "https://github.com/Behat/Gherkin/issues", - "source": "https://github.com/Behat/Gherkin/tree/v4.17.0" + "source": "https://github.com/Behat/Gherkin/tree/v4.18.0" }, "funding": [ { @@ -193,7 +193,80 @@ "type": "github" } ], - "time": "2026-05-18T09:33:47+00:00" + "time": "2026-09-25T21:26:10+00:00" + }, + { + "name": "behat/phpunit-assertions-extension", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/Behat/PHPUnitAssertionsExtension.git", + "reference": "055f263f4d59c7d424dabf3765be1e99cc0a7ddd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Behat/PHPUnitAssertionsExtension/zipball/055f263f4d59c7d424dabf3765be1e99cc0a7ddd", + "reference": "055f263f4d59c7d424dabf3765be1e99cc0a7ddd", + "shasum": "" + }, + "require": { + "behat/behat": "^3.33 || ^4.0@alpha", + "php": ">=8.2 <8.6", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12.5 || ^13.3", + "symfony/dependency-injection": "^5.4 || ^6.4 || ^7.0 || ^8.0" + }, + "require-dev": { + "composer-runtime-api": "*", + "php-cs-fixer/shim": "^3.89", + "phpstan/phpstan": "2.1.46", + "rector/rector": "2.3.9", + "sebastian/diff": ">=3.0.6 <10", + "symfony/filesystem": "^5.4 || ^6.4 || ^7.0 || ^8.0", + "symfony/process": "^5.4 || ^6.4 || ^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Behat\\PHPUnitAssertionsExtension\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Behat contributors", + "homepage": "https://behat.org" + } + ], + "description": "Behat extension to support PHPUnit assertions in step definitions. NOTE: Not recommended for new projects", + "homepage": "https://docs.behat.org/en/latest/useful_resources.html#assertion-tools", + "keywords": [ + "BDD", + "Behat", + "documentation", + "testing" + ], + "support": { + "issues": "https://github.com/Behat/PHPUnitAssertionsExtension/issues", + "source": "https://github.com/Behat/PHPUnitAssertionsExtension/tree/v1.0.0" + }, + "funding": [ + { + "url": "https://github.com/acoulton", + "type": "github" + }, + { + "url": "https://github.com/carlos-granados", + "type": "github" + }, + { + "url": "https://github.com/stof", + "type": "github" + } + ], + "time": "2026-09-21T20:20:17+00:00" }, { "name": "composer/pcre", @@ -2328,16 +2401,16 @@ }, { "name": "symfony/console", - "version": "v7.4.19", + "version": "v7.4.20", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "3a1973458b153f566a8d7499bc06ece323d60063" + "reference": "d7bca2fe05241dc7732d0c8b6d551b879f5d0a7d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/3a1973458b153f566a8d7499bc06ece323d60063", - "reference": "3a1973458b153f566a8d7499bc06ece323d60063", + "url": "https://api.github.com/repos/symfony/console/zipball/d7bca2fe05241dc7732d0c8b6d551b879f5d0a7d", + "reference": "d7bca2fe05241dc7732d0c8b6d551b879f5d0a7d", "shasum": "" }, "require": { @@ -2402,7 +2475,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.4.19" + "source": "https://github.com/symfony/console/tree/v7.4.20" }, "funding": [ { @@ -2422,20 +2495,20 @@ "type": "tidelift" } ], - "time": "2026-09-13T10:38:41+00:00" + "time": "2026-09-18T15:55:00+00:00" }, { "name": "symfony/dependency-injection", - "version": "v7.4.17", + "version": "v7.4.20", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "f318ac9da5aba0be2cf43ecdd562c05a33bc11c0" + "reference": "a7faee783a87b55f27460fc571f8c639bf9d93a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f318ac9da5aba0be2cf43ecdd562c05a33bc11c0", - "reference": "f318ac9da5aba0be2cf43ecdd562c05a33bc11c0", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/a7faee783a87b55f27460fc571f8c639bf9d93a2", + "reference": "a7faee783a87b55f27460fc571f8c639bf9d93a2", "shasum": "" }, "require": { @@ -2486,7 +2559,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v7.4.17" + "source": "https://github.com/symfony/dependency-injection/tree/v7.4.20" }, "funding": [ { @@ -2506,7 +2579,7 @@ "type": "tidelift" } ], - "time": "2026-08-21T17:40:08+00:00" + "time": "2026-09-29T12:35:16+00:00" }, { "name": "symfony/deprecation-contracts", @@ -2899,16 +2972,16 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.41.0", + "version": "v1.43.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "bb899c1db0aa8127dc3afe8cda4a67eb24915f8d" + "reference": "5cac8f4db97208823aa353f59a01faad2da52c75" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/bb899c1db0aa8127dc3afe8cda4a67eb24915f8d", - "reference": "bb899c1db0aa8127dc3afe8cda4a67eb24915f8d", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/5cac8f4db97208823aa353f59a01faad2da52c75", + "reference": "5cac8f4db97208823aa353f59a01faad2da52c75", "shasum": "" }, "require": { @@ -2957,7 +3030,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.41.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.43.0" }, "funding": [ { @@ -2977,20 +3050,20 @@ "type": "tidelift" } ], - "time": "2026-07-28T08:25:59+00:00" + "time": "2026-09-25T15:46:47+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.42.0", + "version": "v1.43.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "aa20edea75bd9c48cfecc8360922e5a6e5c44502" + "reference": "ebd57ccc7edb93d632e184efbe7693d2517bab3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/aa20edea75bd9c48cfecc8360922e5a6e5c44502", - "reference": "aa20edea75bd9c48cfecc8360922e5a6e5c44502", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/ebd57ccc7edb93d632e184efbe7693d2517bab3b", + "reference": "ebd57ccc7edb93d632e184efbe7693d2517bab3b", "shasum": "" }, "require": { @@ -3042,7 +3115,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.42.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.43.0" }, "funding": [ { @@ -3062,20 +3135,20 @@ "type": "tidelift" } ], - "time": "2026-08-07T06:33:24+00:00" + "time": "2026-09-23T22:02:09+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.38.2", + "version": "v1.43.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6" + "reference": "4d5d331bf731e0aedbc6b2f5e61135b7b7996a72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", - "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/4d5d331bf731e0aedbc6b2f5e61135b7b7996a72", + "reference": "4d5d331bf731e0aedbc6b2f5e61135b7b7996a72", "shasum": "" }, "require": { @@ -3127,7 +3200,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.2" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.43.0" }, "funding": [ { @@ -3147,7 +3220,7 @@ "type": "tidelift" } ], - "time": "2026-05-27T06:59:30+00:00" + "time": "2026-09-24T15:19:04+00:00" }, { "name": "symfony/service-contracts", @@ -3592,16 +3665,16 @@ }, { "name": "symfony/yaml", - "version": "v7.4.18", + "version": "v7.4.20", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "4cef939e55b8a21c5780418de0d98ab00d0736e1" + "reference": "0222bf4dfaa1e3ceb8fff579635d655f2950d5a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/4cef939e55b8a21c5780418de0d98ab00d0736e1", - "reference": "4cef939e55b8a21c5780418de0d98ab00d0736e1", + "url": "https://api.github.com/repos/symfony/yaml/zipball/0222bf4dfaa1e3ceb8fff579635d655f2950d5a7", + "reference": "0222bf4dfaa1e3ceb8fff579635d655f2950d5a7", "shasum": "" }, "require": { @@ -3644,7 +3717,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.4.18" + "source": "https://github.com/symfony/yaml/tree/v7.4.20" }, "funding": [ { @@ -3664,7 +3737,7 @@ "type": "tidelift" } ], - "time": "2026-08-30T00:47:26+00:00" + "time": "2026-09-26T06:31:10+00:00" }, { "name": "theseer/tokenizer",