diff --git a/.drone.jsonnet b/.drone.jsonnet index 4033c02aeaf..9920a39f547 100644 --- a/.drone.jsonnet +++ b/.drone.jsonnet @@ -16,6 +16,7 @@ local Pipeline(test_set, database, services) = { APP_NAME: "spreed", CORE_BRANCH: "master", GUESTS_BRANCH: "master", + NOTIFICATIONS_BRANCH: "master", DATABASEHOST: database }, commands: [ @@ -24,6 +25,8 @@ local Pipeline(test_set, database, services) = { "bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST", "cd ../server", "./occ app:enable $APP_NAME", + "git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications apps/notifications", + "./occ app:enable notifications" ] + ( if test_set == "conversation" || test_set == "conversation-2" then [ "git clone --depth 1 -b $GUESTS_BRANCH https://github.com/nextcloud/guests apps/guests" diff --git a/.drone.yml b/.drone.yml index 47fad6ef9e4..b20111fc060 100644 --- a/.drone.yml +++ b/.drone.yml @@ -11,6 +11,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - cd apps/$APP_NAME - cd tests/integration/ - bash run.sh features/callapi @@ -19,6 +22,7 @@ steps: CORE_BRANCH: master DATABASEHOST: sqlite GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-callapi trigger: @@ -40,6 +44,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - cd apps/$APP_NAME - cd tests/integration/ - bash run.sh features/chat @@ -48,6 +55,7 @@ steps: CORE_BRANCH: master DATABASEHOST: sqlite GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-chat trigger: @@ -69,6 +77,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - cd apps/$APP_NAME - cd tests/integration/ - bash run.sh features/command @@ -77,6 +88,7 @@ steps: CORE_BRANCH: master DATABASEHOST: sqlite GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-command trigger: @@ -98,6 +110,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - git clone --depth 1 -b $GUESTS_BRANCH https://github.com/nextcloud/guests apps/guests - cd apps/$APP_NAME - cd tests/integration/ @@ -107,6 +122,7 @@ steps: CORE_BRANCH: master DATABASEHOST: sqlite GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-conversation trigger: @@ -128,6 +144,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - git clone --depth 1 -b $GUESTS_BRANCH https://github.com/nextcloud/guests apps/guests - cd apps/$APP_NAME - cd tests/integration/ @@ -137,6 +156,7 @@ steps: CORE_BRANCH: master DATABASEHOST: sqlite GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-conversation-2 trigger: @@ -158,6 +178,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - cd apps/$APP_NAME - cd tests/integration/ - bash run.sh features/federation @@ -166,6 +189,7 @@ steps: CORE_BRANCH: master DATABASEHOST: sqlite GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-federation trigger: @@ -187,6 +211,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - cd apps/$APP_NAME - cd tests/integration/ - bash run.sh features/reaction @@ -195,6 +222,7 @@ steps: CORE_BRANCH: master DATABASEHOST: sqlite GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-reaction trigger: @@ -216,6 +244,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - cd apps/$APP_NAME - cd tests/integration/ - bash run.sh features/sharing @@ -224,6 +255,7 @@ steps: CORE_BRANCH: master DATABASEHOST: sqlite GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-sharing trigger: @@ -245,6 +277,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - cd apps/$APP_NAME - cd tests/integration/ - bash run.sh features/sharing-2 @@ -253,6 +288,7 @@ steps: CORE_BRANCH: master DATABASEHOST: sqlite GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-sharing-2 trigger: @@ -288,6 +324,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - cd apps/$APP_NAME - cd tests/integration/ - bash run.sh features/callapi @@ -296,6 +335,7 @@ steps: CORE_BRANCH: master DATABASEHOST: mysql GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-callapi trigger: @@ -332,6 +372,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - cd apps/$APP_NAME - cd tests/integration/ - bash run.sh features/chat @@ -340,6 +383,7 @@ steps: CORE_BRANCH: master DATABASEHOST: mysql GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-chat trigger: @@ -376,6 +420,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - cd apps/$APP_NAME - cd tests/integration/ - bash run.sh features/command @@ -384,6 +431,7 @@ steps: CORE_BRANCH: master DATABASEHOST: mysql GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-command trigger: @@ -420,6 +468,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - git clone --depth 1 -b $GUESTS_BRANCH https://github.com/nextcloud/guests apps/guests - cd apps/$APP_NAME - cd tests/integration/ @@ -429,6 +480,7 @@ steps: CORE_BRANCH: master DATABASEHOST: mysql GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-conversation trigger: @@ -465,6 +517,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - git clone --depth 1 -b $GUESTS_BRANCH https://github.com/nextcloud/guests apps/guests - cd apps/$APP_NAME - cd tests/integration/ @@ -474,6 +529,7 @@ steps: CORE_BRANCH: master DATABASEHOST: mysql GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-conversation-2 trigger: @@ -510,6 +566,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - cd apps/$APP_NAME - cd tests/integration/ - bash run.sh features/federation @@ -518,6 +577,7 @@ steps: CORE_BRANCH: master DATABASEHOST: mysql GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-federation trigger: @@ -554,6 +614,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - cd apps/$APP_NAME - cd tests/integration/ - bash run.sh features/reaction @@ -562,6 +625,7 @@ steps: CORE_BRANCH: master DATABASEHOST: mysql GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-reaction trigger: @@ -598,6 +662,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - cd apps/$APP_NAME - cd tests/integration/ - bash run.sh features/sharing @@ -606,6 +673,7 @@ steps: CORE_BRANCH: master DATABASEHOST: mysql GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-sharing trigger: @@ -642,6 +710,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - cd apps/$APP_NAME - cd tests/integration/ - bash run.sh features/sharing-2 @@ -650,6 +721,7 @@ steps: CORE_BRANCH: master DATABASEHOST: mysql GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-sharing-2 trigger: @@ -681,6 +753,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - cd apps/$APP_NAME - cd tests/integration/ - bash run.sh features/callapi @@ -689,6 +764,7 @@ steps: CORE_BRANCH: master DATABASEHOST: pgsql GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-callapi trigger: @@ -719,6 +795,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - cd apps/$APP_NAME - cd tests/integration/ - bash run.sh features/chat @@ -727,6 +806,7 @@ steps: CORE_BRANCH: master DATABASEHOST: pgsql GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-chat trigger: @@ -757,6 +837,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - cd apps/$APP_NAME - cd tests/integration/ - bash run.sh features/command @@ -765,6 +848,7 @@ steps: CORE_BRANCH: master DATABASEHOST: pgsql GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-command trigger: @@ -795,6 +879,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - git clone --depth 1 -b $GUESTS_BRANCH https://github.com/nextcloud/guests apps/guests - cd apps/$APP_NAME - cd tests/integration/ @@ -804,6 +891,7 @@ steps: CORE_BRANCH: master DATABASEHOST: pgsql GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-conversation trigger: @@ -834,6 +922,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - git clone --depth 1 -b $GUESTS_BRANCH https://github.com/nextcloud/guests apps/guests - cd apps/$APP_NAME - cd tests/integration/ @@ -843,6 +934,7 @@ steps: CORE_BRANCH: master DATABASEHOST: pgsql GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-conversation-2 trigger: @@ -873,6 +965,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - cd apps/$APP_NAME - cd tests/integration/ - bash run.sh features/federation @@ -881,6 +976,7 @@ steps: CORE_BRANCH: master DATABASEHOST: pgsql GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-federation trigger: @@ -911,6 +1007,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - cd apps/$APP_NAME - cd tests/integration/ - bash run.sh features/reaction @@ -919,6 +1018,7 @@ steps: CORE_BRANCH: master DATABASEHOST: pgsql GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-reaction trigger: @@ -949,6 +1049,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - cd apps/$APP_NAME - cd tests/integration/ - bash run.sh features/sharing @@ -957,6 +1060,7 @@ steps: CORE_BRANCH: master DATABASEHOST: pgsql GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-sharing trigger: @@ -987,6 +1091,9 @@ steps: - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST - cd ../server - ./occ app:enable $APP_NAME + - git clone --depth 1 -b $NOTIFICATIONS_BRANCH https://github.com/nextcloud/notifications + apps/notifications + - ./occ app:enable notifications - cd apps/$APP_NAME - cd tests/integration/ - bash run.sh features/sharing-2 @@ -995,6 +1102,7 @@ steps: CORE_BRANCH: master DATABASEHOST: pgsql GUESTS_BRANCH: master + NOTIFICATIONS_BRANCH: master image: ghcr.io/nextcloud/continuous-integration-php8.0:latest name: integration-sharing-2 trigger: diff --git a/tests/integration/features/bootstrap/FeatureContext.php b/tests/integration/features/bootstrap/FeatureContext.php index 2d78ad37d91..3d0d3dc7bd0 100644 --- a/tests/integration/features/bootstrap/FeatureContext.php +++ b/tests/integration/features/bootstrap/FeatureContext.php @@ -49,6 +49,9 @@ class FeatureContext implements Context, SnippetAcceptingContext { protected static $userToAttendeeId; /** @var array[] */ protected static $messages; + protected static $textToMessageId; + /** @var array[] */ + protected static $messageIdToText; protected static $permissionsMap = [ @@ -138,7 +141,8 @@ public function setUp() { self::$sessionIdToUser = []; self::$userToSessionId = []; self::$userToAttendeeId = []; - self::$messages = []; + self::$textToMessageId = []; + self::$messageIdToText = []; $this->createdUsers = []; $this->createdGroups = []; @@ -861,6 +865,36 @@ public function userJoinsRoom(string $user, string $identifier, int $statusCode, } } + /** + * @Then /^user "([^"]*)" sets notifications to (default|disabled|mention|all) for room "([^"]*)" \((v4)\)$/ + * + * @param string $user + * @param string $level + * @param string $identifier + * @param string $apiVersion + */ + public function userSetsNotificationLevelForRoom(string $user, string $level, string $identifier, string $apiVersion): void { + $this->setCurrentUser($user); + + $intLevel = 0; // default + if ($level === 'disabled') { + $intLevel = 3; + } elseif ($level === 'mention') { + $intLevel = 2; + } elseif ($level === 'all') { + $intLevel = 1; + } + + $this->sendRequest( + 'POST', '/apps/spreed/api/' . $apiVersion . '/room/' . self::$identifierToToken[$identifier] . '/notify', + new TableNode([ + ['level', $intLevel], + ]) + ); + + $this->assertStatusCode($this->response, 200); + } + /** * @Then /^user "([^"]*)" leaves room "([^"]*)" with (\d+) \((v4)\)$/ * @@ -1381,7 +1415,8 @@ public function userSendsMessageToRoom($user, $message, $identifier, $statusCode $response = $this->getDataFromResponse($this->response); if (isset($response['id'])) { - self::$messages[$message] = $response['id']; + self::$textToMessageId[$message] = $response['id']; + self::$messageIdToText[$response['id']] = $message; } } @@ -1411,7 +1446,7 @@ public function userSharesRichObjectToRoom($user, $type, $id, $metaData, $identi $response = $this->getDataFromResponse($this->response); if (isset($response['id'])) { - self::$messages['shared::' . $type . '::' . $id] = $response['id']; + self::$textToMessageId['shared::' . $type . '::' . $id] = $response['id']; } } @@ -1427,7 +1462,7 @@ public function userSharesRichObjectToRoom($user, $type, $id, $metaData, $identi public function userDeletesMessageFromRoom($user, $message, $identifier, $statusCode, $apiVersion = 'v1') { $this->setCurrentUser($user); $this->sendRequest( - 'DELETE', '/apps/spreed/api/' . $apiVersion . '/chat/' . self::$identifierToToken[$identifier] . '/' . self::$messages[$message], + 'DELETE', '/apps/spreed/api/' . $apiVersion . '/chat/' . self::$identifierToToken[$identifier] . '/' . self::$textToMessageId[$message], new TableNode([['message', $message]]) ); $this->assertStatusCode($this->response, $statusCode); @@ -1462,7 +1497,7 @@ public function userReadsMessageInRoom($user, $message, $identifier, $statusCode $this->setCurrentUser($user); $this->sendRequest( 'POST', '/apps/spreed/api/' . $apiVersion . '/chat/' . self::$identifierToToken[$identifier] . '/read', - new TableNode([['lastReadMessage', self::$messages[$message]]]) + new TableNode([['lastReadMessage', self::$textToMessageId[$message]]]) ); $this->assertStatusCode($this->response, $statusCode); } @@ -1504,7 +1539,7 @@ public function userSendsMessageWithReferenceIdToRoom($user, $message, $referenc $response = $this->getDataFromResponse($this->response); if (isset($response['id'])) { - self::$messages[$message] = $response['id']; + self::$textToMessageId[$message] = $response['id']; } Assert::assertStringStartsWith($response['referenceId'], $referenceId); @@ -1521,7 +1556,7 @@ public function userSendsMessageWithReferenceIdToRoom($user, $message, $referenc * @param string $apiVersion */ public function userSendsReplyToRoom($user, $reply, $message, $identifier, $statusCode, $apiVersion = 'v1') { - $replyTo = self::$messages[$message]; + $replyTo = self::$textToMessageId[$message]; $this->setCurrentUser($user); $this->sendRequest( @@ -1533,7 +1568,7 @@ public function userSendsReplyToRoom($user, $reply, $message, $identifier, $stat $response = $this->getDataFromResponse($this->response); if (isset($response['id'])) { - self::$messages[$reply] = $response['id']; + self::$textToMessageId[$reply] = $response['id']; } } @@ -1587,7 +1622,7 @@ public function userReceivedDeleteMessage($user, $identifier, $message, $apiVers foreach ($actual as $m) { if ($m['systemMessage'] === 'message_deleted') { - if (isset($m['parent']['id']) && $m['parent']['id'] === self::$messages[$message]) { + if (isset($m['parent']['id']) && $m['parent']['id'] === self::$textToMessageId[$message]) { return; } } @@ -1607,7 +1642,7 @@ public function userReceivedDeleteMessage($user, $identifier, $message, $apiVers */ public function userAwaitsTheFollowingMessagesInRoom($user, $identifier, $knownMessage, $statusCode, $apiVersion = 'v1', TableNode $formData = null) { $this->setCurrentUser($user); - $this->sendRequest('GET', '/apps/spreed/api/' . $apiVersion . '/chat/' . self::$identifierToToken[$identifier] . '?lookIntoFuture=1&includeLastKnown=1&lastKnownMessageId=' . self::$messages[$knownMessage]); + $this->sendRequest('GET', '/apps/spreed/api/' . $apiVersion . '/chat/' . self::$identifierToToken[$identifier] . '?lookIntoFuture=1&includeLastKnown=1&lastKnownMessageId=' . self::$textToMessageId[$knownMessage]); $this->assertStatusCode($this->response, $statusCode); $this->compareDataResponse($formData); @@ -1630,9 +1665,9 @@ protected function compareDataResponse(TableNode $formData = null) { // Include the received messages in the list of messages used for // replies; this is needed to get special messages not explicitly // sent like those for shared files. - self::$messages[$message['message']] = $message['id']; + self::$textToMessageId[$message['message']] = $message['id']; if ($message['message'] === '{file}' && isset($message['messageParameters']['file']['name'])) { - self::$messages['shared::file::' . $message['messageParameters']['file']['name']] = $message['id']; + self::$textToMessageId['shared::file::' . $message['messageParameters']['file']['name']] = $message['id']; } } @@ -1699,7 +1734,7 @@ public function userSeesTheFollowingSystemMessagesInRoom($user, $identifier, $st foreach ($messages as $systemMessage) { // Include the received system messages in the list of messages used // for replies. - self::$messages[$systemMessage['systemMessage']] = $systemMessage['id']; + self::$textToMessageId[$systemMessage['systemMessage']] = $systemMessage['id']; } if ($formData === null) { @@ -1803,10 +1838,10 @@ public function hasNoChatLastCommonReadHeader($no) { public function hasChatLastCommonReadHeader($setOrLower, $message) { Assert::assertArrayHasKey('X-Chat-Last-Common-Read', $this->response->getHeaders()); if ($setOrLower === 'set to') { - Assert::assertEquals(self::$messages[$message], $this->response->getHeader('X-Chat-Last-Common-Read')[0]); + Assert::assertEquals(self::$textToMessageId[$message], $this->response->getHeader('X-Chat-Last-Common-Read')[0]); } else { // Less than might be required for the first message, because the last read message before is the join/room creation message and we don't know that ID - Assert::assertLessThan(self::$messages[$message], $this->response->getHeader('X-Chat-Last-Common-Read')[0]); + Assert::assertLessThan(self::$textToMessageId[$message], $this->response->getHeader('X-Chat-Last-Common-Read')[0]); } } @@ -1892,6 +1927,54 @@ public function setAppConfig(string $appId, TableNode $formData): void { $this->setCurrentUser($currentUser); } + /** + * @Then user :user has the following notifications + * + * @param string $user + * @param TableNode|null $body + */ + public function userNotifications(string $user, TableNode $body = null): void { + $this->setCurrentUser($user); + $this->sendRequest( + 'GET', '/apps/notifications/api/v2/notifications' + ); + + $data = $this->getDataFromResponse($this->response); + + if ($body === null) { + Assert::assertCount(0, $data); + return; + } + + $this->assertNotifications($data, $body); + } + + private function assertNotifications($notifications, TableNode $formData) { + Assert::assertCount(count($formData->getHash()), $notifications, 'Notifications count does not match'); + Assert::assertEquals($formData->getHash(), array_map(function ($notification, $expectedNotification) { + $data = []; + if (isset($expectedNotification['object_id'])) { + if (strpos($notification['object_id'], '/') !== false) { + [$roomToken, $message] = explode('/', $notification['object_id']); + $data['object_id'] = self::$tokenToIdentifier[$roomToken] . '/' . self::$messageIdToText[$message] ?? 'UNKNOWN_MESSAGE'; + } else { + [$roomToken,] = explode('/', $notification['object_id']); + $data['object_id'] = self::$tokenToIdentifier[$roomToken]; + } + } + if (isset($expectedNotification['subject'])) { + $data['subject'] = (string) $notification['subject']; + } + if (isset($expectedNotification['object_type'])) { + $data['object_type'] = (string) $notification['object_type']; + } + if (isset($expectedNotification['app'])) { + $data['app'] = (string) $notification['app']; + } + + return $data; + }, $notifications, $formData->getHash())); + } /** * @Given /^guest accounts can be created$/ @@ -2171,7 +2254,7 @@ public function removeUserFromGroup($user, $group) { */ public function userReactWithOnMessageToRoomWith(string $user, string $action, string $reaction, string $message, string $identifier, int $statusCode, string $apiVersion = 'v1', TableNode $formData = null): void { $token = self::$identifierToToken[$identifier]; - $messageId = self::$messages[$message]; + $messageId = self::$textToMessageId[$message]; $this->setCurrentUser($user); $verb = $action === 'react' ? 'POST' : 'DELETE'; $this->sendRequest($verb, '/apps/spreed/api/' . $apiVersion . '/reaction/' . $token . '/' . $messageId, [ @@ -2186,7 +2269,7 @@ public function userReactWithOnMessageToRoomWith(string $user, string $action, s */ public function userRetrieveReactionsOfMessageInRoomWith(string $user, string $reaction, string $message, string $identifier, int $statusCode, string $apiVersion = 'v1', TableNode $formData): void { $token = self::$identifierToToken[$identifier]; - $messageId = self::$messages[$message]; + $messageId = self::$textToMessageId[$message]; $this->setCurrentUser($user); $reaction = $reaction !== 'all' ? '?reaction=' . $reaction : ''; $this->sendRequest('GET', '/apps/spreed/api/' . $apiVersion . '/reaction/' . $token . '/' . $messageId . $reaction); diff --git a/tests/integration/features/chat/notifications.feature b/tests/integration/features/chat/notifications.feature new file mode 100644 index 00000000000..467e421753c --- /dev/null +++ b/tests/integration/features/chat/notifications.feature @@ -0,0 +1,216 @@ +Feature: chat/notifications + + Background: + Given user "participant1" exists + Given user "participant2" exists + + Scenario: Normal message when recipient is online in the one-to-one + When user "participant1" creates room "one-to-one room" (v4) + | roomType | 1 | + | invite | participant2 | + Given user "participant2" joins room "one-to-one room" with 200 (v4) + When user "participant1" sends message "Message 1" to room "one-to-one room" with 201 + Then user "participant2" has the following notifications + | app | object_type | object_id | subject | + + Scenario: Normal message when recipient is offline in the one-to-one + When user "participant1" creates room "one-to-one room" (v4) + | roomType | 1 | + | invite | participant2 | + # Join and leave to clear the invite notification + Given user "participant2" joins room "one-to-one room" with 200 (v4) + Given user "participant2" leaves room "one-to-one room" with 200 (v4) + When user "participant1" sends message "Message 1" to room "one-to-one room" with 201 + Then user "participant2" has the following notifications + | app | object_type | object_id | subject | + | spreed | chat | one-to-one room/Message 1 | participant1-displayname sent you a private message | + + Scenario: Normal message when recipient disabled notifications in the one-to-one + When user "participant1" creates room "one-to-one room" (v4) + | roomType | 1 | + | invite | participant2 | + # Join and leave to clear the invite notification + Given user "participant2" joins room "one-to-one room" with 200 (v4) + Given user "participant2" leaves room "one-to-one room" with 200 (v4) + And user "participant2" sets notifications to disabled for room "one-to-one room" (v4) + When user "participant1" sends message "Message 1" to room "one-to-one room" with 201 + Then user "participant2" has the following notifications + | app | object_type | object_id | subject | + + Scenario: Mention when recipient is online in the one-to-one + When user "participant1" creates room "one-to-one room" (v4) + | roomType | 1 | + | invite | participant2 | + Given user "participant2" joins room "one-to-one room" with 200 (v4) + When user "participant1" sends message "Hi @participant2 bye" to room "one-to-one room" with 201 + Then user "participant2" has the following notifications + | app | object_type | object_id | subject | + | spreed | chat | one-to-one room/Hi @participant2 bye | participant1-displayname mentioned you in a private conversation | + + Scenario: Mention when recipient is offline in the one-to-one + When user "participant1" creates room "one-to-one room" (v4) + | roomType | 1 | + | invite | participant2 | + # Join and leave to clear the invite notification + Given user "participant2" joins room "one-to-one room" with 200 (v4) + Given user "participant2" leaves room "one-to-one room" with 200 (v4) + When user "participant1" sends message "Hi @participant2 bye" to room "one-to-one room" with 201 + Then user "participant2" has the following notifications + | app | object_type | object_id | subject | + | spreed | chat | one-to-one room/Hi @participant2 bye | participant1-displayname mentioned you in a private conversation | + + Scenario: Mention when recipient disabled notifications in the one-to-one + When user "participant1" creates room "one-to-one room" (v4) + | roomType | 1 | + | invite | participant2 | + # Join and leave to clear the invite notification + Given user "participant2" joins room "one-to-one room" with 200 (v4) + Given user "participant2" leaves room "one-to-one room" with 200 (v4) + And user "participant2" sets notifications to disabled for room "one-to-one room" (v4) + When user "participant1" sends message "Hi @participant2 bye" to room "one-to-one room" with 201 + Then user "participant2" has the following notifications + | app | object_type | object_id | subject | + + Scenario: At-all when recipient is online in the one-to-one + When user "participant1" creates room "one-to-one room" (v4) + | roomType | 1 | + | invite | participant2 | + Given user "participant2" joins room "one-to-one room" with 200 (v4) + When user "participant1" sends message "Hi @all bye" to room "one-to-one room" with 201 + Then user "participant2" has the following notifications + | app | object_type | object_id | subject | + | spreed | chat | one-to-one room/Hi @all bye | participant1-displayname mentioned you in a private conversation | + + Scenario: At-all when recipient is offline in the one-to-one + When user "participant1" creates room "one-to-one room" (v4) + | roomType | 1 | + | invite | participant2 | + # Join and leave to clear the invite notification + Given user "participant2" joins room "one-to-one room" with 200 (v4) + Given user "participant2" leaves room "one-to-one room" with 200 (v4) + When user "participant1" sends message "Hi @all bye" to room "one-to-one room" with 201 + Then user "participant2" has the following notifications + | app | object_type | object_id | subject | + | spreed | chat | one-to-one room/Hi @all bye | participant1-displayname mentioned you in a private conversation | + + Scenario: At-all when recipient disabled notifications in the one-to-one + When user "participant1" creates room "one-to-one room" (v4) + | roomType | 1 | + | invite | participant2 | + # Join and leave to clear the invite notification + Given user "participant2" joins room "one-to-one room" with 200 (v4) + Given user "participant2" leaves room "one-to-one room" with 200 (v4) + And user "participant2" sets notifications to disabled for room "one-to-one room" (v4) + When user "participant1" sends message "Hi @all bye" to room "one-to-one room" with 201 + Then user "participant2" has the following notifications + | app | object_type | object_id | subject | + + Scenario: Normal message when recipient is online in the group room + When user "participant1" creates room "room" (v4) + | roomType | 2 | + | roomName | room | + And user "participant1" adds user "participant2" to room "room" with 200 (v4) + Given user "participant2" joins room "room" with 200 (v4) + When user "participant1" sends message "Message 1" to room "room" with 201 + Then user "participant2" has the following notifications + | app | object_type | object_id | subject | + + Scenario: Normal message when recipient is offline in the group room + When user "participant1" creates room "room" (v4) + | roomType | 2 | + | roomName | room | + And user "participant1" adds user "participant2" to room "room" with 200 (v4) + # Join and leave to clear the invite notification + Given user "participant2" joins room "room" with 200 (v4) + Given user "participant2" leaves room "room" with 200 (v4) + When user "participant1" sends message "Message 1" to room "room" with 201 + Then user "participant2" has the following notifications + | app | object_type | object_id | subject | + + Scenario: Normal message when recipient with all notifications in the group room + When user "participant1" creates room "room" (v4) + | roomType | 2 | + | roomName | room | + And user "participant1" adds user "participant2" to room "room" with 200 (v4) + # Join and leave to clear the invite notification + Given user "participant2" joins room "room" with 200 (v4) + Given user "participant2" leaves room "room" with 200 (v4) + And user "participant2" sets notifications to all for room "room" (v4) + When user "participant1" sends message "Message 1" to room "room" with 201 + Then user "participant2" has the following notifications + | app | object_type | object_id | subject | + | spreed | chat | room/Message 1 | participant1-displayname sent a message in conversation room | + + Scenario: Mention when recipient is online in the group room + When user "participant1" creates room "room" (v4) + | roomType | 2 | + | roomName | room | + And user "participant1" adds user "participant2" to room "room" with 200 (v4) + Given user "participant2" joins room "room" with 200 (v4) + When user "participant1" sends message "Hi @participant2 bye" to room "room" with 201 + Then user "participant2" has the following notifications + | app | object_type | object_id | subject | + | spreed | chat | room/Hi @participant2 bye | participant1-displayname mentioned you in conversation room | + + Scenario: Mention when recipient is offline in the group room + When user "participant1" creates room "room" (v4) + | roomType | 2 | + | roomName | room | + And user "participant1" adds user "participant2" to room "room" with 200 (v4) + # Join and leave to clear the invite notification + Given user "participant2" joins room "room" with 200 (v4) + Given user "participant2" leaves room "room" with 200 (v4) + When user "participant1" sends message "Hi @participant2 bye" to room "room" with 201 + Then user "participant2" has the following notifications + | app | object_type | object_id | subject | + | spreed | chat | room/Hi @participant2 bye | participant1-displayname mentioned you in conversation room | + + Scenario: Mention when recipient with disabled notifications in the group room + When user "participant1" creates room "room" (v4) + | roomType | 2 | + | roomName | room | + And user "participant1" adds user "participant2" to room "room" with 200 (v4) + # Join and leave to clear the invite notification + Given user "participant2" joins room "room" with 200 (v4) + Given user "participant2" leaves room "room" with 200 (v4) + And user "participant2" sets notifications to disabled for room "room" (v4) + When user "participant1" sends message "Hi @participant2 bye" to room "room" with 201 + Then user "participant2" has the following notifications + | app | object_type | object_id | subject | + + Scenario: At-all when recipient is online in the group room + When user "participant1" creates room "room" (v4) + | roomType | 2 | + | roomName | room | + And user "participant1" adds user "participant2" to room "room" with 200 (v4) + Given user "participant2" joins room "room" with 200 (v4) + When user "participant1" sends message "Hi @all bye" to room "room" with 201 + Then user "participant2" has the following notifications + | app | object_type | object_id | subject | + | spreed | chat | room/Hi @all bye | participant1-displayname mentioned you in conversation room | + + Scenario: At-all when recipient is offline in the group room + When user "participant1" creates room "room" (v4) + | roomType | 2 | + | roomName | room | + And user "participant1" adds user "participant2" to room "room" with 200 (v4) + # Join and leave to clear the invite notification + Given user "participant2" joins room "room" with 200 (v4) + Given user "participant2" leaves room "room" with 200 (v4) + When user "participant1" sends message "Hi @all bye" to room "room" with 201 + Then user "participant2" has the following notifications + | app | object_type | object_id | subject | + | spreed | chat | room/Hi @all bye | participant1-displayname mentioned you in conversation room | + + Scenario: At-all when recipient with disabled notifications in the group room + When user "participant1" creates room "room" (v4) + | roomType | 2 | + | roomName | room | + And user "participant1" adds user "participant2" to room "room" with 200 (v4) + # Join and leave to clear the invite notification + Given user "participant2" joins room "room" with 200 (v4) + Given user "participant2" leaves room "room" with 200 (v4) + And user "participant2" sets notifications to disabled for room "room" (v4) + When user "participant1" sends message "Hi @all bye" to room "room" with 201 + Then user "participant2" has the following notifications + | app | object_type | object_id | subject | diff --git a/tests/integration/features/conversation/add-participant.feature b/tests/integration/features/conversation/add-participant.feature index 81e340c598b..eb2051e7bcc 100644 --- a/tests/integration/features/conversation/add-participant.feature +++ b/tests/integration/features/conversation/add-participant.feature @@ -15,6 +15,9 @@ Feature: public And user "participant2" is participant of the following rooms (v4) | id | type | participantType | | room | 3 | 3 | + Then user "participant2" has the following notifications + | app | object_type | object_id | subject | + | spreed | room | room | participant1-displayname invited you to a group conversation: room | And user "participant3" is not participant of room "room" (v4) And user "participant1" sees the following attendees in room "room" with 200 (v4) | actorType | actorId | participantType | @@ -34,6 +37,8 @@ Feature: public | room | 3 | 3 | And user "participant3" is not participant of room "room" (v4) When user "participant2" adds user "participant3" to room "room" with 403 (v4) + Then user "participant3" has the following notifications + | app | object_type | object_id | subject | And user "participant3" is not participant of room "room" (v4) And user "participant1" sees the following attendees in room "room" with 200 (v4) | actorType | actorId | participantType | @@ -54,6 +59,9 @@ Feature: public | room | 3 | 2 | And user "participant3" is not participant of room "room" (v4) When user "participant2" adds user "participant3" to room "room" with 200 (v4) + Then user "participant3" has the following notifications + | app | object_type | object_id | subject | + | spreed | room | room | participant2-displayname invited you to a group conversation: room | Then user "participant1" is participant of the following rooms (v4) | id | type | participantType | | room | 3 | 1 | @@ -79,6 +87,8 @@ Feature: public | users | participant1 | 1 | | users | participant2 | 5 | When user "participant1" adds user "participant2" to room "room" with 200 (v4) + Then user "participant2" has the following notifications + | app | object_type | object_id | subject | Then user "participant2" is participant of the following rooms (v4) | id | type | participantType | | room | 3 | 3 | @@ -98,6 +108,8 @@ Feature: public # participant3 already present, so it will be skipped And user "participant1" adds user "participant3" to room "room" with 200 (v4) When user "participant1" adds group "group1" to room "room" with 200 (v4) + Then user "participant2" has the following notifications + | app | object_type | object_id | subject | Then user "participant2" is participant of the following rooms (v4) | id | type | participantType | | room | 3 | 3 | diff --git a/tests/integration/run.sh b/tests/integration/run.sh index 51e1e72af42..ce3ebd25e0f 100755 --- a/tests/integration/run.sh +++ b/tests/integration/run.sh @@ -1,39 +1,79 @@ #!/usr/bin/env bash APP_NAME=spreed +NOTIFICATIONS_BRANCH="master" +GUESTS_BRANCH="master" APP_INTEGRATION_DIR=$PWD ROOT_DIR=${APP_INTEGRATION_DIR}/../../../.. +echo '' +echo '#' +echo '# Installing composer dependencies from tests/integration/' +echo '#' composer install +echo '' +echo '#' +echo '# Starting PHP webserver' +echo '#' php -S localhost:8080 -t ${ROOT_DIR} & PHPPID=$! +echo 'Running on process ID:' echo $PHPPID +# also kill php process in case of ctrl+c +trap 'kill -TERM $PHPPID; wait $PHPPID' TERM + # The federated server is started and stopped by the tests themselves PORT_FED=8180 export PORT_FED NEXTCLOUD_ROOT_DIR=${ROOT_DIR} export NEXTCLOUD_ROOT_DIR +export TEST_SERVER_URL="http://localhost:8080/" +export TEST_REMOTE_URL="http://localhost:8180/" -# also kill php process in case of ctrl+c -trap 'kill -TERM $PHPPID; wait $PHPPID' TERM - +echo '' +echo '#' +echo '# Setting up apps' +echo '#' cp -R ./spreedcheats ../../../spreedcheats +${ROOT_DIR}/occ app:getpath spreedcheats + +# Add apps to the parent directory of "spreed" (unless they are +# already there or in "apps"). +${ROOT_DIR}/occ app:getpath notifications || (cd ../../../ && git clone --depth 1 --branch ${NOTIFICATIONS_BRANCH} https://github.com/nextcloud/notifications) +${ROOT_DIR}/occ app:getpath guests || (cd ../../../ && git clone --depth 1 --branch ${GUESTS_BRANCH} https://github.com/nextcloud/guests) + ${ROOT_DIR}/occ app:enable spreed || exit 1 ${ROOT_DIR}/occ app:enable spreedcheats || exit 1 +${ROOT_DIR}/occ app:enable notifications || exit 1 +${ROOT_DIR}/occ app:enable guests || exit 1 + ${ROOT_DIR}/occ app:list | grep spreed +${ROOT_DIR}/occ app:list | grep notifications +${ROOT_DIR}/occ app:list | grep guests +echo '' +echo '#' +echo '# Optimizing configuration' +echo '#' # Disable bruteforce protection because the integration tests do trigger them ${ROOT_DIR}/occ config:system:set auth.bruteforce.protection.enabled --value false --type bool # Allow local remote urls otherwise we can not share ${ROOT_DIR}/occ config:system:set allow_local_remote_servers --value true --type bool -export TEST_SERVER_URL="http://localhost:8080/" -export TEST_REMOTE_URL="http://localhost:8180/" + +echo '' +echo '#' +echo '# Running tests' +echo '#' ${APP_INTEGRATION_DIR}/vendor/bin/behat -f junit -f pretty $1 $2 RESULT=$? +echo '' +echo '#' +echo '# Stopping PHP webserver and disabling spreedcheats' +echo '#' kill $PHPPID ${ROOT_DIR}/occ app:disable spreedcheats diff --git a/tests/integration/spreedcheats/lib/Controller/ApiController.php b/tests/integration/spreedcheats/lib/Controller/ApiController.php index 712041f159e..3145407b3b2 100644 --- a/tests/integration/spreedcheats/lib/Controller/ApiController.php +++ b/tests/integration/spreedcheats/lib/Controller/ApiController.php @@ -85,6 +85,15 @@ public function resetSpreed(): DataResponse { )) ->executeStatement(); + try { + $delete = $this->db->getQueryBuilder(); + $delete->delete('notifications') + ->where($delete->expr()->eq('app', $delete->createNamedParameter('spreed'))) + ->executeStatement(); + } catch (\Throwable $e) { + // Ignore + } + return new DataResponse(); } }