diff --git a/tests/acceptance/config/behat.yml b/tests/acceptance/config/behat.yml index 7b97371de48..73aa64c21ed 100644 --- a/tests/acceptance/config/behat.yml +++ b/tests/acceptance/config/behat.yml @@ -26,6 +26,7 @@ default: - ChecksumContext: - FavoritesContext: - FilesVersionsContext: + - NotificationContext: - OCSContext: - PublicWebDavContext: - TrashbinContext: @@ -43,6 +44,7 @@ default: - ChecksumContext: - FavoritesContext: - FilesVersionsContext: + - NotificationContext: - OCSContext: - PublicWebDavContext: - SearchContext: diff --git a/tests/acceptance/features/apiSpaces/notification.feature b/tests/acceptance/features/apiSpaces/notification.feature new file mode 100644 index 00000000000..f88a72c3f80 --- /dev/null +++ b/tests/acceptance/features/apiSpaces/notification.feature @@ -0,0 +1,127 @@ +@api @skipOnOcV10 +Feature: Notification + As a user + I want to be notified of actions related to me + + Background: + Given these users have been created with default attributes and without skeleton files: + | username | + | Alice | + | Brian | + | Carol | + And the administrator has given "Alice" the role "Space Admin" using the settings api + + + Scenario: user gets a notification of space sharing + Given user "Alice" has created a space "notificaton checking" with the default quota using the GraphApi + And user "Alice" has shared a space "notificaton checking" with settings: + | shareWith | Brian | + | role | editor | + When user "Brian" lists all notifications + Then the HTTP status code should be "200" + And the JSON response should contain a notification message with the subject "Space shared" and the message-details should match + """ + { + "type": "object", + "required": [ + "app", + "datetime", + "message", + "messageRich", + "messageRichParameters", + "notification_id", + "object_id", + "object_type", + "subject", + "subjectRich", + "user" + ], + "properties": { + "app": { + "type": "string", + "enum": ["userlog"] + }, + "message": { + "type": "string", + "enum": ["Alice Hansen added you to Space notificaton checking"] + }, + "messageRich": { + "type": "string", + "enum": ["{user} added you to Space {space}"] + }, + "messageRichParameters": { + "type": "object", + "required": [ + "space", + "user" + ], + "properties": { + "space": { + "type": "object", + "required": [ + "id", + "name" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\\$[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}![a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$" + }, + "name": { + "type": "string", + "enum": ["notificaton checking"] + } + } + }, + "user": { + "type": "object", + "required": [ + "displayname", + "id", + "name" + ], + "properties": { + "displayname": { + "type": "string", + "enum": ["Alice Hansen"] + }, + "id": { + "type": "string", + "enim": ["%user_id%"] + }, + "name": { + "type": "string", + "enum": ["Alice"] + } + } + } + } + }, + "notification_id": { + "type": "string" + + }, + "object_id": { + "type": "string" + + }, + "object_type": { + "type": "string", + "enum": ["storagespace"] + }, + "subject": { + "type": "string", + "enum": ["Space shared"] + }, + "subjectRich": { + "type": "string", + "enum": ["Space shared"] + }, + "user": { + "type": "string", + "enum": ["Alice"] + } + } + } + """ + diff --git a/tests/acceptance/features/bootstrap/NotificationContext.php b/tests/acceptance/features/bootstrap/NotificationContext.php new file mode 100644 index 00000000000..1cd68b9905e --- /dev/null +++ b/tests/acceptance/features/bootstrap/NotificationContext.php @@ -0,0 +1,148 @@ + + * @copyright Copyright (c) 2023 Viktor Scharf vscharf@owncloud.com + */ + +use Behat\Behat\Context\Context; +use Behat\Behat\Hook\Scope\BeforeScenarioScope; +use TestHelpers\OcsApiHelper; +use Behat\Gherkin\Node\PyStringNode; +use Helmich\JsonAssert\JsonAssertions; + +require_once 'bootstrap.php'; + +/** + * Defines application features from the specific context. + */ +class NotificationContext implements Context { + /** + * @var FeatureContext + */ + private $featureContext; + + /** + * @var string + */ + private string $notificationEndpointPath = '/apps/notifications/api/v1/notifications?format=json'; + + /** + * @var array[] + */ + private $notificationIds; + + /** + * @return array[] + */ + public function getNotificationIds():array { + return $this->notificationIds; + } + + /** + * @return array[] + */ + public function getLastNotificationId():array { + return \end($this->notificationIds); + } + + /** + * @var string + */ + private string $userRecipient; + + /** + * @param string $userRecipient + * + * @return void + */ + public function setUserRecipient(string $userRecipient): void { + $this->userRecipient = $userRecipient; + } + + /** + * @return string + */ + public function getUserRecipient(): string { + return $this->userRecipient; + } + + /** + * @BeforeScenario + * + * @param BeforeScenarioScope $scope + * + * @return void + * @throws Exception + */ + public function setUpScenario(BeforeScenarioScope $scope):void { + // Get the environment + $environment = $scope->getEnvironment(); + // Get all the contexts you need in this context + $this->featureContext = $environment->getContext('FeatureContext'); + } + + /** + * @Then /^user "([^"]*)" lists all notifications$/ + * + * @param string $user + * + * @return void + */ + public function userListAllNotifications(string $user):void { + $this->setUserRecipient($user); + $response = OcsApiHelper::sendRequest( + $this->featureContext->getBaseUrl(), + $this->featureContext->getActualUsername($user), + $this->featureContext->getPasswordForUser($user), + 'GET', + $this->notificationEndpointPath, + $this->featureContext->getStepLineRef() + ); + $this->featureContext->setResponse($response); + } + + /** + * @Then /^the JSON response should contain a notification message with the subject "([^"]*)" and the message-details should match$/ + * + * @param string $subject + * @param PyStringNode $schemaString + * + * @return void + * @throws Exception + */ + public function theJsonDataFromLastResponseShouldMatch( + string $subject, + PyStringNode $schemaString + ): void { + if (isset($this->featureContext->getJsonDecodedResponseBodyContent()->ocs->data)) { + $responseBody = $this->featureContext->getJsonDecodedResponseBodyContent()->ocs->data; + foreach ($responseBody as $value) { + if (isset($value->subject) && $value->subject === $subject) { + $responseBody = $value; + // set notificationId + $this->notificationIds[] = $value->notification_id; + break; + } + } + } else { + $responseBody = $this->featureContext->getJsonDecodedResponseBodyContent(); + } + + // substitute the value here + $schemaString = $schemaString->getRaw(); + $schemaString = $this->featureContext->substituteInLineCodes( + $schemaString, + $this->featureContext->getCurrentUser(), + [], + [], + null, + $this->getUserRecipient(), + ); + JsonAssertions::assertJsonDocumentMatchesSchema( + $responseBody, + $this->featureContext->getJSONSchema($schemaString) + ); + } +}