Skip to content

Commit

Permalink
Add ability to check for expected email attachments
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisolof committed Jul 9, 2024
1 parent 22d69d8 commit bcfeb30
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 16 deletions.
35 changes: 25 additions & 10 deletions src/Drupal/DrupalExtension/Context/MailContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,14 @@ public function drupalSendsMail(TableNode $fields)
* @Then (a )(an )(e)mail(s) has/have been sent to :to:
* @Then (a )(an )(e)mail(s) has/have been sent with the subject :subject:
* @Then (a )(an )(e)mail(s) has/have been sent to :to with the subject :subject:
* @Then (a )(an )(e)mail(s) has/have been sent with the attachment(s) :attachments:
* @Then (a )(an )(e)mail(s) has/have been sent to :to with the attachment(s) :attachments:
* @Then (a )(an )(e)mail(s) has/have been sent to :to with the subject :subject and the attachment(s) :attachments:
*/
public function mailHasBeenSent(TableNode $expectedMailTable, $to = '', $subject = '')
public function mailHasBeenSent(TableNode $expectedMailTable, $to = '', $subject = '', $attachments = '')
{
$expectedMail = $expectedMailTable->getHash();
$actualMail = $this->getMail(['to' => $to, 'subject' => $subject], false);
$actualMail = $this->getMail(['to' => $to, 'subject' => $subject], false, null, null, explode(',', $attachments));
$this->compareMail($actualMail, $expectedMail);
}

