import rt 3.4.4
[freeside.git] / rt / lib / t / regression / 04send_email.t
diff --git a/rt/lib/t/regression/04send_email.t b/rt/lib/t/regression/04send_email.t
new file mode 100644 (file)
index 0000000..09e6e6f
--- /dev/null
@@ -0,0 +1,511 @@
+#!/usr/bin/perl -w
+
+use strict;
+use Test::More tests => 137;
+use RT;
+RT::LoadConfig();
+RT::Init;
+use RT::EmailParser;
+use RT::Tickets;
+use RT::Action::SendEmail;
+
+my @_outgoing_messages;
+my @scrips_fired;
+
+#We're not testing acls here.
+my $everyone = RT::Group->new($RT::SystemUser);
+$everyone->LoadSystemInternalGroup('Everyone');
+$everyone->PrincipalObj->GrantRight(Right =>'SuperUser');
+
+
+is (__PACKAGE__, 'main', "We're operating in the main package");
+
+
+{
+no warnings qw/redefine/;
+sub RT::Action::SendEmail::SendMessage {
+        my $self = shift;
+        my $MIME = shift;
+
+        main::_fired_scrip($self->ScripObj);
+        main::ok(ref($MIME) eq 'MIME::Entity', "hey, look. it's a mime entity");
+}
+
+}
+
+# instrument SendEmail to pass us what it's about to send.
+# create a regular ticket
+
+my $parser = RT::EmailParser->new();
+
+
+# Let's test to make sure a multipart/report is processed correctly
+my $content =  `cat $RT::BasePath/lib/t/data/multipart-report` || die "couldn't find new content";
+# be as much like the mail gateway as possible.
+use RT::Interface::Email;
+                                  
+my %args =        (message => $content, queue => 1, action => 'correspond');
+ RT::Interface::Email::Gateway(\%args);
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+my $tick= $tickets->First();
+isa_ok($tick, "RT::Ticket", "got a ticket object");
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+ok ($tick->Transactions->First->Content =~ /The original message was received/, "It's the bounce");
+
+
+# make sure it fires scrips.
+is ($#scrips_fired, 1, "Fired 2 scrips on ticket creation");
+
+undef @scrips_fired;
+
+
+
+
+$parser->ParseMIMEEntityFromScalar('From: root@localhost
+To: rt@example.com
+Subject: This is a test of new ticket creation as an unknown user
+
+Blah!
+Foob!');
+
+                                  
+use Data::Dumper;
+
+my $ticket = RT::Ticket->new($RT::SystemUser);
+my  ($id,  undef, $msg ) = $ticket->Create(Requestor => ['root@localhost'], Queue => 'general', Subject => 'I18NTest', MIMEObj => $parser->Entity);
+ok ($id,$msg);
+$tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+ $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+ok ($tick->Subject eq 'I18NTest', "failed to create the new ticket from an unprivileged account");
+
+# make sure it fires scrips.
+is ($#scrips_fired, 1, "Fired 2 scrips on ticket creation");
+# make sure it sends an autoreply
+# make sure it sends a notification to adminccs
+
+
+# we need to swap out SendMessage to test the new things we care about;
+&utf8_redef_sendmessage;
+
+# create an iso 8859-1 ticket
+@scrips_fired = ();
+
+$content =  `cat $RT::BasePath/lib/t/data/new-ticket-from-iso-8859-1` || die "couldn't find new content";
+
+
+
+$parser->ParseMIMEEntityFromScalar($content);
+
+
+# be as much like the mail gateway as possible.
+use RT::Interface::Email;
+                           
+ %args =        (message => $content, queue => 1, action => 'correspond');
+ RT::Interface::Email::Gateway(\%args);
+ $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+ $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+ok ($tick->Transactions->First->Content =~ /H\x{e5}vard/, "It's signed by havard. yay");
+
+
+# make sure it fires scrips.
+is ($#scrips_fired, 1, "Fired 2 scrips on ticket creation");
+# make sure it sends an autoreply
+
+
+# make sure it sends a notification to adminccs
+
+# If we correspond, does it do the right thing to the outbound messages?
+
+$parser->ParseMIMEEntityFromScalar($content);
+  ($id, $msg) = $tick->Comment(MIMEObj => $parser->Entity);
+ok ($id, $msg);
+
+$parser->ParseMIMEEntityFromScalar($content);
+($id, $msg) = $tick->Correspond(MIMEObj => $parser->Entity);
+ok ($id, $msg);
+
+
+
+
+
+# we need to swap out SendMessage to test the new things we care about;
+&iso8859_redef_sendmessage;
+$RT::EmailOutputEncoding = 'iso-8859-1';
+# create an iso 8859-1 ticket
+@scrips_fired = ();
+
+ $content =  `cat $RT::BasePath/lib/t/data/new-ticket-from-iso-8859-1` || die "couldn't find new content";
+# be as much like the mail gateway as possible.
+use RT::Interface::Email;
+                                  
+ %args =        (message => $content, queue => 1, action => 'correspond');
+ RT::Interface::Email::Gateway(\%args);
+$tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+ $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+ok ($tick->Transactions->First->Content =~ /H\x{e5}vard/, "It's signed by havard. yay");
+
+
+# make sure it fires scrips.
+is ($#scrips_fired, 1, "Fired 2 scrips on ticket creation");
+# make sure it sends an autoreply
+
+
+# make sure it sends a notification to adminccs
+
+
+# If we correspond, does it do the right thing to the outbound messages?
+
+$parser->ParseMIMEEntityFromScalar($content);
+ ($id, $msg) = $tick->Comment(MIMEObj => $parser->Entity);
+ok ($id, $msg);
+
+$parser->ParseMIMEEntityFromScalar($content);
+($id, $msg) = $tick->Correspond(MIMEObj => $parser->Entity);
+ok ($id, $msg);
+
+
+sub _fired_scrip {
+        my $scrip = shift;
+        push @scrips_fired, $scrip;
+}       
+
+sub utf8_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval ' 
+    sub RT::Action::SendEmail::SendMessage {
+        my $self = shift;
+        my $MIME = shift;
+
+        my $scrip = $self->ScripObj->id;
+        ok(1, $self->ScripObj->ConditionObj->Name . " ".$self->ScripObj->ActionObj->Name);
+        main::_fired_scrip($self->ScripObj);
+        $MIME->make_singlepart;
+        main::ok( ref($MIME) eq \'MIME::Entity\',
+                  "hey, look. it\'s a mime entity" );
+        main::ok( ref( $MIME->head ) eq \'MIME::Head\',
+                  "its mime header is a mime header. yay" );
+        main::ok( $MIME->head->get(\'Content-Type\') =~ /utf-8/,
+                  "Its content type is utf-8" );
+        my $message_as_string = $MIME->bodyhandle->as_string();
+        use Encode;
+        $message_as_string = Encode::decode_utf8($message_as_string);
+        main::ok(
+            $message_as_string =~ /H\x{e5}vard/,
+"The message\'s content contains havard\'s name. this will fail if it\'s not utf8 out");
+
+    }';
+}
+
+sub iso8859_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval ' 
+    sub RT::Action::SendEmail::SendMessage {
+        my $self = shift;
+        my $MIME = shift;
+
+        my $scrip = $self->ScripObj->id;
+        ok(1, $self->ScripObj->ConditionObj->Name . " ".$self->ScripObj->ActionObj->Name);
+        main::_fired_scrip($self->ScripObj);
+        $MIME->make_singlepart;
+        main::ok( ref($MIME) eq \'MIME::Entity\',
+                  "hey, look. it\'s a mime entity" );
+        main::ok( ref( $MIME->head ) eq \'MIME::Head\',
+                  "its mime header is a mime header. yay" );
+        main::ok( $MIME->head->get(\'Content-Type\') =~ /iso-8859-1/,
+                  "Its content type is iso-8859-1 - " . $MIME->head->get("Content-Type") );
+        my $message_as_string = $MIME->bodyhandle->as_string();
+        use Encode;
+        $message_as_string = Encode::decode("iso-8859-1",$message_as_string);
+        main::ok(
+            $message_as_string =~ /H\x{e5}vard/, "The message\'s content contains havard\'s name. this will fail if it\'s not utf8 out");
+
+    }';
+}
+
+# {{{ test a multipart alternative containing a text-html part with an umlaut
+
+ $content =  `cat $RT::BasePath/lib/t/data/multipart-alternative-with-umlaut` || die "couldn't find new content";
+
+$parser->ParseMIMEEntityFromScalar($content);
+
+
+# be as much like the mail gateway as possible.
+&umlauts_redef_sendmessage;
+
+ %args =        (message => $content, queue => 1, action => 'correspond');
+ RT::Interface::Email::Gateway(\%args);
+ $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+ $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+ok ($tick->Transactions->First->Content =~ /causes Error/, "We recorded the content right as text-plain");
+is ($tick->Transactions->First->Attachments->Count , 3 , "Has three attachments, presumably a text-plain, a text-html and a multipart alternative");
+
+sub umlauts_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval 'sub RT::Action::SendEmail::SendMessage { }';
+}
+
+# }}}
+
+# {{{ test a text-html message with an umlaut
+
+ $content =  `cat $RT::BasePath/lib/t/data/text-html-with-umlaut` || die "couldn't find new content";
+
+$parser->ParseMIMEEntityFromScalar($content);
+
+
+# be as much like the mail gateway as possible.
+&text_html_umlauts_redef_sendmessage;
+
+ %args =        (message => $content, queue => 1, action => 'correspond');
+ RT::Interface::Email::Gateway(\%args);
+ $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+ $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+ok ($tick->Transactions->First->Attachments->First->Content =~ /causes Error/, "We recorded the content as containing 'causes error'");
+ok ($tick->Transactions->First->Attachments->First->ContentType =~ /text\/html/, "We recorded the content as text/html");
+ok ($tick->Transactions->First->Attachments->Count ==1 , "Has one attachment, presumably a text-html and a multipart alternative");
+
+sub text_html_umlauts_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval 'sub RT::Action::SendEmail::SendMessage { 
+                my $self = shift; 
+                my $MIME = shift; 
+                use Data::Dumper;
+                return (1) unless ($self->ScripObj->ScripActionObj->Name eq "Notify AdminCcs" );
+                ok (is $MIME->parts, 2, "generated correspondence mime entityis composed of three parts");
+                is ($MIME->head->mime_type , "multipart/mixed", "The first part is a multipart mixed". $MIME->head->mime_type);
+                is ($MIME->parts(0)->head->mime_type , "text/plain", "The second part is a plain");
+                is ($MIME->parts(1)->head->mime_type , "text/html", "The third part is an html ");
+                 }';
+}
+
+# }}}
+
+# {{{ test a text-html message with russian characters
+
+ $content =  `cat $RT::BasePath/lib/t/data/text-html-in-russian` || die "couldn't find new content";
+
+$parser->ParseMIMEEntityFromScalar($content);
+
+
+# be as much like the mail gateway as possible.
+&text_html_russian_redef_sendmessage;
+
+ %args =        (message => $content, queue => 1, action => 'correspond');
+ RT::Interface::Email::Gateway(\%args);
+ $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+ $tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+ok ($tick->Transactions->First->Attachments->First->ContentType =~ /text\/html/, "We recorded the content right as text-html");
+ok ($tick->Transactions->First->Attachments->Count ==1 , "Has one attachment, presumably a text-html and a multipart alternative");
+
+sub text_html_russian_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval 'sub RT::Action::SendEmail::SendMessage { 
+                my $self = shift; 
+                my $MIME = shift; 
+                use Data::Dumper;
+                return (1) unless ($self->ScripObj->ScripActionObj->Name eq "Notify AdminCcs" );
+                ok (is $MIME->parts, 2, "generated correspondence mime entityis composed of three parts");
+                is ($MIME->head->mime_type , "multipart/mixed", "The first part is a multipart mixed". $MIME->head->mime_type);
+                is ($MIME->parts(0)->head->mime_type , "text/plain", "The second part is a plain");
+                is ($MIME->parts(1)->head->mime_type , "text/html", "The third part is an html ");
+                my $content_1251;
+                $content_1251 = $MIME->parts(1)->bodyhandle->as_string();
+                ok ($content_1251 =~ qr{Ó÷eáíûé Öeíòp "ÊÀÄÐÛ ÄÅËÎÂÎÃΠÌÈÐÀ" ïpèãëaøaeò ía òpeíèíã:},
+"Content matches drugim in codepage 1251" );
+                 }';
+}
+
+# }}}
+
+# {{{ test a message containing a russian subject and NO content type
+
+unshift (@RT::EmailInputEncodings, 'koi8-r');
+$RT::EmailOutputEncoding = 'koi8-r';
+$content =  `cat $RT::BasePath/lib/t/data/russian-subject-no-content-type` || die "couldn't find new content";
+
+$parser->ParseMIMEEntityFromScalar($content);
+
+
+# be as much like the mail gateway as possible.
+&text_plain_russian_redef_sendmessage;
+ %args =        (message => $content, queue => 1, action => 'correspond');
+ RT::Interface::Email::Gateway(\%args);
+ $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+$tick= $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+ok ($tick->Transactions->First->Attachments->First->ContentType =~ /text\/plain/, "We recorded the content type right");
+ok ($tick->Transactions->First->Attachments->Count ==1 , "Has one attachment, presumably a text-plain");
+is ($tick->Subject, "\x{442}\x{435}\x{441}\x{442} \x{442}\x{435}\x{441}\x{442}", "Recorded the subject right");
+sub text_plain_russian_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval 'sub RT::Action::SendEmail::SendMessage { 
+                my $self = shift; 
+                my $MIME = shift; 
+                return (1) unless ($self->ScripObj->ScripActionObj->Name eq "Notify AdminCcs" );
+                is ($MIME->head->mime_type , "text/plain", "The only part is text/plain ");
+                 my $subject  = $MIME->head->get("subject");
+                chomp($subject);
+                #is( $subject ,      /^=\?KOI8-R\?B\?W2V4YW1wbGUuY39tICM3XSDUxdPUINTF09Q=\?=/ , "The $subject is encoded correctly");
+               };
+                 ';
+}
+
+shift @RT::EmailInputEncodings;
+$RT::EmailOutputEncoding = 'utf-8';
+# }}}
+
+
+# {{{ test a message containing a nested RFC 822 message
+
+ $content =  `cat $RT::BasePath/lib/t/data/nested-rfc-822` || die "couldn't find new content";
+ok ($content, "Loaded nested-rfc-822 to test");
+
+$parser->ParseMIMEEntityFromScalar($content);
+
+
+# be as much like the mail gateway as possible.
+&text_plain_nested_redef_sendmessage;
+ %args =        (message => $content, queue => 1, action => 'correspond');
+ RT::Interface::Email::Gateway(\%args);
+ $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+$tick= $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+is ($tick->Subject, "[Jonas Liljegren] Re: [Para] Niv\x{e5}er?");
+ok ($tick->Transactions->First->Attachments->First->ContentType =~ /multipart\/mixed/, "We recorded the content type right");
+is ($tick->Transactions->First->Attachments->Count , 5 , "Has one attachment, presumably a text-plain and a message RFC 822 and another plain");
+sub text_plain_nested_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval 'sub RT::Action::SendEmail::SendMessage { 
+                my $self = shift; 
+                my $MIME = shift; 
+                return (1) unless ($self->ScripObj->ScripActionObj->Name eq "Notify AdminCcs" );
+                is ($MIME->head->mime_type , "multipart/mixed", "It is a mixed multipart");
+                 my $subject  =  $MIME->head->get("subject");
+                 $subject  = MIME::Base64::decode_base64( $subject);
+                chomp($subject);
+               # TODO, why does this test fail
+                #ok($subject =~ qr{Niv\x{e5}er}, "The subject matches the word - $subject");
+               1;
+                 }';
+}
+
+# }}}
+
+
+# {{{ test a multipart alternative containing a uuencoded mesage generated by lotus notes
+
+ $content =  `cat $RT::BasePath/lib/t/data/notes-uuencoded` || die "couldn't find new content";
+
+$parser->ParseMIMEEntityFromScalar($content);
+
+
+# be as much like the mail gateway as possible.
+&notes_redef_sendmessage;
+
+ %args =        (message => $content, queue => 1, action => 'correspond');
+ RT::Interface::Email::Gateway(\%args);
+$tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+$tick= $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+ok ($tick->Transactions->First->Content =~ /from Lotus Notes/, "We recorded the content right");
+is ($tick->Transactions->First->Attachments->Count , 3 , "Has three attachments");
+
+sub notes_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval 'sub RT::Action::SendEmail::SendMessage { }';
+}
+
+# }}}
+
+# {{{ test a multipart that crashes the file-based mime-parser works
+
+ $content =  `cat $RT::BasePath/lib/t/data/crashes-file-based-parser` || die "couldn't find new content";
+
+$parser->ParseMIMEEntityFromScalar($content);
+
+
+# be as much like the mail gateway as possible.
+&crashes_redef_sendmessage;
+
+ %args =        (message => $content, queue => 1, action => 'correspond');
+ RT::Interface::Email::Gateway(\%args);
+ $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+$tick= $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+ok ($tick->Transactions->First->Content =~ /FYI/, "We recorded the content right");
+is ($tick->Transactions->First->Attachments->Count , 5 , "Has three attachments");
+
+sub crashes_redef_sendmessage {
+    no warnings qw/redefine/;
+    eval 'sub RT::Action::SendEmail::SendMessage { }';
+}
+
+
+
+# }}}
+
+# {{{ test a multi-line RT-Send-CC header
+
+ $content =  `cat $RT::BasePath/lib/t/data/rt-send-cc` || die "couldn't find new content";
+
+$parser->ParseMIMEEntityFromScalar($content);
+
+
+
+ %args =        (message => $content, queue => 1, action => 'correspond');
+ RT::Interface::Email::Gateway(\%args);
+ $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+$tick= $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+
+my $cc = $tick->Transactions->First->Attachments->First->GetHeader('RT-Send-Cc');
+ok ($cc =~ /test1/, "Found test 1");
+ok ($cc =~ /test2/, "Found test 2");
+ok ($cc =~ /test3/, "Found test 3");
+ok ($cc =~ /test4/, "Found test 4");
+ok ($cc =~ /test5/, "Found test 5");
+
+# }}}
+
+# Don't taint the environment
+$everyone->PrincipalObj->RevokeRight(Right =>'SuperUser');
+1;