From 74542d0ac95f8fa6a956b737c7f15020b910afeb Mon Sep 17 00:00:00 2001 From: Guilherme Donato Date: Wed, 8 Aug 2018 14:21:30 -0300 Subject: [PATCH] sending change notifications and unit test coverage PROCERGS#797 --- .../AccountRecoveryDataController.php | 4 +- .../Entity/AccountRecoveryDataRepository.php | 2 + .../AccountRecoveryDataEventSubscriber.php | 79 ++++++++++++ .../Form/AccountRecoveryDataType.php | 5 + .../Mailer/AccountRecoveryMailer.php | 61 ++++++++++ .../Resources/config/services.yml | 17 +++ .../Resources/translations/messages.en.yml | 23 ++++ .../Resources/translations/messages.pt_BR.yml | 11 ++ .../views/Email/email_changed.html.twig | 20 ++++ .../views/Email/phone_changed.html.twig | 20 ++++ .../Tests/Entity/AccountRecoveryDataTest.php | 36 ++++++ .../AccountRecoveryDataEditEventTest.php | 35 ++++++ ...AccountRecoveryDataEventSubscriberTest.php | 112 ++++++++++++++++++ .../Service/AccountRecoveryServiceTest.php | 104 ++++++++++++++++ 14 files changed, 527 insertions(+), 2 deletions(-) create mode 100644 src/LoginCidadao/AccountRecoveryBundle/Event/AccountRecoveryDataEventSubscriber.php create mode 100644 src/LoginCidadao/AccountRecoveryBundle/Mailer/AccountRecoveryMailer.php create mode 100644 src/LoginCidadao/AccountRecoveryBundle/Resources/views/Email/email_changed.html.twig create mode 100644 src/LoginCidadao/AccountRecoveryBundle/Resources/views/Email/phone_changed.html.twig create mode 100644 src/LoginCidadao/AccountRecoveryBundle/Tests/Entity/AccountRecoveryDataTest.php create mode 100644 src/LoginCidadao/AccountRecoveryBundle/Tests/Event/AccountRecoveryDataEditEventTest.php create mode 100644 src/LoginCidadao/AccountRecoveryBundle/Tests/Event/AccountRecoveryDataEventSubscriberTest.php create mode 100644 src/LoginCidadao/AccountRecoveryBundle/Tests/Service/AccountRecoveryServiceTest.php diff --git a/src/LoginCidadao/AccountRecoveryBundle/Controller/AccountRecoveryDataController.php b/src/LoginCidadao/AccountRecoveryBundle/Controller/AccountRecoveryDataController.php index 214c00dc3..c1be5f245 100644 --- a/src/LoginCidadao/AccountRecoveryBundle/Controller/AccountRecoveryDataController.php +++ b/src/LoginCidadao/AccountRecoveryBundle/Controller/AccountRecoveryDataController.php @@ -50,11 +50,11 @@ public function editAction(Request $request) $form = $this->createForm(AccountRecoveryDataType::class, $recoveryData); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $this->getDoctrine()->getManager()->flush(); - $event = new AccountRecoveryDataEditEvent($recoveryData); $eventDispatcher->dispatch(AccountRecoveryEvents::ACCOUNT_RECOVERY_DATA_EDIT_SUCCESS, $event); + $this->getDoctrine()->getManager()->flush(); + if (null === $response = $event->getResponse()) { $response = $this->redirectToRoute('account_recovery_edit'); } diff --git a/src/LoginCidadao/AccountRecoveryBundle/Entity/AccountRecoveryDataRepository.php b/src/LoginCidadao/AccountRecoveryBundle/Entity/AccountRecoveryDataRepository.php index d57068add..0acb43440 100644 --- a/src/LoginCidadao/AccountRecoveryBundle/Entity/AccountRecoveryDataRepository.php +++ b/src/LoginCidadao/AccountRecoveryBundle/Entity/AccountRecoveryDataRepository.php @@ -18,6 +18,8 @@ * * This class was generated by the Doctrine ORM. Add your own custom * repository methods below. + * + * @codeCoverageIgnore */ class AccountRecoveryDataRepository extends EntityRepository { diff --git a/src/LoginCidadao/AccountRecoveryBundle/Event/AccountRecoveryDataEventSubscriber.php b/src/LoginCidadao/AccountRecoveryBundle/Event/AccountRecoveryDataEventSubscriber.php new file mode 100644 index 000000000..293f8af5d --- /dev/null +++ b/src/LoginCidadao/AccountRecoveryBundle/Event/AccountRecoveryDataEventSubscriber.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace LoginCidadao\AccountRecoveryBundle\Event; + +use libphonenumber\PhoneNumber; +use LoginCidadao\AccountRecoveryBundle\Entity\AccountRecoveryData; +use LoginCidadao\AccountRecoveryBundle\Mailer\AccountRecoveryMailer; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +class AccountRecoveryDataEventSubscriber implements EventSubscriberInterface +{ + /** @var string|null */ + private $originalRecoveryEmail; + + /** @var PhoneNumber|null */ + private $originalRecoveryPhone; + + /** @var AccountRecoveryMailer */ + private $mailer; + + /** + * AccountRecoveryDataEventSubscriber constructor. + * @param AccountRecoveryMailer $mailer + */ + public function __construct(AccountRecoveryMailer $mailer) + { + $this->mailer = $mailer; + } + + public static function getSubscribedEvents() + { + return [ + AccountRecoveryEvents::ACCOUNT_RECOVERY_DATA_EDIT_INITIALIZE => 'onEditInitialize', + AccountRecoveryEvents::ACCOUNT_RECOVERY_DATA_EDIT_COMPLETED => 'onEditCompleted', + ]; + } + + public function onEditInitialize(AccountRecoveryDataEditEvent $event) + { + $this->originalRecoveryEmail = $event->getAccountRecoveryData()->getEmail(); + $this->originalRecoveryPhone = $event->getAccountRecoveryData()->getMobile(); + } + + public function onEditCompleted(AccountRecoveryDataEditEvent $event) + { + $currentEmail = $event->getAccountRecoveryData()->getEmail(); + $currentPhone = $event->getAccountRecoveryData()->getMobile(); + + if (null !== $this->originalRecoveryEmail && $this->originalRecoveryEmail !== $currentEmail) { + $this->notifyEmailChanged($event->getAccountRecoveryData(), $this->originalRecoveryEmail); + } + if (null !== $this->originalRecoveryPhone && $this->originalRecoveryPhone !== $currentPhone) { + $this->notifyPhoneChanged($event->getAccountRecoveryData(), $this->originalRecoveryPhone); + } + } + + private function notifyEmailChanged(AccountRecoveryData $accountRecoveryData, string $oldEmail) + { + $person = $accountRecoveryData->getPerson(); + $this->mailer->sendRecoveryEmailChangedMessage($accountRecoveryData, $oldEmail); + $this->mailer->sendRecoveryEmailChangedMessage($accountRecoveryData, $person->getEmail()); + $this->mailer->sendRecoveryEmailChangedMessage($accountRecoveryData, $accountRecoveryData->getEmail()); + } + + private function notifyPhoneChanged(AccountRecoveryData $accountRecoveryData, PhoneNumber $oldPhone) + { + $person = $accountRecoveryData->getPerson(); + $this->mailer->sendRecoveryPhoneChangedMessage($accountRecoveryData, $person->getEmail()); + $this->mailer->sendRecoveryPhoneChangedMessage($accountRecoveryData, $accountRecoveryData->getEmail()); + } +} diff --git a/src/LoginCidadao/AccountRecoveryBundle/Form/AccountRecoveryDataType.php b/src/LoginCidadao/AccountRecoveryBundle/Form/AccountRecoveryDataType.php index ce82f13ac..10e30a91b 100644 --- a/src/LoginCidadao/AccountRecoveryBundle/Form/AccountRecoveryDataType.php +++ b/src/LoginCidadao/AccountRecoveryBundle/Form/AccountRecoveryDataType.php @@ -18,6 +18,11 @@ use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * Class AccountRecoveryDataType + * @package LoginCidadao\AccountRecoveryBundle\Form + * @codeCoverageIgnore + */ class AccountRecoveryDataType extends AbstractType { /** diff --git a/src/LoginCidadao/AccountRecoveryBundle/Mailer/AccountRecoveryMailer.php b/src/LoginCidadao/AccountRecoveryBundle/Mailer/AccountRecoveryMailer.php new file mode 100644 index 000000000..56ce7512d --- /dev/null +++ b/src/LoginCidadao/AccountRecoveryBundle/Mailer/AccountRecoveryMailer.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace LoginCidadao\AccountRecoveryBundle\Mailer; + +use FOS\UserBundle\Mailer\TwigSwiftMailer; +use LoginCidadao\AccountRecoveryBundle\Entity\AccountRecoveryData; + +/** + * Class AccountRecoveryMailer + * @package LoginCidadao\AccountRecoveryBundle\Mailer + * @codeCoverageIgnore Twig is too troublesome to test... + */ +class AccountRecoveryMailer extends TwigSwiftMailer +{ + private const TEMPLATE_EMAIL_CHANGED = 'LoginCidadaoAccountRecoveryBundle:Email:email_changed.html.twig'; + private const TEMPLATE_PHONE_CHANGED = 'LoginCidadaoAccountRecoveryBundle:Email:phone_changed.html.twig'; + + public function sendRecoveryEmailChangedMessage(AccountRecoveryData $accountRecoveryData, string $toEmail) + { + $this->sendRecoveryDataChangedMessage( + self::TEMPLATE_EMAIL_CHANGED, + $accountRecoveryData, + $toEmail, + ['newEmail' => $accountRecoveryData->getEmail()] + ); + } + + public function sendRecoveryPhoneChangedMessage(AccountRecoveryData $accountRecoveryData, string $toEmail) + { + $this->sendRecoveryDataChangedMessage( + self::TEMPLATE_PHONE_CHANGED, + $accountRecoveryData, + $toEmail, + ['newPhone' => $accountRecoveryData->getMobile()] + ); + } + + private function sendRecoveryDataChangedMessage( + string $template, + AccountRecoveryData $accountRecoveryData, + string $toEmail, + array $context + ) { + $person = $accountRecoveryData->getPerson(); + $context['name'] = $person->getFirstName() ?? $person->getEmail(); + + $fromEmail = $this->parameters['from_email']['recovery_data_changed']; + $fromName = $this->parameters['from_email']['email_sender_name']; + $from = [$fromEmail => $fromName]; + + $this->sendMessage($template, $context, $from, $toEmail); + } +} diff --git a/src/LoginCidadao/AccountRecoveryBundle/Resources/config/services.yml b/src/LoginCidadao/AccountRecoveryBundle/Resources/config/services.yml index a8c71c921..1a4ca9eb6 100644 --- a/src/LoginCidadao/AccountRecoveryBundle/Resources/config/services.yml +++ b/src/LoginCidadao/AccountRecoveryBundle/Resources/config/services.yml @@ -12,3 +12,20 @@ services: arguments: - "@doctrine.orm.entity_manager" - "@lc.account_recovery.repository" + + lc.account_recovery.data.subscriber: + class: LoginCidadao\AccountRecoveryBundle\Event\AccountRecoveryDataEventSubscriber + arguments: + - "@lc.account_recovery.mailer" + tags: + - { name: kernel.event_subscriber } + + lc.account_recovery.mailer: + class: LoginCidadao\AccountRecoveryBundle\Mailer\AccountRecoveryMailer + arguments: + - "@mailer" + - "@router" + - "@twig" + - from_email: + recovery_data_changed: "%mailer_sender_mail%" + email_sender_name: "%mailer_sender_name%" diff --git a/src/LoginCidadao/AccountRecoveryBundle/Resources/translations/messages.en.yml b/src/LoginCidadao/AccountRecoveryBundle/Resources/translations/messages.en.yml index e69de29bb..d351ac4b4 100644 --- a/src/LoginCidadao/AccountRecoveryBundle/Resources/translations/messages.en.yml +++ b/src/LoginCidadao/AccountRecoveryBundle/Resources/translations/messages.en.yml @@ -0,0 +1,23 @@ +account_recovery: + edit: + title: 'Account Recovery Information' + description: 'Configure alternate contact information so you can recover your account in the event you lose access to your main email and mobile.' + form: + email: + label: 'Recovery Email Address' + placeholder: 'Type your recovery email address' + mobile: + label: 'Recovery Mobile' + placeholder: 'Type your recovery mobile number' + submit: 'Save' + email: + email_changed: + message: + subject: 'Your recovery email was changed' + text: 'Hi, %name%!\n\nWe are sending your this message to let you know that your recovery email, the one you can use to recover your account in case you lose access to your main email and mobile, was changed to %email%.\n\nIf your are not behind this change, please contact us immediately!\n' + html: 'Hi, %name%!

