[Maintenance] Bring back swiftmailer-based tests in packages

This commit is contained in:
Jan Goralski 2022-09-27 14:42:53 +02:00 committed by Mateusz Zalewski
parent bd261c4f22
commit 254682f9a5
No known key found for this signature in database
GPG key ID: 9BECA0BB71612E52
6 changed files with 294 additions and 4 deletions

View file

@ -27,7 +27,8 @@
"HWI\\Bundle\\OAuthBundle\\OAuth\\Response\\UserResponseInterface",
"HWI\\Bundle\\OAuthBundle\\Security\\Core\\User\\OAuthAwareUserProviderInterface",
"League\\Flysystem\\FilesystemOperator",
"Symfony\\Component\\Security\\Core\\Encoder\\EncoderFactoryInterface"
"Symfony\\Component\\Security\\Core\\Encoder\\EncoderFactoryInterface",
"PHPUnit\\Framework\\ExpectationFailedException"
],
"php-core-extensions" : [
"Core",

View file

@ -16,13 +16,17 @@ namespace Sylius\Bundle\AdminBundle\Tests\MessageHandler\Admin;
use Sylius\Bundle\CoreBundle\Message\Admin\Account\SendResetPasswordEmail;
use Sylius\Bundle\CoreBundle\MessageHandler\Admin\Account\SendResetPasswordEmailHandler;
use Sylius\Component\Core\Model\AdminUser;
use Sylius\Component\Core\Test\SwiftmailerAssertionTrait;
use Sylius\Component\Mailer\Sender\SenderInterface;
use Sylius\Component\User\Repository\UserRepositoryInterface;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Contracts\Translation\TranslatorInterface;
final class SendResetPasswordEmailHandlerTest extends KernelTestCase
{
use SwiftmailerAssertionTrait;
/** @test */
public function it_sends_password_reset_token_email(): void
{
@ -64,6 +68,52 @@ final class SendResetPasswordEmailHandlerTest extends KernelTestCase
);
}
/** @test */
public function it_sends_password_reset_token_email_with_swiftmailer(): void
{
if (!self::isItSwiftmailerTestEnv()) {
$this->markTestSkipped('Test is relevant only for the environment with swiftmailer');
}
$container = self::bootKernel()->getContainer();
self::setSpoolDirectory($container->getParameter('kernel.cache_dir') . '/spool');
/** @var Filesystem $filesystem */
$filesystem = $container->get('test.filesystem.public');
$filesystem->remove(self::getSpoolDirectory());
/** @var TranslatorInterface $translator */
$translator = $container->get('translator');
/** @var SenderInterface $emailSender */
$emailSender = $container->get('sylius.email_sender');
$adminUser = new AdminUser();
$adminUser->setEmail('sylius@example.com');
$adminUser->setPasswordResetToken('my_reset_token');
$adminUserRepository = $this->createMock(UserRepositoryInterface::class);
$adminUserRepository
->method('findOneByEmail')
->with('sylius@example.com')
->willReturn($adminUser)
;
$resetPasswordEmailHandler = new SendResetPasswordEmailHandler($adminUserRepository, $emailSender);
$resetPasswordEmailHandler(new SendResetPasswordEmail(
'sylius@example.com',
'en_US',
));
self::assertSpooledMessagesCountWithRecipient(1, 'sylius@example.com');
self::assertSpooledMessageWithContentHasRecipient(
$translator->trans('sylius.email.admin_password_reset.to_reset_your_password', [], null, 'en_US'),
'sylius@example.com',
);
}
private static function isItSwiftmailerTestEnv(): bool
{
$env = self::getContainer()->getParameter('kernel.environment');

View file

@ -18,13 +18,17 @@ use Sylius\Bundle\ApiBundle\Command\Account\SendAccountRegistrationEmail;
use Sylius\Bundle\ApiBundle\CommandHandler\Account\SendAccountRegistrationEmailHandler;
use Sylius\Component\Channel\Repository\ChannelRepositoryInterface;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Test\SwiftmailerAssertionTrait;
use Sylius\Component\User\Model\UserInterface;
use Sylius\Component\User\Repository\UserRepositoryInterface;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Contracts\Translation\TranslatorInterface;
final class SendAccountRegistrationEmailHandlerTest extends KernelTestCase
{
use SwiftmailerAssertionTrait;
/** @test */
public function it_sends_account_registration_email(): void
{
@ -74,6 +78,63 @@ final class SendAccountRegistrationEmailHandlerTest extends KernelTestCase
self::assertEmailHtmlBodyContains($email, $translator->trans('sylius.email.user_registration.start_shopping', [], null, 'en_US'));
}
/** @test */
public function it_sends_account_registration_email_with_swiftmailer(): void
{
if (!$this->isItSwiftmailerTestEnv()) {
$this->markTestSkipped('Test is relevant only for the environment with swiftmailer');
}
$container = self::getContainer();
self::setSpoolDirectory($container->getParameter('kernel.cache_dir') . '/spool');
/** @var Filesystem $filesystem */
$filesystem = $container->get('test.filesystem.public');
/** @var TranslatorInterface $translator */
$translator = $container->get('translator');
$filesystem->remove(self::getSpoolDirectory());
$emailSender = $container->get('sylius.email_sender');
/** @var ChannelRepositoryInterface|ObjectProphecy $channelRepository */
$channelRepository = $this->prophesize(ChannelRepositoryInterface::class);
/** @var UserRepositoryInterface|ObjectProphecy $userRepository */
$userRepository = $this->prophesize(UserRepositoryInterface::class);
/** @var ChannelInterface|ObjectProphecy $channel */
$channel = $this->prophesize(ChannelInterface::class);
/** @var UserInterface|ObjectProphecy $user */
$user = $this->prophesize(UserInterface::class);
$user->getUsername()->willReturn('username');
$user->getEmailVerificationToken()->willReturn('token');
$channelRepository->findOneByCode('CHANNEL_CODE')->willReturn($channel->reveal());
$userRepository->findOneByEmail('user@example.com')->willReturn($user->reveal());
$sendAccountRegistrationEmailHandler = new SendAccountRegistrationEmailHandler(
$userRepository->reveal(),
$channelRepository->reveal(),
$emailSender,
);
$sendAccountRegistrationEmailHandler(
new SendAccountRegistrationEmail(
'user@example.com',
'en_US',
'CHANNEL_CODE',
),
);
self::assertSpooledMessagesCountWithRecipient(1, 'user@example.com');
self::assertSpooledMessageWithContentHasRecipient(
$translator->trans('sylius.email.user_registration.start_shopping', [], null, 'en_US'),
'user@example.com',
);
}
private function isItSwiftmailerTestEnv(): bool
{
$env = self::getContainer()->getParameter('kernel.environment');

View file

@ -18,20 +18,22 @@ use Sylius\Bundle\CoreBundle\Mailer\OrderEmailManagerInterface;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\CustomerInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Test\SwiftmailerAssertionTrait;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Contracts\Translation\TranslatorInterface;
final class OrderEmailManagerTest extends KernelTestCase
{
use SwiftmailerAssertionTrait;
private const RECIPIENT_EMAIL = 'test@example.com';
private const LOCALE_CODE = 'en_US';
private const ORDER_NUMBER = '#000001';
/**
* @test
*/
/** @test */
public function it_sends_order_confirmation_email_with_symfony_mailer_if_swift_mailer_is_not_present(): void
{
if ($this->isItSwiftmailerTestEnv()) {
@ -75,6 +77,54 @@ final class OrderEmailManagerTest extends KernelTestCase
);
}
/** @test */
public function it_sends_order_confirmation_email_with_swift_mailer_by_default_if_is_present(): void
{
if (!$this->isItSwiftmailerTestEnv()) {
$this->markTestSkipped('This test should be executed only in test_with_swiftmailer environment');
}
$container = self::getContainer();
self::setSpoolDirectory($container->getParameter('kernel.cache_dir') . '/spool');
/** @var Filesystem $filesystem */
$filesystem = $container->get('filesystem');
/** @var TranslatorInterface $translator */
$translator = $container->get('translator');
$filesystem->remove(self::getSpoolDirectory());
$orderEmailManager = static::$kernel->getContainer()->get('sylius.mailer.order_email_manager');
/** @var OrderInterface|ObjectProphecy $order */
$order = $this->prophesize(OrderInterface::class);
/** @var CustomerInterface|ObjectProphecy $customer */
$customer = $this->prophesize(CustomerInterface::class);
$customer->getEmail()->willReturn(self::RECIPIENT_EMAIL);
/** @var ChannelInterface|ObjectProphecy $channel */
$channel = $this->prophesize(ChannelInterface::class);
$order->getCustomer()->willReturn($customer->reveal());
$order->getChannel()->willReturn($channel->reveal());
$order->getLocaleCode()->willReturn(self::LOCALE_CODE);
$order->getNumber()->willReturn(self::ORDER_NUMBER);
$order->getTokenValue()->willReturn('ASFAFA4654AF');
$orderEmailManager->sendConfirmationEmail($order->reveal());
self::assertSpooledMessagesCountWithRecipient(1, self::RECIPIENT_EMAIL);
self::assertSpooledMessageWithContentHasRecipient(
sprintf(
'%s %s %s',
$translator->trans('sylius.email.order_confirmation.your_order_number', [], null, self::LOCALE_CODE),
self::ORDER_NUMBER,
$translator->trans('sylius.email.order_confirmation.has_been_successfully_placed', [], null, self::LOCALE_CODE),
),
self::RECIPIENT_EMAIL,
);
}
private function isItSwiftmailerTestEnv(): bool
{
$env = self::getContainer()->getParameter('kernel.environment');

View file

@ -0,0 +1,127 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Sylius\Component\Core\Test;
use PHPUnit\Framework\ExpectationFailedException;
use Symfony\Component\Finder\Exception\DirectoryNotFoundException;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;
use Webmozart\Assert\Assert;
trait SwiftmailerAssertionTrait
{
private static ?string $spoolDirectory = null;
public static function assertSpooledMessagesHaveRecipient(string $recipient): void
{
self::assertRecipientIsValid($recipient);
try {
$messages = self::getMessages(self::getSpoolDirectory());
foreach ($messages as $message) {
if (self::isMessageTo($message, $recipient)) {
return;
}
}
} catch (DirectoryNotFoundException) {
}
throw new ExpectationFailedException(sprintf('No message spooled with recipient "%s"', $recipient));
}
public static function assertSpooledMessageWithContentHasRecipient(string $message, string $recipient): void
{
self::assertRecipientIsValid($recipient);
$messages = self::getMessages(self::getSpoolDirectory());
foreach ($messages as $sentMessage) {
if (self::isMessageTo($sentMessage, $recipient)) {
$body = strip_tags($sentMessage->getBody());
$body = str_replace("\n", ' ', $body);
$body = preg_replace('/ {2,}/', ' ', $body);
if (str_contains($body, $message)) {
return;
}
}
}
throw new ExpectationFailedException(sprintf(
'No message spooled with recipient "%s" and content "%s"',
$recipient,
$message
));
}
public static function assertSpooledMessagesCountWithRecipient(int $expectedCount, string $recipient): void
{
self::assertRecipientIsValid($recipient);
$messagesCount = 0;
$messages = self::getMessages(self::getSpoolDirectory());
foreach ($messages as $message) {
if (self::isMessageTo($message, $recipient)) {
++$messagesCount;
}
}
self::assertEquals($expectedCount, $messagesCount);
}
public static function getSpoolDirectory(): string
{
Assert::notNull(
self::$spoolDirectory,
'Spool directory needs to be configured. Use the `setSpoolDirectory` method.',
);
return self::$spoolDirectory;
}
protected static function setSpoolDirectory(string $spoolDirectory): void
{
self::$spoolDirectory = $spoolDirectory;
}
private static function isMessageTo(object $message, string $recipient): bool
{
return array_key_exists($recipient, $message->getTo());
}
private static function assertRecipientIsValid(string $recipient): void
{
Assert::notEmpty($recipient, 'The recipient cannot be empty.');
Assert::notEq(
false,
filter_var($recipient, \FILTER_VALIDATE_EMAIL),
'Given recipient is not a valid email address.',
);
}
private static function getMessages(string $directory): array
{
$finder = new Finder();
$finder->files()->name('*.message')->in($directory);
Assert::notEq($finder->count(), 0, sprintf('No message files found in %s.', $directory));
$messages = [];
/** @var SplFileInfo $file */
foreach ($finder as $file) {
$messages[] = unserialize($file->getContents());
}
return $messages;
}
}

View file

@ -58,6 +58,7 @@
},
"require-dev": {
"phpspec/phpspec": "^7.2",
"phpunit/phpunit": "^8.5",
"symfony/property-access": "^5.4 || ^6.0"
},
"config": {