Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 23f237b

Browse filesBrowse files
committed
added PHPUnit constraints and assertions for the Mailer
1 parent fdaf0e0 commit 23f237b
Copy full SHA for 23f237b

22 files changed

+677
-11
lines changed

‎src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
4.4.0
55
-----
66

7+
* Added `MailerAssertionsTrait`
78
* Deprecated support for `templating` engine in `TemplateController`, use Twig instead
89
* Deprecated the `$parser` argument of `ControllerResolver::__construct()` and `DelegatingLoader::__construct()`
910
* Deprecated the `controller_name_converter` and `resolve_controller_name_subscriber` services

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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+3-4Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -553,10 +553,6 @@ private function registerProfilerConfiguration(array $config, ContainerBuilder $
553553
$loader->load('messenger_debug.xml');
554554
}
555555

556-
if (class_exists(Mailer::class)) {
557-
$loader->load('mailer_debug.xml');
558-
}
559-
560556
$container->setParameter('profiler_listener.only_exceptions', $config['only_exceptions']);
561557
$container->setParameter('profiler_listener.only_master_requests', $config['only_master_requests']);
562558

@@ -1969,6 +1965,9 @@ private function registerMailerConfiguration(array $config, ContainerBuilder $co
19691965
}
19701966

19711967
$loader->load('mailer.xml');
1968+
if ($container->getParameter('kernel.debug')) {
1969+
$loader->load('mailer_debug.xml');
1970+
}
19721971
$loader->load('mailer_transports.xml');
19731972
$container->getDefinition('mailer.default_transport')->setArgument(0, $config['dsn']);
19741973

+126Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
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\Bundle\FrameworkBundle\Test;
13+
14+
use PHPUnit\Framework\Constraint\LogicalNot;
15+
use Symfony\Component\Mailer\Event\MessageEvent;
16+
use Symfony\Component\Mailer\Event\MessageEvents;
17+
use Symfony\Component\Mailer\Test\Constraint as MailerConstraint;
18+
use Symfony\Component\Mime\RawMessage;
19+
use Symfony\Component\Mime\Test\Constraint as MimeConstraint;
20+
21+
trait MailerAssertionsTrait
22+
{
23+
public static function assertEmailCount(int $count, string $transport = null, string $message = ''): void
24+
{
25+
self::assertThat(self::getMessageMailerEvents(), new MailerConstraint\EmailCount($count, $transport), $message);
26+
}
27+
28+
public static function assertEmailIsQueued(MessageEvent $event, string $message = ''): void
29+
{
30+
self::assertThat($event, new MailerConstraint\EmailIsQueued(), $message);
31+
}
32+
33+
public static function assertEmailIsNotQueued(MessageEvent $event, string $message = ''): void
34+
{
35+
self::assertThat($event, new LogicalNot(new MailerConstraint\EmailIsQueued()), $message);
36+
}
37+
38+
public static function assertEmailAttachementCount(RawMessage $email, int $count, string $message = ''): void
39+
{
40+
self::assertThat($email, new MimeConstraint\EmailAttachmentCount($count), $message);
41+
}
42+
43+
public static function assertEmailTextBodyContains(RawMessage $email, string $text, string $message = ''): void
44+
{
45+
self::assertThat($email, new MimeConstraint\EmailTextBodyContains($text), $message);
46+
}
47+
48+
public static function assertEmailTextBodyNotContains(RawMessage $email, string $text, string $message = ''): void
49+
{
50+
self::assertThat($email, new LogicalNot(new MimeConstraint\EmailTextBodyContains($text)), $message);
51+
}
52+
53+
public static function assertEmailHtmlBodyContains(RawMessage $email, string $text, string $message = ''): void
54+
{
55+
self::assertThat($email, new MimeConstraint\EmailHtmlBodyContains($text), $message);
56+
}
57+
58+
public static function assertEmailHtmlBodyNotContains(RawMessage $email, string $text, string $message = ''): void
59+
{
60+
self::assertThat($email, new LogicalNot(new MimeConstraint\EmailHtmlBodyContains($text)), $message);
61+
}
62+
63+
public static function assertEmailHasHeader(RawMessage $email, string $headerName, string $message = ''): void
64+
{
65+
self::assertThat($email, new MimeConstraint\EmailHasHeader($headerName), $message);
66+
}
67+
68+
public static function assertEmailNotHasHeader(RawMessage $email, string $headerName, string $message = ''): void
69+
{
70+
self::assertThat($email, new LogicalNot(new MimeConstraint\EmailHasHeader($headerName)), $message);
71+
}
72+
73+
public static function assertEmailHeaderSame(RawMessage $email, string $headerName, string $expectedValue, string $message = ''): void
74+
{
75+
self::assertThat($email, new MimeConstraint\EmailHeaderSame($headerName, $expectedValue), $message);
76+
}
77+
78+
public static function assertEmailHeaderNotSame(RawMessage $email, string $headerName, string $expectedValue, string $message = ''): void
79+
{
80+
self::assertThat($email, new LogicalNot(new MimeConstraint\EmailHeaderSame($headerName, $expectedValue)), $message);
81+
}
82+
83+
public static function assertEmailAddressContains(RawMessage $email, string $headerName, string $expectedValue, string $message = ''): void
84+
{
85+
self::assertThat($email, new MimeConstraint\EmailAddressContains($headerName, $expectedValue), $message);
86+
}
87+
88+
/**
89+
* @return MessageEvents[]
90+
*/
91+
public static function getMailerEvents(string $transport = null): array
92+
{
93+
return self::getMessageMailerEvents()->getEvents($transport);
94+
}
95+
96+
public static function getMailerEvent(int $index = 0, string $transport = null): ?MessageEvent
97+
{
98+
return self::getMailerEvents($transport)[$index] ?? null;
99+
}
100+
101+
/**
102+
* @return RawMessage[]
103+
*/
104+
public static function getMailerMessages(string $transport = null): array
105+
{
106+
return self::getMessageMailerEvents()->getMessages($transport);
107+
}
108+
109+
public static function getMailerMessage(int $index = 0, string $transport = null): ?RawMessage
110+
{
111+
return self::getMailerMessages($transport)[$index] ?? null;
112+
}
113+
114+
private static function getMessageMailerEvents(): MessageEvents
115+
{
116+
if (!self::getClient()->getRequest()) {
117+
static::fail('Unable to make email assertions. Did you forget to make an HTTP request?');
118+
}
119+
120+
if (!$logger = self::$container->get('mailer.logger_message_listener')) {
121+
static::fail('A client must have Mailer enabled to make email assertions. Did you forget to require symfony/mailer?');
122+
}
123+
124+
return $logger->getEvents();
125+
}
126+
}

