From bcfeb30f1544e42f6e11898ca6690d35443e85bb Mon Sep 17 00:00:00 2001 From: "Christopher O. Caldwell" Date: Tue, 9 Jul 2024 17:36:03 -0600 Subject: [PATCH] Add ability to check for expected email attachments gh-672 --- .../DrupalExtension/Context/MailContext.php | 35 +++++++++++++------ .../Context/RawMailContext.php | 26 ++++++++++---- 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/Drupal/DrupalExtension/Context/MailContext.php b/src/Drupal/DrupalExtension/Context/MailContext.php index 4be77f1d..756a3375 100644 --- a/src/Drupal/DrupalExtension/Context/MailContext.php +++ b/src/Drupal/DrupalExtension/Context/MailContext.php @@ -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); } @@ -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); } @@ -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; @@ -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; @@ -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.'); } diff --git a/src/Drupal/DrupalExtension/Context/RawMailContext.php b/src/Drupal/DrupalExtension/Context/RawMailContext.php index 348b9d67..9242c195 100644 --- a/src/Drupal/DrupalExtension/Context/RawMailContext.php +++ b/src/Drupal/DrupalExtension/Context/RawMailContext.php @@ -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); @@ -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. @@ -104,14 +106,18 @@ 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. @@ -119,6 +125,14 @@ protected function matchesMail($mail = [], $matches = []) 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; } @@ -183,7 +197,7 @@ protected function assertMailCount($actualMail, $expectedCount = null) } } } - + /** * Sort mail by to, subject and body. *