2012-12-19 15:56:20 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace SilverStripe\BehatExtension\Context;
|
|
|
|
|
2014-08-02 08:30:27 +02:00
|
|
|
use Behat\Behat\Context\Context;
|
|
|
|
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
|
2016-08-10 03:35:13 +02:00
|
|
|
use Behat\Gherkin\Node\TableNode;
|
2016-09-01 06:22:47 +02:00
|
|
|
use Behat\Mink\Session;
|
2021-10-27 06:14:44 +02:00
|
|
|
use PHPUnit\Framework\Assert;
|
2016-09-01 06:22:47 +02:00
|
|
|
use SilverStripe\BehatExtension\Utility\TestMailer;
|
|
|
|
use SilverStripe\Control\Email\Email;
|
2014-08-02 08:30:27 +02:00
|
|
|
use SilverStripe\Control\Email\Mailer;
|
2016-09-01 06:22:47 +02:00
|
|
|
use SilverStripe\Core\Injector\Injector;
|
2012-12-19 15:56:20 +01:00
|
|
|
use Symfony\Component\DomCrawler\Crawler;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Context used to define steps related to email sending.
|
|
|
|
*/
|
2014-08-02 08:30:27 +02:00
|
|
|
class EmailContext implements Context
|
2012-12-19 15:56:20 +01:00
|
|
|
{
|
2014-08-02 08:30:27 +02:00
|
|
|
use MainContextAwareTrait;
|
2012-12-19 15:56:20 +01:00
|
|
|
|
2016-09-01 06:22:47 +02:00
|
|
|
/**
|
|
|
|
* @var TestMailer
|
|
|
|
*/
|
2012-12-19 15:56:20 +01:00
|
|
|
protected $mailer;
|
|
|
|
|
2013-12-13 17:52:42 +01:00
|
|
|
/**
|
|
|
|
* Stored to simplify later assertions
|
|
|
|
*/
|
|
|
|
protected $lastMatchedEmail;
|
|
|
|
|
2012-12-19 15:56:20 +01:00
|
|
|
/**
|
|
|
|
* Get Mink session from MinkContext
|
2016-09-01 06:22:47 +02:00
|
|
|
*
|
|
|
|
* @param string $name
|
|
|
|
* @return Session
|
2012-12-19 15:56:20 +01:00
|
|
|
*/
|
|
|
|
public function getSession($name = null)
|
|
|
|
{
|
|
|
|
return $this->getMainContext()->getSession($name);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @BeforeScenario
|
2014-08-02 08:30:27 +02:00
|
|
|
* @param BeforeScenarioScope $event
|
2012-12-19 15:56:20 +01:00
|
|
|
*/
|
2014-08-02 08:30:27 +02:00
|
|
|
public function before(BeforeScenarioScope $event)
|
2012-12-19 15:56:20 +01:00
|
|
|
{
|
|
|
|
// Also set through the 'supportbehat' extension
|
|
|
|
// to ensure its available both in CLI execution and the tested browser session
|
2016-09-01 06:22:47 +02:00
|
|
|
$this->mailer = new TestMailer();
|
2014-08-02 08:30:27 +02:00
|
|
|
Injector::inst()->registerService($this->mailer, Mailer::class);
|
2016-09-01 06:22:47 +02:00
|
|
|
Email::config()->update("send_all_emails_to", null);
|
2022-03-22 01:02:06 +01:00
|
|
|
Email::config()->update('admin_email', 'no-reply@example.com');
|
2012-12-19 15:56:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-02-26 01:55:37 +01:00
|
|
|
* @Given /^there should (not |)be an email (to|from) "([^"]*)"$/
|
2014-08-02 08:30:27 +02:00
|
|
|
* @param string $negate
|
|
|
|
* @param string $direction
|
|
|
|
* @param string $email
|
2012-12-19 15:56:20 +01:00
|
|
|
*/
|
2014-02-26 01:55:37 +01:00
|
|
|
public function thereIsAnEmailFromTo($negate, $direction, $email)
|
2012-12-19 15:56:20 +01:00
|
|
|
{
|
|
|
|
$to = ($direction == 'to') ? $email : null;
|
|
|
|
$from = ($direction == 'from') ? $email : null;
|
|
|
|
$match = $this->mailer->findEmail($to, $from);
|
2016-08-10 03:35:13 +02:00
|
|
|
if (trim($negate)) {
|
2021-10-27 06:14:44 +02:00
|
|
|
Assert::assertNull($match);
|
2014-02-26 01:55:37 +01:00
|
|
|
} else {
|
2021-10-27 06:14:44 +02:00
|
|
|
Assert::assertNotNull($match);
|
2014-02-26 01:55:37 +01:00
|
|
|
}
|
2013-12-13 17:52:42 +01:00
|
|
|
$this->lastMatchedEmail = $match;
|
2012-12-19 15:56:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-02-26 01:55:37 +01:00
|
|
|
* @Given /^there should (not |)be an email (to|from) "([^"]*)" titled "([^"]*)"$/
|
2014-08-02 08:30:27 +02:00
|
|
|
* @param string $negate
|
|
|
|
* @param string $direction
|
|
|
|
* @param string $email
|
|
|
|
* @param string $subject
|
2012-12-19 15:56:20 +01:00
|
|
|
*/
|
2014-02-26 01:55:37 +01:00
|
|
|
public function thereIsAnEmailFromToTitled($negate, $direction, $email, $subject)
|
2012-12-19 15:56:20 +01:00
|
|
|
{
|
|
|
|
$to = ($direction == 'to') ? $email : null;
|
|
|
|
$from = ($direction == 'from') ? $email : null;
|
|
|
|
$match = $this->mailer->findEmail($to, $from, $subject);
|
2014-02-27 11:02:43 +01:00
|
|
|
$allMails = $this->mailer->findEmails($to, $from);
|
2016-08-10 03:35:13 +02:00
|
|
|
$allTitles = $allMails ? '"' . implode('","', array_map(function ($email) {
|
|
|
|
return $email->Subject;
|
|
|
|
}, $allMails)) . '"' : null;
|
|
|
|
if (trim($negate)) {
|
2021-10-27 06:14:44 +02:00
|
|
|
Assert::assertNull($match);
|
2014-02-26 01:55:37 +01:00
|
|
|
} else {
|
2014-02-27 11:02:43 +01:00
|
|
|
$msg = sprintf(
|
|
|
|
'Could not find email %s "%s" titled "%s".',
|
|
|
|
$direction,
|
|
|
|
$email,
|
|
|
|
$subject
|
|
|
|
);
|
2016-08-10 03:35:13 +02:00
|
|
|
if ($allTitles) {
|
2014-02-27 11:02:43 +01:00
|
|
|
$msg .= ' Existing emails: ' . $allTitles;
|
|
|
|
}
|
2021-10-27 06:14:44 +02:00
|
|
|
Assert::assertNotNull($match, $msg);
|
2014-02-26 01:55:37 +01:00
|
|
|
}
|
2013-12-13 17:52:42 +01:00
|
|
|
$this->lastMatchedEmail = $match;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-11-13 23:47:17 +01:00
|
|
|
* Example: Given the email should contain "Thank you for registering!".
|
2013-12-13 17:52:42 +01:00
|
|
|
* Assumes an email has been identified by a previous step,
|
|
|
|
* e.g. through 'Given there should be an email to "test@test.com"'.
|
2016-08-10 03:35:13 +02:00
|
|
|
*
|
|
|
|
* @Given /^the email should (not |)contain "([^"]*)"$/
|
2014-08-02 08:30:27 +02:00
|
|
|
* @param string $negate
|
|
|
|
* @param string $content
|
2016-08-10 03:35:13 +02:00
|
|
|
*/
|
|
|
|
public function thereTheEmailContains($negate, $content)
|
|
|
|
{
|
|
|
|
if (!$this->lastMatchedEmail) {
|
|
|
|
throw new \LogicException('No matched email found from previous step');
|
|
|
|
}
|
2014-11-13 23:47:17 +01:00
|
|
|
|
2016-08-10 03:35:13 +02:00
|
|
|
$email = $this->lastMatchedEmail;
|
|
|
|
$emailContent = null;
|
|
|
|
if ($email->Content) {
|
|
|
|
$emailContent = $email->Content;
|
|
|
|
} else {
|
|
|
|
$emailContent = $email->PlainContent;
|
|
|
|
}
|
2014-11-13 23:47:17 +01:00
|
|
|
|
2016-08-10 03:35:13 +02:00
|
|
|
if (trim($negate)) {
|
2021-11-07 22:28:45 +01:00
|
|
|
Assert::assertStringNotContainsString($content, $emailContent);
|
2016-08-10 03:35:13 +02:00
|
|
|
} else {
|
2021-11-07 22:28:45 +01:00
|
|
|
Assert::assertStringContainsString($content, $emailContent);
|
2016-08-10 03:35:13 +02:00
|
|
|
}
|
|
|
|
}
|
2012-12-19 15:56:20 +01:00
|
|
|
|
2016-08-10 03:35:13 +02:00
|
|
|
/**
|
|
|
|
* Example: Given the email contains "Thank you for <strong>registering!<strong>".
|
|
|
|
* Then the email should contain plain text "Thank you for registering!"
|
|
|
|
* Assumes an email has been identified by a previous step,
|
|
|
|
* e.g. through 'Given there should be an email to "test@test.com"'.
|
|
|
|
*
|
|
|
|
* @Given /^the email should contain plain text "([^"]*)"$/
|
2014-08-02 08:30:27 +02:00
|
|
|
* @param string $content
|
2016-08-10 03:35:13 +02:00
|
|
|
*/
|
|
|
|
public function thereTheEmailContainsPlainText($content)
|
|
|
|
{
|
|
|
|
if (!$this->lastMatchedEmail) {
|
|
|
|
throw new \LogicException('No matched email found from previous step');
|
|
|
|
}
|
2015-07-02 04:12:10 +02:00
|
|
|
|
2016-08-10 03:35:13 +02:00
|
|
|
$email = $this->lastMatchedEmail;
|
|
|
|
$emailContent = ($email->Content) ? ($email->Content) : ($email->PlainContent);
|
|
|
|
$emailPlainText = strip_tags($emailContent);
|
|
|
|
$emailPlainText = preg_replace("/\h+/", " ", $emailPlainText);
|
2015-07-02 04:12:10 +02:00
|
|
|
|
2021-11-07 22:28:45 +01:00
|
|
|
Assert::assertStringContainsString($content, $emailPlainText);
|
2016-08-10 03:35:13 +02:00
|
|
|
}
|
2015-07-02 04:12:10 +02:00
|
|
|
|
2012-12-19 15:56:20 +01:00
|
|
|
/**
|
2013-10-22 00:04:15 +02:00
|
|
|
* @When /^I click on the "([^"]*)" link in the email (to|from) "([^"]*)"$/
|
2014-08-02 08:30:27 +02:00
|
|
|
* @param string $linkSelector
|
|
|
|
* @param string $direction
|
|
|
|
* @param string $email
|
2012-12-19 15:56:20 +01:00
|
|
|
*/
|
|
|
|
public function iGoToInTheEmailTo($linkSelector, $direction, $email)
|
|
|
|
{
|
|
|
|
$to = ($direction == 'to') ? $email : null;
|
|
|
|
$from = ($direction == 'from') ? $email : null;
|
|
|
|
$match = $this->mailer->findEmail($to, $from);
|
2021-10-27 06:14:44 +02:00
|
|
|
Assert::assertNotNull($match);
|
2012-12-19 15:56:20 +01:00
|
|
|
|
2014-03-01 06:26:21 +01:00
|
|
|
$crawler = new Crawler($match->Content);
|
2013-10-22 00:04:15 +02:00
|
|
|
$linkEl = $crawler->selectLink($linkSelector);
|
2021-10-27 06:14:44 +02:00
|
|
|
Assert::assertNotNull($linkEl);
|
2012-12-19 15:56:20 +01:00
|
|
|
$link = $linkEl->attr('href');
|
2021-10-27 06:14:44 +02:00
|
|
|
Assert::assertNotNull($link);
|
2016-09-01 06:22:47 +02:00
|
|
|
|
2014-08-02 08:30:27 +02:00
|
|
|
$this->getMainContext()->visit($link);
|
2012-12-19 15:56:20 +01:00
|
|
|
}
|
|
|
|
|
2014-05-01 00:28:20 +02:00
|
|
|
/**
|
|
|
|
* @When /^I click on the "([^"]*)" link in the email (to|from) "([^"]*)" titled "([^"]*)"$/
|
2014-08-02 08:30:27 +02:00
|
|
|
* @param string $linkSelector
|
|
|
|
* @param string $direction
|
|
|
|
* @param string $email
|
|
|
|
* @param string $title
|
2014-05-01 00:28:20 +02:00
|
|
|
*/
|
|
|
|
public function iGoToInTheEmailToTitled($linkSelector, $direction, $email, $title)
|
|
|
|
{
|
|
|
|
$to = ($direction == 'to') ? $email : null;
|
|
|
|
$from = ($direction == 'from') ? $email : null;
|
|
|
|
$match = $this->mailer->findEmail($to, $from, $title);
|
2021-10-27 06:14:44 +02:00
|
|
|
Assert::assertNotNull($match);
|
2014-05-01 00:28:20 +02:00
|
|
|
|
|
|
|
$crawler = new Crawler($match->Content);
|
|
|
|
$linkEl = $crawler->selectLink($linkSelector);
|
2021-10-27 06:14:44 +02:00
|
|
|
Assert::assertNotNull($linkEl);
|
2014-05-01 00:28:20 +02:00
|
|
|
$link = $linkEl->attr('href');
|
2021-10-27 06:14:44 +02:00
|
|
|
Assert::assertNotNull($link);
|
2014-08-02 08:30:27 +02:00
|
|
|
$this->getMainContext()->visit($link);
|
2014-05-01 00:28:20 +02:00
|
|
|
}
|
2016-09-01 06:22:47 +02:00
|
|
|
|
2013-12-13 17:52:42 +01:00
|
|
|
/**
|
|
|
|
* Assumes an email has been identified by a previous step,
|
|
|
|
* e.g. through 'Given there should be an email to "test@test.com"'.
|
2016-08-10 03:35:13 +02:00
|
|
|
*
|
2013-12-13 17:52:42 +01:00
|
|
|
* @When /^I click on the "([^"]*)" link in the email"$/
|
2014-08-02 08:30:27 +02:00
|
|
|
* @param string $linkSelector
|
2013-12-13 17:52:42 +01:00
|
|
|
*/
|
|
|
|
public function iGoToInTheEmail($linkSelector)
|
|
|
|
{
|
2016-08-10 03:35:13 +02:00
|
|
|
if (!$this->lastMatchedEmail) {
|
2013-12-13 17:52:42 +01:00
|
|
|
throw new \LogicException('No matched email found from previous step');
|
|
|
|
}
|
|
|
|
|
|
|
|
$match = $this->lastMatchedEmail;
|
2014-03-01 06:26:21 +01:00
|
|
|
$crawler = new Crawler($match->Content);
|
2013-12-13 17:52:42 +01:00
|
|
|
$linkEl = $crawler->selectLink($linkSelector);
|
2021-10-27 06:14:44 +02:00
|
|
|
Assert::assertNotNull($linkEl);
|
2013-12-13 17:52:42 +01:00
|
|
|
$link = $linkEl->attr('href');
|
2021-10-27 06:14:44 +02:00
|
|
|
Assert::assertNotNull($link);
|
2013-12-13 17:52:42 +01:00
|
|
|
|
2014-08-02 08:30:27 +02:00
|
|
|
$this->getMainContext()->visit($link);
|
2013-12-13 17:52:42 +01:00
|
|
|
}
|
|
|
|
|
2012-12-19 15:56:20 +01:00
|
|
|
/**
|
|
|
|
* @Given /^I clear all emails$/
|
|
|
|
*/
|
|
|
|
public function iClearAllEmails()
|
|
|
|
{
|
2013-12-13 17:52:42 +01:00
|
|
|
$this->lastMatchedEmail = null;
|
2014-08-02 08:30:27 +02:00
|
|
|
$this->mailer->clearEmails();
|
2012-12-19 15:56:20 +01:00
|
|
|
}
|
2014-11-13 23:47:17 +01:00
|
|
|
|
2016-08-10 03:35:13 +02:00
|
|
|
/**
|
|
|
|
* Example: Then the email should contain the following data:
|
|
|
|
* | row1 |
|
|
|
|
* | row2 |
|
|
|
|
* Assumes an email has been identified by a previous step.
|
|
|
|
* @Then /^the email should (not |)contain the following data:$/
|
2014-08-02 08:30:27 +02:00
|
|
|
* @param string $negate
|
|
|
|
* @param TableNode $table
|
2016-08-10 03:35:13 +02:00
|
|
|
*/
|
|
|
|
public function theEmailContainFollowingData($negate, TableNode $table)
|
|
|
|
{
|
|
|
|
if (!$this->lastMatchedEmail) {
|
|
|
|
throw new \LogicException('No matched email found from previous step');
|
|
|
|
}
|
2014-11-13 23:47:17 +01:00
|
|
|
|
2016-08-10 03:35:13 +02:00
|
|
|
$email = $this->lastMatchedEmail;
|
|
|
|
$emailContent = null;
|
|
|
|
if ($email->Content) {
|
|
|
|
$emailContent = $email->Content;
|
|
|
|
} else {
|
|
|
|
$emailContent = $email->PlainContent;
|
|
|
|
}
|
|
|
|
// Convert html content to plain text
|
|
|
|
$emailContent = strip_tags($emailContent);
|
|
|
|
$emailContent = preg_replace("/\h+/", " ", $emailContent);
|
|
|
|
$rows = $table->getRows();
|
2016-09-01 06:22:47 +02:00
|
|
|
|
2016-08-10 03:35:13 +02:00
|
|
|
// For "should not contain"
|
|
|
|
if (trim($negate)) {
|
|
|
|
foreach ($rows as $row) {
|
2021-11-07 22:28:45 +01:00
|
|
|
Assert::assertStringNotContainsString($row[0], $emailContent);
|
2016-08-10 03:35:13 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
foreach ($rows as $row) {
|
2021-11-07 22:28:45 +01:00
|
|
|
Assert::assertStringContainsString($row[0], $emailContent);
|
2016-08-10 03:35:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-07-21 06:27:09 +02:00
|
|
|
|
2016-08-10 03:35:13 +02:00
|
|
|
/**
|
|
|
|
* @Then /^there should (not |)be an email titled "([^"]*)"$/
|
2014-08-02 08:30:27 +02:00
|
|
|
* @param string $negate
|
|
|
|
* @param string $subject
|
2016-08-10 03:35:13 +02:00
|
|
|
*/
|
|
|
|
public function thereIsAnEmailTitled($negate, $subject)
|
|
|
|
{
|
|
|
|
$match = $this->mailer->findEmail(null, null, $subject);
|
|
|
|
if (trim($negate)) {
|
2021-10-27 06:14:44 +02:00
|
|
|
Assert::assertNull($match);
|
2016-08-10 03:35:13 +02:00
|
|
|
} else {
|
|
|
|
$msg = sprintf(
|
|
|
|
'Could not find email titled "%s".',
|
|
|
|
$subject
|
|
|
|
);
|
2021-10-27 06:14:44 +02:00
|
|
|
Assert::assertNotNull($match, $msg);
|
2016-08-10 03:35:13 +02:00
|
|
|
}
|
|
|
|
$this->lastMatchedEmail = $match;
|
|
|
|
}
|
2015-07-21 06:27:09 +02:00
|
|
|
|
2016-08-10 03:35:13 +02:00
|
|
|
/**
|
|
|
|
* @Then /^the email should (not |)be sent from "([^"]*)"$/
|
2014-08-02 08:30:27 +02:00
|
|
|
* @param string $negate
|
|
|
|
* @param string $from
|
2016-08-10 03:35:13 +02:00
|
|
|
*/
|
|
|
|
public function theEmailSentFrom($negate, $from)
|
|
|
|
{
|
|
|
|
if (!$this->lastMatchedEmail) {
|
|
|
|
throw new \LogicException('No matched email found from previous step');
|
|
|
|
}
|
2015-07-21 06:27:09 +02:00
|
|
|
|
2016-08-10 03:35:13 +02:00
|
|
|
$match = $this->lastMatchedEmail;
|
|
|
|
if (trim($negate)) {
|
2021-11-07 22:28:45 +01:00
|
|
|
Assert::assertStringNotContainsString($from, $match->From);
|
2016-08-10 03:35:13 +02:00
|
|
|
} else {
|
2021-11-07 22:28:45 +01:00
|
|
|
Assert::assertStringContainsString($from, $match->From);
|
2016-08-10 03:35:13 +02:00
|
|
|
}
|
|
|
|
}
|
2015-07-21 06:27:09 +02:00
|
|
|
|
2016-08-10 03:35:13 +02:00
|
|
|
/**
|
|
|
|
* @Then /^the email should (not |)be sent to "([^"]*)"$/
|
2014-08-02 08:30:27 +02:00
|
|
|
* @param string $negate
|
|
|
|
* @param string $to
|
2016-08-10 03:35:13 +02:00
|
|
|
*/
|
|
|
|
public function theEmailSentTo($negate, $to)
|
|
|
|
{
|
|
|
|
if (!$this->lastMatchedEmail) {
|
|
|
|
throw new \LogicException('No matched email found from previous step');
|
|
|
|
}
|
2015-07-21 06:27:09 +02:00
|
|
|
|
2016-08-10 03:35:13 +02:00
|
|
|
$match = $this->lastMatchedEmail;
|
|
|
|
if (trim($negate)) {
|
2021-11-07 22:28:45 +01:00
|
|
|
Assert::assertStringNotContainsString($to, $match->To);
|
2016-08-10 03:35:13 +02:00
|
|
|
} else {
|
2021-11-07 22:28:45 +01:00
|
|
|
Assert::assertStringContainsString($to, $match->To);
|
2016-08-10 03:35:13 +02:00
|
|
|
}
|
|
|
|
}
|
2016-08-18 23:20:05 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The link text is the link address itself which contains special characters
|
|
|
|
* e.g. http://localhost/Security/changepassword?m=199&title=reset
|
|
|
|
* Example: When I click on the http link "changepassword" in the email
|
|
|
|
* @When /^I click on the http link "([^"]*)" in the email$/
|
2014-08-02 08:30:27 +02:00
|
|
|
* @param string $httpText
|
2016-08-18 23:20:05 +02:00
|
|
|
*/
|
|
|
|
public function iClickOnHttpLinkInEmail($httpText)
|
|
|
|
{
|
|
|
|
if (!$this->lastMatchedEmail) {
|
|
|
|
throw new \LogicException('No matched email found from previous step');
|
|
|
|
}
|
|
|
|
|
|
|
|
$email = $this->lastMatchedEmail;
|
|
|
|
$html = $email->Content;
|
|
|
|
$dom = new \DOMDocument();
|
|
|
|
$dom->loadHTML($html);
|
|
|
|
|
|
|
|
$tags = $dom->getElementsByTagName('a');
|
|
|
|
$href = null;
|
|
|
|
foreach ($tags as $tag) {
|
|
|
|
$linkText = $tag->nodeValue;
|
|
|
|
if (strpos($linkText, $httpText) !== false) {
|
|
|
|
$href = $linkText;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2021-10-27 06:14:44 +02:00
|
|
|
Assert::assertNotNull($href);
|
2016-08-18 23:20:05 +02:00
|
|
|
|
2014-08-02 08:30:27 +02:00
|
|
|
$this->getMainContext()->visit($href);
|
2016-08-18 23:20:05 +02:00
|
|
|
}
|
2012-12-19 15:56:20 +01:00
|
|
|
}
|