Expand All @@ -102,11 +105,14 @@ public function mailHasBeenSent(TableNode $expectedMailTable, $to = '', $subject
* @Then (a )(an )new (e)mail(s) is/are sent to :to:
* @Then (a )(an )new (e)mail(s) is/are sent with the subject :subject:
* @Then (a )(an )new (e)mail(s) is/are sent to :to with the subject :subject:
* @Then (a )(an )new (e)mail(s) is/are sent with the attachment(s) :attachments:
* @Then (a )(an )new (e)mail(s) is/are sent to :to with the attachment(s) :attachments:
* @Then (a )(an )new (e)mail(s) is/are sent to :to with the subject :subject and the attachment(s) :attachments:
*/
public function newMailIsSent(TableNode $expectedMailTable, $to = '', $subject = '')
public function newMailIsSent(TableNode $expectedMailTable, $to = '', $subject = '', $attachments = '')
{
$expectedMail = $expectedMailTable->getHash();
$actualMail = $this->getMail(['to' => $to, 'subject' => $subject], true);
$actualMail = $this->getMail(['to' => $to, 'subject' => $subject], true, null, null, explode(',', $attachments));
$this->compareMail($actualMail, $expectedMail);
}

Expand All @@ -117,10 +123,13 @@ public function newMailIsSent(TableNode $expectedMailTable, $to = '', $subject =
* @Then :count (e)mail(s) has/have been sent to :to
* @Then :count (e)mail(s) has/have been sent with the subject :subject
* @Then :count (e)mail(s) has/have been sent to :to with the subject :subject
* @Then :count (e)mail(s) has/have been sent with the attachment(s) :attachments
* @Then :count (e)mail(s) has/have been sent to :to with the attachment(s) :attachments
* @Then :count (e)mail(s) has/have been sent to :to with the subject :subject and the attachment(s) :attachments
*/
public function noMailHasBeenSent($count, $to = '', $subject = '')
public function noMailHasBeenSent($count, $to = '', $subject = '', $attachments = '')
{
$actualMail = $this->getMail(['to' => $to, 'subject' => $subject], false);
$actualMail = $this->getMail(['to' => $to, 'subject' => $subject], false, null, null, explode(',', $attachments));
$count = $count === 'no' ? 0 : $count;
$count = $count === 'a' ? null : $count;
$count = $count === 'an' ? null : $count;
Expand All @@ -134,10 +143,13 @@ public function noMailHasBeenSent($count, $to = '', $subject = '')
* @Then :count new (e)mail(s) is/are sent to :to
* @Then :count new (e)mail(s) is/are sent with the subject :subject
* @Then :count new (e)mail(s) is/are sent to :to with the subject :subject
* @Then :count new (e)mail(s) is/are sent with the attachment(s) :attachments
* @Then :count new (e)mail(s) is/are sent to :to with the attachment(s) :attachments
* @Then :count new (e)mail(s) is/are sent to :to with the subject :subject and the attachment(s) :attachments
*/
public function noNewMailIsSent($count, $to = '', $subject = '')
public function noNewMailIsSent($count, $to = '', $subject = '', $attachments = '')
{
$actualMail = $this->getMail(['to' => $to, 'subject' => $subject], true);
$actualMail = $this->getMail(['to' => $to, 'subject' => $subject], true, null, null, explode(',', $attachments));
$count = $count === 'no' ? 0 : $count;
$count = $count === 'a' ? 1 : $count;
$count = $count === 'an' ? 1 : $count;
Expand All @@ -149,12 +161,15 @@ public function noNewMailIsSent($count, $to = '', $subject = '')
* @When I follow the link to :urlFragment from the (e)mail to :to
* @When I follow the link to :urlFragment from the (e)mail with the subject :subject
* @When I follow the link to :urlFragment from the (e)mail to :to with the subject :subject
* @When I follow the link to :urlFragment from the (e)mail with the attachment(s) :attachments
* @When I follow the link to :urlFragment from the (e)mail to :to with the attachment(s) :attachments
* @When I follow the link to :urlFragment from the (e)mail to :to with the subject :subject and the attachment(s) :attachments
*/
public function followLinkInMail($urlFragment, $to = '', $subject = '')
public function followLinkInMail($urlFragment, $to = '', $subject = '', $attachments = '')
{
// Get the mail
$matches = ['to' => $to, 'subject' => $subject];
$mail = $this->getMail($matches, false, -1);
$mail = $this->getMail($matches, false, -1, null, explode(',', $attachments));
if (count($mail) == 0) {
throw new \Exception('No such mail found.');
}
Expand Down
26 changes: 20 additions & 6 deletions src/Drupal/DrupalExtension/Context/RawMailContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,14 @@ protected function getMailManager()
* A particular mail to return, e.g. 0 for first or -1 for last.
* @param string $store
* The name of the mail store to get mail from.
* @param array $attachments
* An array of attachments (filenames) the mail must contain.
*
* @return \stdClass[]
* An array of mail, each formatted as a Drupal 8
* \Drupal\Core\Mail\MailInterface::mail $message array.
*/
protected function getMail($matches = [], $new = false, $index = null, $store = 'default')
protected function getMail($matches = [], $new = false, $index = null, $store = 'default', array $attachments = [])
{
$mail = $this->getMailManager()->getMail($store);
$previousMailCount = $this->getMailCount($store);
Expand All @@ -69,8 +71,8 @@ protected function getMail($matches = [], $new = false, $index = null, $store =

// Filter mail based on $matches; keep only mail where each field mentioned
// in $matches contains the value specified for that field.
$mail = array_values(array_filter($mail, function ($singleMail) use ($matches) {
return ($this->matchesMail($singleMail, $matches));
$mail = array_values(array_filter($mail, function ($singleMail) use ($matches, $attachments) {
return ($this->matchesMail($singleMail, $matches, $attachments));
}));

// Return an individual mail if specified by an index.
Expand Down Expand Up @@ -104,21 +106,33 @@ protected function getMailCount($store)
* The mail, as an array of mail fields.
* @param array $matches
* The criteria: an associative array of mail fields and desired values.
* @param array $attachments
* An array of attachments (filenames) the mail must contain.
*
* @return bool
* Whether the mail matches the criteria.
*/
protected function matchesMail($mail = [], $matches = [])
protected function matchesMail($mail = [], $matches = [], array $attachments = [])
{
// Discard criteria that are just zero-length strings.
// Discard criteria or attachments that are just zero-length strings.
$matches = array_filter($matches, 'strlen');
$attachments = array_filter($attachments, 'strlen');

// For each criteria, check the specified mail field contains the value.
foreach ($matches as $field => $value) {
// Case insensitive.
if (stripos($mail[$field], $value) === false) {
return false;
}
}

// Check that the mail contains each specified attachment .
foreach ($attachments as $attachment) {
if (!isset($mail['params']['attachments']) || !in_array($attachment, array_column($mail['params']['attachments'], 'filename'))) {
return false;
}
}

return true;
}

Expand Down Expand Up @@ -183,7 +197,7 @@ protected function assertMailCount($actualMail, $expectedCount = null)
}
}
}

/**
* Sort mail by to, subject and body.
*
Expand Down

0 comments on commit bcfeb30

Please sign in to comment.