diff options
-rw-r--r-- | lib/Contracts/IMailManager.php | 31 | ||||
-rwxr-xr-x | lib/Controller/MessagesController.php | 4 | ||||
-rw-r--r-- | lib/Controller/TagsController.php | 52 | ||||
-rw-r--r-- | lib/Service/MailManager.php | 83 | ||||
-rw-r--r-- | tests/Unit/Controller/MessagesControllerTest.php | 4 | ||||
-rw-r--r-- | tests/Unit/Controller/TagsControllerTest.php | 110 | ||||
-rw-r--r-- | tests/Unit/Service/MailManagerTest.php | 78 |
7 files changed, 287 insertions, 75 deletions
diff --git a/lib/Contracts/IMailManager.php b/lib/Contracts/IMailManager.php index 34458c862..76eb2f1d5 100644 --- a/lib/Contracts/IMailManager.php +++ b/lib/Contracts/IMailManager.php @@ -23,14 +23,14 @@ declare(strict_types=1); namespace OCA\Mail\Contracts; -use OCA\Mail\Db\Tag; use OCA\Mail\Account; use OCA\Mail\Db\Mailbox; use OCA\Mail\Db\Message; -use OCA\Mail\Service\Quota; -use OCA\Mail\Model\IMAPMessage; +use OCA\Mail\Db\Tag; use OCA\Mail\Exception\ClientException; use OCA\Mail\Exception\ServiceException; +use OCA\Mail\Model\IMAPMessage; +use OCA\Mail\Service\Quota; use OCP\AppFramework\Db\DoesNotExistException; interface IMailManager { @@ -237,7 +237,30 @@ interface IMailManager { * @param string $imapLabel * @param string $userId * @return Tag - * @throws DoesNotExistException + * @throws ClientException */ public function getTagByImapLabel(string $imapLabel, string $userId): Tag; + + /** + * Create a mail tag + * + * @param string $userId + * @param string $displayName + * @param string $color + * @return Tag + * @throws ClientException if display name does not work as imap label + */ + public function createTag(string $displayName, string $color, string $userId): Tag; + + /** + * Update a mail tag + * + * @param string $userId + * @param int $id + * @param string $displayName + * @param string $color + * @return Tag + * @throws ClientException if the given tag does not exist + */ + public function updateTag(int $id, string $displayName, string $color, string $userId): Tag; } diff --git a/lib/Controller/MessagesController.php b/lib/Controller/MessagesController.php index 548ffa713..a39de7001 100755 --- a/lib/Controller/MessagesController.php +++ b/lib/Controller/MessagesController.php @@ -671,7 +671,7 @@ class MessagesController extends Controller { try { $tag = $this->mailManager->getTagByImapLabel($imapLabel, $this->currentUserId); - } catch (DoesNotExistException $e) { + } catch (ClientException $e) { return new JSONResponse([], Http::STATUS_FORBIDDEN); } @@ -702,7 +702,7 @@ class MessagesController extends Controller { try { $tag = $this->mailManager->getTagByImapLabel($imapLabel, $this->currentUserId); - } catch (DoesNotExistException $e) { + } catch (ClientException $e) { return new JSONResponse([], Http::STATUS_FORBIDDEN); } diff --git a/lib/Controller/TagsController.php b/lib/Controller/TagsController.php index feccf38ed..e3530bebc 100644 --- a/lib/Controller/TagsController.php +++ b/lib/Controller/TagsController.php @@ -24,11 +24,9 @@ declare(strict_types=1); namespace OCA\Mail\Controller; use OCA\Mail\AppInfo\Application; -use OCA\Mail\Db\Tag; -use OCA\Mail\Db\TagMapper; +use OCA\Mail\Contracts\IMailManager; use OCA\Mail\Exception\ClientException; use OCP\AppFramework\Controller; -use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Http\JSONResponse; use OCP\IRequest; @@ -37,23 +35,16 @@ class TagsController extends Controller { /** @var string */ private $currentUserId; - /** @var TagMapper */ - private $tagMapper; + /** @var IMailManager */ + private $mailManager; - /** - * TagsController constructor. - * - * @param IRequest $request - * @param $UserId - * @param TagMapper $tagMapper - */ public function __construct(IRequest $request, - $UserId, - TagMapper $tagMapper + string $UserId, + IMailManager $mailManager ) { parent::__construct(Application::APP_ID, $request); $this->currentUserId = $UserId; - $this->tagMapper = $tagMapper; + $this->mailManager = $mailManager; } /** @@ -70,28 +61,7 @@ class TagsController extends Controller { $this->validateDisplayName($displayName); $this->validateColor($color); - $imapLabel = str_replace(' ', '_', $displayName); - /** @var string|false $imapLabel */ - $imapLabel = mb_convert_encoding($imapLabel, 'UTF7-IMAP', 'UTF-8'); - if ($imapLabel === false) { - throw new ClientException('Error converting display name to UTF7-IMAP ', 0); - } - $imapLabel = mb_strcut($imapLabel, 0, 64); - - try { - return new JSONResponse($this->tagMapper->getTagByImapLabel($imapLabel, $this->currentUserId)); - } catch (DoesNotExistException $e) { - // it's valid that a tag does not exist. - } - - $tag = new Tag(); - $tag->setUserId($this->currentUserId); - $tag->setDisplayName($displayName); - $tag->setImapLabel($imapLabel); - $tag->setColor($color); - $tag->setIsDefaultTag(false); - - $tag = $this->tagMapper->insert($tag); + $tag = $this->mailManager->createTag($displayName, $color, $this->currentUserId); return new JSONResponse($tag); } @@ -105,18 +75,12 @@ class TagsController extends Controller { * * @return JSONResponse * @throws ClientException - * @throws DoesNotExistException */ public function update(int $id, string $displayName, string $color): JSONResponse { $this->validateDisplayName($displayName); $this->validateColor($color); - $tag = $this->tagMapper->getTagForUser($id, $this->currentUserId); - - $tag->setDisplayName($displayName); - $tag->setColor($color); - - $tag = $this->tagMapper->update($tag); + $tag = $this->mailManager->updateTag($id, $displayName, $color, $this->currentUserId); return new JSONResponse($tag); } diff --git a/lib/Service/MailManager.php b/lib/Service/MailManager.php index 29030a000..dd283f9f1 100644 --- a/lib/Service/MailManager.php +++ b/lib/Service/MailManager.php @@ -23,35 +23,35 @@ declare(strict_types=1); namespace OCA\Mail\Service; -use OCA\Mail\Db\Tag; -use OCA\Mail\Folder; -use OCA\Mail\Account; use Horde_Imap_Client; -use function array_map; +use Horde_Imap_Client_Exception; +use Horde_Imap_Client_Exception_NoSupportExtension; +use Horde_Imap_Client_Socket; +use OCA\Mail\Account; +use OCA\Mail\Contracts\IMailManager; use OCA\Mail\Db\Mailbox; +use OCA\Mail\Db\MailboxMapper; use OCA\Mail\Db\Message; -use function array_values; +use OCA\Mail\Db\MessageMapper as DbMessageMapper; +use OCA\Mail\Db\Tag; use OCA\Mail\Db\TagMapper; -use Psr\Log\LoggerInterface; -use Horde_Imap_Client_Socket; -use OCA\Mail\Db\MailboxMapper; -use OCA\Mail\IMAP\MailboxSync; -use OCA\Mail\IMAP\FolderMapper; -use OCA\Mail\Model\IMAPMessage; -use Horde_Imap_Client_Exception; -use OCA\Mail\Contracts\IMailManager; -use OCA\Mail\IMAP\IMAPClientFactory; -use OCA\Mail\Exception\ClientException; +use OCA\Mail\Events\BeforeMessageDeletedEvent; use OCA\Mail\Events\MessageDeletedEvent; use OCA\Mail\Events\MessageFlaggedEvent; +use OCA\Mail\Exception\ClientException; use OCA\Mail\Exception\ServiceException; -use OCP\EventDispatcher\IEventDispatcher; -use OCA\Mail\Events\BeforeMessageDeletedEvent; -use OCP\AppFramework\Db\DoesNotExistException; -use OCA\Mail\Db\MessageMapper as DbMessageMapper; -use Horde_Imap_Client_Exception_NoSupportExtension; use OCA\Mail\Exception\TrashMailboxNotSetException; +use OCA\Mail\Folder; +use OCA\Mail\IMAP\FolderMapper; +use OCA\Mail\IMAP\IMAPClientFactory; +use OCA\Mail\IMAP\MailboxSync; use OCA\Mail\IMAP\MessageMapper as ImapMessageMapper; +use OCA\Mail\Model\IMAPMessage; +use OCP\AppFramework\Db\DoesNotExistException; +use OCP\EventDispatcher\IEventDispatcher; +use Psr\Log\LoggerInterface; +use function array_map; +use function array_values; class MailManager implements IMailManager { @@ -559,17 +559,16 @@ class MailManager implements IMailManager { * @param string $imapLabel * @param string $userId * @return Tag - * @throws DoesNotExistException + * @throws ClientException */ public function getTagByImapLabel(string $imapLabel, string $userId): Tag { try { return $this->tagMapper->getTagByImapLabel($imapLabel, $userId); } catch (DoesNotExistException $e) { - throw new ClientException('Unknow Tag', (int)$e->getCode(), $e); + throw new ClientException('Unknown Tag', 0, $e); } } - /** * Filter out IMAP flags that aren't supported by the client server * @@ -612,4 +611,42 @@ class MailManager implements IMailManager { } return (is_array($capabilities) === true && array_key_exists('permflags', $capabilities) === true && in_array("\*", $capabilities['permflags'], true) === true); } + + public function createTag(string $displayName, string $color, string $userId): Tag { + $imapLabel = str_replace(' ', '_', $displayName); + /** @var string|false $imapLabel */ + $imapLabel = mb_convert_encoding($imapLabel, 'UTF7-IMAP', 'UTF-8'); + if ($imapLabel === false) { + throw new ClientException('Error converting display name to UTF7-IMAP ', 0); + } + $imapLabel = mb_strcut($imapLabel, 0, 64); + + try { + return $this->getTagByImapLabel($imapLabel, $userId); + } catch (ClientException $e) { + // it's valid that a tag does not exist. + } + + $tag = new Tag(); + $tag->setUserId($userId); + $tag->setDisplayName($displayName); + $tag->setImapLabel($imapLabel); + $tag->setColor($color); + $tag->setIsDefaultTag(false); + + return $this->tagMapper->insert($tag); + } + + public function updateTag(int $id, string $displayName, string $color, string $userId): Tag { + try { + $tag = $this->tagMapper->getTagForUser($id, $userId); + } catch (DoesNotExistException $e) { + throw new ClientException('Tag not found', 0, $e); + } + + $tag->setDisplayName($displayName); + $tag->setColor($color); + + return $this->tagMapper->update($tag); + } } diff --git a/tests/Unit/Controller/MessagesControllerTest.php b/tests/Unit/Controller/MessagesControllerTest.php index 8943aa331..f89ed523b 100644 --- a/tests/Unit/Controller/MessagesControllerTest.php +++ b/tests/Unit/Controller/MessagesControllerTest.php @@ -706,7 +706,7 @@ class MessagesControllerTest extends TestCase { $this->mailManager->expects($this->once()) ->method('getTagByImapLabel') ->with($imapLabel,$this->userId) - ->willThrowException(new DoesNotExistException('')); + ->willThrowException(new ClientException('Computer says no')); $this->mailManager->expects($this->never()) ->method('tagMessage'); @@ -807,7 +807,7 @@ class MessagesControllerTest extends TestCase { $this->mailManager->expects($this->once()) ->method('getTagByImapLabel') ->with($imapLabel,$this->userId) - ->willThrowException(new DoesNotExistException('')); + ->willThrowException(new ClientException('Computer says no')); $this->mailManager->expects($this->never()) ->method('tagMessage'); diff --git a/tests/Unit/Controller/TagsControllerTest.php b/tests/Unit/Controller/TagsControllerTest.php new file mode 100644 index 000000000..bd92f85e1 --- /dev/null +++ b/tests/Unit/Controller/TagsControllerTest.php @@ -0,0 +1,110 @@ +<?php + +declare(strict_types=1); + +/** + * @author Daniel Kesselberg <mail@danielkesselberg.de> + * + * 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\Controller; + +use ChristophWurst\Nextcloud\Testing\ServiceMockObject; +use OCA\Mail\Controller\TagsController; +use OCA\Mail\Exception\ClientException; +use OCA\Mail\Service\MailManager; +use OCA\Mail\Tests\Integration\TestCase; + +class TagsControllerTest extends TestCase { + + /** @var ServiceMockObject */ + private $serviceMock; + + /** @var MailManager */ + private $mailManager; + + /** @var TagsController */ + private $tagsController; + + protected function setUp(): void { + parent::setUp(); + $this->serviceMock = $this->createServiceMock( + TagsController::class, + ['UserId' => '1'] + ); + $this->mailManager = $this->serviceMock->getParameter('mailManager'); + $this->tagsController = $this->serviceMock->getService(); + } + + public function testCreateInvalidDisplayName(): void { + $this->mailManager->expects($this->never()) + ->method('createTag'); + + $this->expectException(ClientException::class); + $this->expectExceptionMessage('The maximum length for displayName is 128'); + + $displayName = str_repeat('Hello', 30); + $this->tagsController->create($displayName, '#0082c9'); + } + + public function testCreateInvalidColor(): void { + $this->mailManager->expects($this->never()) + ->method('createTag'); + + $this->expectException(ClientException::class); + $this->expectExceptionMessage('The maximum length for color is 9'); + + $color = str_repeat('#0082c9', 30); + $this->tagsController->create('Hello', $color); + } + + public function testCreate(): void { + $this->mailManager->expects($this->once()) + ->method('createTag'); + + $this->tagsController->create('Hello', '#0082c9'); + } + + public function testUpdateInvalidDisplayName(): void { + $this->mailManager->expects($this->never()) + ->method('updateTag'); + + $this->expectException(ClientException::class); + $this->expectExceptionMessage('The maximum length for displayName is 128'); + + $displayName = str_repeat('Hello', 30); + $this->tagsController->update(100, $displayName, '#0082c9'); + } + + public function testUpdateInvalidColor(): void { + $this->mailManager->expects($this->never()) + ->method('updateTag'); + + $this->expectException(ClientException::class); + $this->expectExceptionMessage('The maximum length for color is 9'); + + $color = str_repeat('#0082c9', 30); + $this->tagsController->update(100, 'Hello', $color); + } + + public function testUpdate(): void { + $this->mailManager->expects($this->once()) + ->method('updateTag'); + + $this->tagsController->update(100, 'Hello', '#0082c9'); + } +} diff --git a/tests/Unit/Service/MailManagerTest.php b/tests/Unit/Service/MailManagerTest.php index 3557027a1..c90b04327 100644 --- a/tests/Unit/Service/MailManagerTest.php +++ b/tests/Unit/Service/MailManagerTest.php @@ -34,6 +34,7 @@ use OCA\Mail\Db\MessageMapper as DbMessageMapper; use OCA\Mail\Db\Tag; use OCA\Mail\Db\TagMapper; use OCA\Mail\Events\BeforeMessageDeletedEvent; +use OCA\Mail\Exception\ClientException; use OCA\Mail\Exception\ServiceException; use OCA\Mail\Folder; use OCA\Mail\IMAP\FolderMapper; @@ -553,4 +554,81 @@ class MailManagerTest extends TestCase { $result = $this->manager->getMailAttachments($account, $mailbox, $message); $this->assertEquals($attachments, $result); } + + public function testCreateTag(): void { + $this->tagMapper->expects($this->once()) + ->method('getTagByImapLabel') + ->willThrowException(new DoesNotExistException('Computer says no')); + $this->tagMapper->expects($this->once()) + ->method('insert') + ->willReturnCallback(static function (Tag $tag) { + return $tag; + }); + + $tag = $this->manager->createTag('Hello Hello 👋', '#0082c9', 'admin'); + + self::assertEquals('admin', $tag->getUserId()); + self::assertEquals('Hello Hello 👋', $tag->getDisplayName()); + self::assertEquals('Hello_Hello_&2D3cSw-', $tag->getImapLabel()); + self::assertEquals('#0082c9', $tag->getColor()); + } + + public function testCreateTagSameImapLabel(): void { + $existingTag = new Tag(); + $existingTag->setUserId('admin'); + $existingTag->setDisplayName('Hello Hello Hello 👋'); + $existingTag->setImapLabel('Hello_Hello_&2D3cSw-'); + $existingTag->setColor('#0082c9'); + + $this->tagMapper->expects($this->once()) + ->method('getTagByImapLabel') + ->willReturn($existingTag); + $this->tagMapper->expects($this->never()) + ->method('insert'); + + $tag = $this->manager->createTag('Hello Hello 👋', '#e9322d', 'admin'); + + self::assertEquals('admin', $tag->getUserId()); + self::assertEquals('Hello Hello Hello 👋', $tag->getDisplayName()); + self::assertEquals('Hello_Hello_&2D3cSw-', $tag->getImapLabel()); + self::assertEquals('#0082c9', $tag->getColor()); + } + + public function testUpdateTag(): void { + $existingTag = new Tag(); + $existingTag->setId(100); + $existingTag->setUserId('admin'); + $existingTag->setDisplayName('Hello Hello Hello 👋'); + $existingTag->setImapLabel('Hello_Hello_&2D3cSw-'); + $existingTag->setColor('#0082c9'); + + $this->tagMapper->expects($this->once()) + ->method('getTagForUser') + ->willReturn($existingTag); + $this->tagMapper->expects($this->once()) + ->method('update') + ->willReturnCallback(static function (Tag $tag) { + return $tag; + }); + + $tag = $this->manager->updateTag(100, 'Hello Hello 👋', '#0082c9', 'admin'); + + self::assertEquals('admin', $tag->getUserId()); + self::assertEquals('Hello Hello 👋', $tag->getDisplayName()); + self::assertEquals('Hello_Hello_&2D3cSw-', $tag->getImapLabel()); + self::assertEquals('#0082c9', $tag->getColor()); + } + + public function testUpdateTagUnknownTag(): void { + $this->expectException(ClientException::class); + $this->expectExceptionMessage('Tag not found'); + + $this->tagMapper->expects($this->once()) + ->method('getTagForUser') + ->willThrowException(new DoesNotExistException('Computer says no')); + $this->tagMapper->expects($this->never()) + ->method('update'); + + $this->manager->updateTag(100, 'Hello Hello 👋', '#0082c9', 'admin'); + } } |