Skip to content

Commit

Permalink
Merge pull request #1 from moondayapp/master
Browse files Browse the repository at this point in the history
Add "EU" region support
  • Loading branch information
gam6itko committed Dec 16, 2022
2 parents 792fa22 + 729a17a commit d71d86d
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 34 deletions.
26 changes: 19 additions & 7 deletions README.md
Expand Up @@ -2,15 +2,15 @@
[![Build Status](https://travis-ci.com/gam6itko/sparkpost-mailer.svg?branch=master)](https://travis-ci.com/gam6itko/sparkpost-mailer)
[![Coverage Status](https://coveralls.io/repos/github/gam6itko/sparkpost-mailer/badge.svg?branch=master)](https://coveralls.io/github/gam6itko/sparkpost-mailer?branch=master)

## install
## Installation

```bash
composer require gam6itko/sparkpost-mailer
```

## configuration
## Configuration

services.yaml
### services.yaml
```yaml
services:
mailer.transport_factory.sparkpost:
Expand All @@ -20,18 +20,30 @@ services:
- {name: mailer.transport_factory}
```

.env
### .env

#### Default region

```dotenv
MAILER_DSN=sparkpost+api://api_key@default
```
```dotenv
MAILER_DSN=sparkpost+smtp://user:password@default:port
```

## tests
#### EU region

```dotenv
MAILER_DSN=sparkpost+api://api_key@default?region=eu
```
```dotenv
MAILER_DSN=sparkpost+smtp://user:password@default:port?region=eu
```

## Tests

### Using sink server
[About sink server](https://www.sparkpost.com/docs/faq/using-sink-server/)
[About sink server](https://support.sparkpost.com/docs/faq/using-sink-server)

```yaml
services:
Expand All @@ -41,4 +53,4 @@ services:

## Also

[Api transmissions](https://developers.sparkpost.com/api/transmissions/)
[Sparkpost's "transmissions" API reference](https://developers.sparkpost.com/api/transmissions/)
27 changes: 18 additions & 9 deletions src/Transport/SparkPostApiTransport.php
Expand Up @@ -21,16 +21,21 @@ class SparkPostApiTransport extends AbstractApiTransport
*/
private $key;

public function __construct(string $key, HttpClientInterface $client = null, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null)
public function __construct(string $key, HttpClientInterface $client = null, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null, ?string $region = null, string $host = 'default')
{
$this->key = $key;

if ('default' === $host) {
$host = \sprintf('api%s.sparkpost.com', $region ? '.'.$region : '');
}
$this->host = $host;

parent::__construct($client, $dispatcher, $logger);
}

public function __toString(): string
{
return 'sparkpost+api://';
return \sprintf('sparkpost+api://%s', $this->host);
}

protected function doSendApi(SentMessage $sentMessage, Email $email, Envelope $envelope): ResponseInterface
Expand All @@ -52,13 +57,17 @@ protected function doSendApi(SentMessage $sentMessage, Email $email, Envelope $e

$this->log($payload);

$response = $this->client->request('POST', 'https://api.sparkpost.com/api/v1/transmissions/', [
'headers' => [
'Authorization' => $this->key,
'Content-Type' => 'application/json',
],
'json' => $payload,
]);
$response = $this->client->request(
'POST',
\sprintf('https://%s/api/v1/transmissions/', $this->host),
[
'headers' => [
'Authorization' => $this->key,
'Content-Type' => 'application/json',
],
'json' => $payload,
]
);

$this->handleError($response);

Expand Down
7 changes: 5 additions & 2 deletions src/Transport/SparkPostSmtpTransport.php
Expand Up @@ -8,9 +8,12 @@

class SparkPostSmtpTransport extends EsmtpTransport
{
public function __construct(string $username, string $password, int $port = null, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null)
public function __construct(string $username, string $password, int $port = null, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null, ?string $region = null, string $host = 'default')
{
parent::__construct('smtp.sparkpostmail.com', $port ?: 587, false, $dispatcher, $logger);
if ('default' === $host) {
$host = \sprintf('smtp%s.sparkpostmail.com', $region ? '.'.$region : '');
}
parent::__construct($host, $port ?: 587, false, $dispatcher, $logger);

$this->setUsername($username);
$this->setPassword($password);
Expand Down
16 changes: 9 additions & 7 deletions src/Transport/SparkPostTransportFactory.php
Expand Up @@ -14,15 +14,17 @@ public function create(Dsn $dsn): TransportInterface
$scheme = $dsn->getScheme();
$user = $this->getUser($dsn);
$port = $dsn->getPort();
$region = $dsn->getOption('region');

if ('sparkpost+api' === $scheme) {
return new SparkPostApiTransport($user, $this->client, $this->dispatcher, $this->logger);
}

if (in_array($scheme, ['sparkpost', 'sparkpost+smtp', 'sparkpost+smtps'])) {
$password = $this->getPassword($dsn);
switch (true) {
case 'sparkpost+api' === $scheme:
return new SparkPostApiTransport($user, $this->client, $this->dispatcher, $this->logger, $region, $dsn->getHost());

return new SparkPostSmtpTransport($user, $password, $port, $this->dispatcher, $this->logger);
case 'sparkpost' === $scheme:
case 'sparkpost+smtp' === $scheme:
case 'sparkpost+smtps' === $scheme:
$password = $this->getPassword($dsn);
return new SparkPostSmtpTransport($user, $password, $port, $this->dispatcher, $this->logger, $region, $dsn->getHost());
}

throw new UnsupportedSchemeException($dsn, 'sparkpost', $this->getSupportedSchemes());
Expand Down
28 changes: 25 additions & 3 deletions tests/Transport/SparkPostApiTransportTest.php
Expand Up @@ -251,11 +251,14 @@ public function testTruncateAttachmentData(): void
$transport->send($this->createDefaultMessage(), $this->createDefaultEnvelope());
}

public function testToString()
/**
* @dataProvider dataToString
*/
public function testToString(?string $region, ?string $host, string $endpoint)
{
$client = $this->createMock(HttpClientInterface::class);
$transport = new SparkPostApiTransport('api-key', $client);
self::assertSame('sparkpost+api://', (string) $transport);
$transport = new SparkPostApiTransport('api-key', $client, null, null, $region, $host);
self::assertSame('sparkpost+api://' . $endpoint, (string) $transport);
}

/**
Expand Down Expand Up @@ -325,4 +328,23 @@ public function dataNotSuccess()
'[{"message":"error 0"},{"message":"error 1"}]',
];
}

public function dataToString(): iterable
{
yield [
null, 'default', 'api.sparkpost.com',
];

yield [
'eu', 'default', 'api.eu.sparkpost.com',
];

yield [
'eu', 'example.com', 'example.com',
];

yield [
null, 'example.com', 'example.com',
];
}
}
70 changes: 70 additions & 0 deletions tests/Transport/SparkPostSmtpTransportTest.php
@@ -0,0 +1,70 @@
<?php declare(strict_types=1);

namespace Gam6itko\Symfony\Mailer\SparkPost\Test\Transport;

use Gam6itko\Symfony\Mailer\SparkPost\Mime\ABTestEmail;
use Gam6itko\Symfony\Mailer\SparkPost\Mime\SparkPostEmail;
use Gam6itko\Symfony\Mailer\SparkPost\Mime\TemplateEmail;
use Gam6itko\Symfony\Mailer\SparkPost\Transport\SparkPostApiTransport;
use Gam6itko\Symfony\Mailer\SparkPost\Transport\SparkPostSmtpTransport;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Symfony\Component\Mailer\DelayedEnvelope;
use Symfony\Component\Mailer\Envelope;
use Symfony\Component\Mailer\Exception\HttpTransportException;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\RawMessage;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;

/**
* @coversDefaultClass \Gam6itko\Symfony\Mailer\SparkPost\Transport\SparkPostApiTransport
*/
class SparkPostSmtpTransportTest extends TestCase
{

/**
* @dataProvider dataToString
*/
public function testToString(?string $region, ?string $host, ?int $port, string $endpoint)
{
$transport = new SparkPostSmtpTransport('username', 'password', $port, null, null, $region, $host);
self::assertSame('smtp://' . $endpoint, (string) $transport);
}

public function dataToString(): iterable
{
yield [
null, 'default', null, 'smtp.sparkpostmail.com:587',
];

yield [
'eu', 'default', null, 'smtp.eu.sparkpostmail.com:587',
];

yield [
'eu', 'example.com', null, 'example.com:587',
];

yield [
null, 'example.com', null, 'example.com:587',
];

yield [
null, 'default', 1111, 'smtp.sparkpostmail.com:1111',
];

yield [
'eu', 'default', 1111, 'smtp.eu.sparkpostmail.com:1111',
];

yield [
'eu', 'example.com', 1111, 'example.com:1111',
];

yield [
null, 'example.com', 1111, 'example.com:1111',
];
}
}
54 changes: 48 additions & 6 deletions tests/Transport/SparkPostTransportFactoryTest.php
Expand Up @@ -26,16 +26,31 @@ public function supportsProvider(): iterable
true,
];

yield [
new Dsn('sparkpost', 'example.com'),
true,
];

yield [
new Dsn('sparkpost+api', 'default'),
true,
];

yield [
new Dsn('sparkpost+api', 'example.com'),
true,
];

yield [
new Dsn('sparkpost+https', 'default'),
false,
];

yield [
new Dsn('sparkpost+https', 'example.com'),
false,
];

yield [
new Dsn('sparkpost+smtp', 'default'),
true,
Expand Down Expand Up @@ -64,19 +79,46 @@ public function createProvider(): iterable
];

yield [
new Dsn('sparkpost', 'default', self::USER, self::PASSWORD),
new SparkPostSmtpTransport(self::USER, self::PASSWORD, null, $dispatcher, $logger),
new Dsn('sparkpost+api', 'default', self::USER, null, null, ['region' => 'eu']),
new SparkPostApiTransport(self::USER, $client, $dispatcher, $logger, 'eu'),
];

yield [
new Dsn('sparkpost+api', 'example.com', self::USER),
new SparkPostApiTransport(self::USER, $client, $dispatcher, $logger, null, 'example.com'),
];

yield [
new Dsn('sparkpost+smtp', 'default', self::USER, self::PASSWORD, 587),
new SparkPostSmtpTransport(self::USER, self::PASSWORD, 587, $dispatcher, $logger),
new Dsn('sparkpost+api', 'example.com', self::USER, null, null, ['region' => 'eu']),
new SparkPostApiTransport(self::USER, $client, $dispatcher, $logger, 'eu', 'example.com'),
];

yield [
new Dsn('sparkpost+smtps', 'default', self::USER, self::PASSWORD, 2525),
new SparkPostSmtpTransport(self::USER, self::PASSWORD, 2525, $dispatcher, $logger),
new Dsn('sparkpost', 'default', self::USER, self::PASSWORD),
new SparkPostSmtpTransport(self::USER, self::PASSWORD, null, $dispatcher, $logger),
];

foreach (['sparkpost', 'sparkpost+smtp', 'sparkpost+smtps'] as $scheme) {
yield [
new Dsn($scheme, 'default', self::USER, self::PASSWORD, null, ['region' => 'eu']),
new SparkPostSmtpTransport(self::USER, self::PASSWORD, null, $dispatcher, $logger, 'eu'),
];

yield [
new Dsn($scheme, 'example.com', self::USER, self::PASSWORD),
new SparkPostSmtpTransport(self::USER, self::PASSWORD, null, $dispatcher, $logger, null, 'example.com'),
];

yield [
new Dsn($scheme, 'example.com', self::USER, self::PASSWORD, null, ['region' => 'eu']),
new SparkPostSmtpTransport(self::USER, self::PASSWORD, null, $dispatcher, $logger, 'eu', 'example.com'),
];

yield [
new Dsn($scheme, 'example.com', self::USER, self::PASSWORD, 1111, ['region' => 'eu']),
new SparkPostSmtpTransport(self::USER, self::PASSWORD, 1111, $dispatcher, $logger, 'eu', 'example.com'),
];
}
}

public function unsupportedSchemeProvider(): iterable
Expand Down

0 comments on commit d71d86d

Please sign in to comment.