From dee0d093b68b8bfc35dc9f563fe531842e6d10f8 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 23 Jul 2022 16:22:54 +0200 Subject: [PATCH] Add a mailer:test command --- .../FrameworkExtension.php | 5 ++ .../Resources/config/mailer.php | 7 ++ src/Symfony/Component/Mailer/CHANGELOG.md | 5 ++ .../Mailer/Command/MailerTestCommand.php | 75 +++++++++++++++++++ .../Tests/Command/MailerTestCommandTest.php | 71 ++++++++++++++++++ 5 files changed, 163 insertions(+) create mode 100644 src/Symfony/Component/Mailer/Command/MailerTestCommand.php create mode 100644 src/Symfony/Component/Mailer/Tests/Command/MailerTestCommandTest.php diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index fc0c05603484a..2c2af01cf5b89 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -101,6 +101,7 @@ use Symfony\Component\Mailer\Bridge\Postmark\Transport\PostmarkTransportFactory; use Symfony\Component\Mailer\Bridge\Sendgrid\Transport\SendgridTransportFactory; use Symfony\Component\Mailer\Bridge\Sendinblue\Transport\SendinblueTransportFactory; +use Symfony\Component\Mailer\Command\MailerTestCommand; use Symfony\Component\Mailer\Mailer; use Symfony\Component\Mercure\HubRegistry; use Symfony\Component\Messenger\Attribute\AsMessageHandler; @@ -386,6 +387,10 @@ public function load(array $configs, ContainerBuilder $container) $this->registerMailerConfiguration($config['mailer'], $container, $loader); } + if (!$this->mailerConfigEnabled || !class_exists(MailerTestCommand::class)) { + $container->removeDefinition('console.command.mailer_test'); + } + $propertyInfoEnabled = $this->isConfigEnabled($container, $config['property_info']); $this->registerHttpCacheConfiguration($config['http_cache'], $container, $config['http_method_override']); $this->registerEsiConfiguration($config['esi'], $container, $loader); diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer.php index 51ad286273e06..4d4bdfbd49013 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer.php @@ -11,6 +11,7 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator; +use Symfony\Component\Mailer\Command\MailerTestCommand; use Symfony\Component\Mailer\EventListener\EnvelopeListener; use Symfony\Component\Mailer\EventListener\MessageListener; use Symfony\Component\Mailer\EventListener\MessageLoggerListener; @@ -72,5 +73,11 @@ ->set('mailer.message_logger_listener', MessageLoggerListener::class) ->tag('kernel.event_subscriber') ->tag('kernel.reset', ['method' => 'reset']) + + ->set('console.command.mailer_test', MailerTestCommand::class) + ->args([ + service('mailer.transports'), + ]) + ->tag('console.command') ; }; diff --git a/src/Symfony/Component/Mailer/CHANGELOG.md b/src/Symfony/Component/Mailer/CHANGELOG.md index 8baf27da0891e..9b6b2ffd4753e 100644 --- a/src/Symfony/Component/Mailer/CHANGELOG.md +++ b/src/Symfony/Component/Mailer/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +6.2 +--- + + * Add a `mailer:test` command + 6.1 --- diff --git a/src/Symfony/Component/Mailer/Command/MailerTestCommand.php b/src/Symfony/Component/Mailer/Command/MailerTestCommand.php new file mode 100644 index 0000000000000..45a1e646a4243 --- /dev/null +++ b/src/Symfony/Component/Mailer/Command/MailerTestCommand.php @@ -0,0 +1,75 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Command; + +use Symfony\Component\Console\Attribute\AsCommand; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Mailer\Transport\TransportInterface; +use Symfony\Component\Mime\Email; + +/** + * A console command to test Mailer transports. + */ +#[AsCommand(name: 'mailer:test', description: 'Test Mailer transports by sending an email')] +final class MailerTestCommand extends Command +{ + public function __construct(private TransportInterface $transport) + { + $this->transport = $transport; + + parent::__construct(); + } + + protected function configure() + { + $this + ->addArgument('to', InputArgument::REQUIRED, 'The recipient of the message') + ->addOption('from', null, InputOption::VALUE_OPTIONAL, 'The sender of the message', 'from@example.org') + ->addOption('subject', null, InputOption::VALUE_OPTIONAL, 'The subject of the message', 'Testing transport') + ->addOption('body', null, InputOption::VALUE_OPTIONAL, 'The body of the message', 'Testing body') + ->addOption('transport', null, InputOption::VALUE_OPTIONAL, 'The transport to be used') + ->setHelp(<<<'EOF' +The %command.name% command tests a Mailer transport by sending a simple email message: + +php %command.full_name% to@example.com + +You can also specify a specific transport: + + php %command.full_name% to@example.com --transport=transport_name + +Note that this command bypasses the Messenger bus if configured. + +EOF + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $message = (new Email()) + ->to($input->getArgument('to')) + ->from($input->getOption('from')) + ->subject($input->getOption('subject')) + ->text($input->getOption('body')) + ; + if ($transport = $input->getOption('transport')) { + $message->getHeaders()->addTextHeader('X-Transport', $transport); + } + + $this->transport->send($message); + + return 0; + } +} diff --git a/src/Symfony/Component/Mailer/Tests/Command/MailerTestCommandTest.php b/src/Symfony/Component/Mailer/Tests/Command/MailerTestCommandTest.php new file mode 100644 index 0000000000000..f6c28172f2e20 --- /dev/null +++ b/src/Symfony/Component/Mailer/Tests/Command/MailerTestCommandTest.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Tests\Command; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Tester\CommandTester; +use Symfony\Component\Mailer\Command\MailerTestCommand; +use Symfony\Component\Mailer\Transport\TransportInterface; +use Symfony\Component\Mime\Email; + +class MailerTestCommandTest extends TestCase +{ + public function testSendsEmail() + { + $from = 'from@example.com'; + $to = 'to@example.com'; + $subject = 'Foobar'; + $body = 'Lorem ipsum dolor sit amet.'; + + $mailer = $this->createMock(TransportInterface::class); + $mailer + ->expects($this->once()) + ->method('send') + ->with(self::callback(static function (Email $message) use ($from, $to, $subject, $body): bool { + return + $message->getFrom()[0]->getAddress() === $from && + $message->getTo()[0]->getAddress() === $to && + $message->getSubject() === $subject && + $message->getTextBody() === $body + ; + })) + ; + + $tester = new CommandTester(new MailerTestCommand($mailer)); + $tester->execute([ + 'to' => $to, + '--from' => $from, + '--subject' => $subject, + '--body' => $body, + ]); + } + + public function testUsesCustomTransport() + { + $transport = 'foobar'; + + $mailer = $this->createMock(TransportInterface::class); + $mailer + ->expects($this->once()) + ->method('send') + ->with(self::callback(static function (Email $message) use ($transport): bool { + return $message->getHeaders()->getHeaderBody('X-Transport') === $transport; + })) + ; + + $tester = new CommandTester(new MailerTestCommand($mailer)); + $tester->execute([ + 'to' => 'to@example.com', + '--transport' => $transport, + ]); + } +}