Skip to content

Commit

Permalink
create ArrayTransport
Browse files Browse the repository at this point in the history
  • Loading branch information
klimov-paul committed May 9, 2024
1 parent 836a1fe commit 8ac8036
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/Mailer.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Symfony\Component\Mailer\Transport;
use Symfony\Component\Mailer\Transport\TransportInterface;
use Symfony\Component\Mime\RawMessage;
use yii1tech\mailer\transport\ArrayTransport;

/**
* @see https://symfony.com/doc/current/mailer.html
Expand Down Expand Up @@ -84,7 +85,11 @@ public function getTransport(): TransportInterface
throw new \LogicException('Either "' . get_class($this) . '::$dsn" or "' . get_class($this) . '::$transport" property should be set.');
}

$this->_transport = Transport::fromDsn($this->dsn);
if ($this->dsn === 'array' || stripos($this->dsn, 'array://') !== false) {
$this->_transport = new ArrayTransport();
} else {
$this->_transport = Transport::fromDsn($this->dsn);
}

return $this->_transport;
}
Expand Down
103 changes: 103 additions & 0 deletions src/transport/ArrayTransport.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php

namespace yii1tech\mailer\transport;

use Symfony\Component\Mailer\SentMessage;
use Symfony\Component\Mailer\Transport\AbstractTransport;
use Symfony\Component\Mime\RawMessage;

/**
* ArrayTransport stores incoming messages in the internal list, instead of sending them.
*
* This transport can be useful while writing unit tests.
*
* In {@see \yii1tech\mailer\Mailer::getTransport()} this transport will be created for DSN 'array' or 'array://'.
*
* @author Paul Klimov <[email protected]>
* @since 1.0
*/
class ArrayTransport extends AbstractTransport
{
/**
* @var \Symfony\Component\Mime\RawMessage[]|\Symfony\Component\Mime\Email[]|\yii1tech\mailer\TemplatedEmail[]
*/
private $sentMessages = [];

/**
* {@inheritDoc}
*/
protected function doSend(SentMessage $message): void
{
$this->sentMessages[] = $message->getOriginalMessage();
}

/**
* {@inheritDoc}
*/
public function __toString(): string
{
return 'array://';
}

/**
* @return \Symfony\Component\Mime\RawMessage[]|\Symfony\Component\Mime\Email[]|\yii1tech\mailer\TemplatedEmail[] sent messages.
*/
public function getSentMessages(): array
{
return $this->sentMessages;
}

/**
* @return \Symfony\Component\Mime\RawMessage|\Symfony\Component\Mime\Email|\yii1tech\mailer\TemplatedEmail|null last sent message.
*/
public function getLastSentMessage(): ?RawMessage
{
if (empty($this->sentMessages)) {
return null;
}

$sentMessages = $this->sentMessages;

return array_pop($sentMessages);
}

/**
* Clears the internal list of sent messages.
*
* @return static self reference.
*/
public function clearSentMessages(): self
{
$this->sentMessages = [];

return $this;
}

/**
* Filters the internal list of sent messages according to the given callback.
*
* Callback signature:
*
* ```
* function (\Symfony\Component\Mailer\SentMessage $message): bool
* ```
*
* The callback is applied over each sent message.
* In case the callback returns `true` the message will be returned in result set.
*
* @param callable $filterCallback filter callback.
* @return \Symfony\Component\Mime\RawMessage[]|\Symfony\Component\Mime\Email[]|\yii1tech\mailer\TemplatedEmail[] sent messages.
*/
public function filterSentMessages(callable $filterCallback): array
{
$result = [];

foreach ($this->sentMessages as $message) {
if (call_user_func($filterCallback, $message)) {
$result[] = $message;
}
}

return $result;
}
}
19 changes: 19 additions & 0 deletions tests/MailerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Symfony\Component\Mailer\Transport\NullTransport;
use Yii;
use yii1tech\mailer\Mailer;
use yii1tech\mailer\transport\ArrayTransport;

class MailerTest extends TestCase
{
Expand Down Expand Up @@ -45,6 +46,24 @@ public function testCreateTransportFromCallable(): void
$this->assertTrue($mailer->getTransport() instanceof NullTransport);
}

public function testCreateArrayTransport(): void
{
/** @var Mailer $mailer */
$mailer = Yii::createComponent([
'class' => Mailer::class,
'dsn' => 'array',
]);

$this->assertTrue($mailer->getTransport() instanceof ArrayTransport);

$mailer = Yii::createComponent([
'class' => Mailer::class,
'dsn' => 'array://',
]);

$this->assertTrue($mailer->getTransport() instanceof ArrayTransport);
}

public function testSetupSymfonyMailer(): void
{
$mailer = new Mailer();
Expand Down
46 changes: 46 additions & 0 deletions tests/transport/ArrayTransportTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

namespace yii1tech\mailer\test\transport;

use Symfony\Component\Mime\Email;
use Yii;
use yii1tech\mailer\Mailer;
use yii1tech\mailer\test\TestCase;
use yii1tech\mailer\transport\ArrayTransport;

class ArrayTransportTest extends TestCase
{
public function testSend(): void
{
$transport = new ArrayTransport();

/** @var Mailer $mailer */
$mailer = Yii::createComponent([
'class' => Mailer::class,
'transport' => $transport,
]);

$email = new Email();
$email->from('[email protected]');
$email->addTo('[email protected]');
$email->subject('Test subject');
$email->text('Test body');

$mailer->send($email);

$this->assertCount(1, $transport->getSentMessages());

$sentMessage = $transport->getLastSentMessage();
$this->assertSame('[email protected]', $sentMessage->getFrom()[0]->getAddress());

$messages = $transport->filterSentMessages(function (Email $message) {
return $message->getSubject() === 'Test subject';
});
$this->assertCount(1, $messages);

$messages = $transport->filterSentMessages(function (Email $message) {
return $message->getSubject() === 'Fake';
});
$this->assertCount(0, $messages);
}
}

0 comments on commit 8ac8036

Please sign in to comment.