diff --git a/src/Symfony/Component/Notifier/Bridge/Sinch/SinchTransportFactory.php b/src/Symfony/Component/Notifier/Bridge/Sinch/SinchTransportFactory.php index 0dc36e196d..0fb16d4101 100644 --- a/src/Symfony/Component/Notifier/Bridge/Sinch/SinchTransportFactory.php +++ b/src/Symfony/Component/Notifier/Bridge/Sinch/SinchTransportFactory.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Notifier\Bridge\Sinch; +use Symfony\Component\Notifier\Exception\IncompleteDsnException; use Symfony\Component\Notifier\Exception\UnsupportedSchemeException; use Symfony\Component\Notifier\Transport\AbstractTransportFactory; use Symfony\Component\Notifier\Transport\Dsn; @@ -26,17 +27,23 @@ final class SinchTransportFactory extends AbstractTransportFactory public function create(Dsn $dsn): TransportInterface { $scheme = $dsn->getScheme(); + + if ('sinch' !== $scheme) { + throw new UnsupportedSchemeException($dsn, 'sinch', $this->getSupportedSchemes()); + } + $accountSid = $this->getUser($dsn); $authToken = $this->getPassword($dsn); $from = $dsn->getOption('from'); + + if (!$from) { + throw new IncompleteDsnException('Missing from.', $dsn->getOriginalDsn()); + } + $host = 'default' === $dsn->getHost() ? null : $dsn->getHost(); $port = $dsn->getPort(); - if ('sinch' === $scheme) { - return (new SinchTransport($accountSid, $authToken, $from, $this->client, $this->dispatcher))->setHost($host)->setPort($port); - } - - throw new UnsupportedSchemeException($dsn, 'sinch', $this->getSupportedSchemes()); + return (new SinchTransport($accountSid, $authToken, $from, $this->client, $this->dispatcher))->setHost($host)->setPort($port); } protected function getSupportedSchemes(): array diff --git a/src/Symfony/Component/Notifier/Bridge/Sinch/Tests/SinchTransportFactoryTest.php b/src/Symfony/Component/Notifier/Bridge/Sinch/Tests/SinchTransportFactoryTest.php new file mode 100644 index 0000000000..72e59b93a0 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Sinch/Tests/SinchTransportFactoryTest.php @@ -0,0 +1,83 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Notifier\Bridge\Sinch\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Notifier\Bridge\Sinch\SinchTransportFactory; +use Symfony\Component\Notifier\Exception\IncompleteDsnException; +use Symfony\Component\Notifier\Exception\UnsupportedSchemeException; +use Symfony\Component\Notifier\Transport\Dsn; + +final class SinchTransportFactoryTest extends TestCase +{ + public function testCreateWithDsn() + { + $factory = $this->createFactory(); + + $dsn = 'sinch://accountSid:authToken@default?from=0611223344'; + $transport = $factory->create(Dsn::fromString($dsn)); + $transport->setHost('host.test'); + + $this->assertSame('sinch://host.test?from=0611223344', (string) $transport); + } + + public function testCreateWithMissingOptionFromThrowsIncompleteDsnException() + { + $factory = $this->createFactory(); + + $this->expectException(IncompleteDsnException::class); + + $dsnIncomplete = 'sinch://accountSid:authToken@default'; + $factory->create(Dsn::fromString($dsnIncomplete)); + } + + public function testSupportsReturnsTrueWithSupportedScheme() + { + $factory = $this->createFactory(); + + $dsn = 'sinch://accountSid:authToken@default?from=0611223344'; + $this->assertTrue($factory->supports(Dsn::fromString($dsn))); + } + + public function testSupportsReturnsFalseWithUnsupportedScheme() + { + $factory = $this->createFactory(); + + $dsnUnsupported = 'sinnnnch://accountSid:authToken@default?from=0611223344'; + $this->assertFalse($factory->supports(Dsn::fromString($dsnUnsupported))); + } + + public function testUnsupportedSchemeThrowsUnsupportedSchemeException() + { + $factory = $this->createFactory(); + + $this->expectException(UnsupportedSchemeException::class); + + $dsnUnsupported = 'sinnnnch://accountSid:authToken@default?from=0611223344'; + $factory->create(Dsn::fromString($dsnUnsupported)); + } + + public function testUnsupportedSchemeThrowsUnsupportedSchemeExceptionEvenIfRequiredOptionIsMissing() + { + $factory = $this->createFactory(); + + $this->expectException(UnsupportedSchemeException::class); + + // unsupported scheme and missing "from" option + $factory->create(Dsn::fromString('sinnnnch://accountSid:authToken@default')); + } + + private function createFactory(): SinchTransportFactory + { + return new SinchTransportFactory(); + } +} diff --git a/src/Symfony/Component/Notifier/Bridge/Sinch/Tests/SinchTransportTest.php b/src/Symfony/Component/Notifier/Bridge/Sinch/Tests/SinchTransportTest.php new file mode 100644 index 0000000000..7f7ea4208c --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Sinch/Tests/SinchTransportTest.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Notifier\Bridge\Sinch\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Notifier\Bridge\Sinch\SinchTransport; +use Symfony\Component\Notifier\Exception\LogicException; +use Symfony\Component\Notifier\Message\MessageInterface; +use Symfony\Component\Notifier\Message\SmsMessage; +use Symfony\Contracts\HttpClient\HttpClientInterface; + +final class SinchTransportTest extends TestCase +{ + public function testToStringContainsProperties() + { + $transport = $this->createTransport(); + + $this->assertSame('sinch://host.test?from=sender', (string) $transport); + } + + public function testSupportsMessageInterface() + { + $transport = $this->createTransport(); + + $this->assertTrue($transport->supports(new SmsMessage('0611223344', 'Hello!'))); + $this->assertFalse($transport->supports($this->createMock(MessageInterface::class))); + } + + public function testSendNonSmsMessageThrowsException() + { + $transport = $this->createTransport(); + + $this->expectException(LogicException::class); + + $transport->send($this->createMock(MessageInterface::class)); + } + + private function createTransport(): SinchTransport + { + return (new SinchTransport('accountSid', 'authToken', 'sender', $this->createMock(HttpClientInterface::class)))->setHost('host.test'); + } +} diff --git a/src/Symfony/Component/Notifier/Bridge/Sinch/composer.json b/src/Symfony/Component/Notifier/Bridge/Sinch/composer.json index 1030cc2611..360139e6b8 100644 --- a/src/Symfony/Component/Notifier/Bridge/Sinch/composer.json +++ b/src/Symfony/Component/Notifier/Bridge/Sinch/composer.json @@ -19,7 +19,7 @@ "php": ">=7.2.5", "ext-json": "*", "symfony/http-client": "^4.3|^5.0", - "symfony/notifier": "^5.0,<5.2" + "symfony/notifier": "~5.1.0" }, "autoload": { "psr-4": { "Symfony\\Component\\Notifier\\Bridge\\Sinch\\": "" }, diff --git a/src/Symfony/Component/Notifier/Bridge/Sinch/phpunit.xml.dist b/src/Symfony/Component/Notifier/Bridge/Sinch/phpunit.xml.dist new file mode 100644 index 0000000000..298663e372 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/Sinch/phpunit.xml.dist @@ -0,0 +1,31 @@ + + + + + + + + + + ./Tests/ + + + + + + ./ + + ./Resources + ./Tests + ./vendor + + + +