Faking email

| Perl | 4 Comments

Recently I've been setting up an extensive test harness suite for a web-based application running on the Catalyst Web Framework for Perl.

In addition to the popular Test::MoreCPAN module, many of the tests make use of the CPAN module Test::WWW::Mechanize::Catalyst where I run automated scripts to access various pages, fill in fields with various values, submit forms and check for success or failure.

One of the tests involves creating a new user account that generates a notification email which is sent to the new user. Within the message text there is a verification link. The idea is that upon receiving this email, the user will click on this link and be redirected back to the application to a welcome page. This welcome page verifies that registration has been completed successfully. The user is invited to login in by submitting a form with the username and password pre-filled.

The problem is that I do not want to be generating all kinds of external emails into the big bad world for these tests. Besides, how can I use automated scripts when they depend on external events like users having to click on links in emails wherever they might be?

So here's the trick. First of all I redefine the Email::Send::send() method so that I can hook into it thereby mocking it's behavior. This redefined method is used to scrape out the embedded validation link we must click on in order to finish the registration process.

our $email_mime_ref;
{
    no warnings qw/once redefine/;
    *Email::Send::send = sub {
        my ($self, $message, @args) = @_;
        $main::email_mime_ref = $message; return 1; };
}

Note that we use no warnings qw/once redefine/ in order to disable the warning messages for redefining the method and only using it once.

Whenever Email::Send::send() is called, we copy the message for later use. Note that since we are in the namespace of Email::Send when this is called, we need to make sure that the message is copied back into the namespace of where we are calling from, namely $main::*:

$main::email_mime_ref = $message;

Later on in the test suite it is time to submit the form like this:

$mech->submit_form(
    form_number => 0,
    fields => $fields,
    button => 'submit' );

Now scan through the message text and extract the uri, there should only be one present. I'm using the CPAN module URI::Find to simplify life.

my @uris;
my $finder = URI::Find->new( sub { push @uris, shift; } );
$finder->find(\$email_mime_ref->body_raw);

As a sanity check (you never know) I check that indeed only one link is present in the message text:

is(@uris, 1, "Found only one URI '$uris[0]' in email message");

Finally, we simulate clicking on this link which should bring us back to the welcome page:

$mech->get_ok($uris[0], "Click on URI '$uris[0]'");
$mech->content_contains("Welcome " . lc($username) . 
    ", your email has been validated. Please log in.");

We did it, so let's pat ourselves on the shoulders and call it a night.

4 Comments

An alternative would be using Email::Sender and using the Test transport or using Email::Send::Test instead of Email::Send. This would avoid the need for monkey patching.

I concur what Lian writes - just today I decided to add this confirming email address procedure to the registration process at my experimental CatalystX::ProtoWiki project - and I was surprised how little time that required. You can see my code at the github: http://github.com/zby/CatalystX--ProtoWiki/blob/40e6b33eb3e98cdf0716ec5c7cb87563a312bbe9/t/01app.t - this is the test using the Test transport. And 'send_confirmation_email' is the email sending method in this controller: http://github.com/zby/CatalystX--ProtoWiki/blob/40e6b33eb3e98cdf0716ec5c7cb87563a312bbe9/lib/CatalystX/ProtoWiki/Controller/User.pm

Leave a comment

Random entries

Here are some random entries that you might be interested in:

Recent Assets

  • Tenerife-flight-path.png
  • listen-to-me-marlon.jpg
  • sneeuwval.jpg
  • frozen-crystals.png
  • winter-is-coming.png
  • donald-trump.png
  • Rex-indian-headdress.png
  • Liam-future-famous-golfer-2016-10.jpg
  • number-one.png
  • Mom-and-me-2016.png
  • 636101580191153661-Kiffen-0003675-02.jpg
  • the-haskell-road-ro-logic.png

Recent Comments

  • Faking email: Well in that case I need to give it another try if ...
    - Kiffin
  • Faking email: I concur what Lian writes - just today I decided t ...
    - Zbigniew Lukasiak
  • Faking email: That is certainly an interesting alternative, Lian ...
    - Kiffin
  • Faking email: An alternative would be using Email::Sender and us ...
    - Lian Wan Situ

Golf Handicap

Information

This personal weblog was started way back on July 21, 2001 which means that it is 7-21-2001 old.

So far this blog contains no less than 2279 entries and as many as 1881 comments.

Important events

Graduated from Stanford 6-5-1979 ago.

Kiffin Rockwell was shot down and killed 9-23-1916 ago.

Believe it or not but I am 10-11-1957 young.

Began well-balanced and healthy life style 1-8-2013 ago.

My father passed away 10-20-2000 ago.

First met Thea in Balestrand, Norway 6-14-1980 ago.