diff options
author | Anna Larch <anna@nextcloud.com> | 2021-05-06 23:36:20 +0300 |
---|---|---|
committer | Anna Larch <anna@nextcloud.com> | 2021-05-26 16:38:18 +0300 |
commit | 540ca4b1ef164f1a05e8c4f457ed8aca7ccebabd (patch) | |
tree | 20a536d98ca52f81010478c620208a2cbe5e6b90 /tests | |
parent | 4f5692a41c64d7878c9e6a167c72665cf70b8a33 (diff) |
Add bg job for label sync
Signed-off-by: Anna Larch <anna@nextcloud.com>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Integration/Framework/ImapTest.php | 2 | ||||
-rw-r--r-- | tests/Integration/IMAP/MessageMapperTest.php | 203 | ||||
-rw-r--r-- | tests/Integration/Migration/MigrateImportantFromImapAndDbTest.php | 239 | ||||
-rw-r--r-- | tests/Unit/IMAP/MessageMapperTest.php | 65 | ||||
-rw-r--r-- | tests/Unit/Job/TestMigrateImportantJob.php | 322 | ||||
-rw-r--r-- | tests/Unit/Listener/DeleteDraftListenerTest.php | 2 | ||||
-rw-r--r-- | tests/Unit/Listener/FlagRepliedMessageListenerTest.php | 2 | ||||
-rw-r--r-- | tests/Unit/Migration/MigrateImportantFromImapAndDbTest.php | 239 | ||||
-rw-r--r-- | tests/Unit/Service/MailManagerTest.php | 6 |
9 files changed, 1075 insertions, 5 deletions
diff --git a/tests/Integration/Framework/ImapTest.php b/tests/Integration/Framework/ImapTest.php index c0b252fb1..1a68ad415 100644 --- a/tests/Integration/Framework/ImapTest.php +++ b/tests/Integration/Framework/ImapTest.php @@ -27,6 +27,7 @@ use Horde_Imap_Client_Fetch_Query; use Horde_Imap_Client_Ids; use Horde_Imap_Client_Socket; use Horde_Mail_Rfc822_Address; +use Horde_Mime_Headers_MessageId; use Horde_Mime_Mail; use Horde_Mime_Part; use OCA\Mail\Account; @@ -145,6 +146,7 @@ trait ImapTest { $mail = new Horde_Mime_Mail(); $mail->addHeaders($headers); + $mail->addHeaderOb(Horde_Mime_Headers_MessageId::create()); $body = new Horde_Mime_Part(); $body->setType('text/plain'); $body->setContents($message->getBody()); diff --git a/tests/Integration/IMAP/MessageMapperTest.php b/tests/Integration/IMAP/MessageMapperTest.php new file mode 100644 index 000000000..c1faa022c --- /dev/null +++ b/tests/Integration/IMAP/MessageMapperTest.php @@ -0,0 +1,203 @@ +<?php + +declare(strict_types=1); + +/** + * @author Anna Larch <anna.larch@nextcloud.com> + * + * Mail + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace OCA\Mail\Tests\Integration\IMAP; + +use ChristophWurst\Nextcloud\Testing\TestCase; +use Horde_Imap_Client; +use Horde_Imap_Client_Exception; +use OC; +use OCA\Mail\Account; +use OCA\Mail\Contracts\IMailManager; +use OCA\Mail\IMAP\MessageMapper as ImapMessageMapper; +use OCA\Mail\Db\MessageMapper; +use OCA\Mail\Service\Sync\SyncService; +use OCA\Mail\Tests\Integration\Framework\ImapTest; +use OCA\Mail\Tests\Integration\Framework\ImapTestAccount; + +class MessageMapperTest extends TestCase { + use ImapTest, + ImapTestAccount; + + public function setUp():void { + parent::setUp(); + } + + public function testTagging() { + // First, set up account and retrieve sync token + $this->resetImapAccount(); + + $account = $this->createTestAccount(); + /** @var SyncService $syncService */ + $syncService = OC::$server->query(SyncService::class); + /** @var ImapMessageMapper $messageMapper */ + $imapMessageMapper = OC::$server->query(ImapMessageMapper::class); + /** @var MessageMapper $messageMapper */ + $messageMapper = OC::$server->query(MessageMapper::class); + /** @var IMailManager $mailManager */ + $mailManager = OC::$server->query(IMailManager::class); + $mailBoxes = $mailManager->getMailboxes(new Account($account)); + $inbox = null; + foreach ($mailBoxes as $mailBox) { + if ($mailBox->getName() === 'INBOX') { + $inbox = $mailBox; + break; + } + } + + // Second, put a new message into the mailbox + $message = $this->getMessageBuilder() + ->from('buffington@domain.tld') + ->to('user@domain.tld') + ->finish(); + $newUid = $this->saveMessage($inbox->getName(), $message, $account); + + // now we tag this message! + try { + $imapMessageMapper->addFlag($this->getClient($account), $mailBox, [$newUid], '$label1'); + } catch (Horde_Imap_Client_Exception $e) { + $this->fail('Could not tag message'); + } + + // sync + $syncService->syncMailbox( + new Account($account), + $inbox, + Horde_Imap_Client::SYNC_NEWMSGSUIDS | Horde_Imap_Client::SYNC_FLAGSUIDS | Horde_Imap_Client::SYNC_VANISHEDUIDS, + null, + false + ); + + // Let's retrieve the DB to see if we have this tag! + $messages = $messageMapper->findByUids($mailBox, [$newUid]); + $related = $messageMapper->findRelatedData($messages, $account->getUserId()); + foreach ($related as $message) { + $tags = $message->getTags(); + $this->assertEquals('$label1', $tags[0]->getImapLabel()); + } + + + // now we untag this message! + try { + $imapMessageMapper->removeFlag($this->getClient($account), $mailBox, [$newUid], '$label1'); + } catch (Horde_Imap_Client_Exception $e) { + $this->fail('Could not untag message'); + } + + // sync again + $syncService->syncMailbox( + new Account($account), + $inbox, + Horde_Imap_Client::SYNC_NEWMSGSUIDS | Horde_Imap_Client::SYNC_FLAGSUIDS | Horde_Imap_Client::SYNC_VANISHEDUIDS, + null, + true + ); + + $messages = $messageMapper->findByUids($mailBox, [$newUid]); + $related = $messageMapper->findRelatedData($messages, $account->getUserId()); + foreach ($related as $message) { + $tags = $message->getTags(); + $this->assertEmpty($tags); + } + } + + public function testGetFlagged() { + // First, set up account and retrieve sync token + $this->resetImapAccount(); + + $account = $this->createTestAccount(); + /** @var ImapMessageMapper $messageMapper */ + $imapMessageMapper = OC::$server->query(ImapMessageMapper::class); + /** @var IMailManager $mailManager */ + $mailManager = OC::$server->query(IMailManager::class); + $mailBoxes = $mailManager->getMailboxes(new Account($account)); + $inbox = null; + foreach ($mailBoxes as $mailBox) { + if ($mailBox->getName() === 'INBOX') { + $inbox = $mailBox; + break; + } + } + + // Put a second new message into the mailbox + $message = $this->getMessageBuilder() + ->from('buffington@domain.tld') + ->to('user@domain.tld') + ->finish(); + $newUid = $this->saveMessage($inbox->getName(), $message, $account); + + + // Put another new message into the mailbox + $message = $this->getMessageBuilder() + ->from('fluffington@domain.tld') + ->to('user@domain.tld') + ->finish(); + $newUid2 = $this->saveMessage($inbox->getName(), $message, $account); + + // Thirdly, create a message that will not be tagged + $message = $this->getMessageBuilder() + ->from('scruffington@domain.tld') + ->to('user@domain.tld') + ->finish(); + $this->saveMessage($inbox->getName(), $message, $account); + + // now we tag this message with $label1 + try { + $imapMessageMapper->addFlag($this->getClient($account), $mailBox, [$newUid], '$label1'); + } catch (Horde_Imap_Client_Exception $e) { + $this->fail('Could not tag message'); + } + + + // now we tag this and the previous message with $label2 + try { + $imapMessageMapper->addFlag($this->getClient($account), $mailBox, [$newUid, $newUid2], '$label2'); + } catch (Horde_Imap_Client_Exception $e) { + $this->fail('Could not tag message'); + } + + // test for labels + $tagged = $imapMessageMapper->getFlagged($this->getClient($account), $mailBox, '$label1'); + $this->assertNotEmpty($tagged); + // are the counts correct? + $this->assertCount(1, $tagged); + + $tagged = $imapMessageMapper->getFlagged($this->getClient($account), $mailBox, '$label2'); + $this->assertNotEmpty($tagged); + $this->assertCount(2, $tagged); + + // test for labels that wasn't set + $tagged = $imapMessageMapper->getFlagged($this->getClient($account), $mailBox, '$notAvailable'); + $this->assertEmpty($tagged); + + // test for regular flag - recent + $tagged = $imapMessageMapper->getFlagged($this->getClient($account), $mailBox, Horde_Imap_Client::FLAG_RECENT); + $this->assertNotEmpty($tagged); + // should return all messages + $this->assertCount(3, $tagged); + } + + public function tearDown(): void { + $this->resetImapAccount(); + } +} diff --git a/tests/Integration/Migration/MigrateImportantFromImapAndDbTest.php b/tests/Integration/Migration/MigrateImportantFromImapAndDbTest.php new file mode 100644 index 000000000..548d63cef --- /dev/null +++ b/tests/Integration/Migration/MigrateImportantFromImapAndDbTest.php @@ -0,0 +1,239 @@ +<?php + +/** + * @copyright 2021 Anna Larch <anna.larch@nextcloud.com> + * + * @author 2021 Anna Larch <anna.larch@nextcloud.com> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\Mail\Tests\Integration\Service; + +use ChristophWurst\Nextcloud\Testing\TestCase; +use Horde_Imap_Client_Exception; +use Horde_Imap_Client_Socket; +use OCA\Mail\Account; +use OCA\Mail\Db\Mailbox; +use OCA\Mail\Db\MailboxMapper; +use OCA\Mail\IMAP\MessageMapper; +use OCA\Mail\Db\Tag; +use OCA\Mail\Exception\ServiceException; +use OCA\Mail\IMAP\IMAPClientFactory; +use OCA\Mail\Migration\MigrateImportantFromImapAndDb; +use Psr\Log\LoggerInterface; + +class MigrateImportantFromImapAndDbTest extends TestCase { + + /** @var MockObject */ + private $clientFactory; + + /** @var MockObject */ + private $client; + + /** @var MockObject */ + private $messageMapper; + + /** @var MockObject */ + private $mailboxMapper; + + /** @var MockObject */ + private $logger; + + /** @var MigrateImportantFromImapAndDb */ + private $migration; + + protected function setUp(): void { + $this->clientFactory = $this->createMock(IMAPClientFactory::class); + $this->client = $this->createMock(Horde_Imap_Client_Socket::class); + $this->messageMapper = $this->createMock(MessageMapper::class); + $this->mailboxMapper = $this->createMock(MailboxMapper::class); + $this->logger = $this->createMock(LoggerInterface::class); + $this->migration = new MigrateImportantFromImapAndDb( + $this->clientFactory, + $this->messageMapper, + $this->mailboxMapper, + $this->logger + ); + parent::setUp(); + } + + public function testMigrateImportantOnImap() { + $account = $this->createMock(Account::class); + $mailbox = $this->createMock(Mailbox::class); + $uids = [1,2,3]; + + $this->clientFactory->expects($this->once()) + ->method('getClient') + ->with($account) + ->willReturn($this->client); + $this->messageMapper->expects($this->once()) + ->method('getFlagged') + ->with($this->client, $mailbox, '$important') + ->willReturn($uids); + $this->messageMapper->expects($this->once()) + ->method('addFlag') + ->with($this->client, $mailbox, $uids, Tag::LABEL_IMPORTANT); + $this->logger->expects($this->never()) + ->method('debug'); + + $this->migration->migrateImportantOnImap($account, $mailbox); + } + + public function testMigrateImportantOnImapNoUids() { + $account = $this->createMock(Account::class); + $mailbox = $this->createMock(Mailbox::class); + $uids = []; + + $this->clientFactory->expects($this->once()) + ->method('getClient') + ->with($account) + ->willReturn($this->client); + $this->messageMapper->expects($this->once()) + ->method('getFlagged') + ->with($this->client, $mailbox, '$important') + ->willReturn($uids); + $this->messageMapper->expects($this->never()) + ->method('addFlag'); + $this->logger->expects($this->never()) + ->method('debug'); + + $this->migration->migrateImportantOnImap($account, $mailbox); + } + + public function testMigrateImportantOnImapExceptionGetFlagged() { + $account = $this->createMock(Account::class); + $mailbox = $this->createMock(Mailbox::class); + $e = new Horde_Imap_Client_Exception(''); + + $this->clientFactory->expects($this->once()) + ->method('getClient') + ->with($account) + ->willReturn($this->client); + $this->messageMapper->expects($this->once()) + ->method('getFlagged') + ->with($this->client, $mailbox, '$important') + ->willThrowException($e); + $this->messageMapper->expects($this->never()) + ->method('addFlag'); + $this->logger->expects($this->never()) + ->method('debug'); + $this->expectException(ServiceException::class); + + $this->migration->migrateImportantOnImap($account, $mailbox); + } + + public function testMigrateImportantOnImapExceptionOnFlag() { + $account = $this->createMock(Account::class); + $mailbox = new Mailbox(); + $mailbox->setName('INBOX'); + $e = new Horde_Imap_Client_Exception(''); + $uids = [1,2,3,4]; + + $this->clientFactory->expects($this->once()) + ->method('getClient') + ->with($account) + ->willReturn($this->client); + $this->messageMapper->expects($this->once()) + ->method('getFlagged') + ->with($this->client, $mailbox, '$important') + ->willReturn($uids); + $this->messageMapper->expects($this->once()) + ->method('addFlag') + ->with($this->client, $mailbox, $uids, Tag::LABEL_IMPORTANT) + ->willThrowException($e); + $this->logger->expects($this->once()) + ->method('debug') + ->with('Could not flag messages in mailbox <' . $mailbox->getId() . '>'); + $this->expectException(ServiceException::class); + + $this->migration->migrateImportantOnImap($account, $mailbox); + } + + public function migrateImportantFromDb() { + $account = $this->createMock(Account::class); + $mailbox = new Mailbox(); + $mailbox->setId(1); + $uids = [1,2,3]; + + $this->clientFactory->expects($this->once()) + ->method('getClient') + ->with($account) + ->willReturn($this->client); + $this->mailboxMapper->expects($this->once()) + ->method('findFlaggedImportantUids') + ->with($mailbox->getId()) + ->willReturn($uids); + $this->messageMapper->expects($this->once()) + ->method('addFlag') + ->with($this->client, $mailbox, $uids, Tag::LABEL_IMPORTANT); + $this->logger->expects($this->never()) + ->method('debug'); + + $this->migration->migrateImportantFromDb($account, $mailbox); + } + + public function testMigrateImportantFromDbNoUids() { + $account = $this->createMock(Account::class); + $mailbox = new Mailbox(); + $mailbox->setId(1); + $uids = []; + + $this->clientFactory->expects($this->once()) + ->method('getClient') + ->with($account) + ->willReturn($this->client); + $this->mailboxMapper->expects($this->once()) + ->method('findFlaggedImportantUids') + ->with($mailbox->getId()) + ->willReturn($uids); + $this->messageMapper->expects($this->never()) + ->method('addFlag'); + $this->logger->expects($this->never()) + ->method('debug'); + + $this->migration->migrateImportantFromDb($account, $mailbox); + } + + public function testMigrateImportantFromDbExceptionOnFlag() { + $account = $this->createMock(Account::class); + $mailbox = new Mailbox(); + $mailbox->setId(1); + $mailbox->setName('INBOX'); + $e = new Horde_Imap_Client_Exception(''); + $uids = [1,2,3]; + + $this->clientFactory->expects($this->once()) + ->method('getClient') + ->with($account) + ->willReturn($this->client); + $this->mailboxMapper->expects($this->once()) + ->method('findFlaggedImportantUids') + ->with($mailbox->getId()) + ->willReturn($uids); + $this->messageMapper->expects($this->once()) + ->method('addFlag') + ->with($this->client, $mailbox, $uids, Tag::LABEL_IMPORTANT) + ->willThrowException($e); + $this->logger->expects($this->once()) + ->method('debug') + ->with('Could not flag messages in mailbox <' . $mailbox->getId() . '>'); + $this->expectException(ServiceException::class); + + $this->migration->migrateImportantFromDb($account, $mailbox); + } +} diff --git a/tests/Unit/IMAP/MessageMapperTest.php b/tests/Unit/IMAP/MessageMapperTest.php index 02625c302..80011fe20 100644 --- a/tests/Unit/IMAP/MessageMapperTest.php +++ b/tests/Unit/IMAP/MessageMapperTest.php @@ -30,6 +30,7 @@ use Horde_Imap_Client_Fetch_Query; use Horde_Imap_Client_Fetch_Results; use Horde_Imap_Client_Ids; use Horde_Imap_Client_Socket; +use OCA\Mail\Db\Mailbox; use OCA\Mail\IMAP\MessageMapper; use OCA\Mail\Model\IMAPMessage; use PHPUnit\Framework\MockObject\MockObject; @@ -236,4 +237,68 @@ class MessageMapperTest extends TestCase { 300 ); } + + public function testGetFlagged() { + /** @var Horde_Imap_Client_Socket|MockObject $imapClient */ + $imapClient = $this->createMock(Horde_Imap_Client_Socket::class); + $mailbox = new Mailbox(); + $mailbox->setName('inbox'); + $flag = '$label1'; + $idsObject = new Horde_Imap_Client_Ids(1); + + $searchResult = [ + 'count' => 1, + 'match' => $idsObject, + 'max' => 1, + 'min' => 1, + 'relevancy' => [] + ]; + + $imapClient->expects($this->once()) + ->method('search') + ->willReturn($searchResult); + + $result = $this->mapper->getFlagged($imapClient, $mailbox, $flag); + $this->assertEquals($result, [1]); + } + + public function testGetFlaggedNoMatches() { + /** @var Horde_Imap_Client_Socket|MockObject $imapClient */ + $imapClient = $this->createMock(Horde_Imap_Client_Socket::class); + $mailbox = new Mailbox(); + $mailbox->setName('inbox'); + $flag = '$label1'; + + $searchResult = [ + 'count' => 0, + 'match' => [], + 'max' => 0, + 'min' => 0, + 'relevancy' => [] + ]; + + $imapClient->expects($this->once()) + ->method('search') + ->willReturn($searchResult); + + $result = $this->mapper->getFlagged($imapClient, $mailbox, $flag); + $this->assertEquals($result, []); + } + + public function testGetFlaggedSearchResultUnexpectedStructure() { + /** @var Horde_Imap_Client_Socket|MockObject $imapClient */ + $imapClient = $this->createMock(Horde_Imap_Client_Socket::class); + $mailbox = new Mailbox(); + $mailbox->setName('inbox'); + $flag = '$label1'; + + $searchResult = [[]]; + + $imapClient->expects($this->once()) + ->method('search') + ->willReturn($searchResult); + + $result = $this->mapper->getFlagged($imapClient, $mailbox, $flag); + $this->assertEquals($result, []); + } } diff --git a/tests/Unit/Job/TestMigrateImportantJob.php b/tests/Unit/Job/TestMigrateImportantJob.php new file mode 100644 index 000000000..095625065 --- /dev/null +++ b/tests/Unit/Job/TestMigrateImportantJob.php @@ -0,0 +1,322 @@ +<?php + +declare(strict_types=1); + +/** + * @author Anna Larch <anna.larch@nextcloud.com> + * + * Mail + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace OCA\Mail\Tests\Unit\Job; + +use ChristophWurst\Nextcloud\Testing\TestCase; +use OCA\Mail\Account; +use OCA\Mail\BackgroundJob\MigrateImportantJob; +use OCA\Mail\Db\MailAccount; +use OCA\Mail\Db\MailAccountMapper; +use OCA\Mail\Db\Mailbox; +use OCA\Mail\Db\MailboxMapper; +use OCA\Mail\Exception\ServiceException; +use OCA\Mail\Migration\MigrateImportantFromImapAndDb; +use OCA\Mail\Service\MailManager; +use OCA\Mail\Tests\Integration\Framework\ImapTest; +use OCP\AppFramework\Db\DoesNotExistException; +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\BackgroundJob\IJobList; +use PHPUnit\Framework\MockObject\MockObject; +use Psr\Log\LoggerInterface; + +class TestMigrateImportantJob extends TestCase { + use ImapTest; + + /** @var MailboxMapper|MockObject */ + private $mailboxMapper; + + /** @var MailAccountMapper|MockObject */ + private $mailAccountMapper; + + /** @var MailManager|MockObject */ + private $mailManager; + + /** @var MigrateImportantFromImapAndDb|MockObject */ + private $migration; + + /** @var LoggerInterface|MockObject */ + private $logger; + + /** @var IJobList|MockObject */ + private $jobList; + + /** @var MigrateImportantJob */ + private $job; + + /** @var [] */ + private static $argument; + + protected function setUp(): void { + parent::setUp(); + $this->mailboxMapper = $this->createMock(MailboxMapper::class); + $this->mailAccountMapper = $this->createMock(MailAccountMapper::class); + $this->mailManager = $this->createMock(MailManager::class); + $this->migration = $this->createMock(MigrateImportantFromImapAndDb::class); + $this->logger = $this->createMock(LoggerInterface::class); + $this->jobList = $this->createMock(IJobList::class); + + $this->job = new MigrateImportantJob( + $this->mailboxMapper, + $this->mailAccountMapper, + $this->mailManager, + $this->migration, + $this->logger, + $this->jobList, + $this->createMock(ITimeFactory::class) + ); + + self::$argument = ['mailboxId' => 1]; + } + + public function testRun() { + $mailbox = new Mailbox(); + $mailbox->setId(self::$argument['mailboxId']); + $mailbox->setName('INBOX'); + $mailbox->setAccountId(1); + $mailAccount = new MailAccount(); + $account = new Account($mailAccount); + + $this->mailboxMapper->expects($this->once()) + ->method('findById') + ->with(self::$argument['mailboxId']) + ->willReturn($mailbox); + $this->mailAccountMapper->expects($this->once()) + ->method('findById') + ->with($mailbox->getAccountId()) + ->willReturn($mailAccount); + $this->mailManager->expects($this->once()) + ->method('isPermflagsEnabled') + ->with($account, $mailbox->getName()) + ->willReturn(true); + $this->migration->expects($this->once()) + ->method('migrateImportantOnImap') + ->with($account, $mailbox); + $this->migration->expects($this->once()) + ->method('migrateImportantFromDb') + ->with($account, $mailbox); + $this->jobList->expects($this->never()) + ->method('remove'); + $this->logger->expects($this->never()) + ->method('debug'); + + $this->job->run(self::$argument); + } + + public function testRunNoMailbox() { + $e = new DoesNotExistException('does not exist'); + + $this->mailboxMapper->expects($this->once()) + ->method('findById') + ->with(self::$argument['mailboxId']) + ->willThrowException($e); + $this->logger->expects($this->once()) + ->method('debug') + ->with('Could not find mailbox <' . self::$argument['mailboxId'] . '>, removing from jobs'); + $this->jobList->expects($this->once()) + ->method('remove') + ->with(MigrateImportantJob::class, self::$argument); + $this->mailAccountMapper->expects($this->never()) + ->method('findById'); + $this->mailManager->expects($this->never()) + ->method('isPermflagsEnabled'); + $this->migration->expects($this->never()) + ->method('migrateImportantOnImap'); + $this->migration->expects($this->never()) + ->method('migrateImportantFromDb'); + + $this->job->run(self::$argument); + } + + public function testRunNoAccount() { + $mailbox = new Mailbox(); + $mailbox->setId(self::$argument['mailboxId']); + $mailbox->setName('INBOX'); + $mailbox->setAccountId(1); + $e = new DoesNotExistException('does not exist'); + + $this->mailboxMapper->expects($this->once()) + ->method('findById') + ->with(self::$argument['mailboxId']) + ->willReturn($mailbox); + $this->mailAccountMapper->expects($this->once()) + ->method('findById') + ->with($mailbox->getAccountId()) + ->willThrowException($e); + $this->logger->expects($this->once()) + ->method('debug') + ->with('Could not find account <' . $mailbox->getAccountId() . '>, removing from jobs'); + $this->jobList->expects($this->once()) + ->method('remove') + ->with(MigrateImportantJob::class, self::$argument); + $this->mailManager->expects($this->never()) + ->method('isPermflagsEnabled'); + $this->migration->expects($this->never()) + ->method('migrateImportantOnImap'); + $this->migration->expects($this->never()) + ->method('migrateImportantFromDb'); + + $this->job->run(self::$argument); + } + + public function testNoPermflags() { + $mailbox = new Mailbox(); + $mailbox->setId(self::$argument['mailboxId']); + $mailbox->setName('INBOX'); + $mailbox->setAccountId(1); + $mailAccount = new MailAccount(); + $account = new Account($mailAccount); + + $this->mailboxMapper->expects($this->once()) + ->method('findById') + ->with(self::$argument['mailboxId']) + ->willReturn($mailbox); + $this->mailAccountMapper->expects($this->once()) + ->method('findById') + ->with($mailbox->getAccountId()) + ->willReturn($mailAccount); + $this->mailManager->expects($this->once()) + ->method('isPermflagsEnabled') + ->with($account, $mailbox->getName()) + ->willReturn(false); + $this->logger->expects($this->once()) + ->method('debug') + ->with('Permflags not enabled for <' . $mailbox->getAccountId() . '>, removing from jobs'); + $this->jobList->expects($this->once()) + ->method('remove') + ->with(MigrateImportantJob::class, self::$argument); + + $this->job->run(self::$argument); + } + + public function testErrorOnMigrateOnImap() { + $mailbox = new Mailbox(); + $mailbox->setId(self::$argument['mailboxId']); + $mailbox->setName('INBOX'); + $mailbox->setAccountId(1); + $mailAccount = new MailAccount(); + $account = new Account($mailAccount); + $e = new ServiceException(''); + + $this->mailboxMapper->expects($this->once()) + ->method('findById') + ->with(self::$argument['mailboxId']) + ->willReturn($mailbox); + $this->mailAccountMapper->expects($this->once()) + ->method('findById') + ->with($mailbox->getAccountId()) + ->willReturn($mailAccount); + $this->mailManager->expects($this->once()) + ->method('isPermflagsEnabled') + ->with($account, $mailbox->getName()) + ->willReturn(true); + $this->migration->expects($this->once()) + ->method('migrateImportantOnImap') + ->with($account, $mailbox) + ->willThrowException($e); + $this->logger->expects($this->once()) + ->method('debug') + ->with('Could not flag messages on IMAP for mailbox <' . $mailbox->getId() . '>.'); + $this->migration->expects($this->once()) + ->method('migrateImportantFromDb') + ->with($account, $mailbox); + $this->jobList->expects($this->never()) + ->method('remove'); + + $this->job->run(self::$argument); + } + + public function testErrorOnMigrateDbToImap() { + $mailbox = new Mailbox(); + $mailbox->setId(self::$argument['mailboxId']); + $mailbox->setName('INBOX'); + $mailbox->setAccountId(1); + $mailAccount = new MailAccount(); + $account = new Account($mailAccount); + $e = new ServiceException(''); + + $this->mailboxMapper->expects($this->once()) + ->method('findById') + ->with(self::$argument['mailboxId']) + ->willReturn($mailbox); + $this->mailAccountMapper->expects($this->once()) + ->method('findById') + ->with($mailbox->getAccountId()) + ->willReturn($mailAccount); + $this->mailManager->expects($this->once()) + ->method('isPermflagsEnabled') + ->with($account, $mailbox->getName()) + ->willReturn(true); + $this->migration->expects($this->once()) + ->method('migrateImportantOnImap') + ->with($account, $mailbox); + $this->migration->expects($this->once()) + ->method('migrateImportantFromDb') + ->with($account, $mailbox) + ->willThrowException($e); + $this->logger->expects($this->once()) + ->method('debug') + ->with('Could not flag messages from DB on IMAP for mailbox <' . $mailbox->getId() . '>.'); + $this->jobList->expects($this->never()) + ->method('remove'); + + $this->job->run(self::$argument); + } + + public function testErrorOnOnBoth() { + $mailbox = new Mailbox(); + $mailbox->setId(self::$argument['mailboxId']); + $mailbox->setName('INBOX'); + $mailbox->setAccountId(1); + $mailAccount = new MailAccount(); + $account = new Account($mailAccount); + $e = new ServiceException(''); + + $this->mailboxMapper->expects($this->once()) + ->method('findById') + ->with(self::$argument['mailboxId']) + ->willReturn($mailbox); + $this->mailAccountMapper->expects($this->once()) + ->method('findById') + ->with($mailbox->getAccountId()) + ->willReturn($mailAccount); + $this->mailManager->expects($this->once()) + ->method('isPermflagsEnabled') + ->with($account, $mailbox->getName()) + ->willReturn(true); + $this->migration->expects($this->once()) + ->method('migrateImportantOnImap') + ->with($account, $mailbox) + ->willThrowException($e); + $this->migration->expects($this->once()) + ->method('migrateImportantFromDb') + ->with($account, $mailbox) + ->willThrowException($e); + $this->logger->expects($this->exactly(2)) + ->method('debug'); + $this->jobList->expects($this->never()) + ->method('remove'); + + $this->job->run(self::$argument); + } +} diff --git a/tests/Unit/Listener/DeleteDraftListenerTest.php b/tests/Unit/Listener/DeleteDraftListenerTest.php index 96503bdf2..fef2852f6 100644 --- a/tests/Unit/Listener/DeleteDraftListenerTest.php +++ b/tests/Unit/Listener/DeleteDraftListenerTest.php @@ -238,7 +238,7 @@ class DeleteDraftListenerTest extends TestCase { ->with( $client, $mailbox, - $uid, + [$uid], \Horde_Imap_Client::FLAG_DELETED ); $client->expects($this->once()) diff --git a/tests/Unit/Listener/FlagRepliedMessageListenerTest.php b/tests/Unit/Listener/FlagRepliedMessageListenerTest.php index 76433984d..20756a3d9 100644 --- a/tests/Unit/Listener/FlagRepliedMessageListenerTest.php +++ b/tests/Unit/Listener/FlagRepliedMessageListenerTest.php @@ -150,7 +150,7 @@ class FlagRepliedMessageListenerTest extends TestCase { ->with( $client, $mailbox, - 321, + [321], \Horde_Imap_Client::FLAG_ANSWERED ); $this->logger->expects($this->never()) diff --git a/tests/Unit/Migration/MigrateImportantFromImapAndDbTest.php b/tests/Unit/Migration/MigrateImportantFromImapAndDbTest.php new file mode 100644 index 000000000..58b799000 --- /dev/null +++ b/tests/Unit/Migration/MigrateImportantFromImapAndDbTest.php @@ -0,0 +1,239 @@ +<?php + +/** + * @copyright 2021 Anna Larch <anna.larch@nextcloud.com> + * + * @author 2021 Anna Larch <anna.larch@nextcloud.com> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\Mail\Tests\Unit\Migration; + +use ChristophWurst\Nextcloud\Testing\TestCase; +use Horde_Imap_Client_Exception; +use Horde_Imap_Client_Socket; +use OCA\Mail\Account; +use OCA\Mail\Db\Mailbox; +use OCA\Mail\Db\MailboxMapper; +use OCA\Mail\IMAP\MessageMapper; +use OCA\Mail\Db\Tag; +use OCA\Mail\Exception\ServiceException; +use OCA\Mail\IMAP\IMAPClientFactory; +use OCA\Mail\Migration\MigrateImportantFromImapAndDb; +use Psr\Log\LoggerInterface; + +class MigrateImportantFromImapAndDbTest extends TestCase { + + /** @var MockObject */ + private $clientFactory; + + /** @var MockObject */ + private $client; + + /** @var MockObject */ + private $messageMapper; + + /** @var MockObject */ + private $mailboxMapper; + + /** @var MockObject */ + private $logger; + + /** @var MigrateImportantFromImapAndDb */ + private $migration; + + protected function setUp(): void { + $this->clientFactory = $this->createMock(IMAPClientFactory::class); + $this->client = $this->createMock(Horde_Imap_Client_Socket::class); + $this->messageMapper = $this->createMock(MessageMapper::class); + $this->mailboxMapper = $this->createMock(MailboxMapper::class); + $this->logger = $this->createMock(LoggerInterface::class); + $this->migration = new MigrateImportantFromImapAndDb( + $this->clientFactory, + $this->messageMapper, + $this->mailboxMapper, + $this->logger + ); + parent::setUp(); + } + + public function testMigrateImportantOnImap() { + $account = $this->createMock(Account::class); + $mailbox = $this->createMock(Mailbox::class); + $uids = [1,2,3]; + + $this->clientFactory->expects($this->once()) + ->method('getClient') + ->with($account) + ->willReturn($this->client); + $this->messageMapper->expects($this->once()) + ->method('getFlagged') + ->with($this->client, $mailbox, '$important') + ->willReturn($uids); + $this->messageMapper->expects($this->once()) + ->method('addFlag') + ->with($this->client, $mailbox, $uids, Tag::LABEL_IMPORTANT); + $this->logger->expects($this->never()) + ->method('debug'); + + $this->migration->migrateImportantOnImap($account, $mailbox); + } + + public function testMigrateImportantOnImapNoUids() { + $account = $this->createMock(Account::class); + $mailbox = $this->createMock(Mailbox::class); + $uids = []; + + $this->clientFactory->expects($this->once()) + ->method('getClient') + ->with($account) + ->willReturn($this->client); + $this->messageMapper->expects($this->once()) + ->method('getFlagged') + ->with($this->client, $mailbox, '$important') + ->willReturn($uids); + $this->messageMapper->expects($this->never()) + ->method('addFlag'); + $this->logger->expects($this->never()) + ->method('debug'); + + $this->migration->migrateImportantOnImap($account, $mailbox); + } + + public function testMigrateImportantOnImapExceptionGetFlagged() { + $account = $this->createMock(Account::class); + $mailbox = $this->createMock(Mailbox::class); + $e = new Horde_Imap_Client_Exception(''); + + $this->clientFactory->expects($this->once()) + ->method('getClient') + ->with($account) + ->willReturn($this->client); + $this->messageMapper->expects($this->once()) + ->method('getFlagged') + ->with($this->client, $mailbox, '$important') + ->willThrowException($e); + $this->messageMapper->expects($this->never()) + ->method('addFlag'); + $this->logger->expects($this->never()) + ->method('debug'); + $this->expectException(ServiceException::class); + + $this->migration->migrateImportantOnImap($account, $mailbox); + } + + public function testMigrateImportantOnImapExceptionOnFlag() { + $account = $this->createMock(Account::class); + $mailbox = new Mailbox(); + $mailbox->setName('INBOX'); + $e = new Horde_Imap_Client_Exception(''); + $uids = [1,2,3]; + + $this->clientFactory->expects($this->once()) + ->method('getClient') + ->with($account) + ->willReturn($this->client); + $this->messageMapper->expects($this->once()) + ->method('getFlagged') + ->with($this->client, $mailbox, '$important') + ->willReturn($uids); + $this->messageMapper->expects($this->once()) + ->method('addFlag') + ->with($this->client, $mailbox, $uids, Tag::LABEL_IMPORTANT) + ->willThrowException($e); + $this->logger->expects($this->once()) + ->method('debug') + ->with('Could not flag messages in mailbox <' . $mailbox->getId() . '>'); + $this->expectException(ServiceException::class); + + $this->migration->migrateImportantOnImap($account, $mailbox); + } + + public function migrateImportantFromDb() { + $account = $this->createMock(Account::class); + $mailbox = new Mailbox(); + $mailbox->setId(1); + $uids = [1,2,3]; + + $this->clientFactory->expects($this->once()) + ->method('getClient') + ->with($account) + ->willReturn($this->client); + $this->mailboxMapper->expects($this->once()) + ->method('findFlaggedImportantUids') + ->with($mailbox->getId()) + ->willReturn($uids); + $this->messageMapper->expects($this->once()) + ->method('addFlag') + ->with($this->client, $mailbox, $uids, Tag::LABEL_IMPORTANT); + $this->logger->expects($this->never()) + ->method('debug'); + + $this->migration->migrateImportantFromDb($account, $mailbox); + } + + public function testMigrateImportantFromDbNoUids() { + $account = $this->createMock(Account::class); + $mailbox = new Mailbox(); + $mailbox->setId(1); + $uids = []; + + $this->clientFactory->expects($this->once()) + ->method('getClient') + ->with($account) + ->willReturn($this->client); + $this->mailboxMapper->expects($this->once()) + ->method('findFlaggedImportantUids') + ->with($mailbox->getId()) + ->willReturn($uids); + $this->messageMapper->expects($this->never()) + ->method('addFlag'); + $this->logger->expects($this->never()) + ->method('debug'); + + $this->migration->migrateImportantFromDb($account, $mailbox); + } + + public function testMigrateImportantFromDbExceptionOnFlag() { + $account = $this->createMock(Account::class); + $mailbox = new Mailbox(); + $mailbox->setId(1); + $mailbox->setName('INBOX'); + $e = new Horde_Imap_Client_Exception(''); + $uids = [1,2,3]; + + $this->clientFactory->expects($this->once()) + ->method('getClient') + ->with($account) + ->willReturn($this->client); + $this->mailboxMapper->expects($this->once()) + ->method('findFlaggedImportantUids') + ->with($mailbox->getId()) + ->willReturn($uids); + $this->messageMapper->expects($this->once()) + ->method('addFlag') + ->with($this->client, $mailbox, $uids, Tag::LABEL_IMPORTANT) + ->willThrowException($e); + $this->logger->expects($this->once()) + ->method('debug') + ->with('Could not flag messages in mailbox <' . $mailbox->getId() . '>'); + $this->expectException(ServiceException::class); + + $this->migration->migrateImportantFromDb($account, $mailbox); + } +} diff --git a/tests/Unit/Service/MailManagerTest.php b/tests/Unit/Service/MailManagerTest.php index f42b586d7..3557027a1 100644 --- a/tests/Unit/Service/MailManagerTest.php +++ b/tests/Unit/Service/MailManagerTest.php @@ -422,7 +422,7 @@ class MailManagerTest extends TestCase { ->method('addFlag'); $this->imapMessageMapper->expects($this->once()) ->method('removeFlag') - ->with($client, $mb, 123, '\\seen'); + ->with($client, $mb, [123], '\\seen'); $this->manager->flagMessage($account, 'INBOX', 123, 'seen', false); } @@ -448,7 +448,7 @@ class MailManagerTest extends TestCase { ->willReturn(['permflags' => [ "11" => "\*"] ]); $this->imapMessageMapper->expects($this->once()) ->method('addFlag') - ->with($client, $mb, 123, Tag::LABEL_IMPORTANT); + ->with($client, $mb, [123], Tag::LABEL_IMPORTANT); $account->expects($this->once()) ->method('getUserId') ->willReturn('test'); @@ -476,7 +476,7 @@ class MailManagerTest extends TestCase { ->willReturn(['permflags' => [ "11" => "\*"] ]); $this->imapMessageMapper->expects($this->once()) ->method('removeFlag') - ->with($client, $mb, 123, Tag::LABEL_IMPORTANT); + ->with($client, $mb, [123], Tag::LABEL_IMPORTANT); $this->imapMessageMapper->expects($this->never()) ->method('addFlag'); $account->expects($this->never()) |