mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
command for sending bulk sms with tests
This commit is contained in:
parent
4c0fef4f44
commit
28c952521f
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\CalendarBundle\Command;
|
||||||
|
|
||||||
|
use Chill\CalendarBundle\Service\ShortMessageNotification\BulkCalendarShortMessageSender;
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
class SendShortMessageOnEligibleCalendar extends Command
|
||||||
|
{
|
||||||
|
private BulkCalendarShortMessageSender $messageSender;
|
||||||
|
|
||||||
|
public function __construct(BulkCalendarShortMessageSender $messageSender)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->messageSender = $messageSender;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'chill:calendar:send-short-messages';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
|
{
|
||||||
|
$this->messageSender->sendBulkMessageToEligibleCalendars();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
@ -567,9 +567,11 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setSmsStatus(string $smsStatus): void
|
public function setSmsStatus(string $smsStatus): self
|
||||||
{
|
{
|
||||||
$this->smsStatus = $smsStatus;
|
$this->smsStatus = $smsStatus;
|
||||||
|
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setStartDate(DateTimeImmutable $startDate): self
|
public function setStartDate(DateTimeImmutable $startDate): self
|
||||||
|
@ -100,17 +100,22 @@ class CalendarRepository implements ObjectRepository
|
|||||||
|
|
||||||
$qb->where(
|
$qb->where(
|
||||||
$qb->expr()->andX(
|
$qb->expr()->andX(
|
||||||
$qb->expr()->eq('c.sendSMS', "'TRUE'"),
|
$qb->expr()->eq('c.sendSMS', ':true'),
|
||||||
$qb->expr()->gte('c.startDate', ':startDate'),
|
$qb->expr()->gte('c.startDate', ':startDate'),
|
||||||
$qb->expr()->lt('c.startDate', ':endDate'),
|
$qb->expr()->lt('c.startDate', ':endDate'),
|
||||||
$qb->expr()->in('c.smsStatus', ':statuses')
|
$qb->expr()->orX(
|
||||||
|
$qb->expr()->eq('c.smsStatus', ':pending'),
|
||||||
|
$qb->expr()->eq('c.smsStatus', ':cancel_pending')
|
||||||
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
$qb->setParameters([
|
$qb->setParameters([
|
||||||
|
'true' => true,
|
||||||
'startDate' => $startDate,
|
'startDate' => $startDate,
|
||||||
'endDate' => $endDate,
|
'endDate' => $endDate,
|
||||||
'statuses' => [Calendar::SMS_PENDING, Calendar::SMS_CANCEL_PENDING],
|
'pending' => Calendar::SMS_PENDING,
|
||||||
|
'cancel_pending' => Calendar::SMS_CANCEL_PENDING,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $qb;
|
return $qb;
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
Votre RDV avec votre travailleur social {{ calendar.mainUser.label }} prévu le {{ calendar.startDate|format_date('short', locale='fr') }} à {{ calendar.startDate|format_time('short', locale='fr') }} est annulé. {% if calendar.mainUser.mainLocation is not null and calendar.mainUser.mainLocation.phonenumber1 is not null %} En cas de question, appelez-nous au {{ calendar.mainUser.mainLocation.phonenumber1|chill_format_phonenumber }}.{% endif %}
|
@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\CalendarBundle\Service\ShortMessageNotification;
|
||||||
|
|
||||||
|
use Chill\CalendarBundle\Entity\Calendar;
|
||||||
|
use DateTimeImmutable;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Symfony\Component\Messenger\MessageBusInterface;
|
||||||
|
|
||||||
|
class BulkCalendarShortMessageSender
|
||||||
|
{
|
||||||
|
private EntityManagerInterface $em;
|
||||||
|
|
||||||
|
private LoggerInterface $logger;
|
||||||
|
|
||||||
|
private MessageBusInterface $messageBus;
|
||||||
|
|
||||||
|
private ShortMessageForCalendarBuilderInterface $messageForCalendarBuilder;
|
||||||
|
|
||||||
|
private CalendarForShortMessageProvider $provider;
|
||||||
|
|
||||||
|
public function __construct(CalendarForShortMessageProvider $provider, EntityManagerInterface $em, LoggerInterface $logger, MessageBusInterface $messageBus, ShortMessageForCalendarBuilderInterface $messageForCalendarBuilder)
|
||||||
|
{
|
||||||
|
$this->provider = $provider;
|
||||||
|
$this->em = $em;
|
||||||
|
$this->logger = $logger;
|
||||||
|
$this->messageBus = $messageBus;
|
||||||
|
$this->messageForCalendarBuilder = $messageForCalendarBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sendBulkMessageToEligibleCalendars()
|
||||||
|
{
|
||||||
|
$countCalendars = 0;
|
||||||
|
$countSms = 0;
|
||||||
|
|
||||||
|
foreach ($this->provider->getCalendars(new DateTimeImmutable('now')) as $calendar) {
|
||||||
|
$smses = $this->messageForCalendarBuilder->buildMessageForCalendar($calendar);
|
||||||
|
|
||||||
|
foreach ($smses as $sms) {
|
||||||
|
$this->messageBus->dispatch($sms);
|
||||||
|
++$countSms;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->em
|
||||||
|
->createQuery('UPDATE ' . Calendar::class . ' c SET c.smsStatus = :smsStatus WHERE c.id = :id')
|
||||||
|
->setParameters(['smsStatus' => Calendar::SMS_SENT, 'id' => $calendar->getId()])
|
||||||
|
->execute();
|
||||||
|
++$countCalendars;
|
||||||
|
$this->em->refresh($calendar);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->logger->info(__CLASS__ . 'a bulk of messages was sent', ['count_calendars' => $countCalendars, 'count_sms' => $countSms]);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\CalendarBundle\Service\ShortMessageNotification;
|
||||||
|
|
||||||
|
use Chill\CalendarBundle\Entity\Calendar;
|
||||||
|
use Chill\CalendarBundle\Repository\CalendarRepository;
|
||||||
|
use DateTimeImmutable;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use function count;
|
||||||
|
|
||||||
|
class CalendarForShortMessageProvider
|
||||||
|
{
|
||||||
|
private CalendarRepository $calendarRepository;
|
||||||
|
|
||||||
|
private EntityManagerInterface $em;
|
||||||
|
|
||||||
|
private RangeGeneratorInterface $rangeGenerator;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
CalendarRepository $calendarRepository,
|
||||||
|
EntityManagerInterface $em,
|
||||||
|
RangeGeneratorInterface $rangeGenerator
|
||||||
|
) {
|
||||||
|
$this->calendarRepository = $calendarRepository;
|
||||||
|
$this->em = $em;
|
||||||
|
$this->rangeGenerator = $rangeGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate calendars instance.
|
||||||
|
*
|
||||||
|
* Warning: this method takes care of clearing the EntityManager at regular interval
|
||||||
|
*
|
||||||
|
* @return iterable|Calendar[]
|
||||||
|
*/
|
||||||
|
public function getCalendars(DateTimeImmutable $at): iterable
|
||||||
|
{
|
||||||
|
['startDate' => $startDate, 'endDate' => $endDate] = $this->rangeGenerator
|
||||||
|
->generateRange($at);
|
||||||
|
|
||||||
|
$offset = 0;
|
||||||
|
$batchSize = 10;
|
||||||
|
|
||||||
|
$calendars = $this->calendarRepository
|
||||||
|
->findByNotificationAvailable($startDate, $endDate, $batchSize, $offset);
|
||||||
|
|
||||||
|
do {
|
||||||
|
foreach ($calendars as $calendar) {
|
||||||
|
++$offset;
|
||||||
|
|
||||||
|
yield $calendar;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->em->clear();
|
||||||
|
|
||||||
|
$calendars = $this->calendarRepository
|
||||||
|
->findByNotificationAvailable($startDate, $endDate, $batchSize, $offset);
|
||||||
|
} while (count($calendars) === $batchSize);
|
||||||
|
}
|
||||||
|
}
|
@ -12,26 +12,22 @@ declare(strict_types=1);
|
|||||||
namespace Chill\CalendarBundle\Service\ShortMessageNotification;
|
namespace Chill\CalendarBundle\Service\ShortMessageNotification;
|
||||||
|
|
||||||
use Chill\CalendarBundle\Entity\Calendar;
|
use Chill\CalendarBundle\Entity\Calendar;
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
use Chill\MainBundle\Service\ShortMessage\ShortMessage;
|
||||||
use Symfony\Component\Templating\EngineInterface;
|
use Symfony\Component\Templating\EngineInterface;
|
||||||
|
|
||||||
class DefaultShortMessageForCalendarBuilder implements ShortMessageForCalendarBuilderInterface
|
class DefaultShortMessageForCalendarBuilder implements ShortMessageForCalendarBuilderInterface
|
||||||
{
|
{
|
||||||
private ?array $config = null;
|
|
||||||
|
|
||||||
private EngineInterface $engine;
|
private EngineInterface $engine;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ParameterBagInterface $parameterBag,
|
|
||||||
EngineInterface $engine
|
EngineInterface $engine
|
||||||
) {
|
) {
|
||||||
$this->config = $parameterBag->get('chill_calendar.short_messages');
|
|
||||||
$this->engine = $engine;
|
$this->engine = $engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildMessageForCalendar(Calendar $calendar): array
|
public function buildMessageForCalendar(Calendar $calendar): array
|
||||||
{
|
{
|
||||||
if (null === $this->config || true !== $calendar->getSendSMS()) {
|
if (true !== $calendar->getSendSMS()) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,10 +38,19 @@ class DefaultShortMessageForCalendarBuilder implements ShortMessageForCalendarBu
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$toUsers[] = new \Chill\MainBundle\Service\ShortMessage\ShortMessage(
|
if (Calendar::SMS_PENDING === $calendar->getSmsStatus()) {
|
||||||
$this->engine->render('@ChillCalendar/CalendarShortMessage/short_message.txt.twig', ['calendar' => $calendar]),
|
$toUsers[] = new ShortMessage(
|
||||||
$person->getMobilenumber()
|
$this->engine->render('@ChillCalendar/CalendarShortMessage/short_message.txt.twig', ['calendar' => $calendar]),
|
||||||
);
|
$person->getMobilenumber(),
|
||||||
|
ShortMessage::PRIORITY_LOW
|
||||||
|
);
|
||||||
|
} elseif (Calendar::SMS_CANCEL_PENDING === $calendar->getSmsStatus()) {
|
||||||
|
$toUsers[] = new ShortMessage(
|
||||||
|
$this->engine->render('@ChillCalendar/CalendarShortMessage/short_message_canceled.txt.twig', ['calendar' => $calendar]),
|
||||||
|
$person->getMobilenumber(),
|
||||||
|
ShortMessage::PRIORITY_LOW
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $toUsers;
|
return $toUsers;
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Chill\CalendarBundle\Service\ShortMessageNotification;
|
|
||||||
|
|
||||||
use Chill\CalendarBundle\Repository\CalendarRepository;
|
|
||||||
use Symfony\Component\Messenger\MessageBusInterface;
|
|
||||||
|
|
||||||
class Generator
|
|
||||||
{
|
|
||||||
private CalendarRepository $calendarRepository;
|
|
||||||
|
|
||||||
private MessageBusInterface $messageBus;
|
|
||||||
|
|
||||||
private RangeGeneratorInterface $rangeGenerator;
|
|
||||||
|
|
||||||
public function generateShortMessages(): void
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,128 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\CalendarBundle\Tests\Service\ShortMessageNotification;
|
||||||
|
|
||||||
|
use ArrayIterator;
|
||||||
|
use Chill\CalendarBundle\Entity\Calendar;
|
||||||
|
use Chill\CalendarBundle\Service\ShortMessageNotification\BulkCalendarShortMessageSender;
|
||||||
|
use Chill\CalendarBundle\Service\ShortMessageNotification\CalendarForShortMessageProvider;
|
||||||
|
use Chill\CalendarBundle\Service\ShortMessageNotification\ShortMessageForCalendarBuilderInterface;
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
|
use Chill\MainBundle\Service\ShortMessage\ShortMessage;
|
||||||
|
use Chill\MainBundle\Test\PrepareUserTrait;
|
||||||
|
use Chill\PersonBundle\DataFixtures\Helper\PersonRandomHelper;
|
||||||
|
use DateInterval;
|
||||||
|
use DateTimeImmutable;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use libphonenumber\PhoneNumberUtil;
|
||||||
|
use Prophecy\Argument;
|
||||||
|
use Prophecy\PhpUnit\ProphecyTrait;
|
||||||
|
use Psr\Log\NullLogger;
|
||||||
|
use stdClass;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||||
|
use Symfony\Component\Messenger\Envelope;
|
||||||
|
use Symfony\Component\Messenger\MessageBusInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
|
final class BulkCalendarShortMessageSenderTest extends KernelTestCase
|
||||||
|
{
|
||||||
|
use PersonRandomHelper;
|
||||||
|
|
||||||
|
use PrepareUserTrait;
|
||||||
|
|
||||||
|
use ProphecyTrait;
|
||||||
|
|
||||||
|
private array $toDelete = [];
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
self::bootKernel();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function tearDown(): void
|
||||||
|
{
|
||||||
|
self::bootKernel();
|
||||||
|
$em = self::$container->get(EntityManagerInterface::class);
|
||||||
|
|
||||||
|
foreach ($this->toDelete as [$entity, $id]) {
|
||||||
|
$entity = $em->find($entity, $id);
|
||||||
|
$em->remove($entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
$em->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSendBulkMessageToEligibleCalendar()
|
||||||
|
{
|
||||||
|
$em = self::$container->get(EntityManagerInterface::class);
|
||||||
|
$calendar = new Calendar();
|
||||||
|
$calendar
|
||||||
|
->addPerson($this->getRandomPerson($em))
|
||||||
|
->setMainUser($user = $this->prepareUser([]))
|
||||||
|
->setStartDate(new DateTimeImmutable('now'))
|
||||||
|
->setEndDate($calendar->getStartDate()->add(new DateInterval('PT30M')))
|
||||||
|
->setSendSMS(true);
|
||||||
|
|
||||||
|
$user->setUsername(uniqid());
|
||||||
|
$user->setEmail(uniqid() . '@gmail.com');
|
||||||
|
$calendar->getPersons()->first()->setAcceptSMS(true);
|
||||||
|
|
||||||
|
// hack to prevent side effect with messages
|
||||||
|
$calendar->preventEnqueueChanges = true;
|
||||||
|
|
||||||
|
$em->persist($user);
|
||||||
|
//$this->toDelete[] = [User::class, $user->getId()];
|
||||||
|
$em->persist($calendar);
|
||||||
|
//$this->toDelete[] = [Calendar::class, $calendar->getId()];
|
||||||
|
$em->flush();
|
||||||
|
|
||||||
|
$provider = $this->prophesize(CalendarForShortMessageProvider::class);
|
||||||
|
$provider->getCalendars(Argument::type(DateTimeImmutable::class))
|
||||||
|
->willReturn(new ArrayIterator([$calendar]));
|
||||||
|
|
||||||
|
$messageBuilder = $this->prophesize(ShortMessageForCalendarBuilderInterface::class);
|
||||||
|
$messageBuilder->buildMessageForCalendar(Argument::type(Calendar::class))
|
||||||
|
->willReturn(
|
||||||
|
[
|
||||||
|
new ShortMessage(
|
||||||
|
'content',
|
||||||
|
PhoneNumberUtil::getInstance()->parse('+32470123456', 'BE'),
|
||||||
|
ShortMessage::PRIORITY_MEDIUM
|
||||||
|
),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$bus = $this->prophesize(MessageBusInterface::class);
|
||||||
|
$bus->dispatch(Argument::type(ShortMessage::class))
|
||||||
|
->willReturn(new Envelope(new stdClass()))
|
||||||
|
->shouldBeCalledTimes(1);
|
||||||
|
|
||||||
|
$bulk = new BulkCalendarShortMessageSender(
|
||||||
|
$provider->reveal(),
|
||||||
|
$em,
|
||||||
|
new NullLogger(),
|
||||||
|
$bus->reveal(),
|
||||||
|
$messageBuilder->reveal()
|
||||||
|
);
|
||||||
|
|
||||||
|
$bulk->sendBulkMessageToEligibleCalendars();
|
||||||
|
|
||||||
|
$em->clear();
|
||||||
|
$calendar = $em->find(Calendar::class, $calendar->getId());
|
||||||
|
|
||||||
|
$this->assertEquals(Calendar::SMS_SENT, $calendar->getSmsStatus());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\CalendarBundle\Tests\Service\ShortMessageNotification;
|
||||||
|
|
||||||
|
use Chill\CalendarBundle\Entity\Calendar;
|
||||||
|
use Chill\CalendarBundle\Repository\CalendarRepository;
|
||||||
|
use Chill\CalendarBundle\Service\ShortMessageNotification\CalendarForShortMessageProvider;
|
||||||
|
use Chill\CalendarBundle\Service\ShortMessageNotification\DefaultRangeGenerator;
|
||||||
|
use DateTimeImmutable;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Prophecy\Argument;
|
||||||
|
use Prophecy\PhpUnit\ProphecyTrait;
|
||||||
|
use function count;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
|
final class CalendarForShortMessageProviderTest extends TestCase
|
||||||
|
{
|
||||||
|
use ProphecyTrait;
|
||||||
|
|
||||||
|
public function testGetCalendars()
|
||||||
|
{
|
||||||
|
$calendarRepository = $this->prophesize(CalendarRepository::class);
|
||||||
|
$calendarRepository->findByNotificationAvailable(
|
||||||
|
Argument::type(DateTimeImmutable::class),
|
||||||
|
Argument::type(DateTimeImmutable::class),
|
||||||
|
Argument::type('int'),
|
||||||
|
Argument::exact(0)
|
||||||
|
)->will(static function ($args) {
|
||||||
|
return array_fill(0, $args[2], new Calendar());
|
||||||
|
})->shouldBeCalledTimes(1);
|
||||||
|
$calendarRepository->findByNotificationAvailable(
|
||||||
|
Argument::type(DateTimeImmutable::class),
|
||||||
|
Argument::type(DateTimeImmutable::class),
|
||||||
|
Argument::type('int'),
|
||||||
|
Argument::not(0)
|
||||||
|
)->will(static function ($args) {
|
||||||
|
return array_fill(0, $args[2] - 1, new Calendar());
|
||||||
|
})->shouldBeCalledTimes(1);
|
||||||
|
|
||||||
|
$em = $this->prophesize(EntityManagerInterface::class);
|
||||||
|
$em->clear()->shouldBeCalled();
|
||||||
|
|
||||||
|
$provider = new CalendarForShortMessageProvider(
|
||||||
|
$calendarRepository->reveal(),
|
||||||
|
$em->reveal(),
|
||||||
|
new DefaultRangeGenerator()
|
||||||
|
);
|
||||||
|
|
||||||
|
$calendars = iterator_to_array($provider->getCalendars(new DateTimeImmutable('now')));
|
||||||
|
|
||||||
|
$this->assertGreaterThan(1, count($calendars));
|
||||||
|
$this->assertLessThan(100, count($calendars));
|
||||||
|
$this->assertContainsOnly(Calendar::class, $calendars);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetCalendarsWithOnlyOneCalendar()
|
||||||
|
{
|
||||||
|
$calendarRepository = $this->prophesize(CalendarRepository::class);
|
||||||
|
$calendarRepository->findByNotificationAvailable(
|
||||||
|
Argument::type(DateTimeImmutable::class),
|
||||||
|
Argument::type(DateTimeImmutable::class),
|
||||||
|
Argument::type('int'),
|
||||||
|
Argument::exact(0)
|
||||||
|
)->will(static function ($args) {
|
||||||
|
return array_fill(0, 1, new Calendar());
|
||||||
|
})->shouldBeCalledTimes(1);
|
||||||
|
$calendarRepository->findByNotificationAvailable(
|
||||||
|
Argument::type(DateTimeImmutable::class),
|
||||||
|
Argument::type(DateTimeImmutable::class),
|
||||||
|
Argument::type('int'),
|
||||||
|
Argument::not(0)
|
||||||
|
)->will(static function ($args) {
|
||||||
|
return [];
|
||||||
|
})->shouldBeCalledTimes(1);
|
||||||
|
|
||||||
|
$em = $this->prophesize(EntityManagerInterface::class);
|
||||||
|
$em->clear()->shouldBeCalled();
|
||||||
|
|
||||||
|
$provider = new CalendarForShortMessageProvider(
|
||||||
|
$calendarRepository->reveal(),
|
||||||
|
$em->reveal(),
|
||||||
|
new DefaultRangeGenerator()
|
||||||
|
);
|
||||||
|
|
||||||
|
$calendars = iterator_to_array($provider->getCalendars(new DateTimeImmutable('now')));
|
||||||
|
|
||||||
|
$this->assertEquals(1, count($calendars));
|
||||||
|
$this->assertContainsOnly(Calendar::class, $calendars);
|
||||||
|
}
|
||||||
|
}
|
@ -83,7 +83,12 @@ final class DefaultRangeGeneratorTest extends TestCase
|
|||||||
|
|
||||||
['startDate' => $actualStartDate, 'endDate' => $actualEndDate] = $generator->generateRange($date);
|
['startDate' => $actualStartDate, 'endDate' => $actualEndDate] = $generator->generateRange($date);
|
||||||
|
|
||||||
$this->assertEquals($startDate->format(DateTimeImmutable::ATOM), $actualStartDate->format(DateTimeImmutable::ATOM));
|
if (null === $startDate) {
|
||||||
$this->assertEquals($endDate->format(DateTimeImmutable::ATOM), $actualEndDate->format(DateTimeImmutable::ATOM));
|
$this->assertNull($actualStartDate);
|
||||||
|
$this->assertNull($actualEndDate);
|
||||||
|
} else {
|
||||||
|
$this->assertEquals($startDate->format(DateTimeImmutable::ATOM), $actualStartDate->format(DateTimeImmutable::ATOM));
|
||||||
|
$this->assertEquals($endDate->format(DateTimeImmutable::ATOM), $actualEndDate->format(DateTimeImmutable::ATOM));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,108 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\CalendarBundle\Tests\Service\ShortMessageNotification;
|
||||||
|
|
||||||
|
use Chill\CalendarBundle\Entity\Calendar;
|
||||||
|
use Chill\CalendarBundle\Service\ShortMessageNotification\DefaultShortMessageForCalendarBuilder;
|
||||||
|
use Chill\MainBundle\Entity\Location;
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use DateInterval;
|
||||||
|
use DateTimeImmutable;
|
||||||
|
use libphonenumber\PhoneNumberFormat;
|
||||||
|
use libphonenumber\PhoneNumberUtil;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Prophecy\Argument;
|
||||||
|
use Prophecy\PhpUnit\ProphecyTrait;
|
||||||
|
use Symfony\Component\Templating\EngineInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* @coversNothing
|
||||||
|
*/
|
||||||
|
final class DefaultShortMessageForCalendarBuilderTest extends TestCase
|
||||||
|
{
|
||||||
|
use ProphecyTrait;
|
||||||
|
|
||||||
|
private PhoneNumberUtil $phoneNumberUtil;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
$this->phoneNumberUtil = PhoneNumberUtil::getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBuildMessageForCalendar()
|
||||||
|
{
|
||||||
|
$calendar = new Calendar();
|
||||||
|
$calendar
|
||||||
|
->setStartDate(new DateTimeImmutable('now'))
|
||||||
|
->setEndDate($calendar->getStartDate()->add(new DateInterval('PT30M')))
|
||||||
|
->setMainUser($user = new User())
|
||||||
|
->addPerson($person = new Person())
|
||||||
|
->setSendSMS(false);
|
||||||
|
$user
|
||||||
|
->setLabel('Alex')
|
||||||
|
->setMainLocation($location = new Location());
|
||||||
|
$location->setName('LOCAMAT');
|
||||||
|
$person
|
||||||
|
->setMobilenumber($this->phoneNumberUtil->parse('+32470123456', 'BE'))
|
||||||
|
->setAcceptSMS(false);
|
||||||
|
|
||||||
|
$engine = $this->prophesize(EngineInterface::class);
|
||||||
|
$engine->render(Argument::exact('@ChillCalendar/CalendarShortMessage/short_message.txt.twig'), Argument::withKey('calendar'))
|
||||||
|
->willReturn('message content')
|
||||||
|
->shouldBeCalledTimes(1);
|
||||||
|
$engine->render(Argument::exact('@ChillCalendar/CalendarShortMessage/short_message_canceled.txt.twig'), Argument::withKey('calendar'))
|
||||||
|
->willReturn('message canceled')
|
||||||
|
->shouldBeCalledTimes(1);
|
||||||
|
|
||||||
|
$builder = new DefaultShortMessageForCalendarBuilder(
|
||||||
|
$engine->reveal()
|
||||||
|
);
|
||||||
|
|
||||||
|
// if the calendar should not send sms
|
||||||
|
$sms = $builder->buildMessageForCalendar($calendar);
|
||||||
|
$this->assertCount(0, $sms);
|
||||||
|
|
||||||
|
// if the person do not accept sms
|
||||||
|
$calendar->setSendSMS(true);
|
||||||
|
$sms = $builder->buildMessageForCalendar($calendar);
|
||||||
|
$this->assertCount(0, $sms);
|
||||||
|
|
||||||
|
// person accepts sms
|
||||||
|
$person->setAcceptSMS(true);
|
||||||
|
$sms = $builder->buildMessageForCalendar($calendar);
|
||||||
|
|
||||||
|
$this->assertCount(1, $sms);
|
||||||
|
$this->assertEquals(
|
||||||
|
'+32470123456',
|
||||||
|
$this->phoneNumberUtil->format($sms[0]->getPhoneNumber(), PhoneNumberFormat::E164)
|
||||||
|
);
|
||||||
|
$this->assertEquals('message content', $sms[0]->getContent());
|
||||||
|
$this->assertEquals('low', $sms[0]->getPriority());
|
||||||
|
|
||||||
|
// if the calendar is canceled
|
||||||
|
$calendar
|
||||||
|
->setSmsStatus(Calendar::SMS_SENT)
|
||||||
|
->setStatus(Calendar::STATUS_CANCELED);
|
||||||
|
|
||||||
|
$sms = $builder->buildMessageForCalendar($calendar);
|
||||||
|
|
||||||
|
$this->assertCount(1, $sms);
|
||||||
|
$this->assertEquals(
|
||||||
|
'+32470123456',
|
||||||
|
$this->phoneNumberUtil->format($sms[0]->getPhoneNumber(), PhoneNumberFormat::E164)
|
||||||
|
);
|
||||||
|
$this->assertEquals('message canceled', $sms[0]->getContent());
|
||||||
|
$this->assertEquals('low', $sms[0]->getPriority());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\Migrations\Calendar;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
final class Version20220613202636 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('ALTER TABLE chill_calendar.calendar DROP smsStatus');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'Add sms status on calendars';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('ALTER TABLE chill_calendar.calendar ADD smsStatus TEXT DEFAULT \'sms_pending\' NOT NULL');
|
||||||
|
}
|
||||||
|
}
|
@ -15,6 +15,10 @@ use libphonenumber\PhoneNumber;
|
|||||||
|
|
||||||
class ShortMessage
|
class ShortMessage
|
||||||
{
|
{
|
||||||
|
public const PRIORITY_LOW = 'low';
|
||||||
|
|
||||||
|
public const PRIORITY_MEDIUM = 'medium';
|
||||||
|
|
||||||
private string $content;
|
private string $content;
|
||||||
|
|
||||||
private PhoneNumber $phoneNumber;
|
private PhoneNumber $phoneNumber;
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\MainBundle\Service\ShortMessage;
|
||||||
|
|
||||||
|
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @AsMessageHandler
|
||||||
|
*/
|
||||||
|
class ShortMessageHandler implements MessageHandlerInterface
|
||||||
|
{
|
||||||
|
private ShortMessageTransporterInterface $messageTransporter;
|
||||||
|
|
||||||
|
public function __construct(ShortMessageTransporterInterface $messageTransporter)
|
||||||
|
{
|
||||||
|
$this->messageTransporter = $messageTransporter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __invoke(ShortMessage $message): void
|
||||||
|
{
|
||||||
|
$this->messageTransporter->send($message);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user