diff --git a/src/Codeception/Module/Symfony.php b/src/Codeception/Module/Symfony.php index c30fe8f3..d71ab511 100644 --- a/src/Codeception/Module/Symfony.php +++ b/src/Codeception/Module/Symfony.php @@ -36,6 +36,7 @@ use Symfony\Component\HttpKernel\Kernel; use Symfony\Component\HttpKernel\Profiler\Profile; use Symfony\Component\HttpKernel\Profiler\Profiler; +use Symfony\Component\Mailer\DataCollector\MessageDataCollector; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouterInterface; use Symfony\Component\VarDumper\Cloner\Data; @@ -74,7 +75,6 @@ * * debug: true - turn on/off debug mode * * cache_router: 'false' - enable router caching between tests in order to [increase performance](http://lakion.com/blog/how-did-we-speed-up-sylius-behat-suite-with-blackfire) * * rebootable_client: 'true' - reboot client's kernel before each request - * * mailer: 'symfony_mailer' - choose the mailer used by your application * * #### Example (`functional.suite.yml`) - Symfony 4 Directory Structure * @@ -95,7 +95,6 @@ * * debug: true - turn on/off debug mode * * cache_router: 'false' - enable router caching between tests in order to [increase performance](http://lakion.com/blog/how-did-we-speed-up-sylius-behat-suite-with-blackfire) * * rebootable_client: 'true' - reboot client's kernel before each request - * * mailer: 'swiftmailer' - choose the mailer used by your application * * #### Example (`functional.suite.yml`) - Symfony 3 Directory Structure * @@ -158,10 +157,6 @@ class Symfony extends Framework implements DoctrineProvider, PartedModule SessionAssertionsTrait ; - private const SWIFTMAILER = 'swiftmailer'; - - private const SYMFONY_MAILER = 'symfony_mailer'; - private static $possibleKernelClasses = [ 'AppKernel', // Symfony Standard 'App\Kernel', // Symfony Flex @@ -181,7 +176,6 @@ class Symfony extends Framework implements DoctrineProvider, PartedModule 'cache_router' => false, 'em_service' => 'doctrine.orm.entity_manager', 'rebootable_client' => true, - 'mailer' => self::SWIFTMAILER, 'guard' => false ]; @@ -462,12 +456,10 @@ protected function debugResponse($url): void $this->debugSection('User', 'Anonymous'); } } - if ($profile->hasCollector('swiftmailer')) { - $emails = $profile->getCollector('swiftmailer')->getMessageCount(); - } elseif ($profile->hasCollector('mailer')) { - $emails = count($profile->getCollector('mailer')->getEvents()->getMessages()); - } - if (isset($emails)) { + if ($profile->hasCollector('mailer')) { + /** @var MessageDataCollector $mailerCollector */ + $mailerCollector = $profile->getCollector('mailer'); + $emails = count($mailerCollector->getEvents()->getMessages()); $this->debugSection('Emails', $emails . ' sent'); } if ($profile->hasCollector('time')) { diff --git a/src/Codeception/Module/Symfony/MailerAssertionsTrait.php b/src/Codeception/Module/Symfony/MailerAssertionsTrait.php index 4917b986..9dba8780 100644 --- a/src/Codeception/Module/Symfony/MailerAssertionsTrait.php +++ b/src/Codeception/Module/Symfony/MailerAssertionsTrait.php @@ -3,58 +3,55 @@ declare(strict_types=1); namespace Codeception\Module\Symfony; -use function count; -use function sprintf; + +use Symfony\Component\Mailer\Event\MessageEvents; +use Symfony\Component\Mailer\EventListener\MessageLoggerListener; +use Symfony\Component\Mailer\Test\Constraint as MailerConstraint; trait MailerAssertionsTrait { /** - * Checks that no email was sent. This is an alias for seeEmailIsSent(0). + * Checks that no email was sent. */ public function dontSeeEmailIsSent(): void { - $this->seeEmailIsSent(0); + $this->assertThat($this->getMessageMailerEvents(), new MailerConstraint\EmailCount(0)); } /** * Checks if the desired number of emails was sent. - * If no argument is provided then at least one email must be sent to satisfy the check. - * The email is checked using Symfony's profiler, which means: + * Asserts that 1 email was sent by default, specify the `expectedCount` parameter to modify it. + * The email is checked using Symfony message logger, which means: * * If your app performs a redirect after sending the email, you need to suppress this using REST Module's [stopFollowingRedirects](https://codeception.com/docs/modules/REST#stopFollowingRedirects) - * * If the email is sent by a Symfony Console Command, Codeception cannot detect it yet. * - * ``` php + * ```php * seeEmailIsSent(2); * ``` * - * @param int|null $expectedCount + * @param int $expectedCount The expected number of emails sent */ - public function seeEmailIsSent(?int $expectedCount = null): void + public function seeEmailIsSent(int $expectedCount = 1): void + { + $this->assertThat($this->getMessageMailerEvents(), new MailerConstraint\EmailCount($expectedCount)); + } + + protected function getMessageMailerEvents(): MessageEvents { - $realCount = 0; - $mailer = $this->config['mailer']; - if ($mailer === self::SWIFTMAILER) { - $mailCollector = $this->grabCollector('swiftmailer', __FUNCTION__); - $realCount = $mailCollector->getMessageCount(); - } elseif ($mailer === self::SYMFONY_MAILER) { - $mailCollector = $this->grabCollector('mailer', __FUNCTION__); - $realCount = count($mailCollector->getEvents()->getMessages()); - } else { - $this->fail( - "Emails can't be tested without Mailer service connector. - Set your mailer service in `functional.suite.yml`: `mailer: swiftmailer` - (Or `mailer: symfony_mailer` for Symfony Mailer)." - ); + $container = $this->_getContainer(); + + if ($container->has('mailer.message_logger_listener')) { + /** @var MessageLoggerListener $messageLogger */ + $messageLogger = $container->get('mailer.message_logger_listener'); + return $messageLogger->getEvents(); } - if ($expectedCount !== null) { - $this->assertEquals($expectedCount, $realCount, sprintf( - 'Expected number of sent emails was %d, but in reality %d %s sent.', - $expectedCount, $realCount, $realCount === 1 ? 'was' : 'were' - )); - return; + if ($container->has('mailer.logger_message_listener')) { + /** @var MessageLoggerListener $messageLogger */ + $messageLogger = $container->get('mailer.logger_message_listener'); + return $messageLogger->getEvents(); } - $this->assertGreaterThan(0, $realCount); + + $this->fail("Emails can't be tested without Symfony Mailer service."); } } \ No newline at end of file