Skip to content

Commit 572a74f

Browse files
add notifier assertions trait
1 parent a516dc6 commit 572a74f

File tree

3 files changed

+271
-0
lines changed

3 files changed

+271
-0
lines changed

src/Codeception/Module/Symfony.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use Codeception\Module\Symfony\LoggerAssertionsTrait;
2222
use Codeception\Module\Symfony\MailerAssertionsTrait;
2323
use Codeception\Module\Symfony\MimeAssertionsTrait;
24+
use Codeception\Module\Symfony\NotifierAssertionsTrait;
2425
use Codeception\Module\Symfony\ParameterAssertionsTrait;
2526
use Codeception\Module\Symfony\RouterAssertionsTrait;
2627
use Codeception\Module\Symfony\SecurityAssertionsTrait;
@@ -52,6 +53,7 @@
5253
use Symfony\Component\HttpKernel\Profiler\Profile;
5354
use Symfony\Component\HttpKernel\Profiler\Profiler;
5455
use Symfony\Component\Mailer\DataCollector\MessageDataCollector;
56+
use Symfony\Component\Notifier\DataCollector\NotificationDataCollector;
5557
use Symfony\Component\Translation\DataCollector\TranslationDataCollector;
5658
use Symfony\Component\VarDumper\Cloner\Data;
5759

@@ -156,6 +158,7 @@ class Symfony extends Framework implements DoctrineProvider, PartedModule
156158
use LoggerAssertionsTrait;
157159
use MailerAssertionsTrait;
158160
use MimeAssertionsTrait;
161+
use NotifierAssertionsTrait;
159162
use ParameterAssertionsTrait;
160163
use RouterAssertionsTrait;
161164
use SecurityAssertionsTrait;
@@ -412,6 +415,7 @@ protected function getProfile(): ?Profile
412415
* ($collector is DataCollectorName::TWIG ? TwigDataCollector :
413416
* ($collector is DataCollectorName::SECURITY ? SecurityDataCollector :
414417
* ($collector is DataCollectorName::MAILER ? MessageDataCollector :
418+
* ($collector is DataCollectorName::NOTIFIER ? NotificationDataCollector :
415419
* DataCollectorInterface
416420
* ))))))))
417421
* )
@@ -465,6 +469,13 @@ protected function debugResponse(mixed $url): void
465469
}
466470
}
467471

