mirror of
https://github.com/silverstripe/silverstripe-behat-extension
synced 2024-10-22 17:05:32 +02:00
NEW Email testing
This commit is contained in:
parent
95b9408c86
commit
6c9be905f9
109
src/SilverStripe/BehatExtension/Context/EmailContext.php
Normal file
109
src/SilverStripe/BehatExtension/Context/EmailContext.php
Normal file
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\BehatExtension\Context;
|
||||
|
||||
use Behat\Behat\Context\ClosuredContextInterface,
|
||||
Behat\Behat\Context\TranslatedContextInterface,
|
||||
Behat\Behat\Context\BehatContext,
|
||||
Behat\Behat\Context\Step,
|
||||
Behat\Behat\Event\FeatureEvent,
|
||||
Behat\Behat\Event\ScenarioEvent,
|
||||
Behat\Behat\Exception\PendingException;
|
||||
use Behat\Gherkin\Node\PyStringNode,
|
||||
Behat\Gherkin\Node\TableNode;
|
||||
use Symfony\Component\DomCrawler\Crawler;
|
||||
|
||||
// PHPUnit
|
||||
require_once 'PHPUnit/Autoload.php';
|
||||
require_once 'PHPUnit/Framework/Assert/Functions.php';
|
||||
|
||||
/**
|
||||
* Context used to define steps related to email sending.
|
||||
*/
|
||||
class EmailContext extends BehatContext
|
||||
{
|
||||
protected $context;
|
||||
|
||||
protected $mailer;
|
||||
|
||||
/**
|
||||
* Initializes context.
|
||||
* Every scenario gets it's own context object.
|
||||
*
|
||||
* @param array $parameters context parameters (set them up through behat.yml)
|
||||
*/
|
||||
public function __construct(array $parameters)
|
||||
{
|
||||
// Initialize your context here
|
||||
$this->context = $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Mink session from MinkContext
|
||||
*/
|
||||
public function getSession($name = null)
|
||||
{
|
||||
return $this->getMainContext()->getSession($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @BeforeScenario
|
||||
*/
|
||||
public function before(ScenarioEvent $event)
|
||||
{
|
||||
// Also set through the 'supportbehat' extension
|
||||
// to ensure its available both in CLI execution and the tested browser session
|
||||
$this->mailer = new \SilverStripe\BehatExtension\Utility\TestMailer();
|
||||
\Email::set_mailer($this->mailer);
|
||||
\Email::send_all_emails_to(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^there should be an email (to|from) "([^"]*)"$/
|
||||
*/
|
||||
public function thereIsAnEmailFromTo($direction, $email)
|
||||
{
|
||||
$to = ($direction == 'to') ? $email : null;
|
||||
$from = ($direction == 'from') ? $email : null;
|
||||
$match = $this->mailer->findEmail($to, $from);
|
||||
assertNotNull($match);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^there should be an email (to|from) "([^"]*)" titled "([^"]*)"$/
|
||||
*/
|
||||
public function thereIsAnEmailFromToTitled($direction, $email, $subject)
|
||||
{
|
||||
$to = ($direction == 'to') ? $email : null;
|
||||
$from = ($direction == 'from') ? $email : null;
|
||||
$match = $this->mailer->findEmail($to, $from, $subject);
|
||||
assertNotNull($match);
|
||||
}
|
||||
|
||||
/**
|
||||
* @When /^I click on the \'([^\']*)\' link in the email (to|from) "([^"]*)"$/
|
||||
*/
|
||||
public function iGoToInTheEmailTo($linkSelector, $direction, $email)
|
||||
{
|
||||
$to = ($direction == 'to') ? $email : null;
|
||||
$from = ($direction == 'from') ? $email : null;
|
||||
$match = $this->mailer->findEmail($to, $from);
|
||||
assertNotNull($match);
|
||||
|
||||
$crawler = new Crawler($match['Content']);
|
||||
$linkEl = $crawler->filter($linkSelector);
|
||||
assertNotNull($linkEl);
|
||||
$link = $linkEl->attr('href');
|
||||
assertNotNull($link);
|
||||
|
||||
return new Step\When(sprintf('I go to "%s"', $link));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^I clear all emails$/
|
||||
*/
|
||||
public function iClearAllEmails()
|
||||
{
|
||||
return $this->mailer->clearEmails();
|
||||
}
|
||||
}
|
@ -160,6 +160,7 @@ class SilverStripeContext extends MinkContext implements SilverStripeAwareContex
|
||||
$url = $this->joinUrlParts($this->getBaseUrl(), '/dev/testsession/start');
|
||||
$params = array(
|
||||
'database' => $this->databaseName,
|
||||
'mailer' => 'SilverStripe\BehatExtension\Utility\TestMailer',
|
||||
);
|
||||
$url .= '?' . http_build_query($params);
|
||||
|
||||
|
136
src/SilverStripe/BehatExtension/Utility/TestMailer.php
Normal file
136
src/SilverStripe/BehatExtension/Utility/TestMailer.php
Normal file
@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\BehatExtension\Utility;
|
||||
|
||||
/**
|
||||
* Same principle as core TestMailer class,
|
||||
* but saves emails in the database instead in order
|
||||
* to share the state between PHP calls (CLI vs. browser).
|
||||
*/
|
||||
class TestMailer extends \Mailer {
|
||||
|
||||
protected $table = '_Behat_TestMailer';
|
||||
|
||||
/**
|
||||
* Send a plain-text email.
|
||||
* TestMailer will merely record that the email was asked to be sent, without sending anything.
|
||||
*/
|
||||
public function sendPlain($to, $from, $subject, $plainContent, $attachedFiles = false, $customHeaders = false) {
|
||||
$this->initTable();
|
||||
|
||||
$this->saveEmail(array(
|
||||
'Type' => 'plain',
|
||||
'To' => $to,
|
||||
'From' => $from,
|
||||
'Subject' => $subject,
|
||||
'Content' => $plainContent,
|
||||
'PlainContent' => $plainContent,
|
||||
'AttachedFiles' => implode(',', $attachedFiles),
|
||||
'CustomHeaders' => implode(',', $customHeaders),
|
||||
));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a multi-part HTML email
|
||||
* TestMailer will merely record that the email was asked to be sent, without sending anything.
|
||||
*/
|
||||
public function sendHTML($to, $from, $subject, $htmlContent, $attachedFiles = false, $customHeaders = false,
|
||||
$plainContent = false, $inlineImages = false) {
|
||||
|
||||
$this->initTable();
|
||||
|
||||
$this->saveEmail(array(
|
||||
'Type' => 'html',
|
||||
'To' => $to,
|
||||
'From' => $from,
|
||||
'Subject' => $subject,
|
||||
'Content' => $htmlContent,
|
||||
'PlainContent' => $plainContent,
|
||||
'AttachedFiles' => implode(',', $attachedFiles),
|
||||
'CustomHeaders' => implode(',', $customHeaders),
|
||||
));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the log of emails sent
|
||||
*/
|
||||
public function clearEmails() {
|
||||
$this->initTable();
|
||||
|
||||
$db = $this->getDb();
|
||||
$db->query(sprintf('TRUNCATE TABLE "%s"', $this->table));
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for an email that was sent.
|
||||
* All of the parameters can either be a string, or, if they start with "/", a PREG-compatible regular expression.
|
||||
* @param $to
|
||||
* @param $from
|
||||
* @param $subject
|
||||
* @param $content
|
||||
* @return array Contains the keys: 'type', 'to', 'from', 'subject', 'content', 'plainContent', 'attachedFiles',
|
||||
* 'customHeaders', 'htmlContent', 'inlineImages'
|
||||
*/
|
||||
public function findEmail($to = null, $from = null, $subject = null, $content = null) {
|
||||
$this->initTable();
|
||||
|
||||
$args = func_get_args();
|
||||
$db = $this->getDb();
|
||||
$emails = $db->query(sprintf('SELECT * FROM "%s"', $this->table));
|
||||
foreach($emails as $email) {
|
||||
$matched = true;
|
||||
|
||||
foreach(array('To','From','Subject','Content') as $i => $field) {
|
||||
$value = (isset($args[$i])) ? $args[$i] : null;
|
||||
if($value) {
|
||||
if($value[0] == '/') $matched = preg_match($value, $email[$field]);
|
||||
else $matched = ($value == $email[$field]);
|
||||
if(!$matched) break;
|
||||
}
|
||||
}
|
||||
if($matched) return $email;
|
||||
}
|
||||
}
|
||||
|
||||
protected function initTable() {
|
||||
$db = $this->getDb();
|
||||
if(!$db->hasTable($this->table)) {
|
||||
$db->beginSchemaUpdate();
|
||||
$db->requireTable($this->table, array(
|
||||
'Type' => 'Enum("plain,html")',
|
||||
'From' => 'Text',
|
||||
'To' => 'Text',
|
||||
'Subject' => 'Text',
|
||||
'Content' => 'Text',
|
||||
'PlainContent' => 'Text',
|
||||
'AttachedFiles' => 'Text',
|
||||
'CustomHeaders' => 'Text',
|
||||
));
|
||||
$db->endSchemaUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
protected function saveEmail($data) {
|
||||
$db = $this->getDb();
|
||||
$data = array_filter($data);
|
||||
$manipulation = array(
|
||||
$this->table => array(
|
||||
'command' => 'insert',
|
||||
'fields' => array()
|
||||
)
|
||||
);
|
||||
foreach($data as $k => $v) {
|
||||
$manipulation[$this->table]['fields'][$k] = $db->prepStringForDB($v);
|
||||
}
|
||||
$db->manipulate($manipulation);
|
||||
}
|
||||
|
||||
protected function getDb() {
|
||||
return \DB::getConn();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user