We are sending your this message to let you know that your recovery email, the one you can use to recover your account in case you lose access to your main email and mobile, was changed to %email%.

If your are not behind this change, please contact us immediately!' + phone_changed: + message: + subject: 'Your recovery mobile number was changed' + text: 'Hi, %name%!\n\nWe are sending your this message to let you know that your recovery mobile number, the one you can use to recover your account in case you lose access to your main email and mobile, was changed to %phone%.\n\nIf your are not behind this change, please contact us immediately!\n' + html: 'Hi, %name%!

We are sending your this message to let you know that your recovery mobile number, the one you can use to recover your account in case you lose access to your main email and mobile, was changed to %phone%.

If your are not behind this change, please contact us immediately!' diff --git a/src/LoginCidadao/AccountRecoveryBundle/Resources/translations/messages.pt_BR.yml b/src/LoginCidadao/AccountRecoveryBundle/Resources/translations/messages.pt_BR.yml index 67a14ea97..3827759a3 100644 --- a/src/LoginCidadao/AccountRecoveryBundle/Resources/translations/messages.pt_BR.yml +++ b/src/LoginCidadao/AccountRecoveryBundle/Resources/translations/messages.pt_BR.yml @@ -10,3 +10,14 @@ account_recovery: label: 'Celular Alternativo' placeholder: 'Digite seu celular alternativo' submit: 'Salvar' + email: + email_changed: + message: + subject: 'Seu email alternativo foi alterado' + text: 'Olá, %name%!\n\nEstamos lhe enviando esse email para informar que seu endereço de email alternativo, utilizado para recuperar sua conta em caso de perda de acesso ao email principal, foi alterado para %email%.\n\nSe não foi você quem fez essa mudança, por favor entre em contato com a equipe do Login Cidadão imediatamente!\n' + html: 'Olá, %name%!

