diff options
-rw-r--r-- | appinfo/info.xml | 1 | ||||
-rw-r--r-- | lib/Command/Developer/AgeChatMessages.php | 112 | ||||
-rw-r--r-- | lib/Command/Developer/UpdateDocs.php | 3 | ||||
-rw-r--r-- | tests/integration/features/bootstrap/FeatureContext.php | 21 | ||||
-rw-r--r-- | tests/integration/features/chat-1/edit-message.feature | 5 |
5 files changed, 138 insertions, 4 deletions
diff --git a/appinfo/info.xml b/appinfo/info.xml index dd5894a1c..e654fdf92 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -87,6 +87,7 @@ <command>OCA\Talk\Command\Bot\State</command> <command>OCA\Talk\Command\Bot\Setup</command> <command>OCA\Talk\Command\Bot\Uninstall</command> + <command>OCA\Talk\Command\Developer\AgeChatMessages</command> <command>OCA\Talk\Command\Developer\UpdateDocs</command> <command>OCA\Talk\Command\Monitor\Calls</command> <command>OCA\Talk\Command\Monitor\HasActiveCalls</command> diff --git a/lib/Command/Developer/AgeChatMessages.php b/lib/Command/Developer/AgeChatMessages.php new file mode 100644 index 000000000..345ed0b09 --- /dev/null +++ b/lib/Command/Developer/AgeChatMessages.php @@ -0,0 +1,112 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCA\Talk\Command\Developer; + +use OC\Core\Command\Base; +use OCA\Talk\Exceptions\RoomNotFoundException; +use OCA\Talk\Manager; +use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\IConfig; +use OCP\IDBConnection; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +class AgeChatMessages extends Base { + public function __construct( + private readonly IConfig $config, + private readonly IDBConnection $connection, + private readonly Manager $manager, + ) { + parent::__construct(); + } + + public function isEnabled(): bool { + return $this->config->getSystemValue('debug', false) === true; + } + + protected function configure(): void { + $this + ->setName('talk:developer:age-chat-messages') + ->setDescription('Artificially ages chat messages in the given conversation, so deletion and other things can be tested') + ->addArgument( + 'token', + InputArgument::REQUIRED, + 'Token of the room to manipulate' + ) + ->addOption( + 'hours', + null, + InputOption::VALUE_REQUIRED, + 'Number of hours to age all chat messages', + 24 + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output): int { + $token = $input->getArgument('token'); + $hours = (int) $input->getOption('hours'); + if ($hours < 1) { + $output->writeln('<error>Invalid age: ' . $hours . '</error>'); + return 1; + } + + try { + $room = $this->manager->getRoomByToken($token); + } catch (RoomNotFoundException) { + $output->writeln('<error>Room not found: ' . $token . '</error>'); + return 1; + } + + $update = $this->connection->getQueryBuilder(); + $update->update('comments') + ->set('creation_timestamp', $update->createParameter('creation_timestamp')) + ->set('expire_date', $update->createParameter('expire_date')) + ->set('meta_data', $update->createParameter('meta_data')) + ->where($update->expr()->eq('id', $update->createParameter('id'))); + + $query = $this->connection->getQueryBuilder(); + $query->select('id', 'creation_timestamp', 'expire_date', 'meta_data') + ->from('comments') + ->where($query->expr()->eq('object_type', $query->createNamedParameter('chat'))) + ->andWhere($query->expr()->eq('object_id', $query->createNamedParameter($room->getId()))); + + $result = $query->executeQuery(); + while ($row = $result->fetch()) { + $creationTimestamp = new \DateTime($row['creation_timestamp']); + $creationTimestamp->sub(new \DateInterval('PT' . $hours . 'H')); + + $expireDate = null; + if ($row['expire_date']) { + $expireDate = new \DateTime($row['expire_date']); + $expireDate->sub(new \DateInterval('PT' . $hours . 'H')); + } + + $metaData = 'null'; + if ($row['meta_data'] !== 'null') { + $metaData = json_decode($row['meta_data'], true); + if (isset($metaData['last_edited_time'])) { + $metaData['last_edited_time'] -= $hours * 3600; + } + $metaData = json_encode($metaData); + } + + $update->setParameter('id', $row['id']); + $update->setParameter('creation_timestamp', $creationTimestamp, IQueryBuilder::PARAM_DATE); + $update->setParameter('expire_date', $expireDate, IQueryBuilder::PARAM_DATE); + $update->setParameter('meta_data', $metaData); + $update->executeStatement(); + } + $result->closeCursor(); + + return 0; + } +} diff --git a/lib/Command/Developer/UpdateDocs.php b/lib/Command/Developer/UpdateDocs.php index f1f469e83..17133498d 100644 --- a/lib/Command/Developer/UpdateDocs.php +++ b/lib/Command/Developer/UpdateDocs.php @@ -41,7 +41,8 @@ class UpdateDocs extends Base { $info = $this->appManager->getAppInfo('spreed'); $documentation = "# Talk occ commands\n\n"; foreach ($info['commands'] as $namespace) { - if ($namespace === self::class) { + if ($namespace === self::class + || $namespace === AgeChatMessages::class) { continue; } diff --git a/tests/integration/features/bootstrap/FeatureContext.php b/tests/integration/features/bootstrap/FeatureContext.php index c90a9711b..8d1a25907 100644 --- a/tests/integration/features/bootstrap/FeatureContext.php +++ b/tests/integration/features/bootstrap/FeatureContext.php @@ -2004,7 +2004,7 @@ class FeatureContext implements Context, SnippetAcceptingContext { * @param string $statusCode * @param string $apiVersion */ - public function userEditsMessageToRoom(string $user, string $oldMessage, string $identifier, string $newMessage, string $statusCode, string $apiVersion = 'v1') { + public function userEditsMessageToRoom(string $user, string $oldMessage, string $identifier, string $newMessage, int $statusCode, string $apiVersion = 'v1', ?TableNode $formData = null) { $oldMessage = substr($oldMessage, 1, -1); $oldMessage = str_replace('\n', "\n", $oldMessage); $messageId = self::$textToMessageId[$oldMessage]; @@ -2020,8 +2020,15 @@ class FeatureContext implements Context, SnippetAcceptingContext { $this->assertStatusCode($this->response, $statusCode); sleep(1); // make sure Postgres manages the order of the messages - self::$textToMessageId[$newMessage] = $messageId; - self::$messageIdToText[$messageId] = $newMessage; + if ($statusCode === 200 || $statusCode === 202) { + self::$textToMessageId[$newMessage] = $messageId; + self::$messageIdToText[$messageId] = $newMessage; + } elseif ($formData instanceof TableNode) { + Assert::assertEquals( + $formData->getRowsHash(), + $this->getDataFromResponse($this->response), + ); + } } /** @@ -3877,6 +3884,14 @@ class FeatureContext implements Context, SnippetAcceptingContext { } /** + * @Given /^aging messages (\d+) hours in room "([^"]*)"$/ + */ + public function occAgeChatMessages(int $hours, string $identifier): void { + $this->runOcc(['talk:developer:age-chat-messages', '--hours', $hours, self::$identifierToToken[$identifier]]); + $this->theCommandWasSuccessful(); + } + + /** * @Given /^the following recording consent is recorded for (room|user) "([^"]*)"$/ */ public function occRecordingConsentLists(string $filterType, string $identifier, TableNode $tableNode): void { diff --git a/tests/integration/features/chat-1/edit-message.feature b/tests/integration/features/chat-1/edit-message.feature index 8d54e8a05..c6a1a7955 100644 --- a/tests/integration/features/chat-1/edit-message.feature +++ b/tests/integration/features/chat-1/edit-message.feature @@ -58,6 +58,11 @@ Feature: chat-1/edit-message Then user "participant1" sees the following messages in room "room" with 200 | room | actorType | actorId | actorDisplayName | message | messageParameters | parentMessage | lastEditActorType | lastEditActorId | lastEditActorDisplayName | | room | deleted_users | deleted_users | | Message 1 - Edit 2 | [] | | deleted_users | deleted_users | | + When aging messages 6 hours in room "room" + And user "participant1" edits message "Message 1 - Edit 1" in room "room" to "Message 1 - Edit 2" with 200 + When aging messages 24 hours in room "room" + And user "participant1" edits message "Message 1 - Edit 2" in room "room" to "Message 1 - Edit Too old" with 400 + | error | age | Scenario: Editing a caption Given user "participant1" creates room "room" (v4) |