Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flexible matching for eg SubjectSpecification #53

Open
xurizaemon opened this issue Jun 19, 2021 · 1 comment
Open

Flexible matching for eg SubjectSpecification #53

xurizaemon opened this issue Jun 19, 2021 · 1 comment

Comments

@xurizaemon
Copy link

xurizaemon commented Jun 19, 2021

I have a site which sends emails with subject like "Your order 123 is confirmed" and would like to test for presence of the order confirmation email using rpkamp/mailhog-behat-extension; in order to simplify tests, I'd like to use a loose match such as "Your order * is confirmed".

Current behaviour for the following appears to be:

Then I should see an email with subject "subject" and body "body" to "recipient@domain.example"
  • subject match is exact (===)
  • body match uses strpos to test for string presence
  • recipient match is any (contains)

I see that matching implementations vary:

public function isSatisfiedBy(Message $message): bool
{
return $message->subject === $this->subject;
}

public function isSatisfiedBy(Message $message): bool
{
return $message->sender->equals($this->sender);
}

public function isSatisfiedBy(Message $message): bool
{
return false !== strpos($message->body, $this->snippet);
}

public function isSatisfiedBy(Message $message): bool
{
return $message->recipients->contains($this->recipient);
}

public function isSatisfiedBy(Message $message): bool
{
foreach ($message->attachments as $attachment) {
if ($attachment->filename === $this->filename) {
return true;
}
}
return false;
}

One approach would be that the looser specification apply (eg subject, recipient, body all are "contains" type implementations). Alternatively we could introduce a way to flag specification matches for the new looser behaviour, to preserve BC better.

I've opened this in rpkamp/mailhog-client as I believe that's the right place for it, but let me know if I'm missing a trick over in rpkamp/mailhog-behat-extension!

@xurizaemon xurizaemon changed the title Regex or looser matching for eg SubjectSpecification Flexible matching for eg SubjectSpecification Jun 19, 2021
@rpkamp
Copy link
Owner

rpkamp commented Jun 20, 2021

That's a good point and something to be expanded upon in the future! I don't want to add that now in haste, but rather chew on it a bit to get it right.

In the meantime you could quite easily add your own Specification and Behat Context.

SubjectMatchesSpecification

final class SubjectMatchesSpecification implements Specification
{
   /**
    * @var string
    */
    private $regex;
      
    public function __construct(string $regex)
    {
        $this->regex = $regex;
    }
    
    public function isSatisfiedBy(Message $message): bool
    {
        return preg_match($this->regex, $message->subject);
     }
}

MessageMatchingContext.php

<?php
declare(strict_types=1);

use rpkamp\Mailhog\MailhogClient;
use rpkamp\Behat\MailhogExtension\Context\MailhogAwareContext;

class FeatureContext implements MailhogAwareContext
{
    private $mailhog;
    
    public function setMailhog(MailhogClient $client)
    {
         $this->mailhog = $client;
    }

    /**
     * @Then /^I should see an email where subject matches "([^"]+)"$/
     */
    public function iShouldSeeAnEmailWhereSubjectMatches(string $regex): void
    {
        $messages = $this->mailhogClient->findMessagesSatisfying(new SubjectMatchesSpecification($regex));

        if (count($message) > 0) {
            return;
        }

        // throw exception
    }
}

With that you can use the step like so

Then I should see an email where subject matches "Your order \d is confirmed"

As a general approach though, I would always suggest wiping the database before any actions like these, so the number in the email becomes predictable and you can directly check against it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants