 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Chatwork;

use Symfony\Component\Notifier\Exception\UnsupportedSchemeException;
use Symfony\Component\Notifier\Transport\AbstractTransportFactory;
use Symfony\Component\Notifier\Transport\Dsn;

/**
 * @author Ippei Sumida <ippey.s@gmail.com

te(Dsn $dsn): ChatworkTransport
    {
        $scheme = $dsn->getScheme();
        if (self::SCHEME !== $scheme) {
            throw new UnsupportedSchemeException($dsn, self::SCHEME, $this->getSupportedSchemes());
        }

        $token = $this->getUse

*/
class ChatworkTransportFactory extends AbstractTransportFactory
{
    private const SCHEME = 'chatwork';

    protected function getSupportedSchemes(): array
    {
        return [self::SCHEME];
    }

    public function crea


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Redlink\Tests;

use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\Notifier\Bridge\Redlink\RedlinkOptions;
use Symfony\Component\Notifier\Bridge\Redlink\RedlinkTransport;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\

HttpClient\HttpClientInterface;

final class RedlinkTransportTest extends TransportTestCase
{
    public static function createTransport(?HttpClientInterface $client = null): RedlinkTransport
    {
        return (new RedlinkTransport(
            'testApi

Component\Notifier\Message\PushMessage;
use Symfony\Component\Notifier\Message\SmsMessage;
use Symfony\Component\Notifier\Test\TransportTestCase;
use Symfony\Component\Notifier\Tests\Transport\DummyMessage;
use Symfony\Contracts\


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Pushover;

use Symfony\Component\Notifier\Exception\TransportException;
use Symfony\Component\Notifier\Exception\UnsupportedMessageTypeException;
use Symfony\Component\Notifier\Message\MessageInterface;
use Symfony\Component\Notifier\Message\PushMessage;
use Symfony\Component\Notifier\Message\SentMessage;
use Symfony\Component\Not

 * @author mocodo <https://github.com/mocodo>
 */
final class PushoverTransport extends AbstractTransport
{
    protected const HOST = 'api.pushover.net';

    public function __construct(
        #[\SensitiveParameter] private readonly string $userKey,

ifier\Transport\AbstractTransport;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;

/**


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Pushover;

use Symfony\Component\Notifier\Exception\UnsupportedSchemeException;
use Symfony\Component\Notifier\Transport\AbstractTransportFactory;
use Symfony\Component\Notifier\Transport\Dsn;
use Symfony\Component\Notifier\Transport\Transpor

$dsn->getScheme()) {
            throw new UnsupportedSchemeException($dsn, 'pushover', $this->getSupportedSchemes());
        }

        $userKey = $dsn->getUser();
        $appToken = $dsn->getPassword();
        $host = 'default' === $dsn->getHost() ? n

tInterface;

/**
 * @author mocodo <https://github.com/mocodo>
 */
final class PushoverTransportFactory extends AbstractTransportFactory
{
    public function create(Dsn $dsn): TransportInterface
    {
        if ('pushover' !==


hp

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Pushover\Tests;

use Symfony\Component\Notifier\Bridge\Pushover\PushoverTransportFactory;
use Symfony\Component\Notifier\Test\AbstractTransportFactoryTestCase;

final class PushoverTransportFactoryTest extends AbstractTransportFactor

over.net', 'pushover://userKey:appToken@api.pushover.net'];
    }

    public static function supportsProvider(): iterable
    {
        yield [true, 'pushover://userKey@appToken'];
        yield [false, 'somethingElse://userKey@appToken'];
    }

    publ

yTestCase
{
    public function createFactory(): PushoverTransportFactory
    {
        return new PushoverTransportFactory();
    }

    public static function createProvider(): iterable
    {
        yield ['pushover://api.push


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Smsc\Tests;

use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\Notifier\Bridge\Smsc\SmscTransport;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Notifier\Message\SmsMessage;
use Symfony\Compone

unction createTransport(?HttpClientInterface $client = null): SmscTransport
    {
        return new SmscTransport('login', 'password', 'MyApp', $client ?? new MockHttpClient());
    }

    public static function toStringProvider(): iterable
    {

nt\Notifier\Test\TransportTestCase;
use Symfony\Component\Notifier\Tests\Transport\DummyMessage;
use Symfony\Contracts\HttpClient\HttpClientInterface;

final class SmscTransportTest extends TransportTestCase
{
    public static f


buted with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Smsbox;

use Symfony\Component\Clock\Clock;
use Symfony\Component\Clock\ClockInterface;
use Symfony\Component\Intl\Countries;
use Symfony\Component\Notifier\Bridge\Smsbox\Enum\Charset;
use Symfony\Component\Notifier\Bridge\Smsbox\Enum\Day;
use Symfony\Component\Notifier\Bridge\Smsbox\Enum\Encoding;
use Symfony\Component\Notifier\Bridge\Smsbox\Enum\Mode;
use Symfony\Component\Notifier\Bridge\Smsbox\Enum\Strategy;
use Symfony\Compon

d Touil <ftouil@smsbox.fr>
 * @author Alexandre Daubois <alex.daubois@gmail.com>
 */
final class SmsboxOptions implements MessageOptionsInterface
{
    private ClockInterface $clock;

    public function __construct(
        private array $options = [],

ent\Notifier\Bridge\Smsbox\Enum\Udh;
use Symfony\Component\Notifier\Exception\InvalidArgumentException;
use Symfony\Component\Notifier\Message\MessageOptionsInterface;

/**
 * @author Alan Zarli <azarli@smsbox.fr>
 * @author Fari


buted with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Smsbox;

use Symfony\Component\Notifier\Bridge\Smsbox\Enum\Mode;
use Symfony\Component\Notifier\Bridge\Smsbox\Enum\Strategy;
use Symfony\Component\Notifier\Exception\InvalidArgumentException;
use Symfony\Component\Notifier\Exception\TransportException;
use Symfony\Component\Notifier\Exception\UnsupportedMessageTypeException;
use Symfony\Component\Notifier\Message\MessageInterface;
use Symfony\Component\Notifier\Message\SentMessage

ExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;

/**
 * @author Alan Zarli <azarli@smsbox.fr>
 * @author Farid Touil <ftouil@smsbox.fr>
 */
final class SmsboxTransport extends AbstractTransport
{
    protected const HOST = 'api.sm

;
use Symfony\Component\Notifier\Message\SmsMessage;
use Symfony\Component\Notifier\Transport\AbstractTransport;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\HttpClient\Exception\Transport


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Smsbox;

use Symfony\Component\Notifier\Bridge\Smsbox\Enum\Mode;
use Symfony\Component\Notifier\Bridge\Smsbox\Enum\Strategy;
use Symfony\Component\Notifier\Exception\UnsupportedSchemeException;
use Symfony\Component\Notifier\Transport\AbstractTransportFac

tion create(Dsn $dsn): SmsboxTransport
    {
        $scheme = $dsn->getScheme();

        if ('smsbox' !== $scheme) {
            throw new UnsupportedSchemeException($dsn, 'smsbox', $this->getSupportedSchemes());
        }

        $apiKey = $this->getUs

tory;
use Symfony\Component\Notifier\Transport\Dsn;

/**
 * @author Alan Zarli <azarli@smsbox.fr>
 * @author Farid Touil <ftouil@smsbox.fr>
 */
final class SmsboxTransportFactory extends AbstractTransportFactory
{
    public func


buted with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Smsbox\Tests;

use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Intl\Countries;
use Symfony\Component\Notifier\Bridge\Smsbox\Enum\Charset;
use Symfony\Component\Notifier\Bridge\Smsbox\Enum\Day;
use Symfony\Component\Notifier\Bridge\Smsbox\Enum\Mode;
use Symfony\Component\Notifier\Bridge\Smsbox\Enum\Strategy;
use Symfony\Component\Notifier\Bridge\Smsbox\Enum\Udh;
use Symfony\Component

boxOptions())
            ->mode(Mode::Expert)
            ->sender('SENDER')
            ->strategy(Strategy::Marketing)
            ->charset(Charset::Utf8)
            ->udh(Udh::DisabledConcat)
            ->maxParts(2)
            ->validity(100)

\Notifier\Bridge\Smsbox\SmsboxOptions;
use Symfony\Component\Notifier\Exception\InvalidArgumentException;

class SmsboxOptionsTest extends TestCase
{
    public function testSmsboxOptions()
    {
        $smsboxOptions = (new Sms


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Smsbox\Tests;

use Symfony\Component\Notifier\Bridge\Smsbox\SmsboxTransportFactory;
use Symfony\Component\Notifier\Test\AbstractTransportFactoryTestCase;
use Symfony\Component\Notifier\Test\IncompleteDsnTestTrait;
use Symfony\Component\Notifier\Test\MissingRequiredOptionTestTrait;

  return new SmsboxTransportFactory();
    }

    public static function createProvider(): iterable
    {
        yield ['smsbox://host.test?mode=Standard&strategy=4', 'smsbox://APIKEY@host.test?mode=Standard&strategy=4'];
        yield ['smsbox://host.tes

final class SmsboxTransportFactoryTest extends AbstractTransportFactoryTestCase
{
    use IncompleteDsnTestTrait;
    use MissingRequiredOptionTestTrait;

    public function createFactory(): SmsboxTransportFactory
    {


buted with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Smsbox\Tests;

use Symfony\Component\Clock\Test\ClockSensitiveTrait;
use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\HttpClient\Response\MockResponse;
use Symfony\Component\Notifier\Bridge\Smsbox\Enum\Day;
use Symfony\Component\Notifier\Bridge\Smsbox\Enum\Encoding;
use Symfony\Component\Notifier\Bridge\Smsbox\Enum\Mode;
use Symfony\Component\Notifier\Bridge\Smsbox\Enum\Strategy;
use Symfony\Component\Notifie

otifier\Message\SmsMessage;
use Symfony\Component\Notifier\Test\TransportTestCase;
use Symfony\Component\Notifier\Tests\Transport\DummyMessage;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;

final

r\Bridge\Smsbox\SmsboxOptions;
use Symfony\Component\Notifier\Bridge\Smsbox\SmsboxTransport;
use Symfony\Component\Notifier\Exception\TransportException;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\N


n Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Smsbox\Tests\Enum;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Notifier\Bridge\Smsbox\Enum\Mode;

class ModeTest extends TestCase
{
    #[DataProvider('provideModeValues')]
    public function testModeValues(Mode $mode, string $value)
    {

    /**
     * @return iterable<array{Mode, string}>
     */
    public static function provideModeValues(): iterable
    {
        yield [Mode::Standard, 'Standard'];
        yield [Mode::Expert, 'Expert'];
        yield [Mode::Response, 'Reponse']; //

       self::assertSame($value, $mode->value);
    }


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Smsbox\Tests\Webhook;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Notifier\Bridge\Smsbox\Webhook\SmsboxRequestParser;
use Symfony\Component\Webhook\Client\RequestParserInterface;
use Symfony\Component\Webhook\Exception\RejectWebhookException;
use Symfony\C

stParser();
    }

    protected function createRequest(string $payload): Request
    {
        parse_str(trim($payload), $parameters);

        return Request::create('/', 'GET', $parameters, [], [], ['REMOTE_ADDR' => '37.59.198.135']);
    }

    protect

omponent\Webhook\Test\AbstractRequestParserTestCase;

class SmsboxRequestParserTest extends AbstractRequestParserTestCase
{
    protected function createRequestParser(): RequestParserInterface
    {
        return new SmsboxReque


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Smsbox\Webhook;

use Symfony\Component\HttpFoundation\ChainRequestMatcher;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestMatcher\IpsRequestMatcher;
use Symfony\Component\HttpFoundation\RequestMatcher\MethodRequestMatcher;
use Symfony\Com

al class SmsboxRequestParser extends AbstractRequestParser
{
    // https://www.smsbox.net/en/tools-development#doc-sms-accusees
    public const PROVIDER_IPS = ['37.59.198.135', '178.33.185.51', '54.36.93.79', '54.36.93.80', '62.4.31.47', '62.4.31.48'];

ponent\HttpFoundation\RequestMatcherInterface;
use Symfony\Component\RemoteEvent\Event\Sms\SmsEvent;
use Symfony\Component\Webhook\Client\AbstractRequestParser;
use Symfony\Component\Webhook\Exception\RejectWebhookException;

fin


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Vonage;

use Symfony\Component\Notifier\Exception\TransportException;
use Symfony\Component\Notifier\Exception\UnsupportedMessageTypeException;
use Symfony\Component\Notifier\Message\MessageInterface;
use Symfony\Component\Notifier\Message\SentMessage;
use Symfony\Component\Notifi

y\Contracts\HttpClient\HttpClientInterface;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class VonageTransport extends AbstractTransport
{
    // see https://developer.vonage.com/messaging/sms/overview
    protected const HOST = 'rest.ne

er\Message\SmsMessage;
use Symfony\Component\Notifier\Transport\AbstractTransport;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfon


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Vonage;

use Symfony\Component\Notifier\Exception\UnsupportedSchemeException;
use Symfony\Component\Notifier\Transport\AbstractTransportFactory;
use Symfony\Component\Notifier\Transport\Dsn;

/**
 * @author Fabien Potencier <fabien@symfony.co

new UnsupportedSchemeException($dsn, 'vonage', $this->getSupportedSchemes());
        }

        $apiKey = $this->getUser($dsn);
        $apiSecret = $this->getPassword($dsn);
        $from = $dsn->getRequiredOption('from');
        $host = 'default' === $

m>
 */
final class VonageTransportFactory extends AbstractTransportFactory
{
    public function create(Dsn $dsn): VonageTransport
    {
        $scheme = $dsn->getScheme();

        if ('vonage' !== $scheme) {
            throw


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Vonage\Tests;

use Symfony\Component\Notifier\Bridge\Vonage\VonageTransportFactory;
use Symfony\Component\Notifier\Test\AbstractTransportFactoryTestCase;
use Symfony\Component\Notifier\Test\IncompleteDsnTestTrait;
use Symfony\Component\Notifier\Test\Missi

nsportFactory
    {
        return new VonageTransportFactory();
    }

    public static function createProvider(): iterable
    {
        yield [
            'vonage://host.test?from=0611223344',
            'vonage://apiKey:apiSecret@host.test?from=0611

ngRequiredOptionTestTrait;

final class VonageTransportFactoryTest extends AbstractTransportFactoryTestCase
{
    use IncompleteDsnTestTrait;
    use MissingRequiredOptionTestTrait;

    public function createFactory(): VonageTra


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Vonage\Tests;

use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\Notifier\Bridge\Vonage\VonageTransport;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Notifier\Message\SmsMessage;
use Symfony\C

static function createTransport(?HttpClientInterface $client = null): VonageTransport
    {
        return new VonageTransport('apiKey', 'apiSecret', 'sender', $client ?? new MockHttpClient());
    }

    public static function toStringProvider(): iterable

omponent\Notifier\Test\TransportTestCase;
use Symfony\Component\Notifier\Tests\Transport\DummyMessage;
use Symfony\Contracts\HttpClient\HttpClientInterface;

final class VonageTransportTest extends TransportTestCase
{
    public


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Vonage\Tests\Webhook;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Notifier\Bridge\Vonage\Webhook\VonageRequestParser;
use Symfony\Component\Webhook\Client\RequestParserInterface;
use Symfony\Component\Webhook\Exception\RejectWebhookException;
use Symfony\C

{}');
        $request->headers->remove('Authorization');
        $parser = $this->createRequestParser();

        $this->expectException(RejectWebhookException::class);
        $this->expectExceptionMessage('Missing "Authorization" header');

        $par

omponent\Webhook\Test\AbstractRequestParserTestCase;

class VonageRequestParserTest extends AbstractRequestParserTestCase
{
    public function testMissingAuthorizationTokenThrows()
    {
        $request = $this->createRequest('


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Vonage\Webhook;

use Symfony\Component\HttpFoundation\ChainRequestMatcher;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestMatcher\IsJsonRequestMatcher;
use Symfony\Component\HttpFoundation\RequestMatcher\MethodRequestMatcher;
use Symfony\Component\HttpFoundation\RequestMatcherInterface;
u

hookException;

final class VonageRequestParser extends AbstractRequestParser
{
    protected function getRequestMatcher(): RequestMatcherInterface
    {
        return new ChainRequestMatcher([
            new MethodRequestMatcher('POST'),
            new

se Symfony\Component\Notifier\Exception\InvalidArgumentException;
use Symfony\Component\RemoteEvent\Event\Sms\SmsEvent;
use Symfony\Component\Webhook\Client\AbstractRequestParser;
use Symfony\Component\Webhook\Exception\RejectWeb


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\GoogleChat;

use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Notifier\Message\MessageOptionsInterface;
use Symfony\Component\Notifier\Notification\Notification;

/**
 * @author Jérôme Tamarelle <jerome@tamarelle.net>
 */
final class GoogleChatOptions impl

: self
    {
        $options = new self();

        $text = $notification->getEmoji().' *'.$notification->getSubject().'* ';

        if ($notification->getContent()) {
            $text .= "\r\n".$notification->getContent();
        }

        if ($excep

ements MessageOptionsInterface
{
    private ?string $threadKey = null;

    public function __construct(
        private array $options = [],
    ) {
    }

    public static function fromNotification(Notification $notification)


buted with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\GoogleChat;

use Symfony\Component\HttpClient\Exception\JsonException;
use Symfony\Component\Notifier\Exception\TransportException;
use Symfony\Component\Notifier\Exception\UnsupportedMessageTypeException;
use Symfony\Component\Notifier\Exception\UnsupportedOptionsException;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Notifier\Message\MessageInterface;
use Symfony\Component\Notifier\Message\SentMessag

nt\HttpClientInterface;

/**
 * @author Jérôme Tamarelle <jerome@tamarelle.net>
 */
final class GoogleChatTransport extends AbstractTransport
{
    protected const HOST = 'chat.googleapis.com';

    /**
     * @param string      $space       The space name

e;
use Symfony\Component\Notifier\Transport\AbstractTransport;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClie


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\GoogleChat;

use Symfony\Component\Notifier\Exception\UnsupportedSchemeException;
use Symfony\Component\Notifier\Transport\AbstractTransportFactory;
use Symfony\Component\Notifier\Transport\Dsn;

/**
 * @author Jérôme Tamarelle <jerome@tamarelle.net>
 */

hatTransport
    {
        $scheme = $dsn->getScheme();

        if ('googlechat' !== $scheme) {
            throw new UnsupportedSchemeException($dsn, 'googlechat', $this->getSupportedSchemes());
        }

        $space = explode('/', $dsn->getPath())[1

final class GoogleChatTransportFactory extends AbstractTransportFactory
{
    /**
     * @param Dsn $dsn Format: googlechat://<key>:<token>@default/<space>?thread_key=<thread>
     */
    public function create(Dsn $dsn): GoogleC


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\GoogleChat\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Notifier\Bridge\GoogleChat\GoogleChatOptions;

final class GoogleChatOptionsTest extends TestCase
{
    public function testToArrayWithCardV2()
    {
        $options = new GoogleCha

-app-avatar.png',
                'imageType' => 'CIRCLE',
                'imageAltText' => 'Avatar for Sasha',
            ],
            'sections' => [
                [
                    'header' => 'Contact Info',
                    'collapsible'

tOptions();

        $cardV2 = [
            'header' => [
                'title' => 'Sasha',
                'subtitle' => 'Software Engineer',
                'imageUrl' => 'https://developers.google.com/chat/images/quickstart


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\GoogleChat\Tests;

use Symfony\Component\Notifier\Bridge\GoogleChat\GoogleChatTransportFactory;
use Symfony\Component\Notifier\Test\AbstractTransportFactoryTestCase;
use Symfony\Component\Notifier\Test\IncompleteDsnTestTrait;

final class GoogleChatTransp

tatic function createProvider(): iterable
    {
        yield [
            'googlechat://chat.googleapis.com/AAAAA_YYYYY',
            'googlechat://abcde-fghij:kl_mnopqrstwxyz%3D@chat.googleapis.com/AAAAA_YYYYY',
        ];

        yield [
            '

ortFactoryTest extends AbstractTransportFactoryTestCase
{
    use IncompleteDsnTestTrait;

    public function createFactory(): GoogleChatTransportFactory
    {
        return new GoogleChatTransportFactory();
    }

    public s


buted with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\GoogleChat\Tests;

use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\HttpClient\Response\MockResponse;
use Symfony\Component\Notifier\Bridge\GoogleChat\GoogleChatOptions;
use Symfony\Component\Notifier\Bridge\GoogleChat\GoogleChatTransport;
use Symfony\Component\Notifier\Exception\TransportException;
use Symfony\Component\Notifier\Exception\UnsupportedOptionsException;
use Symfony\Component\Notifier\Message\Ch

TestCase;
use Symfony\Component\Notifier\Tests\Transport\DummyMessage;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;

final class GoogleChatTransportTest extends TransportTestCase
{
    public sta

atMessage;
use Symfony\Component\Notifier\Message\MessageOptionsInterface;
use Symfony\Component\Notifier\Message\SmsMessage;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Test\Transport


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Expo;

use Symfony\Component\Notifier\Message\MessageOptionsInterface;

/**
 * @author Imad ZAIRIG <https://github.com/zairigimad>
 *
 * @see https://docs.expo.dev/push-notifications/sending-notifications/
 */
final class ExpoOptions implements MessageOptionsInterface
{
    /**
     * @param array $options @see https://docs.expo.d

blic function toArray(): array
    {
        return array_merge($this->options, [
            'to' => $this->to,
            'data' => $this->data,
        ]);
    }

    public function getRecipientId(): ?string
    {
        return $this->to;
    }

ev/push-notifications/sending-notifications/#message-request-format
     */
    public function __construct(
        private string $to,
        private array $options = [],
        private array $data = [],
    ) {
    }

    pu


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Expo;

use Symfony\Component\Notifier\Exception\InvalidArgumentException;
use Symfony\Component\Notifier\Exception\TransportException;
use Symfony\Component\Notifier\Exception\UnsupportedMessageTypeException;
use Symfony\Component\Notifier\Message\MessageInterface;
use Symfony\Component\Notifier\Message\PushMessage;
use Symfony\Co

ace;
use Symfony\Contracts\HttpClient\HttpClientInterface;

/**
 * @author Imad ZAIRIG <https://github.com/zairigimad>
 */
final class ExpoTransport extends AbstractTransport
{
    protected const HOST = 'exp.host/--/api/v2/push/send';

    public function

mponent\Notifier\Message\SentMessage;
use Symfony\Component\Notifier\Transport\AbstractTransport;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterf


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Expo;

use Symfony\Component\Notifier\Exception\UnsupportedSchemeException;
use Symfony\Component\Notifier\Transport\AbstractTransportFactory;
use Symfony\Component\Notifier\Transport\Dsn;

/**
 * @author Imad ZAIRIG <https://github.com

row new UnsupportedSchemeException($dsn, 'expo', $this->getSupportedSchemes());
        }

        $token = $dsn->getUser();
        $host = 'default' === $dsn->getHost() ? null : $dsn->getHost();
        $port = $dsn->getPort();

        return (new ExpoT

/zairigimad>
 */
final class ExpoTransportFactory extends AbstractTransportFactory
{
    public function create(Dsn $dsn): ExpoTransport
    {
        $scheme = $dsn->getScheme();

        if ('expo' !== $scheme) {
            th


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Expo\Tests;

use Symfony\Component\Notifier\Bridge\Expo\ExpoTransportFactory;
use Symfony\Component\Notifier\Test\AbstractTransportFactoryTestCase;

/**
 * @author Imad ZAIRIG <https://github.com/zairigimad>
 */
final class ExpoTranspor

        yield [
            'expo://exp.host/--/api/v2/push/send',
            'expo://default',
        ];
    }

    public static function supportsProvider(): iterable
    {
        yield [true, 'expo://default?accessToken=test'];
        yield [false,

tFactoryTest extends AbstractTransportFactoryTestCase
{
    public function createFactory(): ExpoTransportFactory
    {
        return new ExpoTransportFactory();
    }

    public static function createProvider(): iterable
    {


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Expo\Tests;

use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\Notifier\Bridge\Expo\ExpoTransport;
use Symfony\Component\Notifier\Message\PushMessage;
use Symfony\Component\Notifier\Message\SmsMessage;
use Symfony\Compone

poTransportTest extends TransportTestCase
{
    public static function createTransport(?HttpClientInterface $client = null): ExpoTransport
    {
        return new ExpoTransport('token', $client ?? new MockHttpClient());
    }

    public static function t

nt\Notifier\Test\TransportTestCase;
use Symfony\Component\Notifier\Tests\Transport\DummyMessage;
use Symfony\Contracts\HttpClient\HttpClientInterface;

/**
 * @author Imad ZAIRIG <https://github.com/zairigimad>
 */
final class Ex


<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Zulip;

use Symfony\Component\Notifier\Message\MessageOptionsInterface;

/**
 * @author Mohammad Emran Hasan <phpfour@gmail.com>
 */
final class ZulipOptions implements MessageOptionsInterface
{
    public function __construct(

ipient,
        ];
    }

    public function getRecipientId(): ?string
    {
        return $this->recipient;
    }

    /**
     * @return $this
     */
    public function topic(string $topic): static
    {
        $this->topic = $topic;

        return

      private ?string $topic = null,
        private ?string $recipient = null,
    ) {
    }

    public function toArray(): array
    {
        return [
            'topic' => $this->topic,
            'recipient' => $this->rec


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Zulip;

use Symfony\Component\Notifier\Exception\LogicException;
use Symfony\Component\Notifier\Exception\TransportException;
use Symfony\Component\Notifier\Exception\UnsupportedMessageTypeException;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Notifier\Message\MessageInterface;
use Symfony\Component\N

Symfony\Contracts\HttpClient\HttpClientInterface;

/**
 * @author Mohammad Emran Hasan <phpfour@gmail.com>
 */
final class ZulipTransport extends AbstractTransport
{
    public function __construct(
        private string $email,
        #[\SensitiveParame

otifier\Message\SentMessage;
use Symfony\Component\Notifier\Transport\AbstractTransport;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Pushover;

use Symfony\Component\Notifier\Exception\InvalidArgumentException;
use Symfony\Component\Notifier\Message\MessageOptionsInterface;
use Symfony\Component\Notifier\Notification\Notification;

/**
 * @author mocodo <https://github.com/mocodo>
 *
 * @see https://pushover.net/api
 */
final class PushoverOptions implements Me

falling',
        'gamelan',
        'incoming',
        'intermission',
        'magic',
        'mechanical',
        'pianobar',
        'siren',
        'spacealarm',
        'tugboat',
        'alien',
        'climb',
        'persistent',
        'e

ssageOptionsInterface
{
    private const PRIORITIES = [-2, -1, 0, 1, 2];

    private const SOUNDS = [
        'pushover',
        'bike',
        'bugle',
        'cashregister',
        'classical',
        'cosmic',
        '


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Sevenio;

use Symfony\Component\Notifier\Exception\TransportException;
use Symfony\Component\Notifier\Exception\UnsupportedMessageTypeException;
use Symfony\Component\Notifier\Message\MessageInterface;
use Symfony\Component\Notifier\Message\SentMessage;
use Symfony\Component\Notifier\Message\SmsMessage;
use Symfony\Component\Notif

* @author Frank Nägler <frank@naegler.hamburg>
 */
final class SevenIoTransport extends AbstractTransport
{
    protected const HOST = 'gateway.seven.io';

    public function __construct(
        #[\SensitiveParameter] private string $apiKey,
        priv

ier\Transport\AbstractTransport;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;

/**


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Sevenio\Tests;

use Symfony\Component\Notifier\Bridge\Sevenio\SevenIoTransportFactory;
use Symfony\Component\Notifier\Test\AbstractTransportFactoryTestCase;
use Symfony\Component\Notifier\Test\IncompleteDsnTestTrait;

final class SevenIoTrans

 function createProvider(): iterable
    {
        yield [
            'sevenio://host.test',
            'sevenio://apiKey@host.test',
        ];

        yield [
            'sevenio://host.test?from=TEST',
            'sevenio://apiKey@host.test?from=TE

portFactoryTest extends AbstractTransportFactoryTestCase
{
    use IncompleteDsnTestTrait;

    public function createFactory(): SevenIoTransportFactory
    {
        return new SevenIoTransportFactory();
    }

    public static


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\TurboSms;

use Symfony\Component\Notifier\Exception\LengthException;
use Symfony\Component\Notifier\Exception\TransportException;
use Symfony\Component\Notifier\Exception\UnsupportedMessageTypeException;
use Symfony\Component\Notifier\Message\MessageInterface;
use Symfony\Component\Notifier\Message\SentMessage;
use Symfony\Compone

em Henvald <genvaldartem@gmail.com>
 *
 * @see https://turbosms.ua/api.html
 */
final class TurboSmsTransport extends AbstractTransport
{
    protected const HOST = 'api.turbosms.ua';

    private const SUBJECT_LATIN_LIMIT = 1521;
    private const SUBJECT

nt\Notifier\Message\SmsMessage;
use Symfony\Component\Notifier\Transport\AbstractTransport;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;

/**
 * @author Art


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Redlink;

use Symfony\Component\Notifier\Exception\TransportException;
use Symfony\Component\Notifier\Exception\UnsupportedMessageTypeException;
use Symfony\Component\Notifier\Message\MessageInterface;
use Symfony\Component\Notifier\Message\SentMessage;
use Symfony\Component\Notifier\Message\SmsMessage;
use Symfony\Component\Notif

* @author Mateusz Żyła <https://github.com/plotkabytes>
 */
final class RedlinkTransport extends AbstractTransport
{
    protected const HOST = 'api.redlink.pl';

    public function __construct(
        #[\SensitiveParameter] private readonly string $apiT


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Redlink\Tests;

use Symfony\Component\Notifier\Bridge\Redlink\RedlinkTransportFactory;
use Symfony\Component\Notifier\Test\AbstractTransportFactoryTestCase;
use Symfony\Component\Notifier\Test\IncompleteDsnTestTrait;
use Symfony\Component\Notifier\Test\Mi

nkTransportFactory
    {
        return new RedlinkTransportFactory();
    }

    public static function createProvider(): iterable
    {
        yield [
            'redlink://api.redlink.pl?from=TEST&version=v2.1',
            'redlink://aaaaa:bbbbbb@api

ssingRequiredOptionTestTrait;

final class RedlinkTransportFactoryTest extends AbstractTransportFactoryTestCase
{
    use IncompleteDsnTestTrait;
    use MissingRequiredOptionTestTrait;

    public function createFactory(): Redli


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\TurboSms;

use Symfony\Component\Notifier\Exception\UnsupportedSchemeException;
use Symfony\Component\Notifier\Transport\AbstractTransportFactory;
use Symfony\Component\Notifier\Transport\Dsn;

/**
 * @author Artem Henvald <genvaldartem@gmail

   throw new UnsupportedSchemeException($dsn, 'turbosms', $this->getSupportedSchemes());
        }

        $authToken = $this->getUser($dsn);
        $from = $dsn->getRequiredOption('from');
        $host = 'default' === $dsn->getHost() ? null : $dsn->get

.com>
 */
final class TurboSmsTransportFactory extends AbstractTransportFactory
{
    public function create(Dsn $dsn): TurboSmsTransport
    {
        $scheme = $dsn->getScheme();

        if ('turbosms' !== $scheme) {


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\RingCentral;

use Symfony\Component\Notifier\Message\MessageOptionsInterface;

/**
 * @author gnito-org <https://github.com/gnito-org>
 */
final class RingCentralOptions implements MessageOptionsInterface
{
    public function __constru

 = null, ?string $name = null, ?string $uri = null, ?string $callingCode = null): static
    {
        $this->options['country'] = [
            'id' => $id,
            'isoCode' => $isoCode,
            'name' => $name,
            'uri' => $uri,

ct(
        private array $options = [],
    ) {
    }

    public function getRecipientId(): ?string
    {
        return null;
    }

    /**
     * @return $this
     */
    public function country(string $id, ?string $isoCode


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\RingCentral;

use Symfony\Component\Notifier\Exception\UnsupportedSchemeException;
use Symfony\Component\Notifier\Transport\AbstractTransportFactory;
use Symfony\Component\Notifier\Transport\Dsn;

/**
 * @author gnito-org <https://github.com/

n->getScheme();
        if (self::TRANSPORT_SCHEME !== $scheme) {
            throw new UnsupportedSchemeException($dsn, self::TRANSPORT_SCHEME, $this->getSupportedSchemes());
        }
        $apiKey = $this->getUser($dsn);
        $from = $dsn->getRequi

gnito-org>
 */
final class RingCentralTransportFactory extends AbstractTransportFactory
{
    private const TRANSPORT_SCHEME = 'ringcentral';

    public function create(Dsn $dsn): RingCentralTransport
    {
        $scheme = $ds


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\RingCentral\Tests;

use Symfony\Component\Notifier\Bridge\RingCentral\RingCentralTransportFactory;
use Symfony\Component\Notifier\Test\AbstractTransportFactoryTestCase;
use Symfony\Component\Notifier\Test\IncompleteDsnTestTrait;
use Symfony\Component\Noti

Factory(): RingCentralTransportFactory
    {
        return new RingCentralTransportFactory();
    }

    public static function createProvider(): iterable
    {
        yield ['ringcentral://host.test?from=0611223344', 'ringcentral://apiToken@host.test?fr

fier\Test\MissingRequiredOptionTestTrait;

final class RingCentralTransportFactoryTest extends AbstractTransportFactoryTestCase
{
    use IncompleteDsnTestTrait;
    use MissingRequiredOptionTestTrait;

    public function create


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Smsapi;

use Symfony\Component\Notifier\Exception\TransportException;
use Symfony\Component\Notifier\Exception\UnsupportedMessageTypeException;
use Symfony\Component\Notifier\Message\MessageInterface;
use Symfony\Component\Notifier\Message\SentMessage;
use Symfony\Component\Notifier\Message\SmsMessage;
use Symfony\Component\Notifi

nterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;

/**
 * @author Marcin Szepczynski <szepczynski@gmail.com>
 */
final class SmsapiTransport extends AbstractTransport
{
    protected const HOST = 'api.smsapi.pl';

    private bool $fast = fal

er\Transport\AbstractTransport;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionI


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Smsapi\Tests;

use Symfony\Component\Notifier\Bridge\Smsapi\SmsapiTransportFactory;
use Symfony\Component\Notifier\Test\AbstractTransportFactoryTestCase;
use Symfony\Component\Notifier\Test\IncompleteDsnTestTrait;

final class SmsapiTransportFactoryTest extends AbstractTransportFa

      yield [
            'smsapi://host.test',
            'smsapi://token@host.test',
        ];

        yield [
            'smsapi://host.test?from=testFrom',
            'smsapi://token@host.test?from=testFrom',
        ];

        yield [

ctoryTestCase
{
    use IncompleteDsnTestTrait;

    public function createFactory(): SmsapiTransportFactory
    {
        return new SmsapiTransportFactory();
    }

    public static function createProvider(): iterable
    {


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Mailjet;

use Symfony\Component\Notifier\Exception\TransportException;
use Symfony\Component\Notifier\Exception\UnsupportedMessageTypeException;
use Symfony\Component\Notifier\Message\MessageInterface;
use Symfony\Component\Notifier\Message\SentMessage;
use Symfony\Component\Notif

ny\Contracts\HttpClient\HttpClientInterface;

/**
 * @author Jérôme Nadaud <jerome@nadaud.io>
 */
final class MailjetTransport extends AbstractTransport
{
    protected const HOST = 'api.mailjet.com';

    public function __construct(
        #[\SensitiveP

ier\Message\SmsMessage;
use Symfony\Component\Notifier\Transport\AbstractTransport;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfo


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Mailjet\Tests;

use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\Notifier\Bridge\Mailjet\MailjetTransport;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Notifier\Message\SmsMessage;
use Symfon

lic static function createTransport(?HttpClientInterface $client = null): MailjetTransport
    {
        return (new MailjetTransport('authtoken', 'Mailjet', $client ?? new MockHttpClient()))->setHost('host.test');
    }

    public static function toStrin

y\Component\Notifier\Test\TransportTestCase;
use Symfony\Component\Notifier\Tests\Transport\DummyMessage;
use Symfony\Contracts\HttpClient\HttpClientInterface;

final class MailjetTransportTest extends TransportTestCase
{
    pub


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Mailjet;

use Symfony\Component\Notifier\Exception\UnsupportedSchemeException;
use Symfony\Component\Notifier\Transport\AbstractTransportFactory;
use Symfony\Component\Notifier\Transport\Dsn;

/**
 * @author Jérôme Nadaud <jerome@nadaud.io>

ew UnsupportedSchemeException($dsn, 'mailjet', $this->getSupportedSchemes());
        }

        $authToken = $this->getPassword($dsn);
        $from = $this->getUser($dsn);
        $host = 'default' === $dsn->getHost() ? null : $dsn->getHost();
        $p

*/
final class MailjetTransportFactory extends AbstractTransportFactory
{
    public function create(Dsn $dsn): MailjetTransport
    {
        $scheme = $dsn->getScheme();

        if ('mailjet' !== $scheme) {
            throw n


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Smsc\Tests;

use Symfony\Component\Notifier\Bridge\Smsc\SmscTransportFactory;
use Symfony\Component\Notifier\Test\AbstractTransportFactoryTestCase;
use Symfony\Component\Notifier\Test\MissingRequiredOptionTestTrait;

final class SmscTransportFactoryTest e

eProvider(): iterable
    {
        yield [
            'smsc://host.test?from=MyApp',
            'smsc://login:password@host.test?from=MyApp',
        ];
    }

    public static function supportsProvider(): iterable
    {
        yield [true, 'smsc://lo

xtends AbstractTransportFactoryTestCase
{
    use MissingRequiredOptionTestTrait;

    public function createFactory(): SmscTransportFactory
    {
        return new SmscTransportFactory();
    }

    public static function creat


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Pushover\Tests;

use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\HttpClient\Response\MockResponse;
use Symfony\Component\Notifier\Bridge\Pushover\PushoverTransport;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Notifier\Message\PushMessage;
use Symfony\Component\Notifier\Notificat

Interface;

final class PushoverTransportTest extends TransportTestCase
{
    public static function createTransport(?HttpClientInterface $client = null): PushoverTransport
    {
        return new PushoverTransport('userKey', 'appToken', $client ?? new Mo

ion\Notification;
use Symfony\Component\Notifier\Test\TransportTestCase;
use Symfony\Component\Notifier\Tests\Transport\DummyMessage;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\Response


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Sevenio;

use Symfony\Component\Notifier\Exception\UnsupportedSchemeException;
use Symfony\Component\Notifier\Transport\AbstractTransportFactory;
use Symfony\Component\Notifier\Transport\Dsn;

/**
 * @author Frank Nägler <frank@naegler.hambur

ow new UnsupportedSchemeException($dsn, 'sevenio', $this->getSupportedSchemes());
        }

        $apiKey = $this->getUser($dsn);
        $from = $dsn->getOption('from');
        $host = 'default' === $dsn->getHost() ? null : $dsn->getHost();
        $p

g>
 */
final class SevenIoTransportFactory extends AbstractTransportFactory
{
    public function create(Dsn $dsn): SevenIoTransport
    {
        $scheme = $dsn->getScheme();

        if ('sevenio' !== $scheme) {
            thr


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Sevenio\Tests;

use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\Notifier\Bridge\Sevenio\SevenIoTransport;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Notifier\Message\SmsMessage;
use Symfon

lic static function createTransport(?HttpClientInterface $client = null, ?string $from = null): SevenIoTransport
    {
        return new SevenIoTransport('apiKey', $from, $client ?? new MockHttpClient());
    }

    public static function toStringProvider

y\Component\Notifier\Test\TransportTestCase;
use Symfony\Component\Notifier\Tests\Transport\DummyMessage;
use Symfony\Contracts\HttpClient\HttpClientInterface;

final class SevenIoTransportTest extends TransportTestCase
{
    pub


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Redlink;

use Symfony\Component\Notifier\Exception\UnsupportedSchemeException;
use Symfony\Component\Notifier\Transport\AbstractTransportFactory;
use Symfony\Component\Notifier\Transport\Dsn;
use Symfony\Component\Notifier\Transport\Transport

nk' !== $dsn->getScheme()) {
            throw new UnsupportedSchemeException($dsn, 'redlink', $this->getSupportedSchemes());
        }

        $apiKey = $dsn->getUser();
        $appToken = $dsn->getPassword();
        $host = 'default' === $dsn->getHost

Interface;

/**
 * @author Mateusz Żyła <https://github.com/plotkabytes>
 */
final class RedlinkTransportFactory extends AbstractTransportFactory
{
    public function create(Dsn $dsn): TransportInterface
    {
        if ('redli


buted with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\TurboSms\Tests;

use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\HttpClient\Response\JsonMockResponse;
use Symfony\Component\Notifier\Bridge\TurboSms\TurboSmsTransport;
use Symfony\Component\Notifier\Exception\LengthException;
use Symfony\Component\Notifier\Exception\TransportException;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Notifier\Message\SentMessage;
use Symfony\Compone

lient\ResponseInterface;

final class TurboSmsTransportTest extends TransportTestCase
{
    public static function createTransport(?HttpClientInterface $client = null): TurboSmsTransport
    {
        return new TurboSmsTransport('authToken', 'sender', $cl

nt\Notifier\Message\SmsMessage;
use Symfony\Component\Notifier\Test\TransportTestCase;
use Symfony\Component\Notifier\Tests\Transport\DummyMessage;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpC


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\RingCentral\Tests;

use PHPUnit\Framework\Attributes\DataProvider;
use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\HttpClient\Response\MockResponse;
use Symfony\Component\Notifier\Bridge\RingCentral\RingCentralOptions;
use Symfony\Component\Notifier\Bridge\RingCentral\RingCentralTransport;
use Symfony\Compon

Notifier\Tests\Transport\DummyMessage;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;

final class RingCentralTransportTest extends TransportTestCase
{
    public static function createTransport(?H

ent\Notifier\Exception\InvalidArgumentException;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Notifier\Message\SmsMessage;
use Symfony\Component\Notifier\Test\TransportTestCase;
use Symfony\Component\


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Smsapi\Tests;

use PHPUnit\Framework\Attributes\DataProvider;
use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\HttpClient\Response\MockResponse;
use Symfony\Component\Notifier\Bridge\Smsapi\SmsapiTransport;
use Symfony\Component\Notifier\Exception\TransportException;
use Symfony\Component\Notifier\Message\Cha

;

final class SmsapiTransportTest extends TransportTestCase
{
    public static function createTransport(?HttpClientInterface $client = null, string $from = '', bool $fast = false, bool $test = false): SmsapiTransport
    {
        return (new SmsapiTrans

tMessage;
use Symfony\Component\Notifier\Message\SmsMessage;
use Symfony\Component\Notifier\Test\TransportTestCase;
use Symfony\Component\Notifier\Tests\Transport\DummyMessage;
use Symfony\Contracts\HttpClient\HttpClientInterface


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Mailjet\Tests;

use Symfony\Component\Notifier\Bridge\Mailjet\MailjetTransportFactory;
use Symfony\Component\Notifier\Test\AbstractTransportFactoryTestCase;
use Symfony\Component\Notifier\Test\IncompleteDsnTestTrait;

final class MailjetTransportFactoryTe

ateProvider(): iterable
    {
        yield [
            'mailjet://Mailjet@host.test',
            'mailjet://Mailjet:authtoken@host.test',
        ];
    }

    public static function supportsProvider(): iterable
    {
        yield [true, 'mailjet://Ma

st extends AbstractTransportFactoryTestCase
{
    use IncompleteDsnTestTrait;

    public function createFactory(): MailjetTransportFactory
    {
        return new MailjetTransportFactory();
    }

    public static function cre


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Zulip\Tests;

use Symfony\Component\Notifier\Bridge\Zulip\ZulipTransportFactory;
use Symfony\Component\Notifier\Test\AbstractTransportFactoryTestCase;
use Symfony\Component\Notifier\Test\IncompleteDsnTestTrait;
use Symfony\Component\Notifier\Test\MissingR

tFactory
    {
        return new ZulipTransportFactory();
    }

    public static function createProvider(): iterable
    {
        yield [
            'zulip://host.test?channel=testChannel',
            'zulip://email:token@host.test?channel=testChanne

equiredOptionTestTrait;

final class ZulipTransportFactoryTest extends AbstractTransportFactoryTestCase
{
    use IncompleteDsnTestTrait;
    use MissingRequiredOptionTestTrait;

    public function createFactory(): ZulipTranspor


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\RingCentral;

use Symfony\Component\Notifier\Exception\InvalidArgumentException;
use Symfony\Component\Notifier\Exception\TransportException;
use Symfony\Component\Notifier\Exception\UnsupportedMessageTypeException;
use Symfony\Component\Notifier\Message\MessageInterface;
use Symfony\Component\Notifier\Message\SentMessage;
use Sym

Interface;
use Symfony\Contracts\HttpClient\HttpClientInterface;

/**
 * @author gnito-org <https://github.com/gnito-org>
 */
final class RingCentralTransport extends AbstractTransport
{
    protected const HOST = 'platform.ringcentral.com';

    public fu

fony\Component\Notifier\Message\SmsMessage;
use Symfony\Component\Notifier\Transport\AbstractTransport;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\HttpClient\Exception\TransportException


hp

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Test\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\Notifier\Message\MessageInterface;

/**
 * @author Smaïne Milianni <smaine.milianni@gmail.com>
 */
final class NotificationTransportIsEqual extends Constra

geInterface $message
     */
    protected function matches($message): bool
    {
        return $message->getTransport() === $this->expectedText;
    }

    /**
     * @param MessageInterface $message
     */
    protected function failureDescription($mes

int
{
    public function __construct(
        private ?string $expectedText,
    ) {
    }

    public function toString(): string
    {
        return \sprintf('is "%s"', $this->expectedText);
    }

    /**
     * @param Messa


php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\FlashMessage;

use Symfony\Component\Notifier\Exception\FlashMessageImportanceMapperException;

/**
 * @author Ben Roberts <ben@headsnet.com>
 */
abstract class AbstractFlashMessageImportanceMapper
{
    public function flashMessageTypeFro

ring $importance): string
    {
        if (!\array_key_exists($importance, static::IMPORTANCE_MAP)) {
            throw new FlashMessageImportanceMapperException($importance, static::class);
        }

        return static::IMPORTANCE_MAP[$importance];


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\FlashMessage;

use Symfony\Component\Notifier\Notification\Notification;

/**
 * @author Ben Roberts <ben@headsnet.com>
 */
class BootstrapFlashMessageImportanceMapper extends AbstractFlashMessageImportanceMapper implements FlashMessageImportanceMap

    protected const IMPORTANCE_MAP = [
        Notification::IMPORTANCE_URGENT => 'danger',
        Notification::IMPORTANCE_HIGH => 'warning',
        Notification::IMPORTANCE_MEDIUM => 'info',
        Notification::IMPORTANCE_LOW => 'success',
    ];
}


 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\FlashMessage;

use Symfony\Component\Notifier\Notification\Notification;

/**
 * @author Ben Roberts <ben@headsnet.com>
 */
class DefaultFlashMessageImportanceMapper extends AbstractFlashMessageImportanceMapper implements FlashMessageImportanceMap

    protected const IMPORTANCE_MAP = [
        Notification::IMPORTANCE_URGENT => 'notification',
        Notification::IMPORTANCE_HIGH => 'notification',
        Notification::IMPORTANCE_MEDIUM => 'notification',
        Notification::IMPORTANCE_LOW => '


?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Channel;

use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Notifier\Exception\LogicException;
use Symfony\Component\Notifier\Transport\TransportInterface;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */

BusInterface $bus = null)
    {
        if (null === $transport && null === $bus) {
            throw new LogicException(\sprintf('"%s" needs a Transport or a Bus but both cannot be "null".', static::class));
        }

        $this->transport = $transpor

abstract class AbstractChannel implements ChannelInterface
{
    protected ?TransportInterface $transport;
    protected ?MessageBusInterface $bus;

    public function __construct(?TransportInterface $transport = null, ?Message


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Channel;

use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Notifier\FlashMessage\DefaultFlashMessageImportanceMapper;
use Symfony\Component\Notifier\FlashMessage\FlashMessageImportanceMapperInterface;
use Symfony\Component\Notifier\Notifi

        private RequestStack $stack,
        private FlashMessageImportanceMapperInterface $mapper = new DefaultFlashMessageImportanceMapper(),
    ) {
    }

    public function notify(Notification $notification, RecipientInterface $recipient, ?string $t

cation\Notification;
use Symfony\Component\Notifier\Recipient\RecipientInterface;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class BrowserChannel implements ChannelInterface
{
    public function __construct(


is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Channel;

use Symfony\Component\Notifier\Exception\InvalidArgumentException;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class ChannelPolicy implements ChannelPolicyInterface
{
    public function __construct(
        private array $policy,

ng $importance): array
    {
        if (!isset($this->policy[$importance])) {
            throw new InvalidArgumentException(\sprintf('Importance "%s" is not defined in the Policy.', $importance));
        }

        return $this->policy[$importance];

    ) {
    }

    public function getChannels(stri


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Channel;

use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Notifier\Notification\ChatNotificationInterface;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Recipient\RecipientInterfac

   {
        $message = null;
        if ($notification instanceof ChatNotificationInterface) {
            $message = $notification->asChatMessage($recipient, $transportName);
        }

        $message ??= ChatMessage::fromNotification($notification);

e;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ChatChannel extends AbstractChannel
{
    public function notify(Notification $notification, RecipientInterface $recipient, ?string $transportName = null): void


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Channel;

use Symfony\Component\Notifier\Message\DesktopMessage;
use Symfony\Component\Notifier\Notification\DesktopNotificationInterface;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Recipient\RecipientIn

ull): void
    {
        if ($notification instanceof DesktopNotificationInterface) {
            $message = $notification->asDesktopMessage($recipient, $transportName);
        }

        $message ??= DesktopMessage::fromNotification($notification);

terface;

/**
 * @author Ahmed Ghanem <ahmedghanem7361@gmail.com>
 */
class DesktopChannel extends AbstractChannel
{
    public function notify(Notification $notification, RecipientInterface $recipient, ?string $transportName = n


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Channel;

use Symfony\Component\Mailer\Envelope;
use Symfony\Component\Mailer\Messenger\SendEmailMessage;
use Symfony\Component\Mailer\Transport\TransportInterface;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use Symfony\Component\Notifier\Exception\LogicExcep

\EmailRecipientInterface;
use Symfony\Component\Notifier\Recipient\RecipientInterface;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
class EmailChannel implements ChannelInterface
{
    private string|Address|null $from;

    public function __

tion;
use Symfony\Component\Notifier\Message\EmailMessage;
use Symfony\Component\Notifier\Notification\EmailNotificationInterface;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Recipient


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Channel;

use Symfony\Component\Notifier\Message\PushMessage;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Notification\PushNotificationInterface;
use Symfony\Component\Notifier\Recipient\RecipientInterfac

    {
        $message = null;
        if ($notification instanceof PushNotificationInterface) {
            $message = $notification->asPushMessage($recipient, $transportName);
        }

        $message ??= PushMessage::fromNotification($notification);

e;

/**
 * @author Tomas Norkūnas <norkunas.tom@gmail.com>
 */
class PushChannel extends AbstractChannel
{
    public function notify(Notification $notification, RecipientInterface $recipient, ?string $transportName = null): void


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Channel;

use Symfony\Component\Notifier\Message\SmsMessage;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Notification\SmsNotificationInterface;
use Symfony\Component\Notifier\Recipient\RecipientInterface;
use Symfony\

nction notify(Notification $notification, RecipientInterface $recipient, ?string $transportName = null): void
    {
        $message = null;
        if ($notification instanceof SmsNotificationInterface) {
            $message = $notification->asSmsMessage

Component\Notifier\Recipient\SmsRecipientInterface;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
class SmsChannel extends AbstractChannel
{
    /**
     * @param SmsRecipientInterface $recipient
     */
    public fu


t\Serializer\Encoder\ContextAwareDecoderInterface;
use Symfony\Component\Serializer\Encoder\ContextAwareEncoderInterface;
use Symfony\Component\Serializer\Encoder\DecoderInterface;
use Symfony\Component\Serializer\Encoder\EncoderInterface;
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\Exception\LogicException;
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
use Symfony\Component\Serializer\Exception\PartialDenormalizationExcep

y\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

/**
 * Serializer serializes and deserializes data.
 *
 * objec

tion;
use Symfony\Component\Serializer\Exception\UnsupportedFormatException;
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface;
use Symfon


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Serializer;

use Symfony\Component\Serializer\Exception\ExceptionInterface;
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;

/**
 * @author Jordi Boggiano <j.boggiano@seld.be>

ueException Occurs when a value cannot be normalized
     * @throws UnexpectedValueException      Occurs when a value cannot be encoded
     * @throws ExceptionInterface            Occurs for all the other cases of serialization-related errors
     */

 */
interface SerializerInterface
{
    /**
     * Serializes data in the appropriate format.
     *
     * @param array<string, mixed> $context Options normalizers/encoders have access to
     *
     * @throws NotNormalizableVal


?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Serializer\Exception;

/**
 * ExtraAttributesException.
 *
 * @author Julien DIDIER <julien@didier.io>
 */
class ExtraAttributesException extends RuntimeException
{
    /**
     * @param list<string> $extraAttributes
     */
    public function __

xtraAttributes) > 1 ? 'are' : 'is');

        parent::__construct($msg, 0, $previous);
    }

    /**
     * Get the extra attributes that are not allowed.
     *
     * @return list<string>
     */
    public function getExtraAttributes(): array
    {

construct(
        private readonly array $extraAttributes,
        ?\Throwable $previous = null,
    ) {
        $msg = \sprintf('Extra attributes are not allowed ("%s" %s unknown).', implode('", "', $extraAttributes), \count($e


hp

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Serializer\Exception;

/**
 * @author Maxime VEBER <maxime.veber@nekland.fr>
 */
class MissingConstructorArgumentsException extends RuntimeException
{
    /**
     * @param string[]          $missingArguments
     * @param class-string|null $class

rent::__construct($message, $code, $previous);
    }

    /**
     * @return string[]
     */
    public function getMissingConstructorArguments(): array
    {
        return $this->missingArguments;
    }

    /**
     * @return class-string|null
     */

    */
    public function __construct(
        string $message,
        int $code = 0,
        ?\Throwable $previous = null,
        private array $missingArguments = [],
        private ?string $class = null,
    ) {
        pa


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Serializer\Exception;

/**
 * @author Christian Flothmann <christian.flothmann@sensiolabs.de>
 */
class NotNormalizableValueException extends UnexpectedValueException
{
    private ?string $currentType = null;
    private ?array $expectedTypes = null;
    private ?string $path = null;
    private

 = null, ?array $expectedTypes = null, ?string $path = null, bool $useMessageForUser = false)
    {
        parent::__construct($message, $code, $previous);

        $this->currentType = $currentType;
        $this->expectedTypes = $expectedTypes ? array_m

 bool $useMessageForUser = false;

    /**
     * @param list<string|\Stringable>|null $expectedTypes
     */
    public function __construct(string $message = '', int $code = 0, ?\Throwable $previous = null, ?string $currentType


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Serializer\Exception;

/**
 * @author Grégoire Pineau <lyrixx@lyrixx.info>
 */
class PartialDenormalizationException extends UnexpectedValueException
{
    private ?ExtraAttributesException $extraAttributesError = null;

    /**
     * @param NotNormalizableValueExceptio

traAttributesErrors = [],
    ) {
        $extraAttributes = [];
        foreach ($extraAttributesErrors as $error) {
            $extraAttributes = array_merge($extraAttributes, $error->getExtraAttributes());
        }
        if ($extraAttributes) {

n[] $notNormalizableErrors
     * @param ExtraAttributesException[]      $extraAttributesErrors
     */
    public function __construct(
        private mixed $data,
        private array $notNormalizableErrors,
        array $ex


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Serializer\Context;

/**
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 */
trait ContextBuilderTrait
{
    /**
     * @var array<string, mixed>
     */
    private array $context = [];

    protected function with(string $key, mixed $value): sta

     */
    public function withContext(ContextBuilderInterface|array $context): static
    {
        if ($context instanceof ContextBuilderInterface) {
            $context = $context->toArray();
        }

        $instance = new static();
        $inst

tic
    {
        $instance = new static();
        $instance->context = array_merge($this->context, [$key => $value]);

        return $instance;
    }

    /**
     * @param ContextBuilderInterface|array<string, mixed> $context


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Serializer\Context;

use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Serializer;

/**
 * A helper providing autocompletion for available Serializer options.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmai

ist (in JSON: []).
     */
    public function withEmptyArrayAsObject(?bool $emptyArrayAsObject): static
    {
        return $this->with(Serializer::EMPTY_ARRAY_AS_OBJECT, $emptyArrayAsObject);
    }

    public function withCollectDenormalizationErrors(?

l.com>
 */
final class SerializerContextBuilder implements ContextBuilderInterface
{
    use ContextBuilderTrait;

    /**
     * Configures whether an empty array should be transformed to an
     * object (in JSON: {}) or to a l


buted with this source code.
 */

namespace Symfony\Component\Serializer\Context\Normalizer;

use Symfony\Component\Serializer\Context\ContextBuilderInterface;
use Symfony\Component\Serializer\Context\ContextBuilderTrait;
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;

/**
 * A helper providing autocompletion for available AbstractNormalizer options.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 */
abstract clas

 when we encounter the same object a
     * second time, we consider that a circular reference.
     *
     * You can raise this value for special cases, e.g. in combination with the
     * max depth setting of the object normalizer.
     *
     * Must be

s AbstractNormalizerContextBuilder implements ContextBuilderInterface
{
    use ContextBuilderTrait;

    /**
     * Configures how many loops of circular reference to allow while normalizing.
     *
     * The value 1 means that


buted with this source code.
 */

namespace Symfony\Component\Serializer\Context\Normalizer;

use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;

/**
 * A helper providing autocompletion for available AbstractObjectNormalizer options.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 */
abstract class AbstractObjectNormalizerContextBuilder extends AbstractNormalizerContextBuilder
{
    /**
     * Configures whethe

  /**
     * Configures a pattern to keep track of the current depth.
     *
     * Must contain exactly two string placeholders.
     *
     * @throws InvalidArgumentException
     */
    public function withDepthKeyPattern(?string $depthKeyPattern): stat

r to respect the max depth metadata on fields.
     */
    public function withEnableMaxDepth(?bool $enableMaxDepth): static
    {
        return $this->with(AbstractObjectNormalizer::ENABLE_MAX_DEPTH, $enableMaxDepth);
    }


hp

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Serializer\Context\Normalizer;

use Symfony\Component\Serializer\Context\ContextBuilderInterface;
use Symfony\Component\Serializer\Context\ContextBuilderTrait;
use Symfony\Component\Serializer\Normalizer\BackedEnumNormalizer;

/**
 * A helper provid

t;

    /**
     * Configures if invalid values are allowed in denormalization.
     * They will be denormalized into `null` values.
     */
    public function withAllowInvalidValues(bool $allowInvalidValues): static
    {
        return $this->with(Backe

ing autocompletion for available BackedEnumNormalizer options.
 *
 * @author Nicolas PHILIPPE <nikophil@gmail.com>
 */
final class BackedEnumNormalizerContextBuilder implements ContextBuilderInterface
{
    use ContextBuilderTrai


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Serializer\Context\Normalizer;

use Symfony\Component\Serializer\Context\ContextBuilderInterface;
use Symfony\Component\Serializer\Context\ContextBuilderTrait;
use Symfony\Component\Serializer\Normalizer\ConstraintViolationListNormalizer;

/**
 * A helper providing autocompletion for available Co

  * Configure the instance field of normalized data.
     */
    public function withInstance(mixed $instance): static
    {
        return $this->with(ConstraintViolationListNormalizer::INSTANCE, $instance);
    }

    /**
     * Configure the status fiel

nstraintViolationList options.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 */
final class ConstraintViolationListNormalizerContextBuilder implements ContextBuilderInterface
{
    use ContextBuilderTrait;

    /**


?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Serializer\Context\Normalizer;

use Symfony\Component\Serializer\Context\ContextBuilderInterface;
use Symfony\Component\Serializer\Context\ContextBuilderTrait;
use Symfony\Component\Serializer\Normalizer\DateIntervalNormalizer;

/**
 * A helper pr

tBuilderTrait;

    /**
     * Configures the format of the interval.
     *
     * @see https://php.net/manual/en/dateinterval.format.php
     */
    public function withFormat(?string $format): static
    {
        return $this->with(DateIntervalNormaliz

oviding autocompletion for available DateIntervalNormalizer options.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 */
final class DateIntervalNormalizerContextBuilder implements ContextBuilderInterface
{
    use Contex


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Serializer\Context\Normalizer;

use Symfony\Component\Serializer\Context\ContextBuilderInterface;
use Symfony\Component\Serializer\Context\ContextBuilderTrait;
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;

/**

 ContextBuilderTrait;

    /**
     * Configures the format of the date.
     *
     * @see https://secure.php.net/manual/en/datetime.format.php
     */
    public function withFormat(?string $format): static
    {
        return $this->with(DateTimeNormal

 * A helper providing autocompletion for available DateTimeNormalizer options.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 */
final class DateTimeNormalizerContextBuilder implements ContextBuilderInterface
{
    use


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Serializer\Context\Normalizer;

use Symfony\Component\Serializer\Context\ContextBuilderInterface;
use Symfony\Component\Serializer\Context\ContextBuilderTrait;
use Symfony\Component\Serializer\Normalizer\FormErrorNormalizer;

/**
 * A helper providing autoco

/**
     * Configures the title of the normalized data.
     */
    public function withTitle(?string $title): static
    {
        return $this->with(FormErrorNormalizer::TITLE, $title);
    }

    /**
     * Configures the type of the normalized data.

mpletion for available FormErrorNormalizer options.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 */
final class FormErrorNormalizerContextBuilder implements ContextBuilderInterface
{
    use ContextBuilderTrait;


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Serializer\Context\Normalizer;

use Symfony\Component\Serializer\Context\ContextBuilderInterface;
use Symfony\Component\Serializer\Context\ContextBuilderTrait;
use Symfony\Component\Serializer\Normalizer\ProblemNormalizer;

/**
 * A helper providing autocomp

   * Configure the title field of normalized data.
     */
    public function withTitle(?string $title): static
    {
        return $this->with(ProblemNormalizer::TITLE, $title);
    }

    /**
     * Configure the type field of normalized data.
     */

letion for available ProblemNormalizer options.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 */
final class ProblemNormalizerContextBuilder implements ContextBuilderInterface
{
    use ContextBuilderTrait;

    /**


ackage.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Serializer\Context\Normalizer;

use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;

/**
 * A helper providing autocompletion for available PropertyNormalizer options.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 */
final class PropertyNormalizerContextBuilder extends

  * Configures whether fields should be output based on visibility.
     */
    public function withNormalizeVisibility(int $normalizeVisibility): static
    {
        return $this->with(PropertyNormalizer::NORMALIZE_VISIBILITY, $normalizeVisibility);

AbstractObjectNormalizerContextBuilder
{
    /**


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Serializer\Context\Normalizer;

use Symfony\Component\Serializer\Context\ContextBuilderInterface;
use Symfony\Component\Serializer\Context\ContextBuilderTrait;
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Symfony\Component\Seriali

ilderInterface
{
    use ContextBuilderTrait;

    /**
     * Configures the uuid format for normalization.
     *
     * @throws InvalidArgumentException
     */
    public function withNormalizationFormat(?string $normalizationFormat): static
    {

zer\Normalizer\UidNormalizer;

/**
 * A helper providing autocompletion for available UidNormalizer options.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 */
final class UidNormalizerContextBuilder implements ContextBu


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Serializer\Context\Normalizer;

use Symfony\Component\PropertyAccess\Exception\InvalidPropertyPathException;
use Symfony\Component\PropertyAccess\PropertyPath;
use Symfony\Component\Serializer\Context\ContextBuilderInterface;
use Symfony\Component\Serializer\Context\Cont

zer options.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 */
final class UnwrappingDenormalizerContextBuilder implements ContextBuilderInterface
{
    use ContextBuilderTrait;

    /**
     * Configures the path of wrapped data during denormali

extBuilderTrait;
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\Normalizer\UnwrappingDenormalizer;

/**
 * A helper providing autocompletion for available UnwrappingDenormali


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Serializer\Context\Encoder;

use Symfony\Component\Serializer\Context\ContextBuilderInterface;
use Symfony\Component\Serializer\Context\ContextBuilderTrait;
use Symfony\Component\Serializer\Encoder\CsvEncoder;
use Symfony\Component\Serializer\Exception\InvalidArgumentException;

/**
 * A helper providing autocompletion for available CsvEncoder op

     *
     * Must be a single character.
     *
     * @throws InvalidArgumentException
     */
    public function withDelimiter(?string $delimiter): static
    {
        if (null !== $delimiter && 1 !== \strlen($delimiter)) {
            throw new Inval

tions.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 */
final class CsvEncoderContextBuilder implements ContextBuilderInterface
{
    use ContextBuilderTrait;

    /**
     * Configures the column delimiter character.


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Zulip\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Notifier\Bridge\Zulip\ZulipOptions;

final class ZulipOptionsTest extends TestCase
{
    public function testZulipOptions()
    {
        $options = new ZulipOptions('Test Topic', 'user@example.com');

        $th

unction testZulipOptionsWithNullValues()
    {
        $options = new ZulipOptions();

        $this->assertSame([
            'topic' => null,
            'recipient' => null,
        ], $options->toArray());

        $this->assertNull($options->getRecipi

is->assertSame([
            'topic' => 'Test Topic',
            'recipient' => 'user@example.com',
        ], $options->toArray());

        $this->assertSame('user@example.com', $options->getRecipientId());
    }

    public f


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Smsc;

use Symfony\Component\Notifier\Exception\TransportException;
use Symfony\Component\Notifier\Exception\UnsupportedMessageTypeException;
use Symfony\Component\Notifier\Message\MessageInterface;
use Symfony\Component\Notifier\Message\SentMessage;
use Symfony\Component\Notifier\Message\SmsMessage;
use Symfony\Component\Notifier

nt\Exception\ExceptionInterface as HttpExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface as HttpTransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;

/**
 * @author Valentin Nazarov <i.

\Transport\AbstractTransport;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface as HttpDecodingExceptionInterface;
use Symfony\Contracts\HttpClie


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Smsc;

use Symfony\Component\Notifier\Exception\UnsupportedSchemeException;
use Symfony\Component\Notifier\Transport\AbstractTransportFactory;
use Symfony\Component\Notifier\Transport\Dsn;

/**
 * @author Valentin Nazarov <i.kozlice@pro

row new UnsupportedSchemeException($dsn, 'smsc', $this->getSupportedSchemes());
        }

        $login = $dsn->getUser();
        $password = $dsn->getPassword();
        $from = $dsn->getRequiredOption('from');
        $host = 'default' === $dsn->getHo

tonmail.com>
 */
final class SmscTransportFactory extends AbstractTransportFactory
{
    public function create(Dsn $dsn): SmscTransport
    {
        $scheme = $dsn->getScheme();

        if ('smsc' !== $scheme) {
            th


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Smsense;

use Symfony\Component\Notifier\Exception\UnsupportedSchemeException;
use Symfony\Component\Notifier\Transport\AbstractTransportFactory;
use Symfony\Component\Notifier\Transport\Dsn;

/**
 * @author Valentin Barbu <jimiero@gmai

Exception($dsn, 'smsense', $this->getSupportedSchemes());
        }

        $host = 'default' === $dsn->getHost() ? null : $dsn->getHost();
        $from = $dsn->getRequiredOption('from');
        $authToken = $this->getUser($dsn);
        $port = $dsn->g

l.com>
 */
final class SmsenseTransportFactory extends AbstractTransportFactory
{
    public function create(Dsn $dsn): SmsenseTransport
    {
        if ('smsense' !== $dsn->getScheme()) {
            throw new UnsupportedScheme


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Smsense\Tests;

use PHPUnit\Framework\Attributes\DataProvider;
use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\HttpClient\Response\JsonMockResponse;
use Symfony\Component\HttpClient\Response\MockResponse;
use Symfony\Component\Notifier\Bridge\Smsense\SmsenseTransport;
use Symfony\Component\Notifier\Exception

;
use Symfony\Component\Notifier\Tests\Transport\DummyMessage;
use Symfony\Contracts\HttpClient\HttpClientInterface;

class SmsenseTransportTest extends TransportTestCase
{
    public static function createTransport(?HttpClientInterface $client = null): Sm

\TransportException;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Notifier\Message\SentMessage;
use Symfony\Component\Notifier\Message\SmsMessage;
use Symfony\Component\Notifier\Test\TransportTestCase


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\SpotHit;

use Symfony\Component\Notifier\Exception\UnsupportedSchemeException;
use Symfony\Component\Notifier\Transport\AbstractTransportFactory;
use Symfony\Component\Notifier\Transport\Dsn;

/**
 * @author James Hemery <james@yieldstudio.fr>
 */
final c

rtedSchemeException($dsn, 'spothit', $this->getSupportedSchemes());
        }

        $token = $this->getUser($dsn);
        $from = $dsn->getOption('from');
        $smsLong = filter_var($dsn->getOption('smslong', '-'), \FILTER_VALIDATE_BOOL, \FILTER_NUL

lass SpotHitTransportFactory extends AbstractTransportFactory
{
    public function create(Dsn $dsn): SpotHitTransport
    {
        $scheme = $dsn->getScheme();

        if ('spothit' !== $scheme) {
            throw new Unsuppo


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\SpotHit\Tests;

use Symfony\Component\Notifier\Bridge\SpotHit\SpotHitTransportFactory;
use Symfony\Component\Notifier\Test\AbstractTransportFactoryTestCase;
use Symfony\Component\Notifier\Test\IncompleteDsnTestTrait;

final class SpotHitTransportFactoryTe

ateProvider(): iterable
    {
        yield [
            'spothit://spot-hit.fr',
            'spothit://api_token@default',
        ];
        yield [
            'spothit://spot-hit.fr?from=MyCompany',
            'spothit://api_token@default?from=MyCom

st extends AbstractTransportFactoryTestCase
{
    use IncompleteDsnTestTrait;

    public function createFactory(): SpotHitTransportFactory
    {
        return new SpotHitTransportFactory();
    }

    public static function cre


hp

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Smsmode;

use Symfony\Component\Notifier\Message\MessageOptionsInterface;

/**
 * @author gnito-org <https://github.com/gnito-org>
 */
final class SmsmodeOptions implements MessageOptionsInterface
{
    public function __construct(

{
        $this->options['refClient'] = $refClient;

        return $this;
    }

    /**
     * @return $this
     */
    public function sentDate(string $sentDate): static
    {
        $this->options['sentDate'] = $sentDate;

        return $this;
    }

       private array $options = [],
    ) {
    }

    public function getRecipientId(): ?string
    {
        return null;
    }

    /**
     * @return $this
     */
    public function refClient(string $refClient): static


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Notifier\Bridge\Smsmode\Tests;

use Symfony\Component\Notifier\Bridge\Smsmode\SmsmodeTransportFactory;
use Symfony\Component\Notifier\Test\AbstractTransportFactoryTestCase;
use Symfony\Component\Notifier\Test\IncompleteDsnTestTrait;
use Symfony\Component\Notifier\Test\Mi

deTransportFactory
    {
        return new SmsmodeTransportFactory();
    }

    public static function createProvider(): iterable
    {
        yield ['smsmode://host.test?from=test', 'smsmode://ApiKey@host.test?from=test'];
    }

    public static func

ssingRequiredOptionTestTrait;

final class SmsmodeTransportFactoryTest extends AbstractTransportFactoryTestCase
{
    use IncompleteDsnTestTrait;
    use MissingRequiredOptionTestTrait;

    public function createFactory(): Smsmo