8000 [Mailer] Add Scaleway bridge · symfony/symfony@bd99226 · GitHub
[go: up one dir, main page]

Skip to content

Commit bd99226

Browse files
MrMicky-FRfabpot
authored andcommitted
[Mailer] Add Scaleway bridge
1 parent 68f27ef commit bd99226

File tree

17 files changed

+564
-0
lines changed

17 files changed

+564
-0
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2601,6 +2601,7 @@ private function registerMailerConfiguration(array $config, ContainerBuilder $co
26012601
MailerBridge\Mailchimp\Transport\MandrillTransportFactory::class => 'mailer.transport_factory.mailchimp',
26022602
MailerBridge\OhMySmtp\Transport\OhMySmtpTransportFactory::class => 'mailer.transport_factory.ohmysmtp',
26032603
MailerBridge\Postmark\Transport\PostmarkTransportFactory::class => 'mailer.transport_factory.postmark',
2604+
MailerBridge\Scaleway\Transport\ScalewayTransportFactory::class => 'mailer.transport_factory.scaleway',
26042605
MailerBridge\Sendgrid\Transport\SendgridTransportFactory::class => 'mailer.transport_factory.sendgrid',
26052606
MailerBridge\Sendinblue\Transport\SendinblueTransportFactory::class => 'mailer.transport_factory.sendinblue',
26062607
MailerBridge\Amazon\Transport\SesTransportFactory::class => 'mailer.transport_factory.amazon',

src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer_transports.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Symfony\Component\Mailer\Bridge\MailPace\Transport\MailPaceTransportFactory;
2323
use Symfony\Component\Mailer\Bridge\OhMySmtp\Transport\OhMySmtpTransportFactory;
2424
use Symfony\Component\Mailer\Bridge\Postmark\Transport\PostmarkTransportFactory;
25+
use Symfony\Component\Mailer\Bridge\Scaleway\Transport\ScalewayTransportFactory;
2526
use Symfony\Component\Mailer\Bridge\Sendgrid\Transport\SendgridTransportFactory;
2627
use Symfony\Component\Mailer\Bridge\Sendinblue\Transport\SendinblueTransportFactory;
2728
use Symfony\Component\Mailer\Transport\AbstractTransportFactory;
@@ -89,6 +90,10 @@
8990
->parent('mailer.transport_factory.abstract')
9091
->tag('mailer.transport_factory')
9192

93+
->set('mailer.transport_factory.scaleway', ScalewayTransportFactory::class)
94+
->parent('mailer.transport_factory.abstract')
95+
->tag('mailer.transport_factory')
96+
9297
->set('mailer.transport_factory.sendmail', SendmailTransportFactory::class)
9398
->parent('mailer.transport_factory.abstract')
9499
->tag('mailer.transport_factory')
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/Tests export-ignore
2+
/phpunit.xml.dist export-ignore
3+
/.gitattributes export-ignore
4+
/.gitignore export-ignore
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
vendor/
2+
composer.lock
3+
phpunit.xml
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CHANGELOG
2+
=========
3+
4+
6.4
5+
-----
6+
7+
* Add the bridge
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2023-present Fabien Potencier
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is furnished
8+
to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Scaleway Bridge
2+
===============
3+
4+
Provides [Scaleway Transactional Email](https://www.scaleway.com/en/transactional-email-tem/) integration for Symfony Mailer.
5+
6+
Configuration example:
7+
8+
```env
9+
# SMTP
10+
MAILER_DSN=scaleway+smtp://PROJECT_ID:API_KEY@default
11+
12+
# API
13+
MAILER_DSN=scaleway+api://PROJECT_ID:API_KEY@default
14+
```
15+
16+
where:
17+
- `PROJECT_ID` is your Scaleway project ID
18+
- `API_KEY` is your Scaleway API secret key
19+
20+
Resources
21+
---------
22+
23+
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
24+
* [Report issues](https://github.com/symfony/symfony/issues) and
25+
[send Pull Requests](https://github.com/symfony/symfony/pulls)
26+
in the [main Symfony repository](https://github.com/symfony/symfony)
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Mailer\Bridge\Scaleway\Tests\Transport;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\HttpClient\MockHttpClient;
16+
use Symfony\Component\HttpClient\Response\MockResponse;
17+
use Symfony\Component\Mailer\Bridge\Scaleway\Transport\ScalewayApiTransport;
18+
use Symfony\Component\Mailer\Exception\HttpTransportException;
19+
use Symfony\Component\Mime\Address;
20+
use Symfony\Component\Mime\Email;
21+
use Symfony\Contracts\HttpClient\ResponseInterface;
22+
23+
class ScalewayApiTransportTest extends TestCase
24+
{
25+
/**
26+
* @dataProvider getTransportData
27+
*/
28+
public function testToString(ScalewayApiTransport $transport, string $expected)
29+
{
30+
$this->assertSame($expected, (string) $transport);
31+
}
32+
33+
public static function getTransportData()
34+
{
35+
return [
36+
[
37+
new< F987 /span> ScalewayApiTransport('PROJECT_ID', 'TOKEN'),
38+
'scaleway+api://api.scaleway.com@PROJECT_ID',
39+
],
40+
[
41+
new ScalewayApiTransport('PROJECT_ID', 'TOKEN', 'fr-par'),
42+
'scaleway+api://api.scaleway.com@PROJECT_ID?region=fr-par',
43+
],
44+
[
45+
(new ScalewayApiTransport('PROJECT_ID', 'TOKEN'))->setHost('example.com'),
46+
'scaleway+api://example.com@PROJECT_ID',
47+
],
48+
[
49+
(new ScalewayApiTransport('PROJECT_ID', 'TOKEN'))->setHost('example.com')->setPort(99),
50+
'scaleway+api://example.com:99@PROJECT_ID',
51+
],
52+
];
53+
}
54+
55+
public function testSend()
56+
{
57+
$client = new MockHttpClient(function (string $method, string $url, array $options): ResponseInterface {
58+
$this->assertSame('POST', $method);
59+
$this->assertSame('https://api.scaleway.com:8984/transactional-email/v1alpha1/regions/fr-par/emails', $url);
60+
$this->assertStringContainsString('X-Auth-Token: TOKEN', $options['headers'][0] ?? $options['request_headers'][0]);
61+
62+
$body = json_decode($options['body'], true);
63+
$this->assertSame(['email' => 'fabpot@symfony.com', 'name' => 'Fabien'], $body['from']);
64+
$this->assertSame(['email' => 'saif.gmati@symfony.com', 'name' => 'Saif Eddin'], $body['to'][0]);
65+
$this->assertSame('Hello!', $body['subject']);
66+
$this->assertSame('Hello There!', $body['text']);
67+
68+
return new MockResponse(json_encode(['emails' => [['message_id' => 'foobar']]]), [
69+
'http_code' => 200,
70+
]);
71+
});
72+
$transport = new ScalewayApiTransport('PROJECT_ID', 'TOKEN', 'fr-par', $client);
73+
$transport->setPort(8984);
74+
75+
$mail = new Email();
76+
$mail->subject('Hello!')
77+
->to(new Address('saif.gmati@symfony.com', 'Saif Eddin'))
78+
->from(new Address('fabpot@symfony.com', 'Fabien'))
79+
->text('Hello There!');
80+
81+
$message = $transport->send($mail);
82+
83+
$this->assertSame('foobar', $message->getMessageId());
84+
}
85+
86+
public function testSendThrowsForErrorResponse()
87+
{
88+
$client = new MockHttpClient(function (string $method, string $url, array $options): ResponseInterface {
89+
return new MockResponse(json_encode(['message' => 'i\'m a teapot']), [
90+
'http_code' => 418,
91+
'response_headers' => [
92+
'content-type' => 'application/json',
93+
],
94+
]);
95+
});
96+
$transport = new ScalewayApiTransport('PROJECT_ID', 'TOKEN', 'fr-par', $client);
97+
98+
$mail = new Email();
99+
$mail->subject('Hello!')
100+
->to(new Address('saif.gmati@symfony.com', 'Saif Eddin'))
101+
->from(new Address('fabpot@symfony.com', 'Fabien'))
102+
->text('Hello There!');
103+
104+
$this->expectException(HttpTransportException::class);
105+
$this->expectExceptionMessage('Unable to send an email: i\'m a teapot (code 418).');
106+
$transport->send($mail);
107+
}
108+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Mailer\Bridge\Scaleway\Tests\Transport;
13+
14+
use Psr\Log\NullLogger;
15+
use Symfony\Component\HttpClient\MockHttpClient;
16+
use Symfony\Component\Mailer\Bridge\Scaleway\Transport\ScalewayApiTransport;
17+
use Symfony\Component\Mailer\Bridge\Scaleway\Transport\ScalewaySmtpTransport;
18+
use Symfony\Component\Mailer\Bridge\Scaleway\Transport\ScalewayTransportFactory;
19+
use Symfony\Component\Mailer\Test\TransportFactoryTestCase;
20+
use Symfony\Component\Mailer\Transport\Dsn;
21+
use Symfony\Component\Mailer\Transport\TransportFactoryInterface;
22+
23+
class ScalewayTransportFactoryTest extends TransportFactoryTestCase
24+
{
25+
public function getFactory(): TransportFactoryInterface
26+
{
27+
return new ScalewayTransportFactory(null, new MockHttpClient(), new NullLogger());
28+
}
29+
30+
public static function supportsProvider(): iterable
31+
{
32+
yield [
33+
new Dsn('scaleway+api', 'default'),
34+
true,
35+
];
36+
37+
yield [
38+
new Dsn('scaleway', 'default'),
39+
true,
40+
];
41+
42+
yield [
43+
new Dsn('scaleway+smtp', 'default'),
44+
true,
45+
];
46+
47+
yield [
48+
new Dsn('scaleway+smtps', 'default'),
49+
true,
50+
];
51+
52+
yield [
53+
new Dsn('scaleway+smtp', 'example.com'),
54+
true,
55+
];
56+
}
57+
58+
public static function createProvider(): iterable
59+
{
60+
$logger = new NullLogger();
61+
62+
yield [
63+
new Dsn('scaleway+api', 'default', self::USER, self::PASSWORD, null, ['region' => 'fr-par']),
64+
new ScalewayApiTransport(self::USER, self::PASSWORD, 'fr-par', new MockHttpClient(), null, $logger),
65+
];
66+
67+
yield [
68+
new Dsn('scaleway', 'default', self::USER, self::PASSWORD),
69+
new ScalewayApiTransport(self::USER, self::PASSWORD, null, new MockHttpClient(), null, $logger),
70+
];
71+
72+
yield [
73+
new Dsn('scaleway+smtp', 'default', self::USER, self::PASSWORD),
74+
new ScalewaySmtpTransport(self::USER, self::PASSWORD, null, $logger),
75+
];
76+
77+
yield [
78+
new Dsn('scaleway+smtps', 'default', self::USER, self::PASSWORD),
79+
new ScalewaySmtpTransport(self::USER, self::PASSWORD, null, $logger),
80+
];
81+
}
82+
83+
public static function unsupportedSchemeProvider(): iterable
84+
{
85+
yield [
86+
new Dsn('scaleway+foo', 'default', self::USER, self::PASSWORD),
87+
'The "scaleway+foo" scheme is not supported; supported schemes for mailer "scaleway" are: "scaleway", "scaleway+api", "scaleway+smtp", "scaleway+smtps".',
88+
];
89+
}
90+
91+
public static function incompleteDsnProvider(): iterable
92+
{
93+
yield [new Dsn('scaleway+api', 'default', self::USER)];
94+
95+
yield [new Dsn('scaleway+api', 'default', null, self::PASSWORD)];
96+
}
97+
}

0 commit comments

Comments
 (0)
0