472+
if ($profile->hasCollector(DataCollectorName::NOTIFIER->value)) {
473+
$notifierCollector = $profile->getCollector(DataCollectorName::NOTIFIER->value);
474+
if ($notifierCollector instanceof NotificationDataCollector) {
475+
$this->debugNotifierData($notifierCollector);
476+
}
477+
}
478+
468479
if ($profile->hasCollector(DataCollectorName::TIME->value)) {
469480
$timeCollector = $profile->getCollector(DataCollectorName::TIME->value);
470481
if ($timeCollector instanceof TimeDataCollector) {
@@ -543,6 +554,12 @@ private function debugMailerData(MessageDataCollector $messageCollector): void
543554
$this->debugSection('Emails', sprintf('%d sent', $count));
544555
}
545556

557+
private function debugNotifierData(NotificationDataCollector $notificationCollector): void
558+
{
559+
$count = count($notificationCollector->getEvents()->getMessages());
560+
$this->debugSection('Notifications', sprintf('%d sent', $count));
561+
}
562+
546563
private function debugTimeData(TimeDataCollector $timeCollector): void
547564
{
548565
$this->debugSection('Time', sprintf('%.2f ms', $timeCollector->getDuration()));

src/Codeception/Module/Symfony/DataCollectorName.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ enum DataCollectorName: string
1818
case TWIG = 'twig';
1919
case SECURITY = 'security';
2020
case MAILER = 'mailer';
21+
case NOTIFIER = 'notifier';
2122
}
Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Codeception\Module\Symfony;
6+
7+
use PHPUnit\Framework\Assert;
8+
use PHPUnit\Framework\Constraint\LogicalNot;
9+
use Symfony\Component\Notifier\Event\MessageEvent;
10+
use Symfony\Component\Notifier\Event\NotificationEvents;
11+
use Symfony\Component\Notifier\EventListener\NotificationLoggerListener;
12+
use Symfony\Component\Notifier\Message\MessageInterface;
13+
use Symfony\Component\Notifier\Test\Constraint as NotifierConstraint;
14+
15+
trait NotifierAssertionsTrait
16+
{
17+
/**
18+
* Asserts that the expected number of notifications was sent.
19+
*
20+
* ```php
21+
* <?php
22+
* $I->assertNotificationCount(2, 'smtp');
23+
* ```
24+
*/
25+
public function assertNotificationCount(int $count, ?string $transportName = null, string $message = ''): void
26+
{
27+
$this->assertThat($this->getNotificationEvents(), new NotifierConstraint\NotificationCount($count, $transportName), $message);
28+
}
29+
30+
/**
31+
* Asserts that the given notifier event is not queued.
32+
* Use `getNotifierEvent(int $index = 0, ?string $transportName = null)` to retrieve a notifier event by index.
33+
*
34+
* ```php
35+
* <?php
36+
* $event = $I->getNotifierEvent();
37+
* $I->asserNotificationIsNotQueued($event);
38+
* ```
39+
*/
40+
public function assertNotificationIsNotQueued(MessageEvent $event, string $message = ''): void
41+
{
42+
$this->assertThat($event, new LogicalNot(new NotifierConstraint\NotificationIsQueued()), $message);
43+
}
44+
45+
/**
46+
* Asserts that the given notifier event is queued.
47+
* Use `getNotifierEvent(int $index = 0, ?string $transportName = null)` to retrieve a notifier event by index.
48+
*
49+
* ```php
50+
* <?php
51+
* $event = $I->getNotifierEvent();
52+
* $I->assertNotificationlIsQueued($event);
53+
* ```
54+
*/
55+
public function assertNotificationIsQueued(MessageEvent $event, string $message = ''): void
56+
{
57+
$this->assertThat($event, new NotifierConstraint\NotificationIsQueued(), $message);
58+
}
59+
60+
/**
61+
* Asserts that the given notification contains given subject.
62+
* Use `getNotifierMessage(int $index = 0, ?string $transportName = null)` to retrieve a notification by index.
63+
*
64+
* ```php
65+
* <?php
66+
* $notification = $I->getNotifierMessage();
67+
* $I->assertNotificationSubjectContains($notification, 'Subject');
68+
* ```
69+
*/
70+
public function assertNotificationSubjectContains(MessageInterface $notification, string $text, string $message = ''): void
71+
{
72+
$bbep = $this->assertThat($notification, new NotifierConstraint\NotificationSubjectContains($text), $message);
73+
$test = $notification;
74+
}
75+
76+
/**
77+
* Asserts that the given notification does not contain given subject.
78+
* Use `getNotifierMessage(int $index = 0, ?string $transportName = null)` to retrieve a notification by index.
79+
*
80+
* ```php
81+
* <?php
82+
* $notification = $I->getNotifierMessage();
83+
* $I->assertNotificationSubjectNotContains($notification, 'Subject');
84+
* ```
85+
*/
86+
public function assertNotificationSubjectNotContains(MessageInterface $notification, string $text, string $message = ''): void
87+
{
88+
$this->assertThat($notification, new LogicalNot(new NotifierConstraint\NotificationSubjectContains($text)), $message);
89+
}
90+
91+
/**
92+
* Asserts that the given notification uses given transport.
93+
* Use `getNotifierMessage(int $index = 0, ?string $transportName = null)` to retrieve a notification by index.
94+
*
95+
* ```php
96+
* <?php
97+
* $notification = $I->getNotifierMessage();
98+
* $I->assertNotificationTransportIsEqual($notification, 'chat');
99+
* ```
100+
*/
101+
public function assertNotificationTransportIsEqual(MessageInterface $notification, ?string $transportName = null, string $message = ''): void
102+
{
103+
$this->assertThat($notification, new NotifierConstraint\NotificationTransportIsEqual($transportName), $message);
104+
}
105+
106+
/**
107+
* Asserts that the given notification does not use given transport.
108+
* Use `getNotifierMessage(int $index = 0, ?string $transportName = null)` to retrieve a notification by index.
109+
*
110+
* ```php
111+
* <?php
112+
* $notification = $I->getNotifierMessage();
113+
* $I->assertNotificationTransportIsNotEqual($notification, 'transport');
114+
* ```
115+
*/
116+
public function assertNotificationTransportIsNotEqual(MessageInterface $notification, ?string $transportName = null, string $message = ''): void
117+
{
118+
$this->assertThat($notification, new LogicalNot(new NotifierConstraint\NotificationTransportIsEqual($transportName)), $message);
119+
}
120+
121+
/**
122+
* Asserts that the expected number of notifications was queued (e.g. using the Notifier component).
123+
*
124+
* ```php
125+
* <?php
126+
* $I->assertQueuedNotificationCount(1, 'smtp');
127+
* ```
128+
*/
129+
public function assertQueuedNotificationCount(int $count, ?string $transportName = null, string $message = ''): void
130+
{
131+
$this->assertThat($this->getNotificationEvents(), new NotifierConstraint\NotificationCount($count, $transportName, true), $message);
132+
}
133+
134+
/**
135+
* Checks that no notification was sent.
136+
* The check is based on `\Symfony\Component\Notifier\EventListener\NotificationLoggerListener`, which means:
137+
* If your app performs an HTTP redirect, you need to suppress it using [stopFollowingRedirects()](#stopFollowingRedirects) first; otherwise this check will *always* pass.
138+
*
139+
* ```php
140+
* <?php
141+
* $I->dontSeeNotificationIsSent();
142+
* ```
143+
*/
144+
public function dontSeeNotificationIsSent(): void
145+
{
146+
$this->assertThat($this->getNotificationEvents(), new NotifierConstraint\NotificationCount(0));
147+
}
148+
149+
/**
150+
* Returns the last sent notification.
151+
* The check is based on `\Symfony\Component\Notifier\EventListener\NotificationLoggerListener`, which means:
152+
* If your app performs an HTTP redirect after sending the notification, you need to suppress it using [stopFollowingRedirects()](#stopFollowingRedirects) first.
153+
* See also: [grabSentNotifications()](https://codeception.com/docs/modules/Symfony#grabSentNotifications)
154+
*
155+
* ```php
156+
* <?php
157+
* $message = $I->grabLastSentNotification();
158+
* $I->assertSame('Subject', $message->getSubject());
159+
* ```
160+
*/
161+
public function grabLastSentNotification(): ?MessageInterface
162+
{
163+
$notification = $this->getNotifierMessages();
164+
$lastNotification = end($notification);
165+
166+
return $lastNotification ?: null;
167+
}
168+
169+
170+
/**
171+
* Returns an array of all sent notifications.
172+
* The check is based on `\Symfony\Component\Notifier\EventListener\NotificationLoggerListener`, which means:
173+
* If your app performs an HTTP redirect after sending the notification, you need to suppress it using [stopFollowingRedirects()](#stopFollowingRedirects) first.
174+
* See also: [grabLastSentNotification()](https://codeception.com/docs/modules/Symfony#grabLastSentNotification)
175+
*
176+
* ```php
177+
* <?php
178+
* $notifications = $I->grabSentNotifications();
179+
* ```
180+
*
181+
* @return MessageEvent[]
182+
*/
183+
public function grabSentNotifications(): array
184+
{
185+
return $this->getNotifierMessages();
186+
}
187+
188+
/**
189+
* Checks if the given number of notifications was sent (default `$expectedCount`: 1).
190+
* The check is based on `\Symfony\Component\Notifier\EventListener\NotificationLoggerListener`, which means:
191+
* If your app performs an HTTP redirect after sending the notification, you need to suppress it using [stopFollowingRedirects()](#stopFollowingRedirects) first.
192+
*
193+
* ```php
194+
* <?php
195+
* $I->seeNotificatoinIsSent(2);
196+
* ```
197+
*
198+
* @param int $expectedCount The expected number of notifications sent
199+
*/
200+
public function seeNotificationIsSent(int $expectedCount = 1): void
201+
{
202+
$this->assertThat($this->getNotificationEvents(), new NotifierConstraint\NotificationCount($expectedCount));
203+
}
204+
205+
public function getNotifierEvents(?string $transportName = null): array
206+
{
207+
return $this->getNotificationEvents()->getEvents($transportName);
208+
}
209+
210+
/**
211+
* Returns the notifier event at the specified index.
212+
*
213+
* ```php
214+
* <?php
215+
* $event = $I->getNotifierEvent();
216+
* ```
217+
*/
218+
public function getNotifierEvent(int $index = 0, ?string $transportName = null): ?MessageEvent
219+
{
220+
return $this->getNotifierEvents($transportName)[$index] ?? null;
221+
}
222+
223+
public function getNotifierMessages(?string $transportName = null): array
224+
{
225+
return $this->getNotificationEvents()->getMessages($transportName);
226+
}
227+
228+
/**
229+
* Returns the notifier message at the specified index.
230+
*
231+
* ```php
232+
* <?php
233+
* $message = $I->getNotifierMessage();
234+
* ```
235+
*/
236+
public function getNotifierMessage(int $index = 0, ?string $transportName = null): ?MessageInterface
237+
{
238+
return $this->getNotifierMessages($transportName)[$index] ?? null;
239+
}
240+
241+
protected function getNotificationEvents(): NotificationEvents
242+
{
243+
$notifier = $this->getService('notifier.notification_logger_listener');
244+
if ($notifier instanceof NotificationLoggerListener) {
245+
return $notifier->getEvents();
246+
}
247+
$notifier = $this->getService('notifier.logger_notification_listener');
248+
if ($notifier instanceof NotificationLoggerListener) {
249+
return $notifier->getEvents();
250+
}
251+
Assert::fail("Notifications can't be tested without Symfony Notifier service.");
252+
}
253+
}

0 commit comments

Comments
 (0)