#! perl BEGIN { chdir 't' if -d 't'; use lib '../lib', '../blib/lib', 'lib'; } use strict; use warnings; use FakeIn; use FakeMail; use File::Path 'rmtree'; use Test::More tests => 30; use_ok( 'Mail::TempAddress' ) or exit; use Test::MockObject; use Test::Exception; use Mail::TempAddress::Addresses; mkdir 'addresses'; END { rmtree 'addresses' unless @ARGV; } my @mails; Test::MockObject->fake_module( 'Mail::Mailer', new => sub ($@) { push @mails, FakeMail->new(); $mails[-1]; }); diag( 'Create a new alias and subscribe another user' ); my $fake_glob = FakeIn->new( split(/\n/, <<'END_HERE') ); From: me@home To: alias@there Subject: *new* Delivered-To: alias@there END_HERE my $ml = Mail::TempAddress->new( 'addresses', $fake_glob ); $ml->process(); my $count = @mails; my $mail = shift @mails; is( $mail->To(), 'me@home', '*new* list should reply to sender' ); is( $mail->From(), 'alias@there', '... from the alias' ); like( $mail->Subject(), qr/Temporary address created/, '... with a good subject' ); like( $mail->body(), qr/A new temporary address has been created for me\@home/, '... and a creation message' ); my $find_address = qr/([a-f0-9]+)\@there/; my ($address) = $mail->body() =~ $find_address; isnt( $address, undef, '... providing the temporary address' ); diag( 'Sending a message to a temp address' ); $fake_glob = FakeIn->new( split(/\n/, <<"END_HERE") ); From: someone\@somewhere To: $address\@there Some-Header: foo Subject: Hi there Delivered-To: $address\@there Here is my message!! END_HERE $ml = Mail::TempAddress->new( 'addresses', $fake_glob ); $ml->process(); $mail = shift @mails; is( $mail->To(), 'me@home', 'message sent to temp addy should be resent to creator' ); is( $mail->Subject(), 'Hi there', '... with subject preserved' ); my $replyto = 'Reply-To'; my $alias = $mail->$replyto(); like( $alias, qr/$address\+(\w+)\@there/, '... setting Reply-To to keyed alias' ); like( $mail->body(), qr/Here is.+my message!!/s, '... preserving message body' ); my $sh = 'Some-header'; is( $mail->$sh(), 'foo', '... preserving other headers' ); diag( 'Replying to a keyed alias' ); $fake_glob = FakeIn->new( split(/\n/, <<"END_HERE") ); From: me\@home To: $alias Another-Header: bar Subject: Well hello! I am responding to you END_HERE $ml = Mail::TempAddress->new( 'addresses', $fake_glob ); $ml->process(); $mail = shift @mails; is( $mail->To(), 'someone@somewhere', 'replying to resent message should respond to its sender' ); is( $mail->From(), "$address\@there", '... from temporary address' ); like( $mail->body(), qr/I am responding.+to.+you/s, '... with body' ); my $ah = 'Another-header'; is( $mail->$ah(), 'bar', '... preserving other headers' ); diag( 'Replying to a keyed alias in a Cc' ); $fake_glob = FakeIn->new( split(/\n/, <<"END_HERE") ); From: me\@home To: some\@other Cc: $alias Delivered-To: $alias Another-Header: bar Subject: Well hello! I am responding to you indirectly END_HERE $ml = Mail::TempAddress->new( 'addresses', $fake_glob ); $ml->process(); $mail = shift @mails; is( $mail->To(), 'someone@somewhere', 'replying to resent message should respond to its sender' ); is( $mail->From(), "$address\@there", '... from temporary address' ); like( $mail->body(), qr/I am responding.+to.+you/s, '... with body' ); $ah = 'Another-header'; is( $mail->$ah(), 'bar', '... preserving other headers' ); my @cc = $mail->Cc(); is( @cc, 0, '... except for Cc' ); diag( 'Expiration dates should work' ); $fake_glob = FakeIn->new( split(/\n/, <<'END_HERE') ); From: me@home To: alias@there Subject: *new* Expires: 7d END_HERE $ml = Mail::TempAddress->new( 'addresses', $fake_glob ); $ml->process(); $mail = shift @mails; ($address) = $mail->body() =~ $find_address; my $addresses = Mail::TempAddress::Addresses->new( 'addresses' ); $alias = $addresses->fetch( $address ); ok( $alias->expires(), 'sending expiration directive should set expires flag to true' ); $alias->{expires} = time() - 100; $addresses->save( $alias, $address ); @mails = (); $fake_glob = FakeIn->new( split(/\n/, <new( 'addresses', $fake_glob ); throws_ok { $ml->process() } qr/Invalid address/, 'mta should throw exception on expired address'; is( $! + 0, 100, '... setting $! to 100' ) or diag( "$address" ); is( @mails, 0, '... sending no messages' ); diag( 'Descriptions should work' ); $fake_glob = FakeIn->new( split(/\n/, <<'END_HERE') ); From: me@home To: alias@there Subject: *new* Description: my temporary address END_HERE $ml = Mail::TempAddress->new( 'addresses', $fake_glob ); $ml->process(); $mail = shift @mails; ($address) = $mail->body() =~ $find_address; $fake_glob = FakeIn->new( split(/\n/, <<"END_HERE") ); From: you\@elsewhere To: $address\@there Subject: hello Description: my temporary address END_HERE $ml = Mail::TempAddress->new( 'addresses', $fake_glob ); $ml->process(); $mail = shift @mails; my $desc_head = 'X-MTA-Description'; my $desc = $mail->$desc_head(); is( $desc, 'my temporary address', 'description header should be present in responses' ); diag( 'Respect multi-part messages' ); my $boundary = "=-o/TyUX3mnxrfgX+Lef56"; $fake_glob = FakeIn->new( split(/\n/, <<"END_HERE" ) ); Subject: attachment test From: me\@home To: $address\@there Content-Type: multipart/mixed; boundary="$boundary" Mime-Version: 1.0 --=-o/TyUX3mnxrfgX+Lef56 Content-Type: text/plain Content-Transfer-Encoding: 7bit hey there -- my signature --=-o/TyUX3mnxrfgX+Lef56 Content-Disposition: attachment; filename=hi.txt Content-Type: text/plain; name=hi.txt; charset= Content-Transfer-Encoding: 7bit Hi there! --=-o/TyUX3mnxrfgX+Lef56-- END_HERE $ml = Mail::TempAddress->new( 'addresses', $fake_glob ); $ml->process(); $mail = shift @mails; my $body = $mail->body(); my $ct = 'Content-type'; like( $mail->$ct(), qr!multipart/mixe!, 'should maintain content type header' ); like( $body, qr/hey there\n\n-- \nmy signature/, '... not adding extra newlines' ); diag( 'Not sending to other To or Cc addresses' ); $fake_glob = FakeIn->new( split(/\n/, <<"END_HERE") ); From: someone\@somewhere To: $address\@there, someone\@elsewhere Cc: another\@elsewhere Subject: Don't Spam Me Delivered-To: $address\@there Here is my message!! END_HERE $ml = Mail::TempAddress->new( 'addresses', $fake_glob ); $ml->process(); is( @mails, 1, 'resent message should go to only one recipient' ); $mail = shift @mails; my $cc = join(', ', $mail->Cc()); my $to = join(', ', $mail->To()); isnt( $cc, '', '... not preserving literal Cc' ); like( $to, qr/<$address\+(\w+)\@there>/, '... or literal To' );