From 53ee61ad87c94b2ecb10f129114b2d2b0d324d4a Mon Sep 17 00:00:00 2001 From: Amrita <54478846+amrita-shrestha@users.noreply.github.com> Date: Wed, 24 May 2023 12:56:43 +0545 Subject: [PATCH] [full-ci][tests-only]Extend notification api tests (#6324) * Add api tests for notification * Address review --- .drone.star | 4 +- docs/ocis/development/testing.md | 2 +- tests/acceptance/config/behat.yml | 4 +- .../emailNotification.feature | 0 .../apiNotification/notification.feature | 242 ++++++++++++++++++ .../acceptance/features/bootstrap/Sharing.php | 64 ++++- 6 files changed, 299 insertions(+), 17 deletions(-) rename tests/acceptance/features/{apiEmailNotification => apiNotification}/emailNotification.feature (100%) create mode 100644 tests/acceptance/features/apiNotification/notification.feature diff --git a/.drone.star b/.drone.star index abcf7d67d69..41ec2b3ba04 100644 --- a/.drone.star +++ b/.drone.star @@ -117,9 +117,9 @@ config = { "skip": False, "earlyFail": True, }, - "apiEmailNotification": { + "apiNotification": { "suites": [ - "apiEmailNotification", + "apiNotification", ], "skip": False, "earlyFail": True, diff --git a/docs/ocis/development/testing.md b/docs/ocis/development/testing.md index ee4063d247b..3e966009595 100644 --- a/docs/ocis/development/testing.md +++ b/docs/ocis/development/testing.md @@ -352,7 +352,7 @@ TEST_OCIS=true \ TEST_SERVER_URL="https://localhost:9200" \ EMAIL_HOST="localhost" \ EMAIL_PORT=9000 \ -BEHAT_FEATURE="tests/acceptance/features/apiEmailNotification/emailNotification.feature" \ +BEHAT_FEATURE="tests/acceptance/features/apiNotification/emailNotification.feature" \ make test-acceptance-api ``` diff --git a/tests/acceptance/config/behat.yml b/tests/acceptance/config/behat.yml index 874db10c58b..74d2e8fda5e 100644 --- a/tests/acceptance/config/behat.yml +++ b/tests/acceptance/config/behat.yml @@ -170,9 +170,9 @@ default: - GraphContext: - OcisConfigContext: - apiEmailNotification: + apiNotification: paths: - - '%paths.base%/../features/apiEmailNotification' + - '%paths.base%/../features/apiNotification' context: *common_ldap_suite_context contexts: - NotificationContext: diff --git a/tests/acceptance/features/apiEmailNotification/emailNotification.feature b/tests/acceptance/features/apiNotification/emailNotification.feature similarity index 100% rename from tests/acceptance/features/apiEmailNotification/emailNotification.feature rename to tests/acceptance/features/apiNotification/emailNotification.feature diff --git a/tests/acceptance/features/apiNotification/notification.feature b/tests/acceptance/features/apiNotification/notification.feature new file mode 100644 index 00000000000..a0a364df324 --- /dev/null +++ b/tests/acceptance/features/apiNotification/notification.feature @@ -0,0 +1,242 @@ +@api +Feature: Notification + As a user + I want to be notified of various events + So that I can stay updated about the information + + Background: + Given these users have been created with default attributes and without skeleton files: + | username | + | Alice | + | Brian | + | Carol | + And user "Alice" has uploaded file with content "other data" to "/textfile1.txt" + And user "Alice" has created folder "my_data" + + + Scenario Outline: user gets a notification of resource sharing + Given user "Alice" has shared entry "" with user "Brian" + 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 "Resource 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 shared with you"] + }, + "messageRich": { + "type": "string", + "enum": ["{user} shared {resource} with you"] + }, + "messageRichParameters": { + "type": "object", + "required": [ + "resource", + "user" + ], + "properties": { + "resource": { + "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": [""] + } + } + }, + "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": ["share"] + }, + "subject": { + "type": "string", + "enum": ["Resource shared"] + }, + "subjectRich": { + "type": "string", + "enum": ["Resource shared"] + }, + "user": { + "type": "string", + "enum": ["Alice"] + } + } + } + """ + Examples: + | resource | + | textfile1.txt | + | my_data | + + + Scenario Outline: user gets a notification of unsharing resource + Given user "Alice" has shared entry "" with user "Brian" + And user "Brian" has accepted share "/" offered by user "Alice" + And user "Alice" has unshared entity "" shared to "Brian" + 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 "Resource unshared" 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 unshared with you"] + }, + "messageRich": { + "type": "string", + "enum": ["{user} unshared {resource} with you"] + }, + "messageRichParameters": { + "type": "object", + "required": [ + "resource", + "user" + ], + "properties": { + "resource": { + "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": [""] + } + } + }, + "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": ["share"] + }, + "subject": { + "type": "string", + "enum": ["Resource unshared"] + }, + "subjectRich": { + "type": "string", + "enum": ["Resource unshared"] + }, + "user": { + "type": "string", + "enum": ["Alice"] + } + } + } + """ + Examples: + | resource | + | textfile1.txt | + | my_data | diff --git a/tests/acceptance/features/bootstrap/Sharing.php b/tests/acceptance/features/bootstrap/Sharing.php index d4db525f70c..013099414fc 100644 --- a/tests/acceptance/features/bootstrap/Sharing.php +++ b/tests/acceptance/features/bootstrap/Sharing.php @@ -3023,13 +3023,13 @@ public function userRemovesAllSharesFromTheFileNamed(string $user, string $fileN public function userHasRemovedAllSharesFromTheFileNamed(string $user, string $fileName):void { $user = $this->getActualUsername($user); $this->removeAllSharesFromResource($user, $fileName); - $dataResponded = $this->getShares($user, $fileName); + $response = $this->getShares($user, $fileName); Assert::assertEquals( 0, - \count($dataResponded), + \count($response), __METHOD__ . " Expected all shares to be removed from '$fileName' but got '" - . \count($dataResponded) + . \count($response) . "' shares still present" ); } @@ -3075,7 +3075,7 @@ public function getShares(string $user, string $path):SimpleXMLElement { */ public function checkPublicShares(string $user, string $path, ?TableNode $TableNode):void { $user = $this->getActualUsername($user); - $dataResponded = $this->getShares($user, $path); + $response = $this->getShares($user, $path); $this->verifyTableNodeColumns($TableNode, ['path', 'permissions', 'name']); if ($TableNode instanceof TableNode) { @@ -3083,7 +3083,7 @@ public function checkPublicShares(string $user, string $path, ?TableNode $TableN foreach ($elementRows as $expectedElementsArray) { $nameFound = false; - foreach ($dataResponded as $elementResponded) { + foreach ($response as $elementResponded) { if ((string) $elementResponded->name[0] === $expectedElementsArray['name']) { Assert::assertEquals( $expectedElementsArray['path'], @@ -3126,14 +3126,14 @@ public function checkPublicShares(string $user, string $path, ?TableNode $TableN public function checkPublicSharesAreEmpty(string $user, string $entry, string $path):void { $user = $this->getActualUsername($user); $this->asFileOrFolderShouldExist($user, $entry, $path); - $dataResponded = $this->getShares($user, $path); + $response = $this->getShares($user, $path); //It shouldn't have public shares Assert::assertEquals( 0, - \count($dataResponded), + \count($response), __METHOD__ . " As '$user', '$path' was expected to have no shares, but got '" - . \count($dataResponded) + . \count($response) . "' shares present" ); } @@ -3146,8 +3146,8 @@ public function checkPublicSharesAreEmpty(string $user, string $entry, string $p * @return string|null */ public function getPublicShareIDByName(string $user, string $path, string $name):?string { - $dataResponded = $this->getShares($user, $path); - foreach ($dataResponded as $elementResponded) { + $response = $this->getShares($user, $path); + foreach ($response as $elementResponded) { if ((string) $elementResponded->name[0] === $name) { return (string) $elementResponded->id[0]; } @@ -3236,9 +3236,9 @@ public function userReactsToShareOfferedBy(string $user, string $action, string $user = $this->getActualUsername($user); $offeredBy = $this->getActualUsername($offeredBy); - $dataResponded = $this->getAllSharesSharedWithUser($user); + $response = $this->getAllSharesSharedWithUser($user); $shareId = null; - foreach ($dataResponded as $shareElement) { + foreach ($response as $shareElement) { // SharingHelper::SHARE_STATES has the mapping between the words for share states // like "accepted", "pending",... and the integer constants 0, 1,... that are in // the "state" field of the share data. @@ -3479,6 +3479,46 @@ public function assertNoSharesOfUserAreInState(string $user, string $state):void ); } + /** + * @Given /^user "([^"]*)" has unshared (?:folder|file|entity) "([^"]*)" shared to "([^"]*)"$/ + * + * @param string $sharer + * @param string $path + * @param string $sharee + * + * @return void + * @throws JsonException + */ + public function userHasUnsharedResourceSharedTo(string $sharer, string $path, string $sharee): void { + $sharer = $this->getActualUsername($sharer); + $sharee = $this->getActualUsername($sharee); + + $response = $this->getShares($sharer, "$path&share_types=0"); + $shareId = null; + foreach ($response as $shareElement) { + if ((string)$shareElement->share_with[0] === $sharee) { + $shareId = (string) $shareElement->id; + break; + } + } + Assert::assertNotNull( + $shareId, + __METHOD__ . " could not find share, offered by $sharer to $sharee" + ); + + $this->ocsContext->userSendsHTTPMethodToOcsApiEndpointWithBody( + $sharer, + 'DELETE', + '/apps/files_sharing/api/v' . $this->sharingApiVersion . '/shares/' . $shareId + ); + + $this->ocsContext->assertOCSResponseIndicatesSuccess( + 'The ocs share response does not indicate success.', + ); + $this->emptyLastHTTPStatusCodesArray(); + $this->emptyLastOCSStatusCodesArray(); + } + /** * @Then the sharing API should report that no shares are shared with user :user *