From 3f312b835ae1ca181e8a5a2715cfcf5d3cc2f671 Mon Sep 17 00:00:00 2001 From: Benjamin Schoch Date: Fri, 9 Dec 2022 11:36:21 +0100 Subject: [PATCH] [Notifier] [FakeChat] Allow missing optional dependency --- .../FakeChat/FakeChatTransportFactory.php | 20 ++++++- .../Tests/FakeChatTransportFactoryTest.php | 56 +++++++++++++++++++ .../Notifier/Bridge/FakeChat/composer.json | 9 ++- 3 files changed, 79 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Notifier/Bridge/FakeChat/FakeChatTransportFactory.php b/src/Symfony/Component/Notifier/Bridge/FakeChat/FakeChatTransportFactory.php index ae74ee689b9af..e5bc2c2096061 100644 --- a/src/Symfony/Component/Notifier/Bridge/FakeChat/FakeChatTransportFactory.php +++ b/src/Symfony/Component/Notifier/Bridge/FakeChat/FakeChatTransportFactory.php @@ -13,6 +13,7 @@ use Psr\Log\LoggerInterface; use Symfony\Component\Mailer\MailerInterface; +use Symfony\Component\Notifier\Exception\LogicException; use Symfony\Component\Notifier\Exception\UnsupportedSchemeException; use Symfony\Component\Notifier\Transport\AbstractTransportFactory; use Symfony\Component\Notifier\Transport\Dsn; @@ -23,10 +24,10 @@ */ final class FakeChatTransportFactory extends AbstractTransportFactory { - private MailerInterface $mailer; - private LoggerInterface $logger; + private ?MailerInterface $mailer; + private ?LoggerInterface $logger; - public function __construct(MailerInterface $mailer, LoggerInterface $logger) + public function __construct(MailerInterface $mailer = null, LoggerInterface $logger = null) { parent::__construct(); @@ -39,6 +40,10 @@ public function create(Dsn $dsn): FakeChatEmailTransport|FakeChatLoggerTransport $scheme = $dsn->getScheme(); if ('fakechat+email' === $scheme) { + if (null === $this->mailer) { + $this->throwMissingDependencyException($scheme, MailerInterface::class, 'symfony/mailer'); + } + $mailerTransport = $dsn->getHost(); $to = $dsn->getRequiredOption('to'); $from = $dsn->getRequiredOption('from'); @@ -47,6 +52,10 @@ public function create(Dsn $dsn): FakeChatEmailTransport|FakeChatLoggerTransport } if ('fakechat+logger' === $scheme) { + if (null === $this->logger) { + $this->throwMissingDependencyException($scheme, LoggerInterface::class, 'psr/log'); + } + return new FakeChatLoggerTransport($this->logger); } @@ -57,4 +66,9 @@ protected function getSupportedSchemes(): array { return ['fakechat+email', 'fakechat+logger']; } + + private function throwMissingDependencyException(string $scheme, string $missingDependency, string $suggestedPackage): void + { + throw new LogicException(sprintf('Cannot create a transport for scheme "%s" without providing an implementation of "%s". Try running "composer require "%s"".', $scheme, $missingDependency, $suggestedPackage)); + } } diff --git a/src/Symfony/Component/Notifier/Bridge/FakeChat/Tests/FakeChatTransportFactoryTest.php b/src/Symfony/Component/Notifier/Bridge/FakeChat/Tests/FakeChatTransportFactoryTest.php index e6821ba92c769..0e595054c015c 100644 --- a/src/Symfony/Component/Notifier/Bridge/FakeChat/Tests/FakeChatTransportFactoryTest.php +++ b/src/Symfony/Component/Notifier/Bridge/FakeChat/Tests/FakeChatTransportFactoryTest.php @@ -14,10 +14,35 @@ use Psr\Log\LoggerInterface; use Symfony\Component\Mailer\MailerInterface; use Symfony\Component\Notifier\Bridge\FakeChat\FakeChatTransportFactory; +use Symfony\Component\Notifier\Exception\LogicException; use Symfony\Component\Notifier\Test\TransportFactoryTestCase; +use Symfony\Component\Notifier\Transport\Dsn; final class FakeChatTransportFactoryTest extends TransportFactoryTestCase { + /** + * @dataProvider missingRequiredDependencyProvider + */ + public function testMissingRequiredDependency(?MailerInterface $mailer, ?LoggerInterface $logger, string $dsn, string $message) + { + $this->expectException(LogicException::class); + $this->expectExceptionMessage($message); + + $factory = new FakeChatTransportFactory($mailer, $logger); + $factory->create(new Dsn($dsn)); + } + + /** + * @dataProvider missingOptionalDependencyProvider + */ + public function testMissingOptionalDependency(?MailerInterface $mailer, ?LoggerInterface $logger, string $dsn) + { + $factory = new FakeChatTransportFactory($mailer, $logger); + $transport = $factory->create(new Dsn($dsn)); + + $this->assertSame($dsn, (string) $transport); + } + public function createFactory(): FakeChatTransportFactory { return new FakeChatTransportFactory($this->createMock(MailerInterface::class), $this->createMock(LoggerInterface::class)); @@ -63,4 +88,35 @@ public function unsupportedSchemeProvider(): iterable { yield ['somethingElse://default?to=recipient@email.net&from=sender@email.net']; } + + public function missingRequiredDependencyProvider(): iterable + { + $exceptionMessage = 'Cannot create a transport for scheme "%s" without providing an implementation of "%s".'; + yield 'missing mailer' => [ + null, + $this->createMock(LoggerInterface::class), + 'fakechat+email://default?to=recipient@email.net&from=sender@email.net', + sprintf($exceptionMessage, 'fakechat+email', MailerInterface::class), + ]; + yield 'missing logger' => [ + $this->createMock(MailerInterface::class), + null, + 'fakechat+logger://default', + sprintf($exceptionMessage, 'fakechat+logger', LoggerInterface::class), + ]; + } + + public function missingOptionalDependencyProvider(): iterable + { + yield 'missing logger' => [ + $this->createMock(MailerInterface::class), + null, + 'fakechat+email://default?to=recipient@email.net&from=sender@email.net', + ]; + yield 'missing mailer' => [ + null, + $this->createMock(LoggerInterface::class), + 'fakechat+logger://default', + ]; + } } diff --git a/src/Symfony/Component/Notifier/Bridge/FakeChat/composer.json b/src/Symfony/Component/Notifier/Bridge/FakeChat/composer.json index 6518b750a70fd..94b4bff1dafa9 100644 --- a/src/Symfony/Component/Notifier/Bridge/FakeChat/composer.json +++ b/src/Symfony/Component/Notifier/Bridge/FakeChat/composer.json @@ -23,9 +23,12 @@ "require": { "php": ">=8.1", "symfony/http-client": "^5.4|^6.0", - "symfony/notifier": "^6.2", - "symfony/event-dispatcher-contracts": "^2|^3", - "symfony/mailer": "^5.4|^6.0" + "symfony/notifier": "^6.2" + }, + "require-dev": { + "symfony/mailer": "^5.4|^6.0", + "symfony/event-dispatcher": "^5.4|^6.0", + "psr/log": "^1|^2|^3" }, "autoload": { "psr-4": { "Symfony\\Component\\Notifier\\Bridge\\FakeChat\\": "" },