diff --git a/.changes/unreleased/Fixed-20230906-154856.yaml b/.changes/unreleased/Fixed-20230906-154856.yaml new file mode 100644 index 000000000..73fb2dc48 --- /dev/null +++ b/.changes/unreleased/Fixed-20230906-154856.yaml @@ -0,0 +1,5 @@ +kind: Fixed +body: Do not send an email to creator twice when adding a comment to a notification +time: 2023-09-06T15:48:56.991246312+02:00 +custom: + Issue: "" diff --git a/src/Bundle/ChillMainBundle/Notification/Email/NotificationMailer.php b/src/Bundle/ChillMainBundle/Notification/Email/NotificationMailer.php index 5290492b1..8facf00b9 100644 --- a/src/Bundle/ChillMainBundle/Notification/Email/NotificationMailer.php +++ b/src/Bundle/ChillMainBundle/Notification/Email/NotificationMailer.php @@ -40,13 +40,18 @@ class NotificationMailer public function postPersistComment(NotificationComment $comment, PostPersistEventArgs $eventArgs): void { - foreach ( - array_merge( - $comment->getNotification()->getAddressees()->toArray(), - [$comment->getNotification()->getSender()] - ) as $dest - ) { - if (null === $dest->getEmail() || $comment->getCreatedBy() !== $dest) { + $dests = [$comment->getNotification()->getSender(), ...$comment->getNotification()->getAddressees()->toArray()]; + + $uniqueDests = []; + foreach ($dests as $dest) { + // avoid duplication + if (in_array(spl_object_hash($dest), $uniqueDests, true)) { + continue; + } + $uniqueDests[] = spl_object_hash($dest); + + // do not send if the sender does not have any email, nor to the creator of the comment + if (null === $dest->getEmail() || $comment->getCreatedBy() === $dest) { continue; } $email = new TemplatedEmail(); diff --git a/src/Bundle/ChillMainBundle/Tests/Notification/Email/NotificationMailerTest.php b/src/Bundle/ChillMainBundle/Tests/Notification/Email/NotificationMailerTest.php new file mode 100644 index 000000000..4c1ae5d42 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Tests/Notification/Email/NotificationMailerTest.php @@ -0,0 +1,118 @@ +expectNotToPerformAssertions(); + $user1 = (new User())->setEmail('user1@foo.com'); + $user2 = (new User())->setEmail('user2@foo.com'); + $user3 = (new User())->setEmail('user3@foo.com'); + + $notification = new Notification(); + $notification + ->setTitle('test notification') + ->setSender($user1) + ->addAddressee($user2) + ->addAddressee($user3) + ; + + $comment = (new NotificationComment()) + ->setContent("foo bar baz") + ->setCreatedBy($user2) + ; + $notification->addComment($comment); + + $mailer = $this->prophesize(MailerInterface::class); + + // a mail only to user1 and user3 should have been sent + $mailer->send(Argument::that(function (Email $email) { + foreach ($email->getTo() as $address) { + if ($address->getAddress() === 'user1@foo.com' || $address->getAddress() === 'user3@foo.com') { + return true; + } + } + + return false; + })); + + $objectManager = $this->prophesize(EntityManagerInterface::class); + + $mailer = $this->buildNotificationMailer($mailer->reveal()); + $mailer->postPersistComment($comment, new PostPersistEventArgs($comment, $objectManager->reveal())); + } + + public function testPostPersistCommentDestWithNullEmail(): void + { + $this->expectNotToPerformAssertions(); + $user1 = (new User())->setEmail('user1@foo.com'); + $user2 = (new User())->setEmail('user2@foo.com'); + $user3 = (new User())->setEmail(null); + + $notification = new Notification(); + $notification + ->setTitle('test notification') + ->setSender($user1) + ->addAddressee($user2) + ->addAddressee($user3) + ; + + $comment = (new NotificationComment()) + ->setContent("foo bar baz") + ->setCreatedBy($user2) + ; + $notification->addComment($comment); + + $mailer = $this->prophesize(MailerInterface::class); + + // a mail only to user1 and user3 should have been sent + $mailer->send(Argument::that(function (Email $email) { + foreach ($email->getTo() as $address) { + if ($address->getAddress() === 'user1@foo.com') { + return true; + } + } + + return false; + })); + + $objectManager = $this->prophesize(EntityManagerInterface::class); + + $mailer = $this->buildNotificationMailer($mailer->reveal()); + $mailer->postPersistComment($comment, new PostPersistEventArgs($comment, $objectManager->reveal())); + } + + private function buildNotificationMailer( + MailerInterface $mailer = null, + ): NotificationMailer + { + return new NotificationMailer( + $mailer, + new NullLogger(), + new Translator('fr') + ); + } + + + +}