Skip to content

Commit

Permalink
feature #48565 [Notifier] [FakeChat] Allow missing optional dependenc…
Browse files Browse the repository at this point in the history
…y (Benjamin Schoch)

This PR was merged into the 6.3 branch.

Discussion
----------

[Notifier] [FakeChat] Allow missing optional dependency

| Q             | A
| ------------- | ---
| Branch?       | 6.3
| Bug fix?      |no
| New feature?  | kind of
| Deprecations? | no
| Tickets       | see #48441
| License       | MIT

Nearly the same as in this PR: #48546

This allows the `FakeChatTransportFactory` to be used without providing an implementation of `MailerInterface` or `LoggerInterface` if one of them is actually not required during runtime.

I did not share any of the implementation now between both components. I could think of pulling out the Exception as well as Parts of the test to something like a `FakeTransportFactoryTestCase` for example. What do you think?

Commits
-------

3f312b8 [Notifier] [FakeChat] Allow missing optional dependency
  • Loading branch information
OskarStark committed Dec 9, 2022
2 parents 45113ba + 3f312b8 commit 0f24e41
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 6 deletions.
Expand Up @@ -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;
Expand All @@ -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();

Expand All @@ -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');
Expand All @@ -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);
}

Expand All @@ -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));
}
}
Expand Up @@ -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));
Expand Down Expand Up @@ -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',
];
}
}
9 changes: 6 additions & 3 deletions src/Symfony/Component/Notifier/Bridge/FakeChat/composer.json
Expand Up @@ -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\\": "" },
Expand Down

0 comments on commit 0f24e41

Please sign in to comment.