Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 800deaa

Browse files
committed
feature #46895 [Notifier] Introduce PHPUnit constraints and assertions for the Notifier (ismail1432)
This PR was merged into the 6.2 branch. Discussion ---------- [Notifier] Introduce PHPUnit constraints and assertions for the Notifier | Q | A | ------------- | --- | Branch? | 6.2 | Bug fix? | no | New feature? | yes | Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tickets | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead --> | License | MIT | Doc PR | symfony/symfony-docs#... <!-- required for new features --> [Since 4.4 we have assertions for email ](https://symfony.com/blog/new-in-symfony-4-4-phpunit-assertions-for-email-messages), the goal of this PR is to introduce the same kind of assertions for the Notifier component. ```php public function testNotifier() { /** @var NotifierInterface $notifier */ $firstNotification = new Notification('Hello World!', ['chat/slack']); $firstNotification->content("Symfony is awesome!"); $notifier->send($firstNotification); $secondNotification = (new Notification('New urgent notification')) ->importance(Notification::IMPORTANCE_URGENT) ; $notifier->send($secondNotification); $this->assertNotificationCount(2); $first = 0; $second = 1; $this->assertNotificationIsNotQueued($this->getNotifierEvent($first)); $this->assertNotificationIsNotQueued($this->getNotifierEvent($second)); $notification = $this->getNotifierMessage($first); $this->assertNotificationSubjectContains($notification, 'Hello World!'); $this->assertNotificationSubjectNotContains($notification, 'New urgent notification'); $this->assertNotificationTransportIsEqual($notification,'slack'); $this->assertNotificationTransportIsNotEqual($notification,'mercure'); $notification = $this->getNotifierMessage($second); $this->assertNotificationSubjectContains($notification, 'New urgent notification'); $this->assertNotificationSubjectNotContains($notification, 'Hello World!'); $this->assertNotificationTransportIsEqual($notification,'mercure'); $this->assertNotificationTransportIsNotEqual($notification,'slack'); } Commits ------- 747e9cb add NotifierAssertionTrait
2 parents 58c50dc + 747e9cb commit 800deaa

File tree

15 files changed

+475
-0
lines changed

15 files changed

+475
-0
lines changed

src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
6.2
55
---
66

7+
* Add `NotificationAssertionsTrait`
78
* Add option `framework.catch_all_throwables` to allow `Symfony\Component\HttpKernel\HttpKernel` to catch all kinds of `Throwable`
89
* Make `AbstractController::render()` able to deal with forms and deprecate `renderForm()`
910
* Deprecate the `Symfony\Component\Serializer\Normalizer\ObjectNormalizer` and

