diff options
author | Christoph Wurst <christoph@winzerhof-wurst.at> | 2020-07-14 17:30:50 +0300 |
---|---|---|
committer | Christoph Wurst <christoph@winzerhof-wurst.at> | 2020-07-17 19:44:36 +0300 |
commit | 24d268d1073e09ac7dedd8a7c71da2c3f4e76a85 (patch) | |
tree | 77b8a0f2d12622f29eb0c51e63b7b24101222cfa | |
parent | e380adfc02d1cbec1bc88c68327be713b026adbc (diff) |
Add a REST resource to fetch a thread
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
-rw-r--r-- | appinfo/routes.php | 5 | ||||
-rw-r--r-- | lib/Contracts/IMailManager.php | 8 | ||||
-rwxr-xr-x | lib/Controller/MessagesController.php | 17 | ||||
-rw-r--r-- | lib/Db/MessageMapper.php | 35 | ||||
-rw-r--r-- | lib/Service/MailManager.php | 36 | ||||
-rw-r--r-- | tests/Unit/Service/MailManagerTest.php | 38 |
6 files changed, 115 insertions, 24 deletions
diff --git a/appinfo/routes.php b/appinfo/routes.php index 29ce1186d..766f7e683 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -105,6 +105,11 @@ return [ 'verb' => 'GET' ], [ + 'name' => 'messages#getThread', + 'url' => '/api/accounts/{accountId}/message/{id}/thread', + 'verb' => 'GET' + ], + [ 'name' => 'messages#setFlags', 'url' => '/api/accounts/{accountId}/folders/{folderId}/messages/{messageId}/flags', 'verb' => 'PUT' diff --git a/lib/Contracts/IMailManager.php b/lib/Contracts/IMailManager.php index ed740a9cc..f77018fd8 100644 --- a/lib/Contracts/IMailManager.php +++ b/lib/Contracts/IMailManager.php @@ -86,6 +86,14 @@ interface IMailManager { public function getMessage(Account $account, string $mailbox, int $id, bool $loadBody = false): IMAPMessage; /** + * @param Account $account + * @param int $messageId database message ID + * + * @return IMAPMessage[] + */ + public function getThread(Account $account, int $messageId): array; + + /** * @param Account $sourceAccount * @param string $sourceFolderId * @param int $messageId diff --git a/lib/Controller/MessagesController.php b/lib/Controller/MessagesController.php index 7e813bbe6..ef6357835 100755 --- a/lib/Controller/MessagesController.php +++ b/lib/Controller/MessagesController.php @@ -236,6 +236,23 @@ class MessagesController extends Controller { /** * @NoAdminRequired + * @NoCSRFRequired + * @TrapError + * + * @param int $accountId + * @param string $folderId + * + * @return JSONResponse + * @throws ClientException + */ + public function getThread(int $accountId, int $id): JSONResponse { + $account = $this->accountService->find($this->currentUserId, $accountId); + + return new JSONResponse($this->mailManager->getThread($account, $id)); + } + + /** + * @NoAdminRequired * @TrapError * * @param int $accountId diff --git a/lib/Db/MessageMapper.php b/lib/Db/MessageMapper.php index a6e3438fb..e6593bb8c 100644 --- a/lib/Db/MessageMapper.php +++ b/lib/Db/MessageMapper.php @@ -340,6 +340,41 @@ class MessageMapper extends QBMapper { } /** + * @param Account $account + * @param int $messageId + * + * @return Message[] + */ + public function findThread(Account $account, int $messageId): array { + $qb = $this->db->getQueryBuilder(); + $subQb1 = $this->db->getQueryBuilder(); + $subQb2 = $this->db->getQueryBuilder(); + + $mailboxIdsQuery = $subQb1 + ->select('id') + ->from('mail_mailboxes') + ->where($qb->expr()->eq('account_id', $qb->createNamedParameter($account->getId(), IQueryBuilder::PARAM_INT))); + $threadRootIdsQuery = $subQb2 + ->select('thread_root_id') + ->from($this->getTableName()) + ->where( + $qb->expr()->eq('id', $qb->createNamedParameter($messageId, IQueryBuilder::PARAM_INT), IQueryBuilder::PARAM_INT) + ); + + $selectMessages = $qb + ->select('*') + ->from($this->getTableName()) + ->where( + $qb->expr()->isNotNull('thread_root_id'), + $qb->expr()->in('thread_root_id', $qb->createFunction($threadRootIdsQuery->getSQL()), IQueryBuilder::PARAM_INT_ARRAY), + $qb->expr()->in('mailbox_id', $qb->createFunction($mailboxIdsQuery->getSQL()), IQueryBuilder::PARAM_INT_ARRAY) + ) + ->orderBy('sent_at', 'desc'); + + return $this->findRecipients($this->findEntities($selectMessages)); + } + + /** * @param Mailbox $mailbox * @param SearchQuery $query * @param int|null $limit diff --git a/lib/Service/MailManager.php b/lib/Service/MailManager.php index b1a1ceec4..dc3e66784 100644 --- a/lib/Service/MailManager.php +++ b/lib/Service/MailManager.php @@ -30,6 +30,7 @@ use OCA\Mail\Account; use OCA\Mail\Contracts\IMailManager; use OCA\Mail\Db\Mailbox; use OCA\Mail\Db\MailboxMapper; +use OCA\Mail\Db\MessageMapper as DbMessageMapper; use OCA\Mail\Events\BeforeMessageDeletedEvent; use OCA\Mail\Events\MessageDeletedEvent; use OCA\Mail\Events\MessageFlaggedEvent; @@ -40,7 +41,7 @@ use OCA\Mail\IMAP\FolderMapper; use OCA\Mail\IMAP\FolderStats; use OCA\Mail\IMAP\IMAPClientFactory; use OCA\Mail\IMAP\MailboxSync; -use OCA\Mail\IMAP\MessageMapper; +use OCA\Mail\IMAP\MessageMapper as ImapMessageMapper; use OCA\Mail\Model\IMAPMessage; use OCP\AppFramework\Db\DoesNotExistException; use OCP\EventDispatcher\IEventDispatcher; @@ -74,8 +75,11 @@ class MailManager implements IMailManager { /** @var FolderMapper */ private $folderMapper; - /** @var MessageMapper */ - private $messageMapper; + /** @var ImapMessageMapper */ + private $imapMessageMapper; + + /** @var DbMessageMapper */ + private $dbMessageMapper; /** @var IEventDispatcher */ private $eventDispatcher; @@ -84,13 +88,15 @@ class MailManager implements IMailManager { MailboxMapper $mailboxMapper, MailboxSync $mailboxSync, FolderMapper $folderMapper, - MessageMapper $messageMapper, + ImapMessageMapper $messageMapper, + DbMessageMapper $dbMessageMapper, IEventDispatcher $eventDispatcher) { $this->imapClientFactory = $imapClientFactory; $this->mailboxMapper = $mailboxMapper; $this->mailboxSync = $mailboxSync; $this->folderMapper = $folderMapper; - $this->messageMapper = $messageMapper; + $this->imapMessageMapper = $messageMapper; + $this->dbMessageMapper = $dbMessageMapper; $this->eventDispatcher = $eventDispatcher; } @@ -151,7 +157,7 @@ class MailManager implements IMailManager { $mailbox = $this->mailboxMapper->find($account, $mailbox); try { - return $this->messageMapper->find( + return $this->imapMessageMapper->find( $client, $mailbox->getName(), $id, @@ -162,6 +168,10 @@ class MailManager implements IMailManager { } } + public function getThread(Account $account, int $messageId): array { + return $this->dbMessageMapper->findThread($account, $messageId); + } + /** * @param Account $account * @param string $mb @@ -176,7 +186,7 @@ class MailManager implements IMailManager { $client = $this->imapClientFactory->getClient($account); try { - return $this->messageMapper->getSource( + return $this->imapMessageMapper->getSource( $client, $mailbox, $id @@ -240,13 +250,13 @@ class MailManager implements IMailManager { if ($mailboxId === $trashMailbox->getName()) { // Delete inside trash -> expunge - $this->messageMapper->expunge( + $this->imapMessageMapper->expunge( $this->imapClientFactory->getClient($account), $sourceMailbox->getName(), $messageId ); } else { - $this->messageMapper->move( + $this->imapMessageMapper->move( $this->imapClientFactory->getClient($account), $sourceMailbox->getName(), $messageId, @@ -276,13 +286,13 @@ class MailManager implements IMailManager { int $messageId): void { $client = $this->imapClientFactory->getClient($account); - $this->messageMapper->move($client, $sourceFolderId, $messageId, $destFolderId); + $this->imapMessageMapper->move($client, $sourceFolderId, $messageId, $destFolderId); } public function markFolderAsRead(Account $account, string $folderId): void { $client = $this->imapClientFactory->getClient($account); - $this->messageMapper->markAllRead($client, $folderId); + $this->imapMessageMapper->markAllRead($client, $folderId); } public function flagMessage(Account $account, string $mailbox, int $uid, string $flag, bool $value): void { @@ -298,9 +308,9 @@ class MailManager implements IMailManager { try { foreach ($imapFlags as $imapFlag) { if ($value) { - $this->messageMapper->addFlag($client, $mb, $uid, $imapFlag); + $this->imapMessageMapper->addFlag($client, $mb, $uid, $imapFlag); } else { - $this->messageMapper->removeFlag($client, $mb, $uid, $imapFlag); + $this->imapMessageMapper->removeFlag($client, $mb, $uid, $imapFlag); } } } catch (Horde_Imap_Client_Exception $e) { diff --git a/tests/Unit/Service/MailManagerTest.php b/tests/Unit/Service/MailManagerTest.php index 6993a1fd1..720d10434 100644 --- a/tests/Unit/Service/MailManagerTest.php +++ b/tests/Unit/Service/MailManagerTest.php @@ -28,6 +28,7 @@ use Horde_Imap_Client_Socket; use OCA\Mail\Account; use OCA\Mail\Db\Mailbox; use OCA\Mail\Db\MailboxMapper; +use OCA\Mail\Db\MessageMapper as DbMessageMapper; use OCA\Mail\Events\BeforeMessageDeletedEvent; use OCA\Mail\Exception\ServiceException; use OCA\Mail\Folder; @@ -35,7 +36,7 @@ use OCA\Mail\IMAP\FolderMapper; use OCA\Mail\IMAP\FolderStats; use OCA\Mail\IMAP\IMAPClientFactory; use OCA\Mail\IMAP\MailboxSync; -use OCA\Mail\IMAP\MessageMapper; +use OCA\Mail\IMAP\MessageMapper as ImapMessageMapper; use OCA\Mail\Service\MailManager; use OCP\AppFramework\Db\DoesNotExistException; use OCP\EventDispatcher\IEventDispatcher; @@ -55,8 +56,11 @@ class MailManagerTest extends TestCase { /** @var FolderMapper|MockObject */ private $folderMapper; - /** @var MessageMapper|MockObject */ - private $messageMapper; + /** @var ImapMessageMapper|MockObject */ + private $imapMessageMapper; + + /** @var DbMessageMapper|MockObject */ + private $dbMessageMapper; /** @var IEventDispatcher|MockObject */ private $eventDispatcher; @@ -70,7 +74,8 @@ class MailManagerTest extends TestCase { $this->imapClientFactory = $this->createMock(IMAPClientFactory::class); $this->mailboxMapper = $this->createMock(MailboxMapper::class); $this->folderMapper = $this->createMock(FolderMapper::class); - $this->messageMapper = $this->createMock(MessageMapper::class); + $this->imapMessageMapper = $this->createMock(ImapMessageMapper::class); + $this->dbMessageMapper = $this->createMock(DbMessageMapper::class); $this->mailboxSync = $this->createMock(MailboxSync::class); $this->eventDispatcher = $this->createMock(IEventDispatcher::class); @@ -79,7 +84,8 @@ class MailManagerTest extends TestCase { $this->mailboxMapper, $this->mailboxSync, $this->folderMapper, - $this->messageMapper, + $this->imapMessageMapper, + $this->dbMessageMapper, $this->eventDispatcher ); } @@ -219,7 +225,7 @@ class MailManagerTest extends TestCase { $this->imapClientFactory->expects($this->once()) ->method('getClient') ->willReturn($client); - $this->messageMapper->expects($this->once()) + $this->imapMessageMapper->expects($this->once()) ->method('move') ->with( $client, @@ -256,7 +262,7 @@ class MailManagerTest extends TestCase { $this->imapClientFactory->expects($this->once()) ->method('getClient') ->willReturn($client); - $this->messageMapper->expects($this->once()) + $this->imapMessageMapper->expects($this->once()) ->method('expunge') ->with( $client, @@ -277,9 +283,9 @@ class MailManagerTest extends TestCase { $this->imapClientFactory->expects($this->once()) ->method('getClient') ->willReturn($client); - $this->messageMapper->expects($this->never()) + $this->imapMessageMapper->expects($this->never()) ->method('addFlag'); - $this->messageMapper->expects($this->never()) + $this->imapMessageMapper->expects($this->never()) ->method('removeFlag'); $this->manager->flagMessage($account, 'INBOX', 123, 'important', true); @@ -296,12 +302,22 @@ class MailManagerTest extends TestCase { ->method('find') ->with($account, 'INBOX') ->willReturn($mb); - $this->messageMapper->expects($this->never()) + $this->imapMessageMapper->expects($this->never()) ->method('addFlag'); - $this->messageMapper->expects($this->once()) + $this->imapMessageMapper->expects($this->once()) ->method('removeFlag') ->with($client, $mb, 123, '\\seen'); $this->manager->flagMessage($account, 'INBOX', 123, 'seen', false); } + + public function testGetThread(): void { + $account = $this->createMock(Account::class); + $messageId = 123; + $this->dbMessageMapper->expects($this->once()) + ->method('findThread') + ->with($account, $messageId); + + $this->manager->getThread($account, $messageId); + } } |