diff --git a/.gitignore b/.gitignore index be106c7f..a595ed07 100755 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /bin/ /vendor/ composer.lock +features/fixtures/tmp diff --git a/behat.yml.dist b/behat.yml.dist index f81ab786..f0238f30 100755 --- a/behat.yml.dist +++ b/behat.yml.dist @@ -5,13 +5,14 @@ default: suites: default: path: %paths.base%/features - contexts: + contexts: - Context\FeatureContext - Knp\FriendlyExtension\Context\PageContext - Knp\FriendlyExtension\Context\MinkContext - Knp\FriendlyExtension\Context\ApiContext + - Knp\FriendlyExtension\Context\SymfonyMailerContext extensions: - Knp\FriendlyExtension: + Knp\FriendlyExtension: smart_tag: 'smart-step' screenshot: recipents: @@ -19,6 +20,8 @@ default: mailer: username: smtp.knplabs@gmail.com password: loremipsum + symfony_kernel: + bootstrap: features/fixtures/index.php Behat\MinkExtension: base_url: 'http://localhost:8080/' goutte: ~ diff --git a/composer.json b/composer.json index f946f063..eaf23e95 100755 --- a/composer.json +++ b/composer.json @@ -17,10 +17,12 @@ "require-dev": { "symfony/http-kernel": "~2.0", "symfony/framework-bundle": "~2.0", - "doctrine/common": "~2.0", + "symfony/swiftmailer-bundle": "~2.0", + "symfony/web-profiler-bundle": "~2.0", + "symfony/twig-bundle": "~2.0", + "symfony/form": "~2.0", + "doctrine/doctrine-bundle": "~1.2", "doctrine/data-fixtures": "~1.0", - "doctrine/orm": "~2.0", - "doctrine/inflector": "~1.0", "behat/mink-extension": "~2.0", "behat/mink-goutte-driver": "~1.0", "behat/mink-selenium2-driver": "~1.0", diff --git a/features/Page/EmailPage.php b/features/Page/EmailPage.php new file mode 100644 index 00000000..4dfb877c --- /dev/null +++ b/features/Page/EmailPage.php @@ -0,0 +1,13 @@ +get('mailer')->send(\Swift_Message::newInstance() + ->setSubject('Hello Subject') + ->setFrom('send@example.com') + ->setTo('recipient@example.com') + ->setBody('Hello Body.') + ); + + return new Response(); + } +} diff --git a/features/fixtures/App/Resources/config/routing.yml b/features/fixtures/App/Resources/config/routing.yml new file mode 100644 index 00000000..ec88a03c --- /dev/null +++ b/features/fixtures/App/Resources/config/routing.yml @@ -0,0 +1,11 @@ +homepage: + pattern: / + defaults: { _controller: 'App:Default:index' } + +mailer_no_emails: + pattern: /mailer/no-emails + defaults: { _controller: 'App:Mailer:noEmails' } + +mailer_email_with_subject: + pattern: /mailer/email + defaults: { _controller: 'App:Mailer:email' } diff --git a/features/fixtures/AppKernel.php b/features/fixtures/AppKernel.php new file mode 100644 index 00000000..5788d3cd --- /dev/null +++ b/features/fixtures/AppKernel.php @@ -0,0 +1,59 @@ +load(function($container) { + $container->loadFromExtension('framework', array( + 'router' => array('resource' => __DIR__.'/App/Resources/config/routing.yml'), + 'templating' => array( + 'engines' => array('twig'), + ), + 'profiler' => array('enabled' => true), + )); + + $container->loadFromExtension('doctrine', array( + 'orm' => array(), + 'dbal' => array(), + )); + + $container->loadFromExtension('swiftmailer', array( + 'disable_delivery' => true, + )); + }); + } + + protected function getKernelParameters() + { + $parameters = parent::getKernelParameters(); + $parameters['kernel.secret'] = 'secret!'; + + return $parameters; + } + + public function getCacheDir() + { + return $this->rootDir.'/tmp/cache/'.$this->name.$this->environment; + } + + public function getLogDir() + { + return $this->rootDir.'/tmp/logs'; + } +} diff --git a/features/fixtures/index.php b/features/fixtures/index.php new file mode 100644 index 00000000..29e0c46a --- /dev/null +++ b/features/fixtures/index.php @@ -0,0 +1,14 @@ +add('App', __DIR__); + +require __DIR__.'/AppKernel.php'; + +$kernel = new AppKernel('test', true); +$request = Request::createFromGlobals(); +$response = $kernel->handle($request); +$response->send(); +$kernel->terminate($request, $response); diff --git a/features/mailer.feature b/features/mailer.feature new file mode 100644 index 00000000..cd906027 --- /dev/null +++ b/features/mailer.feature @@ -0,0 +1,41 @@ +Feature: I am able to describe sending emails + + Scenario: No emails sent + When I go to the noEmails page + Then no email should have been sent + And 0 emails should have been sent + + Scenario: Email with subject sent + When I go to the email page + Then email with subject "Hello Subject" should have been sent + And 1 emails should have been sent + + Scenario: Email with subject not sent + When I go to the email page + And email with subject "Not sent" should not be sent + + Scenario: Email sent to recipeient + When I go to the email page + Then email should have been sent to "recipient@example.com" + + Scenario: Email not sent to recipeient + When I go to the email page + Then email should not be sent to "umpirsky@gmail.com" + + Scenario: Email with subject sent to recipeient + When I go to the email page + Then email with subject "Hello Subject" should have been sent to "recipient@example.com" + And the following emails should have been sent: + | subject | recipient | + | Hello Subject | recipient@example.com | + + Scenario: Email with subject not sent to recipeient + When I go to the email page + Then email with subject "Not sent" should not be sent to "recipient@example.com" + And email with subject "Hello Subject" should not be sent to "umpirsky@gmail.com" + And email with subject "Not sent" should not be sent to "umpirsky@gmail.com" + And the following emails should not be sent: + | subject | recipient | + | Not sent | recipient@example.com | + | Hello Subject | umpirsky@gmail.com | + | Not sent | umpirsky@gmail.com | diff --git a/src/Knp/FriendlyExtension.php b/src/Knp/FriendlyExtension.php index 3d5d1783..49c12f08 100755 --- a/src/Knp/FriendlyExtension.php +++ b/src/Knp/FriendlyExtension.php @@ -28,7 +28,6 @@ public function getConfigKey() public function initialize(ExtensionManager $extensionManager) { - } public function configure(ArrayNodeDefinition $builder) diff --git a/src/Knp/FriendlyExtension/Context/Helper/ProfilerHelper.php b/src/Knp/FriendlyExtension/Context/Helper/ProfilerHelper.php new file mode 100644 index 00000000..19883697 --- /dev/null +++ b/src/Knp/FriendlyExtension/Context/Helper/ProfilerHelper.php @@ -0,0 +1,44 @@ +profiler = $profiler; + } + + public function getProfile($token = null) + { + if (null === $token) { + $headers = $this->get('mink')->getSession()->getResponseHeaders(); + + if (!isset($headers['X-Debug-Token']) && !isset($headers['x-debug-token'])) { + throw new \RuntimeException('Debug-Token not found in response headers. Have you turned on the debug flag?'); + } + + $token = isset($headers['X-Debug-Token']) ? $headers['X-Debug-Token'] : $headers['x-debug-token']; + if (is_array($token)) { + $token = end($token); + } + } + + return $this->profiler->loadProfile($token); + } + + public function getCollector($name, $token = null) + { + return $this->getProfile($token)->getCollector($name); + } + + public function getName() + { + return 'profiler'; + } +} diff --git a/src/Knp/FriendlyExtension/Context/Helper/SwiftMailerHelper.php b/src/Knp/FriendlyExtension/Context/Helper/SwiftMailerHelper.php new file mode 100644 index 00000000..5b813a05 --- /dev/null +++ b/src/Knp/FriendlyExtension/Context/Helper/SwiftMailerHelper.php @@ -0,0 +1,36 @@ +getCollector()->getMessageCount(); + } + + public function isEmailSent($subject = null, $to = null) + { + foreach ($this->getCollector()->getMessages('default') as $message) { + if ((null === $subject || $subject === trim($message->getSubject())) && + (null === $to || array_key_exists($to, $message->getTo())) + ) { + return true; + } + } + + return false; + } + + protected function getCollector() + { + return $this->get('profiler')->getCollector('swiftmailer'); + } + + public function getName() + { + return 'swiftmailer'; + } +} diff --git a/src/Knp/FriendlyExtension/Context/SymfonyMailerContext.php b/src/Knp/FriendlyExtension/Context/SymfonyMailerContext.php new file mode 100644 index 00000000..164e261d --- /dev/null +++ b/src/Knp/FriendlyExtension/Context/SymfonyMailerContext.php @@ -0,0 +1,149 @@ +get('swiftmailer')->countEmailsSent(); + + $this->get('asserter')->assertEquals( + 0, + $count, + sprintf('%d emails have been sent.', $count) + ); + } + + /** + * @Then :count emails should have been sent + */ + public function countEmailShouldHaveBeenSent($expected) + { + $count = $this->get('swiftmailer')->countEmailsSent(); + + $this->get('asserter')->assertEquals( + (int) $expected, + $count, + sprintf('%d emails have been sent.', $count) + ); + } + + /** + * @Then email with subject :subject should have been sent + */ + public function emailWithSubjectShouldHaveBeenSent($subject) + { + if (!$this->get('swiftmailer')->isEmailSent($subject)) { + throw new \Exception(sprintf( + 'No email with subject "%s" has been sent.', + $subject + )); + } + } + + /** + * @Then email with subject :subject should not be sent + */ + public function emailWithSubjectShouldNotBeSent($subject) + { + if ($this->get('swiftmailer')->isEmailSent($subject)) { + throw new \Exception(sprintf( + 'Email with subject "%s" have been sent.', + $subject + )); + } + } + + /** + * @Then email should have been sent to :recipient + */ + public function emailShouldHaveBeenSentToRecipient($recipient) + { + if (!$this->get('swiftmailer')->isEmailSent(null, $recipient)) { + throw new \Exception(sprintf( + 'No email has been sent to "%s".', + $recipient + )); + } + } + + /** + * @Then email should not be sent to :recipient + */ + public function emailShouldNotBeSentToRecipient($recipient) + { + if ($this->get('swiftmailer')->isEmailSent(null, $recipient)) { + throw new \Exception(sprintf( + 'Email have been sent to "%s".', + $recipient + )); + } + } + + /** + * @Then email with subject :subject should have been sent to :recipient + */ + public function emailWithSubjectShouldHaveBeenSentToRecipient($subject, $recipient) + { + if (!$this->get('swiftmailer')->isEmailSent($subject, $recipient)) { + throw new \Exception(sprintf( + 'No email with subject "%s" has been sent to "%s".', + $subject, + $recipient + )); + } + } + + /** + * @Then email with subject :subject should not be sent to :recipient + */ + public function emailWithSubjectShouldNotBeSentToRecipient($subject, $recipient) + { + if ($this->get('swiftmailer')->isEmailSent($subject, $recipient)) { + throw new \Exception(sprintf( + 'Email with subject "%s" have been sent to "%s".', + $subject, + $recipient + )); + } + } + + /** + * @Then the following emails should have been sent: + */ + public function followingEmailsShouldHaveBeenSent(TableNode $table) + { + foreach ($table->getHash() as $data) { + if (!$this->get('swiftmailer')->isEmailSent($data['subject'], $data['recipient'])) { + throw new \Exception(sprintf( + 'No email with subject "%s" has been sent to "%s".', + $data['subject'], + $data['recipient'] + )); + } + } + } + + /** + * @Then the following emails should not be sent: + */ + public function followingEmailsShouldNotBeSent(TableNode $table) + { + foreach ($table->getHash() as $data) { + if ($this->get('swiftmailer')->isEmailSent($data['subject'], $data['recipient'])) { + throw new \Exception(sprintf( + 'Email with subject "%s" have been sent to "%s".', + $data['subject'], + $data['recipient'] + )); + } + } + } +} diff --git a/src/Knp/FriendlyExtension/DependencyInjection/Compiler/KernelPass.php b/src/Knp/FriendlyExtension/DependencyInjection/Compiler/KernelPass.php new file mode 100644 index 00000000..5cef1b57 --- /dev/null +++ b/src/Knp/FriendlyExtension/DependencyInjection/Compiler/KernelPass.php @@ -0,0 +1,43 @@ +loadFileFromParameter($container, 'friendly.symfony_kernel.bootstrap'); + $this->loadFileFromParameter($container, 'friendly.symfony_kernel.path'); + + if (null !== $class = $this->getKernelClass($container)) { + $definition = new Definition($class); + $definition + ->addArgument($container->getParameter('friendly.symfony_kernel.env')) + ->addArgument($container->getParameter('friendly.symfony_kernel.debug')) + ; + $container->setDefinition('friendly.symfony.kernel', $definition); + } + } + + protected function loadFileFromParameter(ContainerBuilder $container, $parameter) + { + $base = $container->getParameter('paths.base'); + $param = $container->getParameter($parameter); + if (file_exists($file = $base.DIRECTORY_SEPARATOR.$param)) { + require_once($file); + } elseif (file_exists($param)) { + require_once($param); + } + } + + protected function getKernelClass(ContainerBuilder $container) + { + $class = $container->getParameter('friendly.symfony_kernel.class'); + + return class_exists($class) ? $class : null; + } +} diff --git a/src/Knp/FriendlyExtension/Resources/config/context.yml b/src/Knp/FriendlyExtension/Resources/config/context.yml index f6316490..3d96aa35 100644 --- a/src/Knp/FriendlyExtension/Resources/config/context.yml +++ b/src/Knp/FriendlyExtension/Resources/config/context.yml @@ -83,4 +83,14 @@ services: tags: - { name: friendly.context.helper } + friendly.context.helper.swiftmailer_helper: + class: Knp\FriendlyExtension\Context\Helper\SwiftMailerHelper + tags: + - { name: friendly.context.helper } + friendly.context.helper.profiler_helper: + class: Knp\FriendlyExtension\Context\Helper\ProfilerHelper + arguments: + - @profiler + tags: + - { name: friendly.context.helper } diff --git a/src/Knp/FriendlyExtension/Resources/config/symfony.yml b/src/Knp/FriendlyExtension/Resources/config/symfony.yml index 7caefb72..27f5f381 100755 --- a/src/Knp/FriendlyExtension/Resources/config/symfony.yml +++ b/src/Knp/FriendlyExtension/Resources/config/symfony.yml @@ -11,3 +11,14 @@ services: - { name: friendly.symfony.service, class: Doctrine\Common\Persistence\AbstractManagerRegistry } - { name: remove-when-missing, service: friendly.symfony.kernel } + mailer: + synthetic: true + tags: + - { name: friendly.symfony.service, class: Swift_Mailer } + - { name: remove-when-missing, service: friendly.symfony.kernel } + + profiler: + synthetic: true + tags: + - { name: friendly.symfony.service, class: Symfony\Component\HttpKernel\Profiler\Profiler } + - { name: remove-when-missing, service: friendly.symfony.kernel }