mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-25 16:14:59 +00:00
Resolve "Notification: envoi à des groupes utilisateurs"
This commit is contained in:
@@ -9,7 +9,7 @@ declare(strict_types=1);
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Entity;
|
||||
namespace Chill\MainBundle\Tests\Entity;
|
||||
|
||||
use Chill\MainBundle\Entity\Notification;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
@@ -49,8 +49,8 @@ final class NotificationTest extends KernelTestCase
|
||||
$notification = new Notification();
|
||||
$notification->addAddressee($user1 = new User());
|
||||
$notification->addAddressee($user2 = new User());
|
||||
$notification->getAddressees()->add($user3 = new User());
|
||||
$notification->getAddressees()->add($user4 = new User());
|
||||
$notification->addAddressee($user3 = new User());
|
||||
$notification->addAddressee($user4 = new User());
|
||||
|
||||
$this->assertCount(4, $notification->getAddressees());
|
||||
|
||||
@@ -85,6 +85,30 @@ final class NotificationTest extends KernelTestCase
|
||||
$this->assertNotContains('other', $notification->getAddressesEmailsAdded());
|
||||
}
|
||||
|
||||
public function testIsSendImmediately(): void
|
||||
{
|
||||
$notification = new Notification();
|
||||
$notification->setType('test_notification_type');
|
||||
|
||||
$user = new User();
|
||||
|
||||
// no notification flags
|
||||
$this->assertTrue($user->isNotificationSendImmediately($notification->getType()), 'Should return true when no notification flags are set, by default immediate email');
|
||||
|
||||
// immediate-email preference
|
||||
$user->setNotificationFlags(['test_notification_type' => [User::NOTIF_FLAG_IMMEDIATE_EMAIL, User::NOTIF_FLAG_DAILY_DIGEST]]);
|
||||
$this->assertTrue($user->isNotificationSendImmediately($notification->getType()), 'Should return true when preferences contain immediate-email');
|
||||
|
||||
// daily-email preference
|
||||
$user->setNotificationFlags(['test_notification_type' => [User::NOTIF_FLAG_DAILY_DIGEST]]);
|
||||
$this->assertFalse($user->isNotificationSendImmediately($notification->getType()), 'Should return false when preference is daily-email only');
|
||||
$this->assertTrue($user->isNotificationDailyDigest($notification->getType()), 'Should return true when preference is daily-email');
|
||||
|
||||
// a different notification type
|
||||
$notification->setType('other_notification_type');
|
||||
$this->assertTrue($user->isNotificationSendImmediately($notification->getType()), 'Should return false when notification type does not match any preference');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider generateNotificationData
|
||||
*/
|
||||
|
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Tests\Notification\Email;
|
||||
|
||||
use Chill\MainBundle\Notification\Email\DailyNotificationDigestCronjob;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
|
||||
/**
|
||||
* Run functional test on the cronjob.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @coversNothing
|
||||
*/
|
||||
class DailyNotificationDigestCronJobFunctionalTest extends KernelTestCase
|
||||
{
|
||||
private DailyNotificationDigestCronjob $dailyNotificationDigestCronjob;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
self::bootKernel();
|
||||
|
||||
$this->dailyNotificationDigestCronjob = self::getContainer()->get(DailyNotificationDigestCronjob::class);
|
||||
}
|
||||
|
||||
public function testRunWithNullPreviousExecutionData(): void
|
||||
{
|
||||
$actual = $this->dailyNotificationDigestCronjob->run([]);
|
||||
|
||||
self::assertArrayHasKey('last_execution', $actual);
|
||||
self::assertInstanceOf(
|
||||
\DateTimeImmutable::class,
|
||||
\DateTimeImmutable::createFromFormat('Y-m-d-H:i:s.u e', $actual['last_execution']),
|
||||
'test that the string can be converted to a date'
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Tests\Notification\Email;
|
||||
|
||||
use Chill\MainBundle\Notification\Email\DailyNotificationDigestCronjob;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Clock\ClockInterface;
|
||||
use Symfony\Component\Messenger\MessageBusInterface;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @coversNothing
|
||||
*/
|
||||
class DailyNotificationDigestCronJobTest extends TestCase
|
||||
{
|
||||
private ClockInterface $clock;
|
||||
private Connection $connection;
|
||||
private MessageBusInterface $messageBus;
|
||||
private LoggerInterface $logger;
|
||||
private DailyNotificationDigestCronjob $cronjob;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->clock = $this->createMock(ClockInterface::class);
|
||||
$this->connection = $this->createMock(Connection::class);
|
||||
$this->messageBus = $this->createMock(MessageBusInterface::class);
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
|
||||
$this->cronjob = new DailyNotificationDigestCronjob(
|
||||
$this->clock,
|
||||
$this->connection,
|
||||
$this->messageBus,
|
||||
$this->logger
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetKey(): void
|
||||
{
|
||||
$this->assertEquals('daily-notification-digest', $this->cronjob->getKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider canRunTimeDataProvider
|
||||
*/
|
||||
public function testCanRunWithNullCronJobExecution(int $hour, bool $expected): void
|
||||
{
|
||||
$now = new \DateTimeImmutable("2024-01-01 {$hour}:00:00");
|
||||
$this->clock->expects($this->once())
|
||||
->method('now')
|
||||
->willReturn($now);
|
||||
|
||||
$result = $this->cronjob->canRun(null);
|
||||
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public static function canRunTimeDataProvider(): array
|
||||
{
|
||||
return [
|
||||
'hour 5 - should not run' => [5, false],
|
||||
'hour 6 - should run' => [6, true],
|
||||
'hour 7 - should run' => [7, true],
|
||||
'hour 8 - should run' => [8, true],
|
||||
'hour 9 - should not run' => [9, false],
|
||||
'hour 10 - should not run' => [10, false],
|
||||
'hour 23 - should not run' => [23, false],
|
||||
];
|
||||
}
|
||||
}
|
@@ -17,13 +17,18 @@ use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Notification\Email\NotificationMailer;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Event\PostPersistEventArgs;
|
||||
use PHPUnit\Framework\MockObject\Exception;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\Argument;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Psr\Log\NullLogger;
|
||||
use Symfony\Component\Mailer\MailerInterface;
|
||||
use Symfony\Component\Messenger\Envelope;
|
||||
use Symfony\Component\Messenger\MessageBusInterface;
|
||||
use Symfony\Component\Mime\Email;
|
||||
use Symfony\Component\Translation\Translator;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use Chill\MainBundle\Notification\Email\NotificationEmailMessages\SendImmediateNotificationEmailMessage;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@@ -112,13 +117,149 @@ class NotificationMailerTest extends TestCase
|
||||
$mailer->postPersistComment($comment, new PostPersistEventArgs($comment, $objectManager->reveal()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \ReflectionException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function testProcessNotificationForAddresseeWithImmediateEmailPreference(): void
|
||||
{
|
||||
// Create a real notification entity
|
||||
$notification = new Notification();
|
||||
$notification->setType('test_notification_type');
|
||||
|
||||
// Use reflection to set the ID since it's normally generated by the database
|
||||
$reflectionNotification = new \ReflectionClass(Notification::class);
|
||||
$idProperty = $reflectionNotification->getProperty('id');
|
||||
$idProperty->setAccessible(true);
|
||||
$idProperty->setValue($notification, 123);
|
||||
|
||||
// Create a real user entity
|
||||
$user = new User();
|
||||
$user->setEmail('user@example.com');
|
||||
|
||||
// Use reflection to set the ID since it's normally generated by the database
|
||||
$reflectionUser = new \ReflectionClass(User::class);
|
||||
$idProperty = $reflectionUser->getProperty('id');
|
||||
$idProperty->setAccessible(true);
|
||||
$idProperty->setValue($user, 456);
|
||||
|
||||
// Set notification flags for the user
|
||||
$user->setNotificationFlags(['test_notification_type' => [User::NOTIF_FLAG_IMMEDIATE_EMAIL]]);
|
||||
|
||||
$messageBus = $this->createMock(MessageBusInterface::class);
|
||||
$messageBus->expects($this->once())
|
||||
->method('dispatch')
|
||||
->with($this->callback(fn (SendImmediateNotificationEmailMessage $message) => 123 === $message->getNotificationId()
|
||||
&& 456 === $message->getAddresseeId()))
|
||||
->willReturn(new Envelope(new \stdClass()));
|
||||
|
||||
$mailer = $this->buildNotificationMailer(null, $messageBus);
|
||||
|
||||
// Call the method that processes notifications
|
||||
$reflection = new \ReflectionClass(NotificationMailer::class);
|
||||
$method = $reflection->getMethod('processNotificationForAddressee');
|
||||
$method->setAccessible(true);
|
||||
$method->invoke($mailer, $notification, $user);
|
||||
}
|
||||
|
||||
public function testSendDailyDigest(): void
|
||||
{
|
||||
// Create a user
|
||||
$user = new User();
|
||||
$user->setEmail('user@example.com');
|
||||
|
||||
// Create some notifications
|
||||
$notification = $this->prophesize(Notification::class);
|
||||
$notification->getTitle()->willReturn('Notification 1');
|
||||
$notification->getMessage()->willReturn('Message 1');
|
||||
$notification->getId()->willReturn(123);
|
||||
|
||||
$notification2 = $this->prophesize(Notification::class);
|
||||
$notification2->getTitle()->willReturn('Notification 2');
|
||||
$notification2->getMessage()->willReturn('Message 2');
|
||||
$notification2->getId()->willReturn(456);
|
||||
|
||||
$notifications = [$notification, $notification2];
|
||||
|
||||
// Mock the mailer to verify that an email is sent with the correct parameters
|
||||
$mailer = $this->prophesize(MailerInterface::class);
|
||||
$mailer->send(Argument::that(function ($email) use ($user) {
|
||||
// Verify that the email is sent to the correct user
|
||||
foreach ($email->getTo() as $address) {
|
||||
if ($user->getEmail() === $address->getAddress()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}))->shouldBeCalledOnce();
|
||||
|
||||
// Create a translator that returns a fixed string for the subject
|
||||
$translator = $this->prophesize(TranslatorInterface::class);
|
||||
$translator->trans('notification.Daily Notification Digest')->willReturn('Daily Digest');
|
||||
|
||||
// Create the notification mailer with the mocked mailer and translator
|
||||
$notificationMailer = $this->buildNotificationMailer($mailer->reveal(), null, $translator->reveal());
|
||||
|
||||
// Call the sendDailyDigest method
|
||||
$notificationMailer->sendDailyDigest($user, $notifications);
|
||||
}
|
||||
|
||||
public function testSendDailyDigestWithNoNotifications(): void
|
||||
{
|
||||
// Create a user
|
||||
$user = new User();
|
||||
$user->setEmail('user@example.com');
|
||||
|
||||
// Empty notifications array
|
||||
$notifications = [];
|
||||
|
||||
// Mock the mailer to verify that no email is sent
|
||||
$mailer = $this->prophesize(MailerInterface::class);
|
||||
$mailer->send(Argument::any())->shouldNotBeCalled();
|
||||
|
||||
// Create the notification mailer with the mocked mailer
|
||||
$notificationMailer = $this->buildNotificationMailer($mailer->reveal());
|
||||
|
||||
// Call the sendDailyDigest method
|
||||
$notificationMailer->sendDailyDigest($user, $notifications);
|
||||
}
|
||||
|
||||
public function testSendDailyDigestWithUserHavingNoEmail(): void
|
||||
{
|
||||
// Create a user with no email
|
||||
$user = new User();
|
||||
$user->setEmail(null);
|
||||
|
||||
// Create some notifications
|
||||
$notification = $this->prophesize(Notification::class);
|
||||
$notification->getTitle()->willReturn('Notification 1');
|
||||
$notification->getMessage()->willReturn('Message 1');
|
||||
$notification->getId()->willReturn(123);
|
||||
|
||||
$notifications = [$notification];
|
||||
|
||||
// Mock the mailer to verify that no email is sent
|
||||
$mailer = $this->prophesize(MailerInterface::class);
|
||||
$mailer->send(Argument::any())->shouldNotBeCalled();
|
||||
|
||||
// Create the notification mailer with the mocked mailer
|
||||
$notificationMailer = $this->buildNotificationMailer($mailer->reveal());
|
||||
|
||||
// Call the sendDailyDigest method
|
||||
$notificationMailer->sendDailyDigest($user, $notifications);
|
||||
}
|
||||
|
||||
private function buildNotificationMailer(
|
||||
?MailerInterface $mailer = null,
|
||||
?MessageBusInterface $messageBus = null,
|
||||
?TranslatorInterface $translator = null,
|
||||
): NotificationMailer {
|
||||
return new NotificationMailer(
|
||||
$mailer,
|
||||
$mailer ?? $this->prophesize(MailerInterface::class)->reveal(),
|
||||
new NullLogger(),
|
||||
new Translator('fr')
|
||||
$messageBus ?? $this->prophesize(MessageBusInterface::class)->reveal(),
|
||||
$translator ?? new Translator('fr')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user