Estamos lhe enviando esse email para informar que seu endereço de email alternativo, utilizado para recuperar sua conta em caso de perda de acesso ao email principal, foi alterado para %email%.

Se não foi você quem fez essa mudança, por favor entre em contato com a equipe do Login Cidadão imediatamente!' + phone_changed: + message: + subject: 'Seu celular alternativo foi alterado' + text: 'Olá, %name%!\n\nEstamos lhe enviando esse email para informar que seu telefone celular alternativo, utilizado para recuperar sua conta em caso de perda de acesso ao celular principal, foi alterado para %phone%.\n\nSe não foi você quem fez essa mudança, por favor entre em contato com a equipe do Login Cidadão imediatamente!\n' + html: 'Olá, %name%!

Estamos lhe enviando esse email para informar que seu telefone celular alternativo, utilizado para recuperar sua conta em caso de perda de acesso ao celular principal, foi alterado para %phone%.

Se não foi você quem fez essa mudança, por favor entre em contato com a equipe do Login Cidadão imediatamente!' diff --git a/src/LoginCidadao/AccountRecoveryBundle/Resources/views/Email/email_changed.html.twig b/src/LoginCidadao/AccountRecoveryBundle/Resources/views/Email/email_changed.html.twig new file mode 100644 index 000000000..d71ffc667 --- /dev/null +++ b/src/LoginCidadao/AccountRecoveryBundle/Resources/views/Email/email_changed.html.twig @@ -0,0 +1,20 @@ +{% block subject %} + {% autoescape false %} + {{ 'account_recovery.email.email_changed.message.subject' | trans }} + {% endautoescape %} +{% endblock %} + +{% block body_text %} + {% autoescape false %} + {{ 'account_recovery.email.email_changed.message.text' | trans({ '%email%': newEmail, '%name%': name }) }} + {% endautoescape %} +{% endblock %} + +{% block body_html %} + {% autoescape false %} + {{ include("LoginCidadaoCoreBundle::common.email.html.twig", { + 'subject' : 'account_recovery.email.email_changed.message.subject' | trans, + 'msg' : 'account_recovery.email.email_changed.message.html' | trans({ '%email%': newEmail | e, '%name%': name | e }) | raw + } ) }} + {% endautoescape %} +{% endblock %} diff --git a/src/LoginCidadao/AccountRecoveryBundle/Resources/views/Email/phone_changed.html.twig b/src/LoginCidadao/AccountRecoveryBundle/Resources/views/Email/phone_changed.html.twig new file mode 100644 index 000000000..7e65c1259 --- /dev/null +++ b/src/LoginCidadao/AccountRecoveryBundle/Resources/views/Email/phone_changed.html.twig @@ -0,0 +1,20 @@ +{% block subject %} + {% autoescape false %} + {{ 'account_recovery.email.phone_changed.message.subject' | trans }} + {% endautoescape %} +{% endblock %} + +{% block body_text %} + {% autoescape false %} + {{ 'account_recovery.email.phone_changed.message.text' | trans({ '%phone%': newPhone, '%name%': name }) }} + {% endautoescape %} +{% endblock %} + +{% block body_html %} + {% autoescape false %} + {{ include("LoginCidadaoCoreBundle::common.email.html.twig", { + 'subject' : 'account_recovery.email.phone_changed.message.subject' | trans, + 'msg' : 'account_recovery.email.phone_changed.message.html' | trans({ '%phone%': newPhone | phone_number_format('NATIONAL') | e, '%name%': name | e }) | raw + } ) }} + {% endautoescape %} +{% endblock %} diff --git a/src/LoginCidadao/AccountRecoveryBundle/Tests/Entity/AccountRecoveryDataTest.php b/src/LoginCidadao/AccountRecoveryBundle/Tests/Entity/AccountRecoveryDataTest.php new file mode 100644 index 000000000..ac553f74a --- /dev/null +++ b/src/LoginCidadao/AccountRecoveryBundle/Tests/Entity/AccountRecoveryDataTest.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace LoginCidadao\AccountRecoveryBundle\Tests\Entity; + +use libphonenumber\PhoneNumber; +use LoginCidadao\AccountRecoveryBundle\Entity\AccountRecoveryData; +use LoginCidadao\CoreBundle\Entity\Person; +use PHPUnit\Framework\TestCase; + +class AccountRecoveryDataTest extends TestCase +{ + public function testEntity() + { + $data = (new AccountRecoveryData()) + ->setPerson($person = new Person()) + ->setMobile($mobile = new PhoneNumber()) + ->setEmail($email = 'user@example.com') + ->setCreatedAt() + ->setUpdatedAt(); + + $this->assertNull($data->getId()); + $this->assertSame($person, $data->getPerson()); + $this->assertSame($mobile, $data->getMobile()); + $this->assertSame($email, $data->getEmail()); + $this->assertInstanceOf(\DateTime::class, $data->getCreatedAt()); + $this->assertInstanceOf(\DateTime::class, $data->getUpdatedAt()); + } +} diff --git a/src/LoginCidadao/AccountRecoveryBundle/Tests/Event/AccountRecoveryDataEditEventTest.php b/src/LoginCidadao/AccountRecoveryBundle/Tests/Event/AccountRecoveryDataEditEventTest.php new file mode 100644 index 000000000..f57076b20 --- /dev/null +++ b/src/LoginCidadao/AccountRecoveryBundle/Tests/Event/AccountRecoveryDataEditEventTest.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace LoginCidadao\AccountRecoveryBundle\Tests\Event; + +use LoginCidadao\AccountRecoveryBundle\Entity\AccountRecoveryData; +use LoginCidadao\AccountRecoveryBundle\Event\AccountRecoveryDataEditEvent; +use PHPUnit\Framework\TestCase; +use Symfony\Component\HttpFoundation\Response; + +class AccountRecoveryDataEditEventTest extends TestCase +{ + public function testEvent() + { + $data = new AccountRecoveryData(); + $initialResponse = new Response('initial'); + $finalResponse = new Response('final'); + + $event = new AccountRecoveryDataEditEvent($data, $initialResponse); + + $this->assertSame($initialResponse, $event->getResponse()); + + $event->setResponse($finalResponse); + $this->assertSame($finalResponse, $event->getResponse()); + + $this->assertSame($data, $event->getAccountRecoveryData()); + } +} diff --git a/src/LoginCidadao/AccountRecoveryBundle/Tests/Event/AccountRecoveryDataEventSubscriberTest.php b/src/LoginCidadao/AccountRecoveryBundle/Tests/Event/AccountRecoveryDataEventSubscriberTest.php new file mode 100644 index 000000000..c270779f8 --- /dev/null +++ b/src/LoginCidadao/AccountRecoveryBundle/Tests/Event/AccountRecoveryDataEventSubscriberTest.php @@ -0,0 +1,112 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace LoginCidadao\AccountRecoveryBundle\Tests\Event; + +use libphonenumber\PhoneNumber; +use LoginCidadao\AccountRecoveryBundle\Entity\AccountRecoveryData; +use LoginCidadao\AccountRecoveryBundle\Event\AccountRecoveryDataEditEvent; +use LoginCidadao\AccountRecoveryBundle\Event\AccountRecoveryDataEventSubscriber; +use LoginCidadao\AccountRecoveryBundle\Event\AccountRecoveryEvents; +use LoginCidadao\AccountRecoveryBundle\Mailer\AccountRecoveryMailer; +use LoginCidadao\CoreBundle\Entity\Person; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + +class AccountRecoveryDataEventSubscriberTest extends TestCase +{ + public function testGetSubscribedEvents() + { + $this->assertSame([ + AccountRecoveryEvents::ACCOUNT_RECOVERY_DATA_EDIT_INITIALIZE => 'onEditInitialize', + AccountRecoveryEvents::ACCOUNT_RECOVERY_DATA_EDIT_COMPLETED => 'onEditCompleted', + ], AccountRecoveryDataEventSubscriber::getSubscribedEvents()); + } + + public function testOnEditInitialize() + { + /** @var AccountRecoveryMailer|MockObject $mailer */ + $mailer = $this->createMock(AccountRecoveryMailer::class); + + /** @var AccountRecoveryData|MockObject $data */ + $data = $this->createMock(AccountRecoveryData::class); + $data->expects($this->once())->method('getEmail'); + $data->expects($this->once())->method('getMobile'); + + $event = new AccountRecoveryDataEditEvent($data); + + $subscriber = new AccountRecoveryDataEventSubscriber($mailer); + $subscriber->onEditInitialize($event); + } + + public function testOnEditCompletedWithChanges() + { + $initialEmail = 'email@example.com'; + $initialPhone = new PhoneNumber(); + + $finalEmail = 'another.email@example.com'; + $finalPhone = new PhoneNumber(); + + /** @var AccountRecoveryMailer|MockObject $mailer */ + $mailer = $this->createMock(AccountRecoveryMailer::class); + $mailer->expects($this->exactly(3))->method('sendRecoveryEmailChangedMessage'); + $mailer->expects($this->exactly(2))->method('sendRecoveryPhoneChangedMessage'); + + /** @var AccountRecoveryData|MockObject $data */ + $data = $this->createMock(AccountRecoveryData::class); + $data->expects($this->once())->method('getEmail')->willReturn($initialEmail); + $data->expects($this->once())->method('getMobile')->willReturn($initialPhone); + + $finalData = (new AccountRecoveryData()) + ->setPerson((new Person()) + ->setEmail($mainEmail = 'main@example.com')) + ->setEmail($finalEmail) + ->setMobile($finalPhone); + + $initialEvent = new AccountRecoveryDataEditEvent($data); + $finalEvent = new AccountRecoveryDataEditEvent($finalData); + + $subscriber = new AccountRecoveryDataEventSubscriber($mailer); + $subscriber->onEditInitialize($initialEvent); + $subscriber->onEditCompleted($finalEvent); + } + + public function testOnEditCompletedWithoutChanges() + { + $initialEmail = 'email@example.com'; + $initialPhone = new PhoneNumber(); + + $finalEmail = $initialEmail; + $finalPhone = $initialPhone; + + /** @var AccountRecoveryMailer|MockObject $mailer */ + $mailer = $this->createMock(AccountRecoveryMailer::class); + $mailer->expects($this->never())->method('sendRecoveryEmailChangedMessage'); + $mailer->expects($this->never())->method('sendRecoveryPhoneChangedMessage'); + + /** @var AccountRecoveryData|MockObject $data */ + $data = $this->createMock(AccountRecoveryData::class); + $data->expects($this->once())->method('getEmail')->willReturn($initialEmail); + $data->expects($this->once())->method('getMobile')->willReturn($initialPhone); + + $finalData = (new AccountRecoveryData()) + ->setPerson((new Person()) + ->setEmail($mainEmail = 'main@example.com')) + ->setEmail($finalEmail) + ->setMobile($finalPhone); + + $initialEvent = new AccountRecoveryDataEditEvent($data); + $finalEvent = new AccountRecoveryDataEditEvent($finalData); + + $subscriber = new AccountRecoveryDataEventSubscriber($mailer); + $subscriber->onEditInitialize($initialEvent); + $subscriber->onEditCompleted($finalEvent); + } +} diff --git a/src/LoginCidadao/AccountRecoveryBundle/Tests/Service/AccountRecoveryServiceTest.php b/src/LoginCidadao/AccountRecoveryBundle/Tests/Service/AccountRecoveryServiceTest.php new file mode 100644 index 000000000..ed44d6df3 --- /dev/null +++ b/src/LoginCidadao/AccountRecoveryBundle/Tests/Service/AccountRecoveryServiceTest.php @@ -0,0 +1,104 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace LoginCidadao\AccountRecoveryBundle\Tests\Service; + +use Doctrine\ORM\EntityManagerInterface; +use libphonenumber\PhoneNumber; +use LoginCidadao\AccountRecoveryBundle\Entity\AccountRecoveryData; +use LoginCidadao\AccountRecoveryBundle\Entity\AccountRecoveryDataRepository; +use LoginCidadao\AccountRecoveryBundle\Service\AccountRecoveryService; +use LoginCidadao\CoreBundle\Entity\Person; +use LoginCidadao\CoreBundle\Model\PersonInterface; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + +class AccountRecoveryServiceTest extends TestCase +{ + public function testGetExistingAccountRecoveryData() + { + $person = new Person(); + $data = (new AccountRecoveryData())->setPerson($person); + + $service = new AccountRecoveryService( + $this->getEntityManager(false), + $this->getRepository($person, $data) + ); + $this->assertSame($data, $service->getAccountRecoveryData($person)); + } + + public function testGetNonExistingAccountRecoveryDataAndDontCreate() + { + $person = new Person(); + + $service = new AccountRecoveryService( + $this->getEntityManager(false), + $this->getRepository($person, null) + ); + $this->assertNull($service->getAccountRecoveryData($person, false)); + } + + public function testGetNonExistingAccountRecoveryDataAndCreate() + { + $person = new Person(); + + $service = new AccountRecoveryService( + $this->getEntityManager(true), + $this->getRepository($person, null) + ); + $this->assertInstanceOf(AccountRecoveryData::class, $service->getAccountRecoveryData($person)); + } + + public function testSetEmail() + { + $person = new Person(); + $service = new AccountRecoveryService( + $this->getEntityManager(true), + $this->getRepository($person, null) + ); + $data = $service->setRecoveryEmail($person, $email = 'email@example.com'); + $this->assertSame($email, $data->getEmail()); + } + + public function testSetPhone() + { + $person = new Person(); + $service = new AccountRecoveryService( + $this->getEntityManager(true), + $this->getRepository($person, null) + ); + $data = $service->setRecoveryPhone($person, $phone = new PhoneNumber()); + $this->assertSame($phone, $data->getMobile()); + } + + private function getRepository(PersonInterface $person, AccountRecoveryData $data = null) + { + /** @var AccountRecoveryDataRepository|MockObject $repo */ + $repo = $this->createMock(AccountRecoveryDataRepository::class); + $repo->expects($this->once())->method('findByPerson') + ->with($person) + ->willReturn($data); + + return $repo; + } + + private function getEntityManager(bool $persist) + { + /** @var EntityManagerInterface|MockObject $em */ + $em = $this->createMock(EntityManagerInterface::class); + if ($persist) { + $em->expects($this->once())->method('persist')->with($this->isInstanceOf(AccountRecoveryData::class)); + } else { + $em->expects($this->never())->method('persist'); + } + + return $em; + } +}