‎src/Symfony/Bundle/FrameworkBundle/Test/WebTestAssertionsTrait.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Test/WebTestAssertionsTrait.php
-5Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,6 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Test;
1313

14-
/**
15-
* Ideas borrowed from Laravel Dusk's assertions.
16-
*
17-
* @see https://laravel.com/docs/5.7/dusk#available-assertions
18-
*/
1914
trait WebTestAssertionsTrait
2015
{
2116
use BrowserKitAssertionsTrait;

‎src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ abstract class WebTestCase extends KernelTestCase
2323
{
2424
use ForwardCompatTestTrait;
2525
use WebTestAssertionsTrait;
26+
use MailerAssertionsTrait;
2627

2728
private function doTearDown()
2829
{
+41Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller;
13+
14+
use Symfony\Component\HttpFoundation\Response;
15+
use Symfony\Component\Mailer\MailerInterface;
16+
use Symfony\Component\Mime\Email;
17+
use Symfony\Component\Mime\NamedAddress;
18+
19+
class EmailController
20+
{
21+
public function indexAction(MailerInterface $mailer)
22+
{
23+
$mailer->send((new Email())->to('fabien@symfony.com')->from('fabien@symfony.com')->subject('Foo')
24+
->addReplyTo('me@symfony.com')
25+
->addCc('cc@symfony.com')
26+
->text('Bar!')
27+
->html('<p>Foo</p>')
28+
->attach(file_get_contents(__FILE__), 'foobar.php')
29+
);
30+
31+
$mailer->send((new Email())->to('fabien@symfony.com', 'thomas@symfony.com')->from('fabien@symfony.com')->subject('Foo')
32+
->addReplyTo(new NamedAddress('me@symfony.com', 'Fabien Potencier'))
33+
->addCc('cc@symfony.com')
34+
->text('Bar!')
35+
->html('<p>Foo</p>')
36+
->attach(file_get_contents(__FILE__), 'foobar.php')
37+
);
38+
39+
return new Response();
40+
}
41+
}

‎src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Resources/config/routing.yml
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,7 @@ fragment_inlined:
5252
array_controller:
5353
path: /array_controller
5454
defaults: { _controller: [ArrayController, someAction] }
55+
56+
send_email:
57+
path: /send_email
58+
defaults: { _controller: Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\EmailController::indexAction }

‎src/Symfony/Bundle/FrameworkBundle/Tests/Functional/MailerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/Functional/MailerTest.php
+24Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,28 @@ protected function doSend(SentMessage $message): void
6464

6565
$mailer->send($message);
6666
}
67+
68+
public function testMailerAssertions()
69+
{
70+
$client = $this->createClient(['test_case' => 'Mailer', 'root_config' => 'config.yml', 'debug' => true]);
71+
$client->request('GET', '/send_email');
72+
73+
$this->assertEmailCount(2);
74+
$this->assertEmailIsQueued($this->getMailerEvent(0));
75+
76+
$email = $this->getMailerMessage(0);
77+
$this->assertEmailHasHeader($email, 'To');
78+
$this->assertEmailHeaderSame($email, 'To', 'fabien@symfony.com');
79+
$this->assertEmailHeaderNotSame($email, 'To', 'helene@symfony.com');
80+
$this->assertEmailTextBodyContains($email, 'Bar');
81+
$this->assertEmailTextBodyNotContains($email, 'Foo');
82+
$this->assertEmailHtmlBodyContains($email, 'Foo');
83+
$this->assertEmailHtmlBodyNotContains($email, 'Bar');
84+
$this->assertEmailAttachementCount($email, 1);
85+
86+
$email = $this->getMailerMessage(1);
87+
$this->assertEmailAddressContains($email, 'To', 'fabien@symfony.com');
88+
$this->assertEmailAddressContains($email, 'To', 'thomas@symfony.com');
89+
$this->assertEmailAddressContains($email, 'Reply-To', 'me@symfony.com');
90+
}
6791
}

‎src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Mailer/config.yml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Mailer/config.yml
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
imports:
22
- { resource: ../config/default.yml }
3+
- { resource: services.yml }
34

45
framework:
56
mailer:
7+
dsn: 'smtp://null'
68
envelope:
79
sender: sender@example.org
810
recipients:
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
_emailtest_bundle:
2+
resource: '@TestBundle/Resources/config/routing.yml'
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
services:
2+
_defaults:
3+
public: true
4+
5+
Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\EmailController:
6+
tags: ['controller.service_arguments']

‎src/Symfony/Bundle/FrameworkBundle/composer.json

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/composer.json
+3-2Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@
4242
"symfony/expression-language": "^3.4|^4.0|^5.0",
4343
"symfony/http-client": "^4.3|^5.0",
4444
"symfony/lock": "^4.4|^5.0",
45-
"symfony/mailer": "^4.3|^5.0",
45+
"symfony/mailer": "^4.4|^5.0",
4646
"symfony/messenger": "^4.3|^5.0",
47-
"symfony/mime": "^4.3|^5.0",
47+
"symfony/mime": "^4.4|^5.0",
4848
"symfony/process": "^3.4|^4.0|^5.0",
4949
"symfony/security-csrf": "^3.4|^4.0|^5.0",
5050
"symfony/security-http": "^3.4|^4.0|^5.0",
@@ -76,6 +76,7 @@
7676
"symfony/lock": "<4.4",
7777
"symfony/mailer": "<4.4",
7878
"symfony/messenger": "<4.3",
79+
"symfony/mime": "<4.4",
7980
"symfony/property-info": "<3.4",
8081
"symfony/serializer": "<4.2",
8182
"symfony/stopwatch": "<3.4",

‎src/Symfony/Component/Mailer/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/Mailer/CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
4.4.0
55
-----
66

7+
* Added PHPUnit constraints
78
* Added `MessageDataCollector`
89
* Added `MessageEvents` and `MessageLoggerListener` to allow collecting sent emails
910
* [BC BREAK] `TransportInterface` has a new `getName()` method
+55Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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\Test\Constraint;
13+
14+
use PHPUnit\Framework\Constraint\Constraint;
15+
use Symfony\Component\Mailer\Event\MessageEvents;
16+
17+
final class EmailCount extends Constraint
18+
{
19+
private $expectedValue;
20+
private $transport;
21+
22+
public function __construct(int $expectedValue, string $transport = null)
23+
{
24+
$this->expectedValue = $expectedValue;
25+
$this->transport = $transport;
26+
}
27+
28+
/**
29+
* {@inheritdoc}
30+
*/
31+
public function toString(): string
32+
{
33+
return sprintf('%shas sent "%d" emails', $this->transport ? $this->transport.' ' : '', $this->expectedValue);
34+
}
35+
36+
/**
37+
* @param MessageEvents $events
38+
*
39+
* {@inheritdoc}
40+
*/
41+
protected function matches($events): bool
42+
{
43+
return $this->expectedValue === \count($events->getEvents($this->transport));
44+
}
45+
46+
/**
47+
* @param MessageEvents $events
48+
*
49+
* {@inheritdoc}
50+
*/
51+
protected function failureDescription($events): string
52+
{
53+
return sprintf('the Transport %s (%d sent)', $this->toString(), \count($events->getEvents($this->transport)));
54+
}
55+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.