diff options
author | Christoph Wurst <christoph@winzerhof-wurst.at> | 2020-03-25 17:05:02 +0300 |
---|---|---|
committer | Christoph Wurst <christoph@winzerhof-wurst.at> | 2020-03-26 12:15:05 +0300 |
commit | 3410205cfe3243f8cb7d24b0835f26a976538016 (patch) | |
tree | 2c07f38b38498b88ede19fbbded805ca6304ddd8 | |
parent | 4127e4cd22b61f456c56c0a42b6e7bfbbb33c261 (diff) |
Dispatch an interaction event for sent messages
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
-rw-r--r-- | lib/AppInfo/BootstrapSingleton.php | 4 | ||||
-rw-r--r-- | lib/Events/MessageSentEvent.php | 2 | ||||
-rw-r--r-- | lib/Listener/InteractionListener.php | 81 | ||||
-rw-r--r-- | tests/Unit/Listener/InteractionListenerTest.php | 99 |
4 files changed, 183 insertions, 3 deletions
diff --git a/lib/AppInfo/BootstrapSingleton.php b/lib/AppInfo/BootstrapSingleton.php index 3275aa2be..cf0afa67d 100644 --- a/lib/AppInfo/BootstrapSingleton.php +++ b/lib/AppInfo/BootstrapSingleton.php @@ -40,6 +40,7 @@ use OCA\Mail\Listener\AddressCollectionListener; use OCA\Mail\Listener\DeleteDraftListener; use OCA\Mail\Listener\DraftMailboxCreatorListener; use OCA\Mail\Listener\FlagRepliedMessageListener; +use OCA\Mail\Listener\InteractionListener; use OCA\Mail\Listener\MessageDeletedCacheUpdaterListener; use OCA\Mail\Listener\SaveSentMessageListener; use OCA\Mail\Listener\TrashMailboxCreatorListener; @@ -54,8 +55,6 @@ use OCA\Mail\Service\MailTransmission; use OCA\Mail\Service\UserPreferenceSevice; use OCP\AppFramework\IAppContainer; use OCP\EventDispatcher\IEventDispatcher; -use OCP\IUser; -use OCP\IUserManager; use OCP\Util; class BootstrapSingleton { @@ -130,6 +129,7 @@ class BootstrapSingleton { $dispatcher->addServiceListener(MessageSentEvent::class, AddressCollectionListener::class); $dispatcher->addServiceListener(MessageSentEvent::class, DeleteDraftListener::class); $dispatcher->addServiceListener(MessageSentEvent::class, FlagRepliedMessageListener::class); + $dispatcher->addServiceListener(MessageSentEvent::class, InteractionListener::class); $dispatcher->addServiceListener(MessageSentEvent::class, SaveSentMessageListener::class); $dispatcher->addServiceListener(SaveDraftEvent::class, DraftMailboxCreatorListener::class); } diff --git a/lib/Events/MessageSentEvent.php b/lib/Events/MessageSentEvent.php index 9d132bdbd..c0642e68a 100644 --- a/lib/Events/MessageSentEvent.php +++ b/lib/Events/MessageSentEvent.php @@ -53,7 +53,7 @@ class MessageSentEvent extends Event { public function __construct(Account $account, NewMessageData $newMessageData, ?RepliedMessageData $repliedMessageData, - ?int $draftUid = null, + ?int $draftUid, IMessage $message, Horde_Mime_Mail $mail) { parent::__construct(); diff --git a/lib/Listener/InteractionListener.php b/lib/Listener/InteractionListener.php new file mode 100644 index 000000000..ae4e63551 --- /dev/null +++ b/lib/Listener/InteractionListener.php @@ -0,0 +1,81 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright 2020 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @author 2020 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @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\Listener; + +use OCA\Mail\Address; +use OCA\Mail\Events\MessageSentEvent; +use OCP\Contacts\Events\ContactInteractedWithEvent; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventDispatcher; +use OCP\EventDispatcher\IEventListener; +use OCP\ILogger; +use OCP\IUserSession; + +class InteractionListener implements IEventListener { + + /** @var IEventDispatcher */ + private $dispatcher; + + /** @var IUserSession */ + private $userSession; + + /** @var ILogger */ + private $logger; + + public function __construct(IEventDispatcher $dispatcher, + IUserSession $userSession, + ILogger $logger) { + $this->dispatcher = $dispatcher; + $this->userSession = $userSession; + $this->logger = $logger; + } + + /** + * @inheritDoc + */ + public function handle(Event $event): void { + if (!($event instanceof MessageSentEvent)) { + return; + } + + $user = $this->userSession->getUser(); + $recipients = $event->getMessage()->getTo() + ->merge($event->getMessage()->getCC()) + ->merge($event->getMessage()->getBCC()); + foreach ($recipients->iterate() as $recipient) { + /** @var Address $recipient */ + $interactionEvent = new ContactInteractedWithEvent($user); + $email = $recipient->getEmail(); + if ($email === null) { + // Weird, bot ok + continue; + } + $interactionEvent->setEmail($email); + $this->dispatcher->dispatch(ContactInteractedWithEvent::class, $interactionEvent); + } + } + +} diff --git a/tests/Unit/Listener/InteractionListenerTest.php b/tests/Unit/Listener/InteractionListenerTest.php new file mode 100644 index 000000000..69d65e058 --- /dev/null +++ b/tests/Unit/Listener/InteractionListenerTest.php @@ -0,0 +1,99 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright 2020 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @author 2020 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @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\Listener; + +use ChristophWurst\Nextcloud\Testing\ServiceMockObject; +use ChristophWurst\Nextcloud\Testing\TestCase; +use OCA\Mail\Address; +use OCA\Mail\AddressList; +use OCA\Mail\Events\MessageSentEvent; +use OCA\Mail\Listener\InteractionListener; +use OCA\Mail\Model\IMessage; +use OCP\EventDispatcher\Event; +use OCP\IUser; + +class InteractionListenerTest extends TestCase { + + /** @var ServiceMockObject */ + private $serviceMock; + + /** @var InteractionListener */ + private $listener; + + protected function setUp(): void { + parent::setUp(); + + $this->serviceMock = $this->createServiceMock(InteractionListener::class); + + $this->listener = $this->serviceMock->getService(); + } + + public function testHandleUnrelated(): void { + $event = new Event(); + + $this->listener->handle($event); + + $this->addToAssertionCount(1); + } + + public function testHandle(): void { + $to = new AddressList([ + new Address('rec 1', 'u1@domain.tld'), + new Address('rec 1', 'u2@domain.tld'), + ]); + $cc = new AddressList([ + new Address('rec 1', 'u3@domain.tld'), + ]); + $bcc = new AddressList([ + new Address('rec 1', 'u4@domain.tld'), + new Address('rec 1', 'u2@domain.tld'), // intentional duplicate + ]); + $event = $this->createMock(MessageSentEvent::class); + $message = $this->createMock(IMessage::class); + $event + ->method('getMessage') + ->willReturn($message); + $message + ->method('getTo') + ->willReturn($to); + $message + ->method('getCC') + ->willReturn($cc); + $message + ->method('getBCC') + ->willReturn($bcc); + $user = $this->createMock(IUser::class); + $this->serviceMock->getParameter('userSession') + ->method('getUser') + ->willReturn($user); + $this->serviceMock->getParameter('dispatcher') + ->expects($this->exactly(4)) + ->method('dispatch'); + + $this->listener->handle($event); + } + +} |