src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
abstract class KernelTestCase extends TestCase
2727
{
2828
use MailerAssertionsTrait;
29+
use NotificationAssertionsTrait;
2930

3031
protected static $class;
3132

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\Notifier\Event\MessageEvent;
16+
use Symfony\Component\Notifier\Event\NotificationEvents;
17+
use Symfony\Component\Notifier\Message\MessageInterface;
18+
use Symfony\Component\Notifier\Test\Constraint as NotifierConstraint;
19+
20+
/*
21+
* @author Smaïne Milianni <[email protected]>
22+
*/
23+
trait NotificationAssertionsTrait
24+
{
25+
public static function assertNotificationCount(int $count, string $transport = null, string $message = ''): void
26+
{
27+
self::assertThat(self::getNotificationEvents(), new NotifierConstraint\NotificationCount($count, $transport), $message);
28+
}
29+
30+
public static function assertQueuedNotificationCount(int $count, string $transport = null, string $message = ''): void
31+
{
32+
self::assertThat(self::getMessageMailerEvents(), new NotifierConstraint\NotificationCount($count, $transport, true), $message);
33+
}
34+
35+
public static function assertNotificationIsQueued(MessageEvent $event, string $message = ''): void
36+
{
37+
self::assertThat($event, new NotifierConstraint\NotificationIsQueued(), $message);
38+
}
39+
40+
public static function assertNotificationIsNotQueued(MessageEvent $event, string $message = ''): void
41+
{
42+
self::assertThat($event, new LogicalNot(new NotifierConstraint\NotificationIsQueued()), $message);
43+
}
44+
45+
public static function assertNotificationSubjectContains(MessageInterface $messageObject, string $text, string $message = ''): void
46+
{
47+
self::assertThat($messageObject, new NotifierConstraint\NotificationSubjectContains($text), $message);
48+
}
49+
50+
public static function assertNotificationSubjectNotContains(MessageInterface $messageObject, string $text, string $message = ''): void
51+
{
52+
self::assertThat($messageObject, new LogicalNot(new NotifierConstraint\NotificationSubjectContains($text)), $message);
53+
}
54+
55+
public static function assertNotificationTransportIsEqual(MessageInterface $messageObject, string $text, string $message = ''): void
56+
{
57+
self::assertThat($messageObject, new NotifierConstraint\NotificationTransportIsEqual($text), $message);
58+
}
59+
60+
public static function assertNotificationTransportIsNotEqual(MessageInterface $messageObject, string $text, string $message = ''): void
61+
{
62+
self::assertThat($messageObject, new LogicalNot(new NotifierConstraint\NotificationTransportIsEqual($text)), $message);
63+
}
64+
65+
/**
66+
* @return MessageEvent[]
67+
*/
68+
public static function getNotifierEvents(string $transport = null): array
69+
{
70+
return self::getNotificationEvents()->getEvents($transport);
71+
}
72+
73+
public static function getNotifierEvent(int $index = 0, string $transport = null): ?MessageEvent
74+
{
75+
return self::getNotifierEvents($transport)[$index] ?? null;
76+
}
77+
78+
/**
79+
* @return MessageInterface[]
80+
*/
81+
public static function getNotifierMessages(string $transport = null): array
82+
{
83+
return self::getNotificationEvents()->getMessages($transport);
84+
}
85+
86+
public static function getNotifierMessage(int $index = 0, string $transport = null): ?MessageInterface
87+
{
88+
return self::getNotifierMessages($transport)[$index] ?? null;
89+
}
90+
91+
public static function getNotificationEvents(): NotificationEvents
92+
{
93+
$container = static::getContainer();
94+
if ($container->has('notifier.logger_notification_listener')) {
95+
return $container->get('notifier.logger_notification_listener')->getEvents();
96+
}
97+
98+
static::fail('A client must have Notifier enabled to make notifications assertions. Did you forget to require symfony/notifier?');
99+
}
100+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\Notifier\Notification\Notification;
16+
use Symfony\Component\Notifier\NotifierInterface;
17+
18+
final class NotificationController
19+
{
20+
public function indexAction(NotifierInterface $notifier)
21+
{
22+
$firstNotification = new Notification('Hello World!', ['chat/slack']);
23+
$firstNotification->content('Symfony is awesome!');
24+
25+
$notifier->send($firstNotification);
26+
27+
$secondNotification = (new Notification('New urgent notification'))
28+
->importance(Notification::IMPORTANCE_URGENT)
29+
;
30+
$notifier->send($secondNotification);
31+
32+
return new Response();
33+
}
34+
}

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

+4
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,7 @@ send_email:
6464
uid:
6565
resource: "../../Controller/UidController.php"
6666
type: "annotation"
67+
68+
send_notification:
69+
path: /send_notification
70+
defaults: { _controller: Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\NotificationController::indexAction }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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;
13+
14+
final class NotificationTest extends AbstractWebTestCase
15+
{
16+
public function testNotifierAssertion()
17+
{
18+
$client = $this->createClient(['test_case' => 'Notifier', 'root_config' => 'config.yml', 'debug' => true]);
19+
$client->request('GET', '/send_notification');
20+
21+
$this->assertNotificationCount(2);
22+
$first = 0;
23+
$second = 1;
24+
$this->assertNotificationIsNotQueued($this->getNotifierEvent($first));
25+
$this->assertNotificationIsNotQueued($this->getNotifierEvent($second));
26+
27+
$notification = $this->getNotifierMessage($first);
28+
$this->assertNotificationSubjectContains($notification, 'Hello World!');
29+
$this->assertNotificationSubjectNotContains($notification, 'New urgent notification');
30+
$this->assertNotificationTransportIsEqual($notification, 'slack');
31+
$this->assertNotificationTransportIsNotEqual($notification, 'mercure');
32+
33+
$notification = $this->getNotifierMessage($second);
34+
$this->assertNotificationSubjectContains($notification, 'New urgent notification');
35+
$this->assertNotificationSubjectNotContains($notification, 'Hello World!');
36+
$this->assertNotificationTransportIsEqual($notification, 'mercure');
37+
$this->assertNotificationTransportIsNotEqual($notification, 'slack');
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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+
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
13+
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestBundle;
14+
use Symfony\Bundle\MercureBundle\MercureBundle;
15+
16+
return [
17+
new FrameworkBundle(),
18+
new TestBundle(),
19+
new MercureBundle(),
20+
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
imports:
2+
- { resource: ../config/default.yml }
3+
- { resource: services.yml }
4+
5+
framework:
6+
mailer:
7+
dsn: 'null://null'
8+
notifier:
9+
chatter_transports:
10+
slack: 'null://null'
11+
mercure: 'null://null'
12+
channel_policy:
13+
urgent: ['chat/mercure']
14+
admin_recipients:
15+
- { email: [email protected] }
16+
profiler: ~
17+
18+
mercure:
19+
hubs:
20+
default:
21+
url: 'null://null'
22+
jwt:
23+
secret: '!ChangeMe!'
24+
publish: [ 'foo', 'https://example.com/foo' ]
25+
subscribe: [ 'bar', 'https://example.com/bar' ]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
_notifiertest_bundle:
2+
resource: '@TestBundle/Resources/config/routing.yml'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
services:
2+
_defaults:
3+
public: true
4+
5+
Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\NotificationController:
6+
tags: ['controller.service_arguments']
7+

src/Symfony/Component/Notifier/CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
6.2
5+
---
6+
7+
* Add PHPUnit constraints
8+
49
6.1
510
---
611

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\Notifier\Test\Constraint;
13+
14+
use PHPUnit\Framework\Constraint\Constraint;
15+
use Symfony\Component\Notifier\Event\NotificationEvents;
16+
17+
/**
18+
* @author Smaïne Milianni <[email protected]>
19+
*/
20+
final class NotificationCount extends Constraint
21+
{
22+
private $expectedValue;
23+
private $transport;
24+
private $queued;
25+
26+
public function __construct(int $expectedValue, string $transport = null, bool $queued = false)
27+
{
28+
$this->expectedValue = $expectedValue;
29+
$this->transport = $transport;
30+
$this->queued = $queued;
31+
}
32+
33+
/**
34+
* {@inheritdoc}
35+
*/
36+
public function toString(): string
37+
{
38+
return sprintf('%shas %s "%d" emails', $this->transport ? $this->transport.' ' : '', $this->queued ? 'queued' : 'sent', $this->expectedValue);
39+
}
40+
41+
/**
42+
* @param NotificationEvents $events
43+
*
44+
* {@inheritdoc}
45+
*/
46+
protected function matches($events): bool
47+
{
48+
return $this->expectedValue === $this->countNotifications($events);
49+
}
50+
51+
/**
52+
* @param NotificationEvents $events
53+
*
54+
* {@inheritdoc}
55+
*/
56+
protected function failureDescription($events): string
57+
{
58+
return sprintf('the Transport %s (%d %s)', $this->toString(), $this->countNotifications($events), $this->queued ? 'queued' : 'sent');
59+
}
60+
61+
private function countNotifications(NotificationEvents $events): int
62+
{
63+
$count = 0;
64+
foreach ($events->getEvents($this->transport) as $event) {
65+
if (
66+
($this->queued && $event->isQueued())
67+
||
68+
(!$this->queued && !$event->isQueued())
69+
) {
70+
++$count;
71+
}
72+
}
73+
74+
return $count;
75+
}
76+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\Notifier\Test\Constraint;
13+
14+
use PHPUnit\Framework\Constraint\Constraint;
15+
use Symfony\Component\Notifier\Event\MessageEvent;
16+
17+
/**
18+
* @author Smaïne Milianni <[email protected]>
19+
*/
20+
final class NotificationIsQueued extends Constraint
21+
{
22+
/**
23+
* {@inheritdoc}
24+
*/
25+
public function toString(): string
26+
{
27+
return 'is queued';
28+
}
29+
30+
/**
31+
* @param MessageEvent $event
32+
*
33+
* {@inheritdoc}
34+
*/
35+
protected function matches($event): bool
36+
{
37+
return $event->isQueued();
38+
}
39+
40+
/**
41+
* @param MessageEvent $event
42+
*
43+
* {@inheritdoc}
44+
*/
45+
protected function failureDescription($event): string
46+
{
47+
return 'the Notification '.$this->toString();
48+
}
49+
}

0 commit comments

Comments
 (0)