summaryrefslogtreecommitdiff
path: root/rt/t
diff options
context:
space:
mode:
Diffstat (limited to 'rt/t')
-rw-r--r--rt/t/api/attachment.t26
-rw-r--r--rt/t/api/attachment_filename.t39
-rw-r--r--rt/t/api/cf_rights.t51
-rw-r--r--rt/t/api/link.t203
-rw-r--r--rt/t/api/password-types.t31
-rw-r--r--rt/t/api/scrip.t74
-rw-r--r--rt/t/api/txn_content.t19
-rw-r--r--rt/t/approval/admincc.t271
-rw-r--r--rt/t/data/gnupg/emails/special/quoted_inline_signature.txt26
-rw-r--r--rt/t/mail/gnupg-incoming.t3
-rw-r--r--rt/t/mail/gnupg-realmail.t13
-rw-r--r--rt/t/mail/gnupg-special.t86
-rw-r--r--rt/t/mail/outlook.t272
-rw-r--r--rt/t/mail/wrong_mime_charset.t25
-rw-r--r--rt/t/web/attachment_encoding.t103
-rw-r--r--rt/t/web/basic.t11
-rw-r--r--rt/t/web/cf_select_one.t10
-rw-r--r--rt/t/web/compilation_errors.t12
-rw-r--r--rt/t/web/html_template.t78
-rw-r--r--rt/t/web/offline_messages_utf8.t6
-rw-r--r--rt/t/web/query_builder.t13
-rw-r--r--rt/t/web/redirect-after-login.t243
-rw-r--r--rt/t/web/rest-non-ascii-subject.t5
-rw-r--r--rt/t/web/rights1.t28
-rw-r--r--rt/t/web/saved_search_update.t63
-rw-r--r--rt/t/web/ticket_seen.t26
-rw-r--r--rt/t/web/ticket_txn_content.t79
27 files changed, 1730 insertions, 86 deletions
diff --git a/rt/t/api/attachment.t b/rt/t/api/attachment.t
index 07c46ba..282d2a3 100644
--- a/rt/t/api/attachment.t
+++ b/rt/t/api/attachment.t
@@ -2,7 +2,7 @@
use strict;
use warnings;
use RT;
-use RT::Test tests => 4;
+use RT::Test tests => 7;
{
@@ -42,4 +42,28 @@ is ($#headers, 2, "testing a bunch of singline multiple headers" );
}
+
+{
+ my $iso_8859_1_ticket_email =
+ RT::Test::get_relocatable_file( 'new-ticket-from-iso-8859-1',
+ ( File::Spec->updir(), 'data', 'emails' ) );
+ my $content = RT::Test->file_content($iso_8859_1_ticket_email);
+
+ my $parser = RT::EmailParser->new;
+ $parser->ParseMIMEEntityFromScalar($content);
+ my $attachment = RT::Attachment->new( $RT::SystemUser );
+ my ( $id, $msg ) =
+ $attachment->Create( TransactionId => 1, Attachment => $parser->Entity );
+ ok( $id, $msg );
+ my $mime = $attachment->ContentAsMIME;
+ like( $mime->head->get('Content-Type'),
+ qr/charset="iso-8859-1"/, 'content type of ContentAsMIME is original' );
+ require Encode;
+ is(
+ Encode::decode( 'iso-8859-1', $mime->stringify_body ),
+ Encode::decode( 'utf8', "Håvard\n" ),
+ 'body of ContentAsMIME is original'
+ );
+}
+
1;
diff --git a/rt/t/api/attachment_filename.t b/rt/t/api/attachment_filename.t
new file mode 100644
index 0000000..2eced01
--- /dev/null
+++ b/rt/t/api/attachment_filename.t
@@ -0,0 +1,39 @@
+use RT::Test tests => 5;
+use MIME::Entity;
+my $ticket = RT::Ticket->new($RT::SystemUser);
+my $mime = MIME::Entity->build(
+ From => 'test@example.com',
+ Type => 'text/html',
+ Data => ["test attachment's filename\n"],
+);
+
+$mime->attach(
+ Path => 'share/html/NoAuth/images/bplogo.gif',
+ Type => 'image/gif',
+);
+
+$mime->attach(
+ Path => 'share/html/NoAuth/images/bplogo.gif',
+ Type => 'image/gif',
+ Filename => 'bplogo.gif',
+);
+
+$mime->attach(
+ Path => 'share/html/NoAuth/images/bplogo.gif',
+ Filename => 'images/bplogo.gif',
+ Type => 'image/gif',
+);
+
+my $id = $ticket->Create( MIMEObj => $mime, Queue => 'General' );
+ok( $id, "created ticket $id" );
+
+my $atts = RT::Attachments->new( $RT::SystemUser );
+$atts->Limit( FIELD => 'ContentType', VALUE => 'image/gif' );
+is( $atts->Count, 3, 'got 3 gif files' );
+
+# no matter if mime's filename include path or not,
+# we should throw away the path all the time.
+while ( my $att = $atts->Next ) {
+ is( $att->Filename, 'bplogo.gif', "attachment's filename" );
+}
+
diff --git a/rt/t/api/cf_rights.t b/rt/t/api/cf_rights.t
new file mode 100644
index 0000000..f55214a
--- /dev/null
+++ b/rt/t/api/cf_rights.t
@@ -0,0 +1,51 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+
+use RT;
+use RT::Test tests => 12;
+
+my $q = RT::Queue->new($RT::SystemUser);
+my ($id,$msg) =$q->Create(Name => "CF-Rights-".$$);
+ok($id,$msg);
+
+my $cf = RT::CustomField->new($RT::SystemUser);
+($id,$msg) = $cf->Create(Name => 'CF-'.$$, Type => 'Select', MaxValues => '1', Queue => $q->id);
+ok($id,$msg);
+
+
+($id,$msg) =$cf->AddValue(Name => 'First');
+ok($id,$msg);
+
+my $u = RT::User->new($RT::SystemUser);
+($id,$msg) = $u->Create( Name => 'User1', Privileged => 1 );
+ok ($id,$msg);
+
+($id,$msg) = $u->PrincipalObj->GrantRight( Object => $cf, Right => 'SeeCustomField' );
+ok ($id,$msg);
+
+my $ucf = RT::CustomField->new($u);
+($id,$msg) = $ucf->Load( $cf->Id );
+ok ($id,$msg);
+
+my $cfv = $ucf->Values->First;
+
+($id,$msg) = $cfv->SetName( 'First1' );
+ok (!$id,$msg);
+
+($id,$msg) = $u->PrincipalObj->GrantRight( Object => $cf, Right => 'AdminCustomFieldValues' );
+ok ($id,$msg);
+
+($id,$msg) = $cfv->SetName( 'First2' );
+ok ($id,$msg);
+
+($id,$msg) = $u->PrincipalObj->RevokeRight( Object => $cf, Right => 'AdminCustomFieldValues' );
+ok ($id,$msg);
+
+($id,$msg) = $u->PrincipalObj->GrantRight( Object => $cf, Right => 'AdminCustomField' );
+ok ($id,$msg);
+
+($id,$msg) = $cfv->SetName( 'First3' );
+ok ($id,$msg);
+
+1;
diff --git a/rt/t/api/link.t b/rt/t/api/link.t
index 1fd66bb..eac9ae2 100644
--- a/rt/t/api/link.t
+++ b/rt/t/api/link.t
@@ -1,24 +1,209 @@
use strict;
use warnings;
-use RT;
-use RT::Test tests => 5;
-
-
-{
+use RT::Test tests => 77;
+use RT::Test::Web;
use RT::Link;
my $link = RT::Link->new($RT::SystemUser);
ok (ref $link);
-ok (UNIVERSAL::isa($link, 'RT::Link'));
-ok (UNIVERSAL::isa($link, 'RT::Base'));
-ok (UNIVERSAL::isa($link, 'RT::Record'));
-ok (UNIVERSAL::isa($link, 'DBIx::SearchBuilder::Record'));
+isa_ok( $link, 'RT::Link');
+isa_ok( $link, 'RT::Base');
+isa_ok( $link, 'RT::Record');
+isa_ok( $link, 'DBIx::SearchBuilder::Record');
+
+my $queue = RT::Test->load_or_create_queue(Name => 'General');
+ok($queue->Id, "loaded the General queue");
+
+my $parent = RT::Ticket->new($RT::SystemUser);
+my ($pid, undef, $msg) = $parent->Create(
+ Queue => $queue->id,
+ Subject => 'parent',
+);
+ok $pid, 'created a ticket #'. $pid or diag "error: $msg";
+
+my $child = RT::Ticket->new($RT::SystemUser);
+my ($cid, undef, $msg) = $child->Create(
+ Queue => $queue->id,
+ Subject => 'child',
+);
+ok $cid, 'created a ticket #'. $cid or diag "error: $msg";
+
+{
+ clean_links();
+ my ($status, $msg) = $parent->AddLink;
+ ok(!$status, "didn't create a link: $msg");
+
+ ($status, $msg) = $parent->AddLink( Base => $parent->id );
+ ok(!$status, "didn't create a link: $msg");
+
+ ($status, $msg) = $parent->AddLink( Base => $parent->id, Type => 'HasMember' );
+ ok(!$status, "didn't create a link: $msg");
+}
+
+{
+ clean_links();
+ my ($status, $msg) = $parent->AddLink(
+ Type => 'MemberOf', Base => $child->id,
+ );
+ ok($status, "created a link: $msg");
+
+ my $children = $parent->Members;
+ $children->RedoSearch; $children->GotoFirstItem;
+ is $children->Count, 1, 'link is there';
+
+ my $link = $children->First;
+ ok $link->id, 'correct link';
+
+ is $link->Type, 'MemberOf', 'type';
+ is $link->LocalTarget, $parent->id, 'local target';
+ is $link->LocalBase, $child->id, 'local base';
+ is $link->Target, 'fsck.com-rt://example.com/ticket/'. $parent->id, 'local target';
+ is $link->Base, 'fsck.com-rt://example.com/ticket/'. $child->id, 'local base';
+
+ isa_ok $link->TargetObj, 'RT::Ticket';
+ is $link->TargetObj->id, $parent->id, 'correct ticket';
+
+ isa_ok $link->TargetURI, 'RT::URI';
+ is $link->TargetURI->Scheme, 'fsck.com-rt', 'correct scheme';
+ is $link->TargetURI->URI,
+ 'fsck.com-rt://example.com/ticket/'. $parent->id,
+ 'correct URI'
+ ;
+ ok $link->TargetURI->IsLocal, 'local object';
+ is $link->TargetURI->AsHREF,
+ RT::Test::Web->rt_base_url .'Ticket/Display.html?id='. $parent->id,
+ 'correct href'
+ ;
+
+ isa_ok $link->BaseObj, 'RT::Ticket';
+ is $link->BaseObj->id, $child->id, 'correct ticket';
+
+ isa_ok $link->BaseURI, 'RT::URI';
+ is $link->BaseURI->Scheme, 'fsck.com-rt', 'correct scheme';
+ is $link->BaseURI->URI,
+ 'fsck.com-rt://example.com/ticket/'. $child->id,
+ 'correct URI'
+ ;
+ ok $link->BaseURI->IsLocal, 'local object';
+ is $link->BaseURI->AsHREF,
+ RT::Test::Web->rt_base_url .'Ticket/Display.html?id='. $child->id,
+ 'correct href'
+ ;
+}
+
+{
+ clean_links();
+ my ($status, $msg) = $parent->AddLink(
+ Type => 'MemberOf', Base => $child->URI,
+ );
+ ok($status, "created a link: $msg");
+
+ my $children = $parent->Members;
+ $children->RedoSearch; $children->GotoFirstItem;
+ is $children->Count, 1, 'link is there';
+
+ my $link = $children->First;
+ ok $link->id, 'correct link';
+
+ is $link->Type, 'MemberOf', 'type';
+ is $link->LocalTarget, $parent->id, 'local target';
+ is $link->LocalBase, $child->id, 'local base';
+ is $link->Target, 'fsck.com-rt://example.com/ticket/'. $parent->id, 'local target';
+ is $link->Base, 'fsck.com-rt://example.com/ticket/'. $child->id, 'local base';
+
+ isa_ok $link->TargetObj, 'RT::Ticket';
+ is $link->TargetObj->id, $parent->id, 'correct ticket';
+
+ isa_ok $link->TargetURI, 'RT::URI';
+ is $link->TargetURI->Scheme, 'fsck.com-rt', 'correct scheme';
+ is $link->TargetURI->URI,
+ 'fsck.com-rt://example.com/ticket/'. $parent->id,
+ 'correct URI'
+ ;
+ ok $link->TargetURI->IsLocal, 'local object';
+ is $link->TargetURI->AsHREF,
+ RT::Test::Web->rt_base_url .'Ticket/Display.html?id='. $parent->id,
+ 'correct href'
+ ;
+
+ isa_ok $link->BaseObj, 'RT::Ticket';
+ is $link->BaseObj->id, $child->id, 'correct ticket';
+
+ isa_ok $link->BaseURI, 'RT::URI';
+ is $link->BaseURI->Scheme, 'fsck.com-rt', 'correct scheme';
+ is $link->BaseURI->URI,
+ 'fsck.com-rt://example.com/ticket/'. $child->id,
+ 'correct URI'
+ ;
+ ok $link->BaseURI->IsLocal, 'local object';
+ is $link->BaseURI->AsHREF,
+ RT::Test::Web->rt_base_url .'Ticket/Display.html?id='. $child->id,
+ 'correct href'
+ ;
+}
+
+{
+ clean_links();
+ my ($status, $msg) = $parent->AddLink(
+ Type => 'MemberOf', Base => 't:'. $child->id,
+ );
+ ok($status, "created a link: $msg");
+
+ my $children = $parent->Members;
+ $children->RedoSearch; $children->GotoFirstItem;
+ is $children->Count, 1, 'link is there';
+
+ my $link = $children->First;
+ ok $link->id, 'correct link';
+ is $link->Type, 'MemberOf', 'type';
+ is $link->LocalTarget, $parent->id, 'local target';
+ is $link->LocalBase, $child->id, 'local base';
+ is $link->Target, 'fsck.com-rt://example.com/ticket/'. $parent->id, 'local target';
+ is $link->Base, 'fsck.com-rt://example.com/ticket/'. $child->id, 'local base';
+
+ isa_ok $link->TargetObj, 'RT::Ticket';
+ is $link->TargetObj->id, $parent->id, 'correct ticket';
+
+ isa_ok $link->TargetURI, 'RT::URI';
+ is $link->TargetURI->Scheme, 'fsck.com-rt', 'correct scheme';
+ is $link->TargetURI->URI,
+ 'fsck.com-rt://example.com/ticket/'. $parent->id,
+ 'correct URI'
+ ;
+ ok $link->TargetURI->IsLocal, 'local object';
+ is $link->TargetURI->AsHREF,
+ RT::Test::Web->rt_base_url .'Ticket/Display.html?id='. $parent->id,
+ 'correct href'
+ ;
+
+ isa_ok $link->BaseObj, 'RT::Ticket';
+ is $link->BaseObj->id, $child->id, 'correct ticket';
+
+ isa_ok $link->BaseURI, 'RT::URI';
+ is $link->BaseURI->Scheme, 'fsck.com-rt', 'correct scheme';
+ is $link->BaseURI->URI,
+ 'fsck.com-rt://example.com/ticket/'. $child->id,
+ 'correct URI'
+ ;
+ ok $link->BaseURI->IsLocal, 'local object';
+ is $link->BaseURI->AsHREF,
+ RT::Test::Web->rt_base_url .'Ticket/Display.html?id='. $child->id,
+ 'correct href'
+ ;
+}
+sub clean_links {
+ my $links = RT::Links->new( $RT::SystemUser );
+ while ( my $link = $links->Next ) {
+ my ($status, $msg) = $link->Delete;
+ $RT::Logger->error("Couldn't delete a link: $msg")
+ unless $status;
+ }
}
1;
diff --git a/rt/t/api/password-types.t b/rt/t/api/password-types.t
new file mode 100644
index 0000000..267a6ed
--- /dev/null
+++ b/rt/t/api/password-types.t
@@ -0,0 +1,31 @@
+#!/usr/bin/perl -w
+use strict;
+use warnings;
+
+use RT::Test;
+use Digest::MD5;
+
+my $root = RT::User->new(RT->SystemUser);
+$root->Load("root");
+
+# Salted truncated SHA-256
+my $old = $root->__Value("Password");
+is(length($old), 40, "Stored as truncated salted SHA-256");
+ok($root->IsPassword("password"));
+is($root->__Value("Password"), $old, "Unchanged after password check");
+
+# Crypt
+$root->_Set( Field => "Password", Value => crypt("something", "salt"));
+ok($root->IsPassword("something"), "crypt()ed password works");
+is(length($root->__Value("Password")), 40, "And is now upgraded to truncated salted SHA-256");
+
+# MD5, hex
+$root->_Set( Field => "Password", Value => Digest::MD5::md5_hex("changed"));
+ok($root->IsPassword("changed"), "Unsalted MD5 hex works");
+is(length($root->__Value("Password")), 40, "And is now upgraded to truncated salted SHA-256");
+
+# MD5, base64
+$root->_Set( Field => "Password", Value => Digest::MD5::md5_base64("new"));
+ok($root->IsPassword("new"), "Unsalted MD5 base64 works");
+is(length($root->__Value("Password")), 40, "And is now upgraded to truncated salted SHA-256");
+
diff --git a/rt/t/api/scrip.t b/rt/t/api/scrip.t
index 8e8f962..9d97e73 100644
--- a/rt/t/api/scrip.t
+++ b/rt/t/api/scrip.t
@@ -2,7 +2,7 @@
use strict;
use warnings;
use RT;
-use RT::Test tests => 7;
+use RT::Test tests => 25;
{
@@ -46,4 +46,76 @@ isnt ($ticket2->Priority , '87', "Ticket priority is set right");
}
+
+{
+ my $scrip = RT::Scrip->new($RT::SystemUser);
+ my ( $val, $msg ) = $scrip->Create(
+ ScripCondition => 'On Comment',
+ ScripAction => 'Notify Owner',
+ );
+ ok( !$val, "missing template: $msg" );
+ ( $val, $msg ) = $scrip->Create(
+ ScripCondition => 'On Comment',
+ ScripAction => 'Notify Owner',
+ Template => 'not exists',
+ );
+ ok( !$val, "invalid template: $msg" );
+
+ ( $val, $msg ) = $scrip->Create(
+ ScripAction => 'Notify Owner',
+ Template => 'Blank',
+ );
+ ok( !$val, "missing condition: $msg" );
+ ( $val, $msg ) = $scrip->Create(
+ ScripCondition => 'not exists',
+ ScripAction => 'Notify Owner',
+ Template => 'Blank',
+ );
+ ok( !$val, "invalid condition: $msg" );
+
+ ( $val, $msg ) = $scrip->Create(
+ ScripCondition => 'On Comment',
+ Template => 'Blank',
+ );
+ ok( !$val, "missing action: $msg" );
+ ( $val, $msg ) = $scrip->Create(
+ ScripCondition => 'On Comment',
+ ScripAction => 'not exists',
+ Template => 'Blank',
+ );
+ ok( !$val, "invalid action: $msg" );
+
+ ( $val, $msg ) = $scrip->Create(
+ ScripAction => 'Notify Owner',
+ ScripCondition => 'On Comment',
+ Template => 'Blank',
+ );
+ ok( $val, "created scrip: $msg" );
+ $scrip->Load($val);
+ ok( $scrip->id, 'loaded scrip ' . $scrip->id );
+
+ ( $val, $msg ) = $scrip->SetScripCondition();
+ ok( !$val, "missing condition: $msg" );
+ ( $val, $msg ) = $scrip->SetScripCondition('not exists');
+ ok( !$val, "invalid condition: $msg" );
+ ( $val, $msg ) = $scrip->SetScripCondition('On Correspond');
+ ok( $val, "updated condition to 'On Correspond': $msg" );
+
+ ( $val, $msg ) = $scrip->SetScripAction();
+ ok( !$val, "missing action: $msg" );
+ ( $val, $msg ) = $scrip->SetScripAction('not exists');
+ ok( !$val, "invalid action: $msg" );
+ ( $val, $msg ) = $scrip->SetScripAction('Notify AdminCcs');
+ ok( $val, "updated action to 'Notify AdminCcs': $msg" );
+
+ ( $val, $msg ) = $scrip->SetTemplate();
+ ok( !$val, "missing template $msg" );
+ ( $val, $msg ) = $scrip->SetTemplate('not exists');
+ ok( !$val, "invalid template $msg" );
+ ( $val, $msg ) = $scrip->SetTemplate('Forward');
+ ok( $val, "updated template to 'Forward': $msg" );
+
+ ok( $scrip->Delete, 'delete the scrip' );
+}
+
1;
diff --git a/rt/t/api/txn_content.t b/rt/t/api/txn_content.t
new file mode 100644
index 0000000..0f5d78c
--- /dev/null
+++ b/rt/t/api/txn_content.t
@@ -0,0 +1,19 @@
+use warnings;
+use strict;
+
+use RT::Test tests => 3;
+use MIME::Entity;
+my $ticket = RT::Ticket->new($RT::SystemUser);
+my $mime = MIME::Entity->build(
+ From => 'test@example.com',
+ Type => 'text/html',
+ Data => ["this is body\n"],
+);
+$mime->attach( Data => ['this is attachment'] );
+my $id = $ticket->Create( MIMEObj => $mime, Queue => 'General' );
+ok( $id, "created ticket $id" );
+my $txns = $ticket->Transactions;
+$txns->Limit( FIELD => 'Type', VALUE => 'Create' );
+my $txn = $txns->First;
+ok( $txn, 'got Create txn' );
+is( $txn->Content, "this is body\n", "txn's content" );
diff --git a/rt/t/approval/admincc.t b/rt/t/approval/admincc.t
new file mode 100644
index 0000000..7915b6a
--- /dev/null
+++ b/rt/t/approval/admincc.t
@@ -0,0 +1,271 @@
+
+use strict;
+use warnings;
+use Test::More;
+BEGIN {
+ eval { require Email::Abstract; require Test::Email; 1 }
+ or plan skip_all => 'require Email::Abstract and Test::Email';
+}
+
+
+use RT;
+use RT::Test tests => 58;
+use RT::Test::Email;
+
+RT->Config->Set( LogToScreen => 'debug' );
+RT->Config->Set( UseTransactionBatch => 1 );
+my ($baseurl, $m) = RT::Test->started_ok;
+
+my $q = RT::Queue->new($RT::SystemUser);
+$q->Load('___Approvals');
+$q->SetDisabled(0);
+
+my %users;
+# minion is the requestor, cto is the approval owner, coo and ceo are approval
+# adminccs
+for my $user_name (qw(minion cto coo ceo )) {
+ my $user = $users{$user_name} = RT::User->new($RT::SystemUser);
+ $user->Create( Name => uc($user_name),
+ Privileged => 1,
+ EmailAddress => $user_name.'@company.com',
+ Password => 'password',
+ );
+ my ($val, $msg);
+ ($val, $msg) = $user->PrincipalObj->GrantRight(Object =>$q, Right => $_)
+ for qw(ModifyTicket OwnTicket ShowTicket);
+}
+
+# XXX: we need to make the first approval ticket open so notification is sent.
+my $approvals =
+'===Create-Ticket: for-CTO
+Queue: ___Approvals
+Type: approval
+Owner: CTO
+AdminCCs: COO, CEO
+Requestors: {$Tickets{"TOP"}->Requestors}
+DependedOnBy: TOP
+Subject: CTO Approval for PO: {$Tickets{"TOP"}->Id} - {$Tickets{"TOP"}->Subject}
+Due: {time + 86400}
+Content-Type: text/plain
+Content: Your approval is requested for the PO ticket {$Tickets{"TOP"}->Id}: {$Tickets{"TOP"}->Subject}
+Blah
+Blah
+ENDOFCONTENT
+';
+
+my $apptemp = RT::Template->new($RT::SystemUser);
+$apptemp->Create( Content => $approvals, Name => "PO Approvals", Queue => "0");
+
+ok($apptemp->Id);
+
+$q = RT::Queue->new($RT::SystemUser);
+$q->Create(Name => 'PO');
+ok ($q->Id, "Created PO queue");
+
+my $scrip = RT::Scrip->new($RT::SystemUser);
+my ($sval, $smsg) =$scrip->Create( ScripCondition => 'On Create',
+ ScripAction => 'Create Tickets',
+ Template => 'PO Approvals',
+ Queue => $q->Id,
+ Description => 'Create Approval Tickets');
+ok ($sval, $smsg);
+ok ($scrip->Id, "Created the scrip");
+ok ($scrip->TemplateObj->Id, "Created the scrip template");
+ok ($scrip->ConditionObj->Id, "Created the scrip condition");
+ok ($scrip->ActionObj->Id, "Created the scrip action");
+
+my $t = RT::Ticket->new($RT::SystemUser);
+my ($tid, $ttrans, $tmsg);
+
+mail_ok {
+ ( $tid, $ttrans, $tmsg ) = $t->Create(
+ Subject => "PO for stationary",
+ Owner => "root",
+ Requestor => 'minion',
+ Queue => $q->Id,
+ );
+} { from => qr/RT System/,
+ bcc => qr/ceo.*coo|coo.*ceo/i,
+ subject => qr/PO for stationary/i,
+},
+{ from => qr/RT System/,
+ to => 'cto@company.com',
+ subject => qr/New Pending Approval: CTO Approval/,
+ body => qr/pending your approval.*Your approval is requested.*Blah/s
+},
+{ from => qr/PO via RT/,
+ to => 'minion@company.com',
+ subject => qr/PO for stationary/,
+ body => qr/automatically generated in response/
+};
+
+ok ($tid,$tmsg);
+
+is ($t->DependsOn->Count, 1, "depends on one ticket");
+my $t_cto = RT::Ticket->new( $RT::SystemUser );
+$t_cto->Load( $t->DependsOn->First->TargetObj->id );
+
+is_deeply(
+ [ $t->Status, $t_cto->Status ],
+ [ 'new', 'open' ],
+ 'tickets in correct state'
+);
+
+mail_ok {
+ my $cto = RT::CurrentUser->new;
+ $cto->Load( $users{cto} );
+
+ $t_cto->CurrentUser($cto);
+ my $notes = MIME::Entity->build(
+ Data => [ 'Resources exist to be consumed.' ]
+ );
+ RT::I18N::SetMIMEEntityToUTF8($notes); # convert text parts into utf-8
+
+ my ( $notesval, $notesmsg ) = $t_cto->Correspond( MIMEObj => $notes );
+ ok($notesval, $notesmsg);
+
+ my ($ok, $msg) = $t_cto->SetStatus( Status => 'resolved' );
+ ok($ok, "cto can approve - $msg");
+ }
+{
+ from => qr/CTO/,
+ bcc => qr/ceo.*coo|coo.*ceo/i,
+ body => qr/Resources exist to be consumed/,
+},
+{
+ from => qr/RT System/,
+ to => 'minion@company.com',
+ subject => qr/Ticket Approved:/,
+ body => qr/approved by CTO.*notes: Resources exist to be consumed/s
+},
+{
+ from => qr/CTO/,
+ to => 'root@localhost',
+ subject => qr/Ticket Approved:/,
+ body => qr/The ticket has been approved, you may now start to act on it/,
+};
+
+is_deeply(
+ [ $t->Status, $t_cto->Status ],
+ [ 'new', 'resolved' ],
+ 'ticket state after coo approval'
+);
+
+for my $admin (qw/coo ceo/) {
+ $t_cto->_Set(
+ Field => 'Status',
+ Value => 'open',
+ );
+
+ RT::Test->clean_caught_mails;
+
+ mail_ok {
+ my $user = RT::CurrentUser->new;
+ $user->Load( $users{$admin} );
+
+ $t_cto->CurrentUser($user);
+ my $notes =
+ MIME::Entity->build( Data => ['Resources exist to be consumed.'] );
+ RT::I18N::SetMIMEEntityToUTF8($notes); # convert text parts into utf-8
+
+ my ( $notesval, $notesmsg ) = $t_cto->Correspond( MIMEObj => $notes );
+ ok( $notesval, $notesmsg );
+
+ my ( $ok, $msg ) = $t_cto->SetStatus( Status => 'resolved' );
+ ok( $ok, "cto can approve - $msg" );
+ }
+ {
+ from => qr/\U$admin/,
+ bcc => $admin eq 'coo' ? qr/ceo/i : qr/coo/,
+ body => qr/Resources exist to be consumed/,
+ },
+ {
+ from => qr/RT System/,
+ to => 'minion@company.com',
+ subject => qr/Ticket Approved:/,
+ body => qr/approved by \U$admin\E.*notes: Resources exist to be consumed/s
+ },
+ {
+ from => qr/\U$admin/,
+ to => 'root@localhost',
+ subject => qr/Ticket Approved:/,
+ body =>
+ qr/The ticket has been approved, you may now start to act on it/,
+ };
+}
+
+# now we test the web
+my $approval_link = $baseurl . '/Approvals/';
+
+$t = RT::Ticket->new($RT::SystemUser);
+( $tid, $ttrans, $tmsg ) = $t->Create(
+ Subject => "first approval",
+ Owner => "root",
+ Requestor => 'minion',
+ Queue => $q->Id,
+);
+ok( $tid, $tmsg );
+
+my $first_ticket = RT::Ticket->new( $RT::SystemUser );
+$first_ticket->Load( $tid );
+my $first_approval = $first_ticket->DependsOn->First->TargetObj;
+
+$t = RT::Ticket->new($RT::SystemUser);
+( $tid, $ttrans, $tmsg ) = $t->Create(
+ Subject => "second approval",
+ Owner => "root",
+ Requestor => 'minion',
+ Queue => $q->Id,
+);
+
+my $second_ticket = RT::Ticket->new( $RT::SystemUser );
+$second_ticket->Load( $tid );
+my $second_approval = $second_ticket->DependsOn->First->TargetObj;
+
+
+ok( $m->login( 'cto', 'password' ), 'logged in as coo' );
+
+my $m_coo = RT::Test::Web->new;
+ok( $m_coo->login( 'coo', 'password' ), 'logged in as coo' );
+
+my $m_ceo = RT::Test::Web->new;
+ok( $m_ceo->login( 'ceo', 'password' ), 'logged in as coo' );
+
+
+$m->get_ok( $approval_link );
+$m_coo->get_ok( $approval_link );
+$m_ceo->get_ok( $approval_link );
+
+$m->content_like( qr/first approval.*second approval/s, 'cto: see both approvals' );
+$m_coo->content_like( qr/first approval.*second approval/s, 'coo: see both approvals' );
+$m_ceo->content_like( qr/first approval.*second approval/s, 'ceo: see both approvals' );
+
+# now let's approve the first one via cto
+$m->content_like( qr/first approval.*second approval/s, 'cto can see both approvals' );
+$m->submit_form(
+ form_number => 3,
+ fields => { 'Approval-' . $first_approval->id . '-Action' => 'approve', },
+);
+
+$m->content_lacks( 'first approval', 'cto: first approval is gone' );
+$m->content_contains( 'second approval', 'cto: second approval is still here' );
+$m_coo->get_ok( $approval_link );
+$m_ceo->get_ok( $approval_link );
+$m_coo->content_lacks( 'first approval', 'coo: first approval is gone' );
+$m_coo->content_contains( 'second approval', 'coo: second approval is still here' );
+$m_ceo->content_lacks( 'first approval', 'ceo: first approval is gone' );
+$m_ceo->content_contains( 'second approval', 'ceo: second approval is still here' );
+
+$m_coo->submit_form(
+ form_number => 3,
+ fields => { 'Approval-' . $second_approval->id . '-Action' => 'approve', },
+);
+
+$m->get_ok( $approval_link );
+$m_ceo->get_ok( $approval_link );
+
+$m->content_lacks( 'second approval', 'cto: second approval is gone too' );
+$m_coo->content_lacks( 'second approval', 'coo: second approval is gone too' );
+$m_ceo->content_lacks( 'second approval', 'ceo: second approval is gone too' );
+
+RT::Test->clean_caught_mails;
diff --git a/rt/t/data/gnupg/emails/special/quoted_inline_signature.txt b/rt/t/data/gnupg/emails/special/quoted_inline_signature.txt
new file mode 100644
index 0000000..131d27a
--- /dev/null
+++ b/rt/t/data/gnupg/emails/special/quoted_inline_signature.txt
@@ -0,0 +1,26 @@
+To: rt-recipient@example.com
+Subject: Test Email ID:4
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: inline
+From: root@localhost
+
+Forwarded email with signature quoted. RT shouldn't bother
+about it.
+
+> ------ Forwarded Message
+> From: Xxx Yyy <xxx.yyy@localhost>
+> Subject: test email
+>
+> -----BEGIN PGP SIGNED MESSAGE-----
+> Hash: SHA1
+>
+> This is a test email with inline signature.
+> ID:4
+> -----BEGIN PGP SIGNATURE-----
+> Version: GnuPG v1.4.6 (GNU/Linux)
+>
+> iD8DBQFGwLI50ygDXYSIHxsRAp40AJ9ErYdLH2SVRXtgRtx7n/FVFOmKDwCgl/0T
+> BeRSaF4Xbi8uGhVIkmU+YCs=
+> =e4u6
+> -----END PGP SIGNATURE-----
diff --git a/rt/t/mail/gnupg-incoming.t b/rt/t/mail/gnupg-incoming.t
index ec31333..230aa9c 100644
--- a/rt/t/mail/gnupg-incoming.t
+++ b/rt/t/mail/gnupg-incoming.t
@@ -34,8 +34,7 @@ RT->Config->Set( 'MailPlugins' => 'Auth::MailFrom', 'Auth::GnuPG' );
my ($baseurl, $m) = RT::Test->started_ok;
# configure key for General queue
-$m->get( $baseurl."?user=root;pass=password" );
-$m->content_like(qr/Logout/, 'we did log in');
+ok( $m->login, 'we did log in' );
$m->get( $baseurl.'/Admin/Queues/');
$m->follow_link_ok( {text => 'General'} );
$m->submit_form( form_number => 3,
diff --git a/rt/t/mail/gnupg-realmail.t b/rt/t/mail/gnupg-realmail.t
index de1d958..198402b 100644
--- a/rt/t/mail/gnupg-realmail.t
+++ b/rt/t/mail/gnupg-realmail.t
@@ -2,7 +2,7 @@
use strict;
use warnings;
-use RT::Test tests => 197;
+use RT::Test tests => 196;
plan skip_all => 'GnuPG required.'
unless eval 'use GnuPG::Interface; 1';
@@ -37,20 +37,11 @@ $m->submit_form( form_number => 3,
fields => { CorrespondAddress => 'rt-recipient@example.com' } );
$m->content_like(qr/rt-recipient\@example.com.* - never/, 'has key info.');
-diag "load Everyone group" if $ENV{'TEST_VERBOSE'};
-my $everyone;
-{
- $everyone = RT::Group->new( $RT::SystemUser );
- $everyone->LoadSystemInternalGroup('Everyone');
- ok $everyone->id, "loaded 'everyone' group";
-}
-
RT::Test->set_rights(
- Principal => $everyone,
+ Principal => 'Everyone',
Right => ['CreateTicket'],
);
-
my $eid = 0;
for my $usage (qw/signed encrypted signed&encrypted/) {
for my $format (qw/MIME inline/) {
diff --git a/rt/t/mail/gnupg-special.t b/rt/t/mail/gnupg-special.t
new file mode 100644
index 0000000..7e50819
--- /dev/null
+++ b/rt/t/mail/gnupg-special.t
@@ -0,0 +1,86 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+use RT::Test tests => 11;
+
+plan skip_all => 'GnuPG required.'
+ unless eval 'use GnuPG::Interface; 1';
+plan skip_all => 'gpg executable is required.'
+ unless RT::Test->find_executable('gpg');
+
+use File::Temp qw(tempdir);
+my $homedir = tempdir( CLEANUP => 1 );
+
+# catch any outgoing emails
+RT::Test->set_mail_catcher;
+
+RT->Config->Set( 'GnuPG',
+ Enable => 1,
+ OutgoingMessagesFormat => 'RFC' );
+
+RT->Config->Set( 'GnuPGOptions',
+ homedir => $homedir,
+ 'no-permission-warning' => undef);
+
+RT->Config->Set( 'MailPlugins' => 'Auth::MailFrom', 'Auth::GnuPG' );
+
+RT::Test->import_gnupg_key('rt-recipient@example.com');
+RT::Test->import_gnupg_key('rt-test@example.com', 'public');
+
+my ($baseurl, $m) = RT::Test->started_ok;
+
+ok( $m->login, 'we did log in' );
+
+# configure key for General queue
+{
+ $m->get( $baseurl.'/Admin/Queues/');
+ $m->follow_link_ok( {text => 'General'} );
+ $m->submit_form(
+ form_number => 3,
+ fields => { CorrespondAddress => 'rt-recipient@example.com' },
+ );
+ $m->content_like(qr/rt-recipient\@example.com.* - never/, 'has key info.');
+}
+
+ok(my $user = RT::User->new($RT::SystemUser));
+ok($user->Load('root'), "Loaded user 'root'");
+$user->SetEmailAddress('recipient@example.com');
+
+RT::Test->set_rights(
+ Principal => 'Everyone',
+ Right => ['CreateTicket'],
+);
+
+{
+ my $id = send_via_mailgate('quoted_inline_signature.txt');
+
+ my $tick = RT::Ticket->new( $RT::SystemUser );
+ $tick->Load( $id );
+ ok ($tick->id, "loaded ticket #$id");
+
+ my $txn = $tick->Transactions->First;
+ my ($msg, @attachments) = @{$txn->Attachments->ItemsArrayRef};
+
+ is( $msg->GetHeader('X-RT-Privacy'),
+ undef,
+ "no privacy is set as this ticket is not encrypted"
+ );
+
+ my @mail = RT::Test->fetch_caught_mails;
+ is(scalar @mail, 1, "autoreply only");
+}
+
+sub send_via_mailgate {
+ my $fname = shift;
+ my $emaildatadir = RT::Test::get_relocatable_dir(File::Spec->updir(),
+ qw(data gnupg emails special));
+ my $file = File::Spec->catfile( $emaildatadir, $fname );
+ my $mail = RT::Test->file_content($file);
+
+ my ($status, $id) = RT::Test->send_via_mailgate($mail);
+ is ($status >> 8, 0, "the mail gateway exited normally");
+ ok ($id, "got id of a newly created ticket - $id");
+ return $id;
+}
+
diff --git a/rt/t/mail/outlook.t b/rt/t/mail/outlook.t
new file mode 100644
index 0000000..15bfa21
--- /dev/null
+++ b/rt/t/mail/outlook.t
@@ -0,0 +1,272 @@
+#!/usr/bin/perl -w
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2004 Best Practical Solutions, LLC
+# <jesse.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
+# This work is made available to you under the terms of Version 2 of
+# the GNU General Public License. A copy of that license should have
+# been provided with this software, but in any event can be snarfed
+# from www.gnu.org.
+#
+# This work is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/copyleft/gpl.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
+=head1 NAME
+
+rt-mailgate - Mail interface to RT3.
+
+=cut
+
+use strict;
+use warnings;
+
+use RT::Test tests => 43;
+my ($baseurl, $m) = RT::Test->started_ok;
+# 12.0 is outlook 2007, 14.0 is 2010
+for my $mailer ( 'Microsoft Office Outlook 12.0', 'Microsoft Outlook 14.0' ) {
+ diag "Test mail with multipart/alternative" if $ENV{'TEST_VERBOSE'};
+ {
+ my $text = <<EOF;
+From: root\@localhost
+X-Mailer: $mailer
+To: rt\@@{[RT->Config->Get('rtname')]}
+Subject: outlook basic test
+Content-Type: multipart/alternative;
+ boundary="----=_NextPart_000_0004_01CB045C.A5A075D0"
+
+------=_NextPart_000_0004_01CB045C.A5A075D0
+Content-Type: text/plain;
+ charset="us-ascii"
+Content-Transfer-Encoding: 7bit
+
+here is the content
+
+
+
+blahmm
+
+another line
+
+
+------=_NextPart_000_0004_01CB045C.A5A075D0
+Content-Type: text/html;
+ charset="us-ascii"
+Content-Transfer-Encoding: quoted-printable
+
+<html>this is fake</html>
+
+
+------=_NextPart_000_0004_01CB045C.A5A075D0--
+
+EOF
+
+ my $content = <<EOF;
+here is the content
+
+blahmm
+another line
+EOF
+ test_email( $text, $content,
+ $mailer . ' with multipart/alternative, \n\n are replaced' );
+ }
+
+ diag "Test mail with multipart/mixed, with multipart/alternative in it"
+ if $ENV{'TEST_VERBOSE'};
+ {
+ my $text = <<EOF;
+From: root\@localhost
+X-Mailer: $mailer
+To: rt\@@{[RT->Config->Get('rtname')]}
+Subject: outlook basic test
+Content-Type: multipart/mixed;
+ boundary="----=_NextPart_000_000F_01CB045E.5222CB40"
+
+------=_NextPart_000_000F_01CB045E.5222CB40
+Content-Type: multipart/alternative;
+ boundary="----=_NextPart_001_0010_01CB045E.5222CB40"
+
+
+------=_NextPart_001_0010_01CB045E.5222CB40
+Content-Type: text/plain;
+ charset="us-ascii"
+Content-Transfer-Encoding: 7bit
+
+foo
+
+
+
+bar
+
+baz
+
+
+------=_NextPart_001_0010_01CB045E.5222CB40
+Content-Type: text/html;
+ charset="us-ascii"
+Content-Transfer-Encoding: quoted-printable
+
+<html>this is fake</html>
+
+------=_NextPart_001_0010_01CB045E.5222CB40--
+
+------=_NextPart_000_000F_01CB045E.5222CB40
+Content-Type: text/plain;
+ name="att.txt"
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: attachment;
+ filename="att.txt"
+
+this is the attachment! :)=0A=
+
+------=_NextPart_000_000F_01CB045E.5222CB40--
+EOF
+
+ my $content = <<EOF;
+foo
+
+bar
+baz
+EOF
+ test_email( $text, $content,
+ $mailer . ' with multipart/multipart, \n\n are replaced' );
+ }
+
+ diag "Test mail with with outlook, but the content type is text/plain"
+ if $ENV{'TEST_VERBOSE'};
+ {
+ my $text = <<EOF;
+From: root\@localhost
+X-Mailer: $mailer
+To: rt\@@{[RT->Config->Get('rtname')]}
+Subject: outlook basic test
+Content-Type: text/plain; charset="us-ascii"
+Content-Transfer-Encoding: 7bit
+
+foo
+
+
+
+bar
+
+baz
+
+EOF
+
+ my $content = <<EOF;
+foo
+
+
+
+bar
+
+baz
+
+EOF
+ test_email( $text, $content,
+ $mailer . ' with only text/plain, \n\n are not replaced' );
+ }
+}
+
+diag "Test mail with with multipart/alternative but x-mailer is not outlook "
+ if $ENV{'TEST_VERBOSE'};
+{
+ my $text = <<EOF;
+From: root\@localhost
+X-Mailer: Mutt
+To: rt\@@{[RT->Config->Get('rtname')]}
+Subject: outlook basic test
+Content-Type: multipart/alternative;
+ boundary="----=_NextPart_000_0004_01CB045C.A5A075D0"
+
+------=_NextPart_000_0004_01CB045C.A5A075D0
+Content-Type: text/plain;
+ charset="us-ascii"
+Content-Transfer-Encoding: 7bit
+
+foo
+
+
+
+bar
+
+baz
+
+
+------=_NextPart_000_0004_01CB045C.A5A075D0
+Content-Type: text/html;
+ charset="us-ascii"
+Content-Transfer-Encoding: quoted-printable
+
+<html>this is fake</html>
+
+
+------=_NextPart_000_0004_01CB045C.A5A075D0--
+
+EOF
+
+ my $content = <<EOF;
+foo
+
+
+
+bar
+
+baz
+
+EOF
+ test_email( $text, $content, 'without outlook, \n\n are not replaced' );
+}
+
+sub test_email {
+ my ( $text, $content, $msg ) = @_;
+ my ( $status, $id ) = RT::Test->send_via_mailgate($text);
+ is( $status >> 8, 0, "The mail gateway exited normally" );
+ ok( $id, "Created ticket" );
+
+ my $ticket = RT::Test->last_ticket;
+ isa_ok( $ticket, 'RT::Ticket' );
+ is( $ticket->Id, $id, "correct ticket id" );
+ is( $ticket->Subject, 'outlook basic test', "subject of ticket $id" );
+ my $txns = $ticket->Transactions;
+ $txns->Limit( FIELD => 'Type', VALUE => 'Create' );
+ my $txn = $txns->First;
+
+ is( $txn->Content, $content, $msg );
+}
+
diff --git a/rt/t/mail/wrong_mime_charset.t b/rt/t/mail/wrong_mime_charset.t
new file mode 100644
index 0000000..f53c872
--- /dev/null
+++ b/rt/t/mail/wrong_mime_charset.t
@@ -0,0 +1,25 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use RT::Test nodata => 1, tests => 3;
+
+use_ok('RT::I18N');
+use utf8;
+use Encode;
+my $test_string = 'À';
+my $encoded_string = encode( 'iso-8859-1', $test_string );
+my $mime = MIME::Entity->build(
+ Subject => $encoded_string,
+ Data => [$encoded_string],
+);
+
+# set the wrong charset mime in purpose
+$mime->head->mime_attr( "Content-Type.charset" => 'utf8' );
+
+RT::I18N::SetMIMEEntityToEncoding( $mime, 'iso-8859-1' );
+my $subject = decode( 'iso-8859-1', $mime->head->get('Subject') );
+chomp $subject;
+is( $subject, $test_string, 'subject is set to iso-8859-1' );
+my $body = decode( 'iso-8859-1', $mime->stringify_body );
+chomp $body;
+is( $body, $test_string, 'body is set to iso-8859-1' );
diff --git a/rt/t/web/attachment_encoding.t b/rt/t/web/attachment_encoding.t
new file mode 100644
index 0000000..6796c99
--- /dev/null
+++ b/rt/t/web/attachment_encoding.t
@@ -0,0 +1,103 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 28;
+use Encode;
+my ( $baseurl, $m ) = RT::Test->started_ok;
+ok $m->login, 'logged in as root';
+
+$RT::Test::SKIP_REQUEST_WORK_AROUND = 1;
+
+use utf8;
+
+use File::Spec;
+
+diag 'test without attachments' if $ENV{TEST_VERBOSE};
+
+{
+ $m->get_ok( $baseurl . '/Ticket/Create.html?Queue=1' );
+
+ $m->form_number(3);
+ $m->submit_form(
+ form_number => 3,
+ fields => { Subject => '标题', Content => '测试' },
+ );
+ $m->content_like( qr/Ticket \d+ created/i, 'created the ticket' );
+ $m->follow_link_ok( { text => 'with headers' },
+ '-> /Ticket/Attachment/WithHeaders/...' );
+ $m->content_contains( '标题', 'has subject 标题' );
+ $m->content_contains( '测试', 'has content 测试' );
+
+ my ( $id ) = $m->uri =~ /(\d+)$/;
+ ok( $id, 'found attachment id' );
+ my $attachment = RT::Attachment->new( $RT::SystemUser );
+ ok($attachment->Load($id), "load att $id");
+ # let make original encoding to gbk
+ ok( $attachment->SetHeader( 'X-RT-Original-Encoding' => 'gbk' ),
+ 'set original encoding to gbk' );
+ $m->get( $m->uri );
+ $m->content_contains( '标题', 'has subject 标题' );
+ $m->content_contains( '测试', 'has content 测试' );
+}
+
+diag 'test with attachemnts' if $ENV{TEST_VERBOSE};
+
+{
+
+ my $file =
+ File::Spec->catfile( File::Spec->tmpdir, 'rt_attachemnt_abcde.txt' );
+ open my $fh, '>', $file or die $!;
+ binmode $fh, ':utf8';
+ print $fh '附件';
+ close $fh;
+
+ $m->get_ok( $baseurl . '/Ticket/Create.html?Queue=1' );
+
+ $m->form_number(3);
+ $m->submit_form(
+ form_number => 3,
+ fields => { Subject => '标题', Content => '测试', Attach => $file },
+ );
+ $m->content_like( qr/Ticket \d+ created/i, 'created the ticket' );
+ $m->follow_link_ok( { text => 'with headers' },
+ '-> /Ticket/Attachment/WithHeaders/...' );
+
+ # subject is in the parent attachment, so there is no 标题
+ $m->content_lacks( '标题', 'does not have content 标题' );
+ $m->content_contains( '测试', 'has content 测试' );
+
+ my ( $id ) = $m->uri =~ /(\d+)$/;
+ ok( $id, 'found attachment id' );
+ my $attachment = RT::Attachment->new( $RT::SystemUser );
+ ok($attachment->Load($id), "load att $id");
+ # let make original encoding to gbk
+ ok( $attachment->SetHeader( 'X-RT-Original-Encoding' => 'gbk' ),
+ 'set original encoding to gbk' );
+ $m->get( $m->uri );
+ $m->content_lacks( '标题', 'does not have content 标题' );
+ $m->content_contains( '测试', 'has content 测试' );
+
+
+ $m->back;
+ $m->back;
+ $m->follow_link_ok( { text_regex => qr/by Enoch Root/ },
+ '-> /Ticket/Attachment/...' );
+ $m->content_contains( '附件', 'has content 附件' );
+
+ ( $id ) = $m->uri =~ /(\d+)\D+$/;
+ ok( $id, 'found attachment id' );
+ $attachment = RT::Attachment->new( $RT::SystemUser );
+ ok($attachment->Load($id), "load att $id");
+
+ # let make original encoding to gbk
+ ok( $attachment->SetHeader( 'X-RT-Original-Encoding' => 'gbk' ),
+ 'set original encoding to gbk' );
+ $m->get( $m->uri );
+ $m->content_contains( '附件', 'has content 附件' );
+
+ unlink $file;
+}
+
+
diff --git a/rt/t/web/basic.t b/rt/t/web/basic.t
index bc4d655..3f94e73 100644
--- a/rt/t/web/basic.t
+++ b/rt/t/web/basic.t
@@ -4,7 +4,7 @@ use strict;
use warnings;
use Encode;
-use RT::Test tests => 24;
+use RT::Test tests => 21;
$RT::Test::SKIP_REQUEST_WORK_AROUND = 1;
my ($baseurl, $agent) = RT::Test->started_ok;
@@ -20,15 +20,8 @@ diag $url if $ENV{TEST_VERBOSE};
# test a login
{
- ok($agent->{form}->find_input('user'));
- ok($agent->{form}->find_input('pass'));
-
- ok($agent->{'content'} =~ /username:/i);
- $agent->field( 'user' => 'root' );
- $agent->field( 'pass' => 'password' );
-
+ $agent->login('root' => 'password');
# the field isn't named, so we have to click link 0
- $agent->click(0);
is( $agent->{'status'}, 200, "Fetched the page ok");
ok( $agent->{'content'} =~ /Logout/i, "Found a logout link");
}
diff --git a/rt/t/web/cf_select_one.t b/rt/t/web/cf_select_one.t
index 39a8080..26c1fcf 100644
--- a/rt/t/web/cf_select_one.t
+++ b/rt/t/web/cf_select_one.t
@@ -3,7 +3,7 @@
use strict;
use warnings;
-use RT::Test tests => 41;
+use RT::Test tests => 46;
my ($baseurl, $m) = RT::Test->started_ok;
ok $m->login, 'logged in as root';
@@ -31,9 +31,9 @@ diag "Create a CF" if $ENV{'TEST_VERBOSE'};
ok $cfid, "found id of the CF in the form, it's #$cfid";
}
-diag "add 'qwe', 'ASD' and '0' as values to the CF" if $ENV{'TEST_VERBOSE'};
+diag "add 'qwe', 'ASD', '0' and ' foo ' as values to the CF" if $ENV{'TEST_VERBOSE'};
{
- foreach my $value(qw(qwe ASD 0)) {
+ foreach my $value(qw(qwe ASD 0), 'foo ') {
$m->submit_form(
form_name => "ModifyCustomField",
fields => {
@@ -42,6 +42,10 @@ diag "add 'qwe', 'ASD' and '0' as values to the CF" if $ENV{'TEST_VERBOSE'};
button => 'Update',
);
$m->content_like( qr/Object created/, 'added a value to the CF' ); # or diag $m->content;
+ my $v = $value;
+ $v =~ s/^\s+$//;
+ $v =~ s/\s+$//;
+ $m->content_like( qr/value="$v"/, 'the added value is right' );
}
}
diff --git a/rt/t/web/compilation_errors.t b/rt/t/web/compilation_errors.t
index 46a8628..4fd9c40 100644
--- a/rt/t/web/compilation_errors.t
+++ b/rt/t/web/compilation_errors.t
@@ -7,7 +7,7 @@ BEGIN {
sub wanted {
-f && /\.html$/ && $_ !~ /Logout.html$/;
}
- my $tests = 7;
+ my $tests = 4;
find( sub { wanted() and $tests += 4 }, 'share/html/' );
plan tests => $tests;
}
@@ -36,15 +36,7 @@ is ($agent->{'status'}, 200, "Loaded a page");
# {{{ test a login
# follow the link marked "Login"
-
-ok($agent->{form}->find_input('user'));
-
-ok($agent->{form}->find_input('pass'));
-like ($agent->{'content'} , qr/username:/i);
-$agent->field( 'user' => 'root' );
-$agent->field( 'pass' => 'password' );
-# the field isn't named, so we have to click link 0
-$agent->click(0);
+$agent->login(root => 'password');
is($agent->{'status'}, 200, "Fetched the page ok");
like( $agent->{'content'} , qr/Logout/i, "Found a logout link");
diff --git a/rt/t/web/html_template.t b/rt/t/web/html_template.t
new file mode 100644
index 0000000..a2461dc
--- /dev/null
+++ b/rt/t/web/html_template.t
@@ -0,0 +1,78 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 19;
+use Encode;
+my ( $baseurl, $m ) = RT::Test->started_ok;
+ok $m->login, 'logged in as root';
+
+$RT::Test::SKIP_REQUEST_WORK_AROUND = 1;
+RT::Test->set_mail_catcher;
+
+use utf8;
+
+diag('make Autoreply template a html one and add utf8 chars')
+ if $ENV{TEST_VERBOSE};
+
+{
+ $m->follow_link_ok( { text => 'Configuration' }, '-> Configuration' );
+ $m->follow_link_ok( { text => 'Global' }, '-> Global' );
+ $m->follow_link_ok( { text => 'Templates' }, '-> Templates' );
+ $m->follow_link_ok( { text => 'Autoreply' }, '-> Autoreply' );
+
+ $m->form_number(3);
+ $m->submit_form(
+ fields => {
+ Content => <<'EOF',
+Subject: AutoReply: {$Ticket->Subject}
+Content-Type: text/html
+
+你好 éèà€
+{$Ticket->Subject}
+-------------------------------------------------------------------------
+{$Transaction->Content()}
+
+EOF
+ },
+ );
+ $m->content_like( qr/Content changed/, 'content is changed' );
+ $m->content_contains( '你好', 'content is really updated' );
+}
+
+diag('create a ticket to see the autoreply mail') if $ENV{TEST_VERBOSE};
+
+{
+ $m->get_ok( $baseurl . '/Ticket/Create.html?Queue=1' );
+
+ $m->form_number(3);
+ $m->submit_form(
+ form_number => 3,
+ fields => { Subject => '标题', Content => '<h1>测试</h1>',
+ ContentType => 'text/html' },
+ );
+ $m->content_like( qr/Ticket \d+ created/i, 'created the ticket' );
+ $m->follow_link( text => 'Show' );
+ $m->content_contains( '你好', 'html has 你好' );
+ $m->content_contains( 'éèà€', 'html has éèà€' );
+ $m->content_contains( '标题',
+ 'html has ticket subject 标题' );
+ $m->content_contains( '&lt;h1&gt;测试&lt;/h1&gt;',
+ 'html has ticket html content 测试' );
+}
+
+diag('test real mail outgoing') if $ENV{TEST_VERBOSE};
+
+{
+
+ # $mail is utf8 encoded
+ my ($mail) = RT::Test->fetch_caught_mails;
+ $mail = decode_utf8 $mail;
+ like( $mail, qr/你好.*你好/s, 'mail has éèà€' );
+ like( $mail, qr/éèà€.*éèà€/s, 'mail has éèà€' );
+ like( $mail, qr/标题.*标题/s, 'mail has ticket subject 标题' );
+ like( $mail, qr/测试.*测试/s, 'mail has ticket content 测试' );
+ like( $mail, qr!<h1>测试</h1>!, 'mail has ticket html content 测试' );
+}
+
diff --git a/rt/t/web/offline_messages_utf8.t b/rt/t/web/offline_messages_utf8.t
index c32e0bc..9901b45 100644
--- a/rt/t/web/offline_messages_utf8.t
+++ b/rt/t/web/offline_messages_utf8.t
@@ -8,7 +8,7 @@ use Encode;
use RT::Ticket;
my ( $url, $m ) = RT::Test->started_ok;
-$m->default_header( 'Accept-Language' => "zh-cn" );
+$m->default_header( 'Accept-Language' => "zh-tw" );
ok( $m->login, 'logged in' );
my $ticket_id;
@@ -38,7 +38,7 @@ EOF
button => 'UpdateTickets',
);
my $content = encode 'utf8', $m->content;
- ok( $content =~ qr/申请单 #(\d+) 成功新增于 &#39;General&#39; 表单/, 'message is shown right' );
+ ok( $content =~ m/申請單 #(\d+) 成功新增於 &#39;General&#39; 表單/, 'message is shown right' );
$ticket_id = $1;
}
@@ -60,7 +60,7 @@ EOF
my $content = encode 'utf8', $m->content;
ok(
$content =~
-qr/主题\s*的值从\s*&#39;test message&#39;\s*改为\s*&#39;test message update&#39;/,
+qr/主題\s*的值從\s*&#39;test message&#39;\s*改為\s*&#39;test message update&#39;/,
'subject is updated'
);
}
diff --git a/rt/t/web/query_builder.t b/rt/t/web/query_builder.t
index 02ed129..fa2c56d 100644
--- a/rt/t/web/query_builder.t
+++ b/rt/t/web/query_builder.t
@@ -5,7 +5,7 @@ use HTTP::Request::Common;
use HTTP::Cookies;
use LWP;
use Encode;
-use RT::Test tests => 42;
+use RT::Test tests => 44;
my $cookie_jar = HTTP::Cookies->new;
my ($baseurl, $agent) = RT::Test->started_ok;
@@ -246,4 +246,13 @@ diag "input a condition, select (several conditions), click delete"
);
}
-1;
+diag "send query with not quoted negative number";
+{
+ my $response = $agent->get($url."Search/Build.html?Query=Priority%20>%20-2");
+ ok( $response->is_success, "Fetched " . $url."Search/Build.html" );
+
+ is( getQueryFromForm,
+ "Priority > -2",
+ "query is the same"
+ );
+}
diff --git a/rt/t/web/redirect-after-login.t b/rt/t/web/redirect-after-login.t
new file mode 100644
index 0000000..d39bb58
--- /dev/null
+++ b/rt/t/web/redirect-after-login.t
@@ -0,0 +1,243 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 120;
+
+my ($baseurl, $agent) = RT::Test->started_ok;
+
+my $url = $agent->rt_base_url;
+diag $url if $ENV{TEST_VERBOSE};
+
+# test a login from the main page
+{
+ $agent->get_ok($url);
+ is($agent->{'status'}, 200, "Loaded a page");
+ is($agent->uri, $url, "didn't redirect to /NoAuth/Login.html for base URL");
+ ok($agent->current_form->find_input('user'));
+ ok($agent->current_form->find_input('pass'));
+ like($agent->current_form->action, qr{/NoAuth/Login\.html$}, "login form action is correct");
+
+ ok($agent->content =~ /username:/i);
+ $agent->field( 'user' => 'root' );
+ $agent->field( 'pass' => 'password' );
+
+ # the field isn't named, so we have to click link 0
+ $agent->click(0);
+ is( $agent->status, 200, "Fetched the page ok");
+ ok( $agent->content =~ /Logout/i, "Found a logout link");
+ is( $agent->uri, $url, "right URL" );
+ like( $agent->{redirected_uri}, qr{/NoAuth/Login\.html$}, "We redirected from login");
+ $agent->logout();
+}
+
+# test a bogus login from the main page
+{
+ $agent->get_ok($url);
+ is($agent->{'status'}, 200, "Loaded a page");
+ is($agent->uri, $url, "didn't redirect to /NoAuth/Login.html for base URL");
+ ok($agent->current_form->find_input('user'));
+ ok($agent->current_form->find_input('pass'));
+ like($agent->current_form->action, qr{/NoAuth/Login\.html$}, "login form action is correct");
+
+ ok($agent->content =~ /username:/i);
+ $agent->field( 'user' => 'root' );
+ $agent->field( 'pass' => 'wrongpass' );
+
+ # the field isn't named, so we have to click link 0
+ $agent->click(0);
+ is( $agent->status, 200, "Fetched the page ok");
+
+ ok( $agent->content =~ /Your username or password is incorrect/i, "Found the error message");
+ like( $agent->uri, qr{/NoAuth/Login\.html$}, "now on /NoAuth/Login.html" );
+ $agent->logout();
+
+ # Handle the warning after we're done with the page, since this leaves us
+ # with a completely different $mech
+ $agent->warning_like(qr/FAILED LOGIN for root/, "got failed login warning");
+}
+
+# test a login from a non-front page, both with a double leading slash and without
+for my $path (qw(Prefs/Other.html /Prefs/Other.html)) {
+ my $requested = $url.$path;
+ $agent->get_ok($requested);
+ is($agent->status, 200, "Loaded a page");
+ like($agent->uri, qr'/NoAuth/Login\.html\?next=[a-z0-9]{32}', "on login page, with next page hash");
+ is($agent->{redirected_uri}, $requested, "redirected from our requested page");
+
+ ok($agent->current_form->find_input('user'));
+ ok($agent->current_form->find_input('pass'));
+ ok($agent->current_form->find_input('next'));
+ like($agent->value('next'), qr/^[a-z0-9]{32}$/i, "next page argument is a hash");
+ like($agent->current_form->action, qr{/NoAuth/Login\.html$}, "login form action is correct");
+
+ ok($agent->content =~ /username:/i);
+ $agent->field( 'user' => 'root' );
+ $agent->field( 'pass' => 'password' );
+
+ # the field isn't named, so we have to click link 0
+ $agent->click(0);
+ is( $agent->status, 200, "Fetched the page ok");
+ ok( $agent->content =~ /Logout/i, "Found a logout link");
+
+ if ($path =~ m{/}) {
+ (my $collapsed = $path) =~ s{^/}{};
+ is( $agent->uri, $url.$collapsed, "right URL, with leading slashes in path collapsed" );
+ } else {
+ is( $agent->uri, $requested, "right URL" );
+ }
+
+ like( $agent->{redirected_uri}, qr{/NoAuth/Login\.html}, "We redirected from login");
+ $agent->logout();
+}
+
+# test a bogus login from a non-front page
+{
+ my $requested = $url.'Prefs/Other.html';
+ $agent->get_ok($requested);
+ is($agent->status, 200, "Loaded a page");
+ like($agent->uri, qr'/NoAuth/Login\.html\?next=[a-z0-9]{32}', "on login page, with next page hash");
+ is($agent->{redirected_uri}, $requested, "redirected from our requested page");
+
+ ok($agent->current_form->find_input('user'));
+ ok($agent->current_form->find_input('pass'));
+ ok($agent->current_form->find_input('next'));
+ like($agent->value('next'), qr/^[a-z0-9]{32}$/i, "next page argument is a hash");
+ like($agent->current_form->action, qr{/NoAuth/Login\.html$}, "login form action is correct");
+
+ ok($agent->content =~ /username:/i);
+ $agent->field( 'user' => 'root' );
+ $agent->field( 'pass' => 'wrongpass' );
+
+ # the field isn't named, so we have to click link 0
+ $agent->click(0);
+ is( $agent->status, 200, "Fetched the page ok");
+
+ ok( $agent->content =~ /Your username or password is incorrect/i, "Found the error message");
+ like( $agent->uri, qr{/NoAuth/Login\.html$}, "still on /NoAuth/Login.html" );
+
+ # try to login again
+ ok($agent->current_form->find_input('user'));
+ ok($agent->current_form->find_input('pass'));
+ ok($agent->current_form->find_input('next'));
+ like($agent->value('next'), qr/^[a-z0-9]{32}$/i, "next page argument is a hash");
+ like($agent->current_form->action, qr{/NoAuth/Login\.html$}, "login form action is correct");
+
+ ok($agent->content =~ /username:/i);
+ $agent->field( 'user' => 'root' );
+ $agent->field( 'pass' => 'password' );
+
+ # the field isn't named, so we have to click link 0
+ $agent->click(0);
+ is( $agent->status, 200, "Fetched the page ok");
+
+ # check out where we got to
+ is( $agent->uri, $requested, "right URL" );
+ like( $agent->{redirected_uri}, qr{/NoAuth/Login\.html}, "We redirected from login");
+ $agent->logout();
+
+ # Handle the warning after we're done with the page, since this leaves us
+ # with a completely different $mech
+ $agent->warning_like(qr/FAILED LOGIN for root/, "got failed login warning");
+}
+
+# test a login from the main page with query params
+{
+ my $requested = $url."?user=root;pass=password";
+ $agent->get_ok($requested);
+ is($agent->{'status'}, 200, "Loaded a page");
+ is($agent->uri, $requested, "didn't redirect to /NoAuth/Login.html for base URL");
+ ok($agent->content =~ /Logout/i, "Found a logout link - we're logged in");
+ $agent->logout();
+}
+
+# test a bogus login from the main page with query params
+{
+ my $requested = $url."?user=root;pass=wrongpass";
+ $agent->get_ok($requested);
+ is($agent->{'status'}, 200, "Loaded a page");
+ is($agent->uri, $requested, "didn't redirect to /NoAuth/Login.html for base URL");
+
+ ok($agent->content =~ /Your username or password is incorrect/i, "Found the error message");
+ ok($agent->current_form->find_input('user'));
+ ok($agent->current_form->find_input('pass'));
+ like($agent->current_form->action, qr{/NoAuth/Login\.html$}, "login form action is correct");
+
+ # Handle the warning after we're done with the page, since this leaves us
+ # with a completely different $mech
+ $agent->warning_like(qr/FAILED LOGIN for root/, "got failed login warning");
+}
+
+# test a bogus login from a non-front page with query params
+{
+ my $requested = $url."Prefs/Other.html?user=root;pass=wrongpass";
+ $agent->get_ok($requested);
+ is($agent->status, 200, "Loaded a page");
+ like($agent->uri, qr'/NoAuth/Login\.html\?next=[a-z0-9]{32}', "on login page, with next page hash");
+ is($agent->{redirected_uri}, $requested, "redirected from our requested page");
+ ok( $agent->content =~ /Your username or password is incorrect/i, "Found the error message");
+
+ ok($agent->current_form->find_input('user'));
+ ok($agent->current_form->find_input('pass'));
+ ok($agent->current_form->find_input('next'));
+ like($agent->value('next'), qr/^[a-z0-9]{32}$/i, "next page argument is a hash");
+ like($agent->current_form->action, qr{/NoAuth/Login\.html$}, "login form action is correct");
+
+ # Try to login again
+ ok($agent->content =~ /username:/i);
+ $agent->field( 'user' => 'root' );
+ $agent->field( 'pass' => 'password' );
+
+ # the field isn't named, so we have to click link 0
+ $agent->click(0);
+ is( $agent->status, 200, "Fetched the page ok");
+
+ # check out where we got to
+ is( $agent->uri, $requested, "right URL" );
+ like( $agent->{redirected_uri}, qr{/NoAuth/Login\.html}, "We redirected from login");
+ $agent->logout();
+
+ # Handle the warning after we're done with the page, since this leaves us
+ # with a completely different $mech
+ $agent->warning_like(qr/FAILED LOGIN for root/, "got failed login warning");
+}
+
+# test REST login response
+{
+ my $requested = $url."REST/1.0/?user=root;pass=password";
+ $agent->get($requested);
+ is($agent->status, 200, "Loaded a page");
+ is($agent->uri, $requested, "didn't redirect to /NoAuth/Login.html for REST");
+ $agent->get_ok($url);
+ $agent->logout();
+}
+
+# test REST login response for wrong pass
+{
+ my $requested = $url."REST/1.0/?user=root;pass=passwrong";
+ $agent->get_ok($requested);
+ is($agent->status, 200, "Loaded a page");
+ is($agent->uri, $requested, "didn't redirect to /NoAuth/Login.html for REST");
+ like($agent->content, qr/401 Credentials required/i, "got error status");
+ like($agent->content, qr/Your username or password is incorrect/, "got error message");
+
+ # Handle the warning after we're done with the page, since this leaves us
+ # with a completely different $mech
+ $agent->warning_like(qr/FAILED LOGIN for root/, "got failed login warning");
+}
+
+# test REST login response for no creds
+{
+ my $requested = $url."REST/1.0/";
+ $agent->get_ok($requested);
+ is($agent->status, 200, "Loaded a page");
+ is($agent->uri, $requested, "didn't redirect to /NoAuth/Login.html for REST");
+ like($agent->content, qr/401 Credentials required/i, "got error status");
+ unlike($agent->content, qr/Your username or password is incorrect/, "didn't get any error message");
+}
+
+# XXX TODO: we should also be testing WebExternalAuth here, but we don't have
+# the framework for dealing with that
+
+1;
diff --git a/rt/t/web/rest-non-ascii-subject.t b/rt/t/web/rest-non-ascii-subject.t
index 70c910a..371b2ff 100644
--- a/rt/t/web/rest-non-ascii-subject.t
+++ b/rt/t/web/rest-non-ascii-subject.t
@@ -49,7 +49,4 @@ is($ticket->Subject, $subject, "ticket subject successfully set");
my $attach = $ticket->Transactions->First->Attachments->First;
is($attach->Subject, $subject, "attachement subject successfully set");
-TODO: {
- local $TODO = "Not fixed yet, but not a regression";
- is($attach->GetHeader('Subject'), $subject, "attachement header subject successfully set");
-}
+is($attach->GetHeader('Subject'), $subject, "attachement header subject successfully set");
diff --git a/rt/t/web/rights1.t b/rt/t/web/rights1.t
index 6da204c..c8892f2 100644
--- a/rt/t/web/rights1.t
+++ b/rt/t/web/rights1.t
@@ -2,7 +2,7 @@
use strict;
use HTTP::Cookies;
-use RT::Test tests => 35;
+use RT::Test tests => 29;
my ($baseurl, $agent) = RT::Test->started_ok;
# Create a user with basically no rights, to start.
@@ -26,7 +26,7 @@ $agent->cookie_jar($cookie_jar);
no warnings 'once';
# get the top page
-login($agent, $user_obj);
+$agent->login( $user_obj->Name, 'customer');
# Test for absence of Configure and Preferences tabs.
ok(!$agent->find_link( url => "$RT::WebPath/Admin/",
@@ -107,28 +107,4 @@ ok($agent->form_name('BuildQuery'), "Yep, form is still there");
my $input = $agent->current_form->find_input('ValueOfActor');
ok(grep(/customer-$$/, $input->value_names()), "Found self in the actor listing");
-sub login {
- my $agent = shift;
-
- my $url = "http://localhost:" . RT->Config->Get('WebPort') . RT->Config->Get('WebPath') . "/";
- $agent->get($url);
- is( $agent->{'status'}, 200,
- "Loaded a page - http://localhost" . RT->Config->Get('WebPath') );
-
- # {{{ test a login
-
- # follow the link marked "Login"
-
- ok( $agent->{form}->find_input('user') );
-
- ok( $agent->{form}->find_input('pass') );
- like( $agent->{'content'} , qr/username:/i );
- $agent->field( 'user' => $user_obj->Name );
- $agent->field( 'pass' => 'customer' );
-
- # the field isn't named, so we have to click link 0
- $agent->click(0);
- is( $agent->{'status'}, 200, "Fetched the page ok" );
- like( $agent->{'content'} , qr/Logout/i, "Found a logout link" );
-}
1;
diff --git a/rt/t/web/saved_search_update.t b/rt/t/web/saved_search_update.t
new file mode 100644
index 0000000..9b2724e
--- /dev/null
+++ b/rt/t/web/saved_search_update.t
@@ -0,0 +1,63 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 16;
+
+my $root = RT::User->new( $RT::SystemUser );
+$root->Load('root');
+my $uid = $root->id;
+ok( $uid, 'loaded root' );
+
+my $group = RT::Group->new( $RT::SystemUser );
+my ($gid) = $group->CreateUserDefinedGroup( Name => 'foo' );
+ok( $gid, 'created group foo');
+ok( $group->AddMember( $root->PrincipalId ) );
+
+my ( $baseurl, $m ) = RT::Test->started_ok;
+ok($m->login, 'logged in');
+
+$m->follow_link_ok({text => "Tickets"}, "to query builder");
+
+$m->form_name("BuildQuery");
+
+$m->field(ValueOfid => 10 );
+$m->click("AddClause");
+$m->content_contains( 'id &lt; 10', "added new clause");
+
+$m->form_name("BuildQuery");
+$m->field(SavedSearchDescription => 'user_saved');
+$m->click("SavedSearchSave");
+
+$m->form_name("BuildQuery");
+is($m->value('SavedSearchDescription'), 'user_saved', "name is correct");
+like($m->value('SavedSearchOwner'), qr/^RT::User-\d+$/, "name is correct");
+ok(
+ scalar grep { $_ eq "RT::Group-$gid" }
+ $m->current_form->find_input('SavedSearchOwner')->possible_values,
+ 'found group foo'
+);
+$m->field(SavedSearchDescription => 'group_saved');
+$m->select(SavedSearchOwner => "RT::Group-$gid");
+$m->click("SavedSearchSave");
+
+$m->form_name("BuildQuery");
+is($m->value('SavedSearchOwner'), "RT::Group-$gid", "privacy is correct");
+is($m->value('SavedSearchDescription'), 'group_saved', "name is correct");
+$m->select(SavedSearchOwner => "RT::User-$uid");
+$m->field(SavedSearchDescription => 'user_saved');
+$m->click("SavedSearchSave");
+
+
+$m->form_name("BuildQuery");
+is($m->value('SavedSearchOwner'), "RT::User-$uid", "privacy is correct");
+is($m->value('SavedSearchDescription'), 'user_saved', "name is correct");
+$m->select(SavedSearchOwner => "RT::System-1");
+$m->field(SavedSearchDescription => 'system_saved');
+$m->click("SavedSearchSave");
+
+$m->form_name("BuildQuery");
+is($m->value('SavedSearchOwner'), "RT::System-1", "privacy is correct");
+is($m->value('SavedSearchDescription'), 'system_saved', "name is correct");
+
diff --git a/rt/t/web/ticket_seen.t b/rt/t/web/ticket_seen.t
index 00b2632..3a77a58 100644
--- a/rt/t/web/ticket_seen.t
+++ b/rt/t/web/ticket_seen.t
@@ -3,7 +3,7 @@
use strict;
use warnings;
-use RT::Test tests => 16;
+use RT::Test tests => 21;
my $queue = RT::Test->load_or_create_queue( Name => 'Regression' );
ok $queue && $queue->id, 'loaded or created queue';
@@ -52,6 +52,14 @@ diag "user B adds a message, we check that user A see notification and can clear
my ($status, $msg) = $ticket->Correspond( Content => 'bla-bla' );
ok $status, 'added reply' or diag "error: $msg";
+ my $txns = $ticket->Transactions;
+ $txns->Limit(
+ FIELD => 'Type',
+ VALUE => "Correspond",
+ );
+ my $txn = $txns->Last;
+ my $reply_id = $txn->id;
+ ok( $reply_id, 'got correspond txn id' );
$agent_a->goto_ticket($tid);
$agent_a->content_like(qr/bla-bla/ims, 'the message on the page');
@@ -61,11 +69,23 @@ diag "user B adds a message, we check that user A see notification and can clear
'we have not seen something'
);
+ $agent_a->follow_link_ok(
+ { text => 'jump to the first unread message' },
+ 'try to jump to first unread message'
+ );
+ like( $agent_a->base, qr/#txn-$reply_id$/, 'contains anchor' );
+
$agent_a->follow_link_ok({text => 'jump to the first unread message and mark all messages as seen'}, 'try to mark all as seen');
$agent_a->content_like(
qr/Marked all messages as seen/ims,
'see success message'
);
+ like( $agent_a->base, qr/#txn-$reply_id$/, 'contains anchor' );
+
+ $agent_a->content_like(
+ qr/Marked all messages as seen/ims,
+ 'see success message'
+ );
$agent_a->goto_ticket($tid);
$agent_a->content_unlike(
@@ -74,7 +94,3 @@ diag "user B adds a message, we check that user A see notification and can clear
);
}
-
-
-
-
diff --git a/rt/t/web/ticket_txn_content.t b/rt/t/web/ticket_txn_content.t
new file mode 100644
index 0000000..1c1056a
--- /dev/null
+++ b/rt/t/web/ticket_txn_content.t
@@ -0,0 +1,79 @@
+#!/usr/bin/perl -w
+use strict;
+
+use RT::Test tests => 37;
+use File::Temp 'tempfile';
+use File::Spec;
+my ( $plain_fh, $plain_file ) =
+ tempfile( 'rttestXXXXXX', SUFFIX => '.txt', UNLINK => 1, TMPDIR => 1 );
+print $plain_fh "this is plain content";
+close $plain_fh;
+my $plain_name = (File::Spec->splitpath($plain_file))[-1];
+
+my ( $html_fh, $html_file ) =
+ tempfile( 'rttestXXXXXX', SUFFIX => '.html', UNLINK => 1, TMPDIR => 1 );
+print $html_fh "this is html content";
+close $html_fh;
+my $html_name = (File::Spec->splitpath($html_file))[-1];
+
+my ($baseurl, $m) = RT::Test->started_ok;
+ok $m->login, 'logged in';
+
+my $queue = RT::Queue->new($RT::Nobody);
+my $qid = $queue->Load('General');
+ok( $qid, "Loaded General queue" );
+
+RT::Test->set_mail_catcher;
+RT::Test->clean_caught_mails;
+
+for my $type ( 'text/plain', 'text/html' ) {
+ $m->form_name('CreateTicketInQueue');
+ $m->field( 'Queue', $qid );
+ $m->submit;
+ is( $m->status, 200, "request successful" );
+ $m->content_like( qr/Create a new ticket/, 'ticket create page' );
+
+ $m->form_name('TicketCreate');
+ $m->field( 'Subject', 'with plain attachment' );
+ $m->field( 'Attach', $plain_file );
+ $m->field( 'Content', 'this is main content' );
+ $m->field( 'ContentType', $type ) unless $type eq 'text/plain';
+ $m->submit;
+ is( $m->status, 200, "request successful" );
+ $m->content_like( qr/with plain attachment/,
+ 'we have subject on the page' );
+ $m->content_like( qr/this is main content/, 'main content' );
+ $m->content_like( qr/Download $plain_name/, 'download plain file link' );
+
+ my ( $mail ) = RT::Test->fetch_caught_mails;
+ like( $mail, qr/this is main content/, 'email contains main content' );
+ # check the email link in page too
+ $m->follow_link_ok( { text => 'Show' }, 'show the email outgoing' );
+ $m->content_like( qr/this is main content/, 'email contains main content');
+ $m->back;
+
+ $m->follow_link_ok( { text => 'Reply' }, "reply to the ticket" );
+ $m->form_name('TicketUpdate');
+ $m->field( 'Attach', $plain_file );
+ $m->click('AddMoreAttach');
+ is( $m->status, 200, "request successful" );
+
+ $m->form_name('TicketUpdate');
+ $m->field( 'Attach', $html_file );
+ # add UpdateCc so we can get email record
+ $m->field( 'UpdateCc', 'rt-test@example.com' );
+ $m->field( 'UpdateContent', 'this is main reply content' );
+ $m->field( 'UpdateContentType', $type ) unless $type eq 'text/plain';
+ $m->click('SubmitTicket');
+ is( $m->status, 200, "request successful" );
+
+ $m->content_like( qr/this is main reply content/, 'main reply content' );
+ $m->content_like( qr/Download $html_name/, 'download html file link' );
+
+ ( $mail ) = RT::Test->fetch_caught_mails;
+ like( $mail, qr/this is main reply content/, 'email contains main reply content' );
+ # check the email link in page too
+ $m->follow_link_ok( { text => 'Show', n => 2 }, 'show the email outgoing' );
+ $m->content_like( qr/this is main reply content/, 'email contains main reply content');
+ $m->back;
+}