summaryrefslogtreecommitdiff
path: root/rt/t/api
diff options
context:
space:
mode:
authorIvan Kohler <ivan@freeside.biz>2012-04-24 11:35:56 -0700
committerIvan Kohler <ivan@freeside.biz>2012-04-24 11:35:56 -0700
commit6587f6ba7d047ddc1686c080090afe7d53365bd4 (patch)
treeec77342668e8865aca669c9b4736e84e3077b523 /rt/t/api
parent47153aae5c2fc00316654e7277fccd45f72ff611 (diff)
first pass RT4 merge, RT#13852
Diffstat (limited to 'rt/t/api')
-rw-r--r--rt/t/api/action-createtickets.t44
-rw-r--r--rt/t/api/attachment.t2
-rw-r--r--rt/t/api/attachment_filename.t26
-rw-r--r--rt/t/api/attribute-tests.t7
-rw-r--r--rt/t/api/attribute.t11
-rw-r--r--rt/t/api/bookmarks.t24
-rw-r--r--rt/t/api/canonical_charset.t30
-rw-r--r--rt/t/api/cf_render_type.t49
-rw-r--r--rt/t/api/condition-ownerchange.t7
-rw-r--r--rt/t/api/condition-reject.t7
-rw-r--r--rt/t/api/config.t33
-rw-r--r--rt/t/api/cron.t89
-rw-r--r--rt/t/api/currentuser.t3
-rw-r--r--rt/t/api/customfield.t11
-rw-r--r--rt/t/api/date.t98
-rw-r--r--rt/t/api/emailparser.t23
-rw-r--r--rt/t/api/execute-code.t108
-rw-r--r--rt/t/api/group-rights.t137
-rw-r--r--rt/t/api/group.t19
-rw-r--r--rt/t/api/groups.t111
-rw-r--r--rt/t/api/has_rights.t43
-rw-r--r--rt/t/api/i18n.t3
-rw-r--r--rt/t/api/i18n_guess.t71
-rw-r--r--rt/t/api/link.t61
-rw-r--r--rt/t/api/password-types.t20
-rw-r--r--rt/t/api/queue.t21
-rw-r--r--rt/t/api/record.t23
-rw-r--r--rt/t/api/reminders.t10
-rw-r--r--rt/t/api/rights.t18
-rw-r--r--rt/t/api/rights_show_ticket.t28
-rw-r--r--rt/t/api/rt.t11
-rw-r--r--rt/t/api/rtname.t34
-rw-r--r--rt/t/api/safe-run-child-util.t201
-rw-r--r--rt/t/api/savedsearch.t181
-rw-r--r--rt/t/api/scrip.t10
-rw-r--r--rt/t/api/scrip_order.t11
-rw-r--r--rt/t/api/searchbuilder.t3
-rw-r--r--rt/t/api/squish.t16
-rw-r--r--rt/t/api/system.t5
-rw-r--r--rt/t/api/template-insert.t2
-rw-r--r--rt/t/api/template-simple.t275
-rw-r--r--rt/t/api/template.t5
-rw-r--r--rt/t/api/ticket.t53
-rw-r--r--rt/t/api/tickets.t29
-rw-r--r--rt/t/api/tickets_overlay_sql.t31
-rw-r--r--rt/t/api/txn_content.t2
-rw-r--r--rt/t/api/uri-fsck_com_rt.t7
-rw-r--r--rt/t/api/uri-t.t5
-rw-r--r--rt/t/api/user.t58
-rw-r--r--rt/t/api/users.t37
-rw-r--r--rt/t/api/versions_sorter.t22
-rw-r--r--rt/t/api/web-config.t163
52 files changed, 1889 insertions, 409 deletions
diff --git a/rt/t/api/action-createtickets.t b/rt/t/api/action-createtickets.t
index 69ceb8d4d..c37e2ed12 100644
--- a/rt/t/api/action-createtickets.t
+++ b/rt/t/api/action-createtickets.t
@@ -2,7 +2,7 @@
use strict;
use warnings;
use RT;
-use RT::Test tests => 49;
+use RT::Test tests => 54;
{
@@ -14,10 +14,33 @@ use_ok('RT::ScripAction');
use_ok('RT::ScripCondition');
use_ok('RT::Ticket');
-my $approvalsq = RT::Queue->new($RT::SystemUser);
+
+use_ok('RT::CustomField');
+
+my $global_cf = RT::CustomField->new($RT::SystemUser);
+my ($id, $msg)= $global_cf->Create( Name => 'GlobalCF',
+ Queue => '0',
+ SortOrder => '1',
+ Description => 'A Testing custom field',
+ Type=> 'SelectSingle');
+ok($id, 'Global custom field correctly created');
+
+
+my $approvalsq = RT::Queue->new(RT->SystemUser);
$approvalsq->Create(Name => 'Approvals');
ok ($approvalsq->Id, "Created Approvals test queue");
+my $queue_cf = RT::CustomField->new($RT::SystemUser);
+($id) = $queue_cf->Create(
+ Name => 'QueueCF',
+ Queue => $approvalsq->Id,
+ SortOrder => 2,
+ Description => 'A testing queue-specific custom field',
+ Type => 'SelectSingle',
+);
+ok($id, 'Queue-specific custom field correctly created');
+
+
my $approvals =
'===Create-Ticket: approval
@@ -26,6 +49,8 @@ Type: approval
AdminCc: {join ("\nAdminCc: ",@admins) }
Depended-On-By: {$Tickets{"TOP"}->Id}
Refers-To: TOP
+CustomField-GlobalCF: A Value
+CustomField-QueueCF: Another Value
Subject: Approval for ticket: {$Tickets{"TOP"}->Id} - {$Tickets{"TOP"}->Subject}
Due: {time + 86400}
Content-Type: text/plain
@@ -45,16 +70,16 @@ ENDOFCONTENT
like ($approvals , qr/Content/, "Read in the approvals template");
-my $apptemp = RT::Template->new($RT::SystemUser);
+my $apptemp = RT::Template->new(RT->SystemUser);
$apptemp->Create( Content => $approvals, Name => "Approvals", Queue => "0");
ok ($apptemp->Id);
-my $q = RT::Queue->new($RT::SystemUser);
+my $q = RT::Queue->new(RT->SystemUser);
$q->Create(Name => 'WorkflowTest');
ok ($q->Id, "Created workflow test queue");
-my $scrip = RT::Scrip->new($RT::SystemUser);
+my $scrip = RT::Scrip->new(RT->SystemUser);
my ($sval, $smsg) =$scrip->Create( ScripCondition => 'On Transaction',
ScripAction => 'Create Tickets',
Template => 'Approvals',
@@ -65,7 +90,7 @@ 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 $t = RT::Ticket->new(RT->SystemUser);
my($tid, $ttrans, $tmsg) = $t->Create(Subject => "Sample workflow test",
Owner => "root",
Queue => $q->Id);
@@ -76,11 +101,15 @@ my $deps = $t->DependsOn;
is ($deps->Count, 1, "The ticket we created depends on one other ticket");
my $dependson= $deps->First->TargetObj;
ok ($dependson->Id, "It depends on a real ticket");
+is ($dependson->FirstCustomFieldValue('GlobalCF'), 'A Value',
+ 'global custom field was set');
+is ($dependson->FirstCustomFieldValue('QueueCF'), 'Another Value',
+ 'queue custom field was set');
unlike ($dependson->Subject, qr/{/, "The subject doesn't have braces in it. that means we're interpreting expressions");
is ($t->ReferredToBy->Count,1, "It's only referred to by one other ticket");
is ($t->ReferredToBy->First->BaseObj->Id,$t->DependsOn->First->TargetObj->Id, "The same ticket that depends on it refers to it.");
use RT::Action::CreateTickets;
-my $action = RT::Action::CreateTickets->new( CurrentUser => $RT::SystemUser);
+my $action = RT::Action::CreateTickets->new( CurrentUser => RT->SystemUser);
# comma-delimited templates
my $commas = <<"EOF";
@@ -237,4 +266,3 @@ foreach my $id ( sort keys %expected ) {
}
-1;
diff --git a/rt/t/api/attachment.t b/rt/t/api/attachment.t
index 282d2a3de..8b7cb608b 100644
--- a/rt/t/api/attachment.t
+++ b/rt/t/api/attachment.t
@@ -65,5 +65,3 @@ is ($#headers, 2, "testing a bunch of singline multiple headers" );
'body of ContentAsMIME is original'
);
}
-
-1;
diff --git a/rt/t/api/attachment_filename.t b/rt/t/api/attachment_filename.t
index 2eced0127..bcbfe0057 100644
--- a/rt/t/api/attachment_filename.t
+++ b/rt/t/api/attachment_filename.t
@@ -1,6 +1,6 @@
use RT::Test tests => 5;
use MIME::Entity;
-my $ticket = RT::Ticket->new($RT::SystemUser);
+my $ticket = RT::Ticket->new(RT->SystemUser);
my $mime = MIME::Entity->build(
From => 'test@example.com',
Type => 'text/html',
@@ -8,32 +8,32 @@ my $mime = MIME::Entity->build(
);
$mime->attach(
- Path => 'share/html/NoAuth/images/bplogo.gif',
- Type => 'image/gif',
+ Path => 'share/html/NoAuth/images/bpslogo.png',
+ Type => 'image/png',
);
$mime->attach(
- Path => 'share/html/NoAuth/images/bplogo.gif',
- Type => 'image/gif',
- Filename => 'bplogo.gif',
+ Path => 'share/html/NoAuth/images/bpslogo.png',
+ Type => 'image/png',
+ Filename => 'bpslogo.png',
);
$mime->attach(
- Path => 'share/html/NoAuth/images/bplogo.gif',
- Filename => 'images/bplogo.gif',
- Type => 'image/gif',
+ Path => 'share/html/NoAuth/images/bpslogo.png',
+ Filename => 'images/bpslogo.png',
+ Type => 'image/png',
);
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' );
+my $atts = RT::Attachments->new( RT->SystemUser );
+$atts->Limit( FIELD => 'ContentType', VALUE => 'image/png' );
+is( $atts->Count, 3, 'got 3 png 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" );
+ is( $att->Filename, 'bpslogo.png', "attachment's filename" );
}
diff --git a/rt/t/api/attribute-tests.t b/rt/t/api/attribute-tests.t
index 90c3ddb7e..8489f1a56 100644
--- a/rt/t/api/attribute-tests.t
+++ b/rt/t/api/attribute-tests.t
@@ -1,7 +1,7 @@
use strict;
use warnings;
use RT;
-use RT::Test tests => 34;
+use RT::Test nodata => 1, tests => 34;
@@ -11,7 +11,7 @@ my $attribute = "squelch-$runid";
ok(require RT::Attributes);
-my $user = RT::User->new($RT::SystemUser);
+my $user = RT::User->new(RT->SystemUser);
ok (UNIVERSAL::isa($user, 'RT::User'));
my ($id,$msg) = $user->Create(Name => 'attrtest-'.$runid);
ok ($id, $msg);
@@ -81,6 +81,3 @@ ok(1, $attr->BuildSelectQuery);
@names = $attr->Names;
is("@names", "TestAttr");
-
-
-1;
diff --git a/rt/t/api/attribute.t b/rt/t/api/attribute.t
index cb2626ad8..417f01528 100644
--- a/rt/t/api/attribute.t
+++ b/rt/t/api/attribute.t
@@ -2,15 +2,15 @@
use strict;
use warnings;
use RT;
-use RT::Test tests => 7;
+use RT::Test nodata => 1, tests => 7;
{
-my $user = $RT::SystemUser;
+my $user = RT->SystemUser;
my ($id, $msg) = $user->AddAttribute(Name => 'SavedSearch', Content => { Query => 'Foo'} );
ok ($id, $msg);
-my $attr = RT::Attribute->new($RT::SystemUser);
+my $attr = RT::Attribute->new(RT->SystemUser);
$attr->Load($id);
is($attr->Name , 'SavedSearch');
$attr->SetSubValues( Format => 'baz');
@@ -28,15 +28,14 @@ is ($format, undef);
$attr->SetSubValues(Format => 'This is a format');
-my $attr2 = RT::Attribute->new($RT::SystemUser);
+my $attr2 = RT::Attribute->new(RT->SystemUser);
$attr2->Load($id);
is ($attr2->SubValue('Format'), 'This is a format');
$attr2->Delete;
-my $attr3 = RT::Attribute->new($RT::SystemUser);
+my $attr3 = RT::Attribute->new(RT->SystemUser);
($id) = $attr3->Load($id);
is ($id, 0);
}
-1;
diff --git a/rt/t/api/bookmarks.t b/rt/t/api/bookmarks.t
new file mode 100644
index 000000000..65b194526
--- /dev/null
+++ b/rt/t/api/bookmarks.t
@@ -0,0 +1,24 @@
+use strict;
+use warnings;
+use RT::Test tests => 36;
+
+my ( $url, $m ) = RT::Test->started_ok;
+my $root = RT::Test->load_or_create_user( Name => 'root' );
+
+my @tickets = RT::Test->create_tickets( { }, map { { Subject => "Test $_" } } ( 1 .. 9 ) );
+
+# 4.2 gives us $user->ToggleBookmark which is nicer
+$root->SetAttribute( Name => 'Bookmarks', Content => { map { $_ => 1 } (3,6,9) } );
+
+my $cu = RT::CurrentUser->new($root);
+my $bookmarks = RT::Tickets->new($cu);
+for my $search ( "Queue = 'General' AND id = '__Bookmarked__'",
+ "id = '__Bookmarked__' AND Queue = 'General'",
+ "id > 0 AND id = '__Bookmarked__'",
+ "id = '__Bookmarked__' AND id > 0",
+ "id = 3 OR id = '__Bookmarked__'",
+ "id = '__Bookmarked__' OR id = 3",
+ ) {
+ $bookmarks->FromSQL($search);
+ is($bookmarks->Count,3,"Found my 3 bookmarks for [$search]");
+}
diff --git a/rt/t/api/canonical_charset.t b/rt/t/api/canonical_charset.t
new file mode 100644
index 000000000..a426d89b6
--- /dev/null
+++ b/rt/t/api/canonical_charset.t
@@ -0,0 +1,30 @@
+use warnings;
+use strict;
+
+use RT::Test nodata => 1, tests => 11;
+use RT::I18N;
+use Encode;
+
+my %map = (
+ 'euc-cn' => 'gbk',
+ 'gb-2312' => 'gbk',
+ gb2312 => 'gbk',
+ utf8 => 'utf-8',
+ 'utf-8' => 'utf-8',
+);
+
+for my $charset ( keys %map ) {
+ is( RT::I18N::_CanonicalizeCharset($charset),
+ $map{$charset}, "$charset => $map{$charset}" );
+ is( RT::I18N::_CanonicalizeCharset( uc $charset ),
+ $map{$charset}, uc( $charset ) . " => $map{$charset}" );
+}
+
+my $mime = MIME::Entity->build(
+ Type => 'text/plain; charset=gb2312',
+ Data => [encode('gbk', decode_utf8("法新社倫敦11日電"))],
+);
+
+RT::I18N::SetMIMEEntityToUTF8($mime);
+is( $mime->stringify_body, '法新社倫敦11日電', 'gb2312 => gbk in mail' );
+
diff --git a/rt/t/api/cf_render_type.t b/rt/t/api/cf_render_type.t
new file mode 100644
index 000000000..ac090495e
--- /dev/null
+++ b/rt/t/api/cf_render_type.t
@@ -0,0 +1,49 @@
+use strict;
+use warnings;
+
+use RT::Test tests => 13;
+
+my $cf = RT::CustomField->new($RT::SystemUser);
+my ( $id, $ret, $msg );
+
+diag "single select";
+( $id, $msg ) = $cf->Create(
+ Name => 'single_select',
+ Type => 'Select',
+ MaxValues => '1',
+ Queue => 0,
+);
+ok( $id, $msg );
+
+is( $cf->RenderType, 'Select box', 'default render type is Select box' );
+( $ret, $msg ) = $cf->SetRenderType('Dropdown');
+ok( $ret, 'changed to Dropdown' );
+is( $cf->RenderType, 'Dropdown', 'render type is indeed updated' );
+
+( $ret, $msg ) = $cf->SetRenderType('List');
+ok( $ret, 'changed to List' );
+is( $cf->RenderType, 'List', 'render type is indeed updated' );
+
+( $ret, $msg ) = $cf->SetRenderType('fakeone');
+ok( !$ret, 'failed to set an invalid render type' );
+is( $cf->RenderType, 'List', 'render type is still List' );
+
+diag "multiple select";
+( $id, $msg ) = $cf->Create(
+ Name => 'multiple_select',
+ Type => 'Select',
+ MaxValues => '0',
+ Queue => 0,
+ RenderType => 'List',
+);
+
+is( $cf->RenderType, 'List', 'set render type to List' );
+( $ret, $msg ) = $cf->SetRenderType('Dropdown');
+ok( !$ret, 'Dropdown is invalid for multiple select' );
+
+is( $cf->RenderType, 'List', 'render type is still List' );
+
+( $ret, $msg ) = $cf->SetRenderType('Select box');
+ok( $ret, 'changed to Select box' );
+is( $cf->RenderType, 'Select box', 'render type is indeed updated' );
+
diff --git a/rt/t/api/condition-ownerchange.t b/rt/t/api/condition-ownerchange.t
index 4c4c49b29..2cfef7422 100644
--- a/rt/t/api/condition-ownerchange.t
+++ b/rt/t/api/condition-ownerchange.t
@@ -7,12 +7,12 @@ use RT::Test tests => 11;
{
-my $q = RT::Queue->new($RT::SystemUser);
+my $q = RT::Queue->new(RT->SystemUser);
$q->Create(Name =>'ownerChangeTest');
ok($q->Id, "Created a scriptest queue");
-my $s1 = RT::Scrip->new($RT::SystemUser);
+my $s1 = RT::Scrip->new(RT->SystemUser);
my ($val, $msg) =$s1->Create( Queue => $q->Id,
ScripAction => 'User Defined',
ScripCondition => 'On Owner Change',
@@ -26,7 +26,7 @@ my ($val, $msg) =$s1->Create( Queue => $q->Id,
);
ok($val,$msg);
-my $ticket = RT::Ticket->new($RT::SystemUser);
+my $ticket = RT::Ticket->new(RT->SystemUser);
my ($tv,$ttv,$tm) = $ticket->Create(Queue => $q->Id,
Subject => "hair on fire",
InitialPriority => '20'
@@ -48,4 +48,3 @@ is ($ticket->Priority , '24', "Ticket priority is set right");
}
-1;
diff --git a/rt/t/api/condition-reject.t b/rt/t/api/condition-reject.t
index 96789509d..c2ec8cdda 100644
--- a/rt/t/api/condition-reject.t
+++ b/rt/t/api/condition-reject.t
@@ -10,12 +10,12 @@ use RT::Test tests => 7;
{
-my $q = RT::Queue->new($RT::SystemUser);
+my $q = RT::Queue->new(RT->SystemUser);
$q->Create(Name =>'rejectTest');
ok($q->Id, "Created a scriptest queue");
-my $s1 = RT::Scrip->new($RT::SystemUser);
+my $s1 = RT::Scrip->new(RT->SystemUser);
my ($val, $msg) =$s1->Create( Queue => $q->Id,
ScripAction => 'User Defined',
ScripCondition => 'On reject',
@@ -29,7 +29,7 @@ my ($val, $msg) =$s1->Create( Queue => $q->Id,
);
ok($val,$msg);
-my $ticket = RT::Ticket->new($RT::SystemUser);
+my $ticket = RT::Ticket->new(RT->SystemUser);
my ($tv,$ttv,$tm) = $ticket->Create(Queue => $q->Id,
Subject => "hair on fire",
InitialPriority => '20'
@@ -42,4 +42,3 @@ is ($ticket->Priority , '21', "Condition is false, scrip skipped");
}
-1;
diff --git a/rt/t/api/config.t b/rt/t/api/config.t
new file mode 100644
index 000000000..a986c3c4f
--- /dev/null
+++ b/rt/t/api/config.t
@@ -0,0 +1,33 @@
+use strict;
+use warnings;
+use RT;
+use RT::Test nodb => 1, tests => 9;
+
+ok(
+ RT::Config->AddOption(
+ Name => 'foo',
+ Section => 'bar',
+ ),
+ 'added option foo'
+);
+
+my $meta = RT::Config->Meta('foo');
+is( $meta->{Section}, 'bar', 'Section is bar' );
+is( $meta->{Widget}, '/Widgets/Form/String', 'default Widget is string' );
+is_deeply( $meta->{WidgetArguments},
+ {},, 'default WidgetArguments is empty hashref' );
+
+ok(
+ RT::Config->UpdateOption(
+ Name => 'foo',
+ Section => 'baz',
+ Widget => '/Widgets/Form/Boolean',
+ ),
+ 'updated option foo to section baz'
+);
+is( $meta->{Section}, 'baz', 'section is updated to baz' );
+is( $meta->{Widget}, '/Widgets/Form/Boolean', 'widget is updated to boolean' );
+
+ok( RT::Config->DeleteOption( Name => 'foo' ), 'removed option foo' );
+is( RT::Config->Meta('foo'), undef, 'foo is indeed deleted' );
+
diff --git a/rt/t/api/cron.t b/rt/t/api/cron.t
new file mode 100644
index 000000000..6f9d7f644
--- /dev/null
+++ b/rt/t/api/cron.t
@@ -0,0 +1,89 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+use RT;
+use RT::Test nodata => 1, tests => 18;
+
+
+### Set up some testing data. Test the testing data because why not?
+
+# Create a user with rights, a queue, and some tickets.
+my $user_obj = RT::User->new(RT->SystemUser);
+my ($ret, $msg) = $user_obj->LoadOrCreateByEmail('tara@example.com');
+ok($ret, 'record test user creation');
+$user_obj->SetName('tara');
+$user_obj->PrincipalObj->GrantRight(Right => 'SuperUser');
+my $CurrentUser = RT::CurrentUser->new('tara');
+
+# Create our template, which will be used for tests of RT::Action::Record*.
+
+my $template_content = 'RT-Send-Cc: tla@example.com
+RT-Send-Bcc: jesse@example.com
+
+This is a content string with no content.';
+
+my $template_obj = RT::Template->new($CurrentUser);
+$template_obj->Create(Queue => '0',
+ Name => 'recordtest',
+ Description => 'testing Record actions',
+ Content => $template_content,
+ );
+
+# Create a queue and some tickets.
+
+my $queue_obj = RT::Queue->new($CurrentUser);
+($ret, $msg) = $queue_obj->Create(Name => 'recordtest', Description => 'queue for Action::Record testing');
+ok($ret, 'record test queue creation');
+
+my $ticket1 = RT::Ticket->new($CurrentUser);
+my ($id, $tobj, $msg2) = $ticket1->Create(Queue => $queue_obj,
+ Requestor => ['tara@example.com'],
+ Subject => 'bork bork bork',
+ Priority => 22,
+ );
+ok($id, 'record test ticket creation 1');
+my $ticket2 = RT::Ticket->new($CurrentUser);
+($id, $tobj, $msg2) = $ticket2->Create(Queue => $queue_obj,
+ Requestor => ['root@localhost'],
+ Subject => 'hurdy gurdy'
+ );
+ok($id, 'record test ticket creation 2');
+
+
+### OK. Have data, will travel.
+
+# First test the search.
+
+ok(require RT::Search::FromSQL, "Search::FromSQL loaded");
+my $ticketsqlstr = "Requestor.EmailAddress = '" . $CurrentUser->EmailAddress .
+ "' AND Priority > '20'";
+my $search = RT::Search::FromSQL->new(Argument => $ticketsqlstr, TicketsObj => RT::Tickets->new($CurrentUser),
+ );
+is(ref($search), 'RT::Search::FromSQL', "search created");
+ok($search->Prepare(), "fromsql search run");
+my $counter = 0;
+while(my $t = $search->TicketsObj->Next() ) {
+ is($t->Id(), $ticket1->Id(), "fromsql search results 1");
+ $counter++;
+}
+is ($counter, 1, "fromsql search results 2");
+
+# Right. Now test the actions.
+
+ok(require RT::Action::RecordComment);
+ok(require RT::Action::RecordCorrespondence);
+
+my ($comment_act, $correspond_act);
+ok($comment_act = RT::Action::RecordComment->new(TicketObj => $ticket1, TemplateObj => $template_obj, CurrentUser => $CurrentUser), "RecordComment created");
+ok($correspond_act = RT::Action::RecordCorrespondence->new(TicketObj => $ticket2, TemplateObj => $template_obj, CurrentUser => $CurrentUser), "RecordCorrespondence created");
+ok($comment_act->Prepare(), "Comment prepared");
+ok($correspond_act->Prepare(), "Correspond prepared");
+ok($comment_act->Commit(), "Comment committed");
+ok($correspond_act->Commit(), "Correspondence committed");
+
+# Now test for loop suppression.
+my ($trans, $desc, $transaction) = $ticket2->Comment(MIMEObj => $template_obj->MIMEObj);
+my $bogus_action = RT::Action::RecordComment->new(TicketObj => $ticket1, TemplateObj => $template_obj, TransactionObj => $transaction, CurrentUser => $CurrentUser);
+ok(!$bogus_action->Prepare(), "Comment aborted to prevent loop");
+
diff --git a/rt/t/api/currentuser.t b/rt/t/api/currentuser.t
index c15804824..f54074af9 100644
--- a/rt/t/api/currentuser.t
+++ b/rt/t/api/currentuser.t
@@ -2,7 +2,7 @@
use strict;
use warnings;
use RT;
-use RT::Test tests => 8;
+use RT::Test noinitialdata => 1, tests => 8;
{
@@ -29,4 +29,3 @@ SKIP: {
}
-1;
diff --git a/rt/t/api/customfield.t b/rt/t/api/customfield.t
index 44319c47f..6be50bb3a 100644
--- a/rt/t/api/customfield.t
+++ b/rt/t/api/customfield.t
@@ -2,14 +2,14 @@
use strict;
use warnings;
use RT;
-use RT::Test tests => 29;
+use RT::Test nodata => 1, tests => 29;
use Test::Warn;
{
use_ok('RT::CustomField');
-ok(my $cf = RT::CustomField->new($RT::SystemUser));
+ok(my $cf = RT::CustomField->new(RT->SystemUser));
ok(my ($id, $msg)= $cf->Create( Name => 'TestingCF',
Queue => '0',
SortOrder => '1',
@@ -28,7 +28,7 @@ ok(!$cf->SingleValue );
ok(my ($bogus_val, $bogus_msg) = $cf->SetType('BogusType') , "Trying to set a custom field's type to a bogus type");
is($bogus_val , 0, "Unable to set a custom field's type to a bogus type");
-ok(my $bad_cf = RT::CustomField->new($RT::SystemUser));
+ok(my $bad_cf = RT::CustomField->new(RT->SystemUser));
ok(my ($bad_id, $bad_msg)= $cf->Create( Name => 'TestingCF-bad',
Queue => '0',
SortOrder => '1',
@@ -41,7 +41,7 @@ is($bad_id , 0, 'Global custom field correctly decided to not create a cf with a
{
-ok(my $cf = RT::CustomField->new($RT::SystemUser));
+ok(my $cf = RT::CustomField->new(RT->SystemUser));
$cf->Load(1);
is($cf->Id , 1);
ok(my ($val,$msg) = $cf->AddValue(Name => 'foo' , Description => 'TestCFValue', SortOrder => '6'));
@@ -54,7 +54,7 @@ ok ($delval,"Deleting a cf value: $delmsg");
{
-ok(my $cf = RT::CustomField->new($RT::SystemUser));
+ok(my $cf = RT::CustomField->new(RT->SystemUser));
warning_like {
ok($cf->ValidateType('SelectSingle'));
@@ -71,4 +71,3 @@ ok(!$cf->ValidateType('SelectFooMultiple'));
}
-1;
diff --git a/rt/t/api/date.t b/rt/t/api/date.t
index bc1446f50..9756e51c4 100644
--- a/rt/t/api/date.t
+++ b/rt/t/api/date.t
@@ -1,47 +1,31 @@
#!/usr/bin/perl
use Test::MockTime qw(set_fixed_time restore_time);
-
-use Test::More;
-my $tests;
-
-my $localized_datetime_tests;
-BEGIN {
- $tests = 167;
- $localized_datetime_tests =
- eval { require DateTime; 1; } && eval { require DateTime::Locale; 1; } &&
- DateTime->can('format_cldr') && DateTime::Locale::root->can('date_format_full');
-
- if ($localized_datetime_tests) {
-
- # Include RT::Date::LocalizedDateTime tests
- $tests += 7;
- }
-}
+use DateTime;
use warnings; use strict;
-use RT::Test tests => $tests;
+use RT::Test tests => 172;
use RT::User;
use Test::Warn;
use_ok('RT::Date');
{
- my $date = RT::Date->new($RT::SystemUser);
+ my $date = RT::Date->new(RT->SystemUser);
isa_ok($date, 'RT::Date', "constructor returned RT::Date oject");
- $date = $date->new($RT::SystemUser);
+ $date = $date->new(RT->SystemUser);
isa_ok($date, 'RT::Date', "constructor returned RT::Date oject");
}
{
# set timezone in all places to UTC
- $RT::SystemUser->UserObj->__Set(Field => 'Timezone', Value => 'UTC')
- if $RT::SystemUser->UserObj->Timezone;
+ RT->SystemUser->UserObj->__Set(Field => 'Timezone', Value => 'UTC')
+ if RT->SystemUser->UserObj->Timezone;
RT->Config->Set( Timezone => 'UTC' );
}
my $current_user;
{
- my $user = RT::User->new($RT::SystemUser);
+ my $user = RT::User->new(RT->SystemUser);
my($uid, $msg) = $user->Create(
Name => "date_api". rand(200),
Lang => 'en',
@@ -53,7 +37,6 @@ my $current_user;
{
my $date = RT::Date->new( $current_user );
- is($date->Timezone, 'UTC', "dropped all timzones to UTC");
is($date->Timezone('user'), 'UTC', "dropped all timzones to UTC");
is($date->Timezone('server'), 'UTC', "dropped all timzones to UTC");
is($date->Timezone('unknown'), 'UTC', "with wrong context returns UTC");
@@ -65,7 +48,6 @@ my $current_user;
is($date->Timezone('user'),
'Europe/Moscow',
"in user context returns user's timezone");
- is($date->Timezone, 'UTC', "the deafult value is always UTC");
is($date->Timezone('server'), 'UTC', "wasn't changed");
RT->Config->Set( Timezone => 'Africa/Ouagadougou' );
@@ -75,7 +57,6 @@ my $current_user;
is($date->Timezone('user'),
'Europe/Moscow',
"in user context still returns user's timezone");
- is($date->Timezone, 'UTC', "the deafult value is always UTC");
$current_user->UserObj->__Set( Field => 'Timezone', Value => '');
is_empty($current_user->UserObj->Timezone,
@@ -83,7 +64,6 @@ my $current_user;
is($date->Timezone('user'),
'Africa/Ouagadougou',
"in user context returns timezone of the server if user's one is not defined");
- is($date->Timezone, 'UTC', "the deafult value is always UTC");
RT->Config->Set( Timezone => 'GMT' );
is($date->Timezone('server'),
@@ -91,7 +71,6 @@ my $current_user;
"timezone is GMT which one is alias for UTC");
RT->Config->Set( Timezone => '' );
- is($date->Timezone, 'UTC', "dropped all timzones to UTC");
is($date->Timezone('user'),
'UTC',
"user's and server's timzones are not defined, so UTC");
@@ -103,7 +82,7 @@ my $current_user;
}
{
- my $date = RT::Date->new($RT::SystemUser);
+ my $date = RT::Date->new(RT->SystemUser);
is($date->Unix, 0, "new date returns 0 in Unix format");
is($date->Get, '1970-01-01 00:00:00', "default is ISO format");
is($date->Get(Format =>'SomeBadFormat'),
@@ -117,7 +96,7 @@ my $current_user;
"RFC2822 format with defaults");
is($date->Get(Format =>'LocalizedDateTime'),
'Thu, Jan 1, 1970 12:00:00 AM',
- "LocalizedDateTime format with defaults") if ( $localized_datetime_tests );
+ "LocalizedDateTime format with defaults");
is($date->ISO(Time => 0),
'1970-01-01',
@@ -130,7 +109,7 @@ my $current_user;
"RFC2822 format without time part");
is($date->LocalizedDateTime(Time => 0),
'Thu, Jan 1, 1970',
- "LocalizedDateTime format without time part") if ( $localized_datetime_tests );
+ "LocalizedDateTime format without time part");
is($date->ISO(Date => 0),
'00:00:00',
@@ -143,7 +122,7 @@ my $current_user;
"RFC2822 format without date part");
is($date->LocalizedDateTime(Date => 0),
'12:00:00 AM',
- "LocalizedDateTime format without date part") if ( $localized_datetime_tests );
+ "LocalizedDateTime format without date part");
is($date->ISO(Date => 0, Seconds => 0),
'00:00',
@@ -164,16 +143,16 @@ my $current_user;
is($date->LocalizedDateTime(AbbrDay => 0),
'Thursday, Jan 1, 1970 12:00:00 AM',
- "LocalizedDateTime format without abbreviation of day") if ( $localized_datetime_tests );
+ "LocalizedDateTime format without abbreviation of day");
is($date->LocalizedDateTime(AbbrMonth => 0),
'Thu, January 1, 1970 12:00:00 AM',
- "LocalizedDateTime format without abbreviation of month") if ( $localized_datetime_tests );
+ "LocalizedDateTime format without abbreviation of month");
is($date->LocalizedDateTime(DateFormat => 'date_format_short'),
'1/1/70 12:00:00 AM',
- "LocalizedDateTime format with non default DateFormat") if ( $localized_datetime_tests );
+ "LocalizedDateTime format with non default DateFormat");
is($date->LocalizedDateTime(TimeFormat => 'time_format_short'),
'Thu, Jan 1, 1970 12:00 AM',
- "LocalizedDateTime format with non default TimeFormat") if ( $localized_datetime_tests );
+ "LocalizedDateTime format with non default TimeFormat");
is($date->Date,
'1970-01-01',
@@ -256,14 +235,14 @@ my $current_user;
warning_like
{ # bad format
- my $date = RT::Date->new($RT::SystemUser);
+ my $date = RT::Date->new(RT->SystemUser);
$date->Set( Format => 'bad' );
is($date->Unix, 0, "bad format");
-} qr'Unknown Date format: bad';
+} qr{Unknown Date format: bad};
{ # setting value via Unix method
- my $date = RT::Date->new($RT::SystemUser);
+ my $date = RT::Date->new(RT->SystemUser);
$date->Unix(1);
is($date->ISO, '1970-01-01 00:00:01', "correct value");
@@ -280,7 +259,7 @@ warning_like
my $year = (localtime(time))[5] + 1900;
{ # set+ISO format
- my $date = RT::Date->new($RT::SystemUser);
+ my $date = RT::Date->new(RT->SystemUser);
warning_like {
$date->Set(Format => 'ISO', Value => 'weird date');
} qr/Couldn't parse date 'weird date' as a ISO format/;
@@ -324,7 +303,7 @@ my $year = (localtime(time))[5] + 1900;
}
{ # set+datemanip format(Time::ParseDate)
- my $date = RT::Date->new($RT::SystemUser);
+ my $date = RT::Date->new(RT->SystemUser);
$date->Set(Format => 'unknown', Value => 'weird date');
is($date->Unix, 0, "date was wrong");
@@ -343,7 +322,7 @@ my $year = (localtime(time))[5] + 1900;
}
{ # set+unknown format(Time::ParseDate)
- my $date = RT::Date->new($RT::SystemUser);
+ my $date = RT::Date->new(RT->SystemUser);
$date->Set(Format => 'unknown', Value => 'weird date');
is($date->Unix, 0, "date was wrong");
@@ -380,7 +359,7 @@ my $year = (localtime(time))[5] + 1900;
}
{ # SetToMidnight
- my $date = RT::Date->new($RT::SystemUser);
+ my $date = RT::Date->new(RT->SystemUser);
RT->Config->Set( Timezone => 'Europe/Moscow' );
$date->Set(Format => 'ISO', Value => '2005-11-28 15:10:00');
@@ -414,7 +393,7 @@ my $year = (localtime(time))[5] + 1900;
}
{ # SetToNow
- my $date = RT::Date->new($RT::SystemUser);
+ my $date = RT::Date->new(RT->SystemUser);
my $time = time;
$date->SetToNow;
ok($date->Unix >= $time, 'close enough');
@@ -422,7 +401,7 @@ my $year = (localtime(time))[5] + 1900;
}
{
- my $date = RT::Date->new($RT::SystemUser);
+ my $date = RT::Date->new(RT->SystemUser);
$date->Unix(0);
$date->AddSeconds;
@@ -484,7 +463,7 @@ my $year = (localtime(time))[5] + 1900;
}
{ # DurationAsString
- my $date = RT::Date->new($RT::SystemUser);
+ my $date = RT::Date->new(RT->SystemUser);
is($date->DurationAsString(1), '1 sec', '1 sec');
is($date->DurationAsString(59), '59 sec', '59 sec');
@@ -505,7 +484,7 @@ my $year = (localtime(time))[5] + 1900;
}
{ # DiffAsString
- my $date = RT::Date->new($RT::SystemUser);
+ my $date = RT::Date->new(RT->SystemUser);
is($date->DiffAsString(1), '', 'no diff, wrong input');
is($date->DiffAsString(-1), '', 'no diff, wrong input');
is($date->DiffAsString('qwe'), '', 'no diff, wrong input');
@@ -516,14 +495,14 @@ my $year = (localtime(time))[5] + 1900;
is($date->DiffAsString(3), '1 sec ago', 'diff: 1 sec ago');
is($date->DiffAsString(1), '1 sec', 'diff: 1 sec');
- my $ndate = RT::Date->new($RT::SystemUser);
+ my $ndate = RT::Date->new(RT->SystemUser);
is($date->DiffAsString($ndate), '', 'no diff, wrong input');
$ndate->Unix(3);
is($date->DiffAsString($ndate), '1 sec ago', 'diff: 1 sec ago');
}
{ # Diff
- my $date = RT::Date->new($RT::SystemUser);
+ my $date = RT::Date->new(RT->SystemUser);
$date->SetToNow;
my $diff = $date->Diff;
ok($diff <= 0, 'close enought');
@@ -531,14 +510,14 @@ my $year = (localtime(time))[5] + 1900;
}
{ # AgeAsString
- my $date = RT::Date->new($RT::SystemUser);
+ my $date = RT::Date->new(RT->SystemUser);
$date->SetToNow;
my $diff = $date->AgeAsString;
like($diff, qr/^(0 sec|[1-5] sec ago)$/, 'close enought');
}
{ # GetWeekday
- my $date = RT::Date->new($RT::SystemUser);
+ my $date = RT::Date->new(RT->SystemUser);
is($date->GetWeekday(7), '', '7 and greater are invalid');
is($date->GetWeekday(6), 'Sat', '6 is Saturday');
is($date->GetWeekday(0), 'Sun', '0 is Sunday');
@@ -548,7 +527,7 @@ my $year = (localtime(time))[5] + 1900;
}
{ # GetMonth
- my $date = RT::Date->new($RT::SystemUser);
+ my $date = RT::Date->new(RT->SystemUser);
is($date->GetMonth(12), '', '12 and greater are invalid');
is($date->GetMonth(11), 'Dec', '11 is December');
is($date->GetMonth(0), 'Jan', '0 is January');
@@ -557,8 +536,19 @@ my $year = (localtime(time))[5] + 1900;
is($date->GetMonth(-13), '', '-13 and lesser are invalid');
}
+{
+ # set unknown format: edge cases
+ my $date = RT::Date->new(RT->SystemUser);
+ $date->Set( Value => 0, Format => 'unknown' );
+ is( $date->Unix(), 0, "unix is 0 with Value => 0, Format => 'unknown'" );
+
+ $date->Set( Value => '', Format => 'unknown' );
+ is( $date->Unix(), 0, "unix is 0 with Value => '', Format => 'unknown'" );
+
+ $date->Set( Value => ' ', Format => 'unknown' );
+ is( $date->Unix(), 0, "unix is 0 with Value => ' ', Format => 'unknown'" );
+}
+
#TODO: AsString
#TODO: RFC2822, W3CDTF with Timezones
-exit(0);
-
diff --git a/rt/t/api/emailparser.t b/rt/t/api/emailparser.t
index 940c26fde..790314603 100644
--- a/rt/t/api/emailparser.t
+++ b/rt/t/api/emailparser.t
@@ -2,7 +2,7 @@
use strict;
use warnings;
-use RT::Test tests => 4;
+use RT::Test nodb => 1, tests => 10;
RT->Config->Set( RTAddressRegexp => qr/^rt\@example.com$/i );
@@ -14,6 +14,23 @@ is(RT::EmailParser::IsRTAddress("","frt\@example.com"),undef, "Regexp didn't mat
my @before = ("rt\@example.com", "frt\@example.com");
my @after = ("frt\@example.com");
-ok(eq_array(RT::EmailParser::CullRTAddresses("",@before),@after), "CullRTAddresses only culls RT addresses");
+ok(eq_array(RT::EmailParser->CullRTAddresses(@before),@after), "CullRTAddresses only culls RT addresses");
+
+{
+ require RT::Interface::Email;
+ my ( $addr, $name ) =
+ RT::Interface::Email::ParseAddressFromHeader('foo@example.com');
+ is( $addr, 'foo@example.com', 'addr for foo@example.com' );
+ is( $name, undef, 'no name for foo@example.com' );
+
+ ( $addr, $name ) =
+ RT::Interface::Email::ParseAddressFromHeader('Foo <foo@example.com>');
+ is( $addr, 'foo@example.com', 'addr for Foo <foo@example.com>' );
+ is( $name, 'Foo', 'name for Foo <foo@example.com>' );
+
+ ( $addr, $name ) =
+ RT::Interface::Email::ParseAddressFromHeader('foo@example.com (Comment)');
+ is( $addr, 'foo@example.com', 'addr for foo@example.com (Comment)' );
+ is( $name, undef, 'no name for foo@example.com (Comment)' );
+}
-1;
diff --git a/rt/t/api/execute-code.t b/rt/t/api/execute-code.t
new file mode 100644
index 000000000..7f72be90a
--- /dev/null
+++ b/rt/t/api/execute-code.t
@@ -0,0 +1,108 @@
+use strict;
+use warnings;
+use RT::Test tests => 17;
+
+my $ticket = RT::Ticket->new(RT->SystemUser);
+ok(
+ $ticket->Create(
+ Subject => 'blue lines',
+ Queue => 'General',
+ )
+);
+
+my $attacker = RT::User->new(RT->SystemUser);
+ok(
+ $attacker->Create(
+ Name => 'attacker',
+ Password => 'foobar',
+ Privileged => 1,
+ )
+);
+
+my $template_as_attacker = RT::Template->new($attacker);
+
+# can't create templates without ModifyTemplate
+my ($ok, $msg) = $template_as_attacker->Create(
+ Name => 'Harmless, honest!',
+ Content => "\nhello ;)",
+ Type => 'Perl',
+);
+ok(!$ok, 'permission to create denied');
+
+
+# permit modifying templates but they must be simple
+$attacker->PrincipalObj->GrantRight(Right => 'ShowTemplate', Object => $RT::System);
+$attacker->PrincipalObj->GrantRight(Right => 'ModifyTemplate', Object => $RT::System);
+
+($ok, $msg) = $template_as_attacker->Create(
+ Name => 'Harmless, honest!',
+ Content => "\nhello ;)",
+ Type => 'Perl',
+);
+ok(!$ok, 'permission to create denied');
+
+
+($ok, $msg) = $template_as_attacker->Create(
+ Name => 'Harmless, honest!',
+ Content => "\nhello ;)",
+ Type => 'Simple',
+);
+ok($ok, 'created template now that we have ModifyTemplate');
+
+($ok, $msg) = $template_as_attacker->SetType('Perl');
+ok(!$ok, 'permission to update type to Perl denied');
+
+my $template_as_root = RT::Template->new(RT->SystemUser);
+$template_as_root->Load('Harmless, honest!');
+is($template_as_root->Content, "\nhello ;)");
+is($template_as_root->Type, 'Simple');
+
+$template_as_root->Parse(TicketObj => $ticket);
+is($template_as_root->MIMEObj->stringify_body, "hello ;)");
+
+
+# update the content to include code (even though Simple won't parse it)
+
+($ok, $msg) = $template_as_attacker->SetContent("\nYou are { (my \$message = 'bjarq') =~ tr/a-z/n-za-m/; \$message }!");
+ok($ok, 'updating Content permitted since the template is Simple');
+
+$template_as_root = RT::Template->new(RT->SystemUser);
+$template_as_root->Load('Harmless, honest!');
+
+is($template_as_root->Content, "\nYou are { (my \$message = 'bjarq') =~ tr/a-z/n-za-m/; \$message }!");
+is($template_as_root->Type, 'Simple');
+
+$template_as_root->Parse(TicketObj => $ticket);
+is($template_as_root->MIMEObj->stringify_body, "You are { (my \$message = 'bjarq') =~ tr/a-z/n-za-m/; \$message }!");
+
+
+# try again, why not
+($ok, $msg) = $template_as_attacker->SetType('Perl');
+ok(!$ok, 'permission to update type to Perl denied');
+
+
+# now root will change the template to genuine code
+$template_as_root = RT::Template->new(RT->SystemUser);
+$template_as_root->Load('Harmless, honest!');
+$template_as_root->SetType('Perl');
+$template_as_root->SetContent("\n{ scalar reverse \$Ticket->Subject }");
+
+$template_as_root->Parse(TicketObj => $ticket);
+is($template_as_root->MIMEObj->stringify_body, "senil eulb");
+
+
+# see if we can update anything
+$template_as_attacker = RT::Template->new($attacker);
+$template_as_attacker->Load('Harmless, honest!');
+
+($ok, $msg) = $template_as_attacker->SetContent("\nYou are { (my \$message = 'bjarq') =~ tr/a-z/n-za-m/; \$message }!");
+ok(!$ok, 'updating Content forbidden since the template is Perl');
+
+# try again just to be absolutely sure it doesn't work
+$template_as_root = RT::Template->new(RT->SystemUser);
+$template_as_root->Load('Harmless, honest!');
+$template_as_root->SetType('Perl');
+$template_as_root->SetContent("\n{ scalar reverse \$Ticket->Subject }");
+
+$template_as_root->Parse(TicketObj => $ticket);
+is($template_as_root->MIMEObj->stringify_body, "senil eulb");
diff --git a/rt/t/api/group-rights.t b/rt/t/api/group-rights.t
new file mode 100644
index 000000000..0494c286e
--- /dev/null
+++ b/rt/t/api/group-rights.t
@@ -0,0 +1,137 @@
+use strict;
+use warnings;
+use RT::Test nodata => 1, tests => 114;
+
+RT::Group->AddRights(
+ 'RTxGroupRight' => 'Just a right for testing rights',
+);
+
+# this company is split into two halves, the hackers and the non-hackers
+# herbert is a hacker but eric is not.
+my $herbert = RT::User->new(RT->SystemUser);
+my ($ok, $msg) = $herbert->Create(Name => 'herbert');
+ok($ok, $msg);
+
+my $eric = RT::User->new(RT->SystemUser);
+($ok, $msg) = $eric->Create(Name => 'eric');
+ok($ok, $msg);
+
+my $hackers = RT::Group->new(RT->SystemUser);
+($ok, $msg) = $hackers->CreateUserDefinedGroup(Name => 'Hackers');
+ok($ok, $msg);
+
+my $employees = RT::Group->new(RT->SystemUser);
+($ok, $msg) = $employees->CreateUserDefinedGroup(Name => 'Employees');
+ok($ok, $msg);
+
+($ok, $msg) = $employees->AddMember($hackers->PrincipalId);
+ok($ok, $msg);
+
+($ok, $msg) = $hackers->AddMember($herbert->PrincipalId);
+ok($ok, $msg);
+
+($ok, $msg) = $employees->AddMember($eric->PrincipalId);
+ok($ok, $msg);
+
+ok($employees->HasMemberRecursively($hackers->PrincipalId), 'employees has member hackers');
+ok($employees->HasMemberRecursively($herbert->PrincipalId), 'employees has member herbert');
+ok($employees->HasMemberRecursively($eric->PrincipalId), 'employees has member eric');
+
+ok($hackers->HasMemberRecursively($herbert->PrincipalId), 'hackers has member herbert');
+ok(!$hackers->HasMemberRecursively($eric->PrincipalId), 'hackers does not have member eric');
+
+# There's also a separate group, "Other", which both are a member of.
+my $other = RT::Group->new(RT->SystemUser);
+($ok, $msg) = $other->CreateUserDefinedGroup(Name => 'Other');
+ok($ok, $msg);
+($ok, $msg) = $other->AddMember($eric->PrincipalId);
+ok($ok, $msg);
+($ok, $msg) = $other->AddMember($herbert->PrincipalId);
+ok($ok, $msg);
+
+
+# Everyone can SeeGroup on all three groups
+my $everyone = RT::Group->new( RT->SystemUser );
+($ok, $msg) = $everyone->LoadSystemInternalGroup( 'Everyone' );
+ok($ok, $msg);
+$everyone->PrincipalObj->GrantRight(Right => 'SeeGroup', Object => $employees);
+$everyone->PrincipalObj->GrantRight(Right => 'SeeGroup', Object => $hackers);
+$everyone->PrincipalObj->GrantRight(Right => 'SeeGroup', Object => $other);
+
+sub CheckRights {
+ my $cu = shift;
+ my %groups = (Employees => 0, Hackers => 0, Other => 0, @_);
+ my $name = $cu->Name;
+
+ my $groups = RT::Groups->new(RT::CurrentUser->new($cu));
+ $groups->LimitToUserDefinedGroups;
+ $groups->ForWhichCurrentUserHasRight(Right => 'RTxGroupRight');
+ my %has_right = map { ($_->Name => 1) } @{ $groups->ItemsArrayRef };
+
+ local $Test::Builder::Level = $Test::Builder::Level + 1;
+ for my $groupname (sort keys %groups) {
+ my $g = RT::Group->new(RT::CurrentUser->new($cu));
+ $g->LoadUserDefinedGroup($groupname);
+ if ($groups{$groupname}) {
+ ok( $g->CurrentUserHasRight("RTxGroupRight"), "$name has right on $groupname (direct query)" );
+ ok( delete $has_right{$groupname}, "..and also in ForWhichCurrentUserHasRight");
+ } else {
+ ok( !$g->CurrentUserHasRight("RTxGroupRight"), "$name doesn't have right on $groupname (direct query)" );
+ ok( !delete $has_right{$groupname}, "..and also not in ForWhichCurrentUserHasRight");
+ }
+ }
+ ok(not(keys %has_right), "ForWhichCurrentUserHasRight has no extra groups");
+}
+
+# Neither should have it on any group yet
+CheckRights($eric);
+CheckRights($herbert);
+
+
+# Grant it to employees, on employees. Both Herbert and Eric will have
+# it on employees, though Herbert gets it by way of hackers. Neither
+# will have it on hackers, because the target does not recurse.
+$employees->PrincipalObj->GrantRight( Right => 'RTxGroupRight', Object => $employees);
+CheckRights($eric, Employees => 1);
+CheckRights($herbert, Employees => 1);
+
+
+# Grant it to employees, on hackers. This means both Eric and Herbert
+# will have the right on hackers, but not on employees.
+$employees->PrincipalObj->RevokeRight(Right => 'RTxGroupRight', Object => $employees);
+$employees->PrincipalObj->GrantRight( Right => 'RTxGroupRight', Object => $hackers);
+CheckRights($eric, Hackers => 1);
+CheckRights($herbert, Hackers => 1);
+
+
+# Grant it to hackers, on employees. Eric will have it nowhere, and
+# Herbert will have it on employees. Note that the target of the right
+# itself does _not_ recurse down, so Herbert will not have it on
+# hackers.
+$employees->PrincipalObj->RevokeRight(Right => 'RTxGroupRight', Object => $hackers);
+$hackers->PrincipalObj->GrantRight( Right => 'RTxGroupRight', Object => $employees);
+CheckRights($eric);
+CheckRights($herbert, Employees => 1);
+
+
+# Grant it globally to hackers; herbert will see the right on all
+# employees, hackers, and other.
+$hackers->PrincipalObj->RevokeRight( Right => 'RTxGroupRight', Object => $employees);
+$hackers->PrincipalObj->GrantRight( Right => 'RTxGroupRight', Object => RT->System);
+CheckRights($eric);
+CheckRights($herbert, Employees => 1, Hackers => 1, Other => 1 );
+
+
+# Grant it globally to employees; both eric and herbert will see the
+# right on all employees, hackers, and other.
+$hackers->PrincipalObj->RevokeRight( Right => 'RTxGroupRight', Object => RT->System);
+$employees->PrincipalObj->GrantRight( Right => 'RTxGroupRight', Object => RT->System);
+CheckRights($eric, Employees => 1, Hackers => 1, Other => 1 );
+CheckRights($herbert, Employees => 1, Hackers => 1, Other => 1 );
+
+
+# Disable the employees group. Neither eric nor herbert will see the
+# right anywhere.
+$employees->SetDisabled(1);
+CheckRights($eric);
+CheckRights($herbert);
diff --git a/rt/t/api/group.t b/rt/t/api/group.t
index 551d4f1a0..3ce3da999 100644
--- a/rt/t/api/group.t
+++ b/rt/t/api/group.t
@@ -2,20 +2,19 @@
use strict;
use warnings;
use RT;
-use RT::Test tests => 38;
+use RT::Test nodata => 1, tests => 38;
{
-# {{{ Tests
ok (require RT::Group);
-ok (my $group = RT::Group->new($RT::SystemUser), "instantiated a group object");
+ok (my $group = RT::Group->new(RT->SystemUser), "instantiated a group object");
ok (my ($id, $msg) = $group->CreateUserDefinedGroup( Name => 'TestGroup', Description => 'A test group',
), 'Created a new group');
isnt ($id , 0, "Group id is $id");
is ($group->Name , 'TestGroup', "The group's name is 'TestGroup'");
-my $ng = RT::Group->new($RT::SystemUser);
+my $ng = RT::Group->new(RT->SystemUser);
ok($ng->LoadUserDefinedGroup('TestGroup'), "Loaded testgroup");
is($ng->id , $group->id, "Loaded the right group");
@@ -30,7 +29,7 @@ ok($id, $msg);
# Group 1 now has members 1, 2 ,3
-my $group_2 = RT::Group->new($RT::SystemUser);
+my $group_2 = RT::Group->new(RT->SystemUser);
ok (my ($id_2, $msg_2) = $group_2->CreateUserDefinedGroup( Name => 'TestGroup2', Description => 'A second test group'), , 'Created a new group');
isnt ($id_2 , 0, "Created group 2 ok- $msg_2 ");
ok (($id,$msg) = $group_2->AddMember($ng->PrincipalId), "Made TestGroup a member of testgroup2");
@@ -40,7 +39,7 @@ ok($id, $msg);
# Group 2 how has 1, g1->{1, 2,3}
-my $group_3 = RT::Group->new($RT::SystemUser);
+my $group_3 = RT::Group->new(RT->SystemUser);
ok (my ($id_3, $msg_3) = $group_3->CreateUserDefinedGroup( Name => 'TestGroup3', Description => 'A second test group'), 'Created a new group');
isnt ($id_3 , 0, "Created group 3 ok - $msg_3");
ok (($id,$msg) =$group_3->AddMember($group_2->PrincipalId), "Made TestGroup a member of testgroup2");
@@ -48,10 +47,10 @@ ok($id, $msg);
# g3 now has g2->{1, g1->{1,2,3}}
-my $principal_1 = RT::Principal->new($RT::SystemUser);
+my $principal_1 = RT::Principal->new(RT->SystemUser);
$principal_1->Load('1');
-my $principal_2 = RT::Principal->new($RT::SystemUser);
+my $principal_2 = RT::Principal->new(RT->SystemUser);
$principal_2->Load('2');
ok (($id,$msg) = $group_3->AddMember('1' ), "Added member RT_System to the group TestGroup2");
@@ -81,14 +80,13 @@ is($group_2->HasMemberRecursively($principal_2), undef, "group 2 doesn't have me
is($ng->HasMember($principal_2), undef, "group 1 doesn't have member 2");
is($group_3->HasMemberRecursively($principal_2), undef, "group 3 has member 2 recursively");
-# }}}
}
{
-ok(my $u = RT::Group->new($RT::SystemUser));
+ok(my $u = RT::Group->new(RT->SystemUser));
ok($u->Load(4), "Loaded the first user");
is($u->PrincipalObj->ObjectId , 4, "user 4 is the fourth principal");
is($u->PrincipalObj->PrincipalType , 'Group' , "Principal 4 is a group");
@@ -96,4 +94,3 @@ is($u->PrincipalObj->PrincipalType , 'Group' , "Principal 4 is a group");
}
-1;
diff --git a/rt/t/api/groups.t b/rt/t/api/groups.t
index 995c844ba..d2dc126dc 100644
--- a/rt/t/api/groups.t
+++ b/rt/t/api/groups.t
@@ -1,87 +1,73 @@
-
use strict;
use warnings;
-use RT;
-use RT::Test tests => 28;
+use RT::Test nodata => 1, tests => 27;
+RT::Group->AddRights(
+ 'RTxGroupRight' => 'Just a right for testing rights',
+);
{
-
-ok (require RT::Groups);
-
-
+ my $g = RT::Group->new(RT->SystemUser);
+ my ($id, $msg) = $g->CreateUserDefinedGroup(Name => 'GroupsNotEqualTest');
+ ok ($id, "created group #". $g->id) or diag("error: $msg");
+
+ my $groups = RT::Groups->new(RT->SystemUser);
+ $groups->Limit( FIELD => 'id', OPERATOR => '!=', VALUE => $g->id );
+ $groups->LimitToUserDefinedGroups();
+ my $bug = grep $_->id == $g->id, @{$groups->ItemsArrayRef};
+ ok (!$bug, "didn't find group");
}
-{
-
-# next had bugs
-# Groups->Limit( FIELD => 'id', OPERATOR => '!=', VALUE => xx );
-my $g = RT::Group->new($RT::SystemUser);
-my ($id, $msg) = $g->CreateUserDefinedGroup(Name => 'GroupsNotEqualTest');
-ok ($id, "created group #". $g->id) or diag("error: $msg");
-
-my $groups = RT::Groups->new($RT::SystemUser);
-$groups->Limit( FIELD => 'id', OPERATOR => '!=', VALUE => $g->id );
-$groups->LimitToUserDefinedGroups();
-my $bug = grep $_->id == $g->id, @{$groups->ItemsArrayRef};
-ok (!$bug, "didn't find group");
-
-
-}
{
-
-my $u = RT::User->new($RT::SystemUser);
-my ($id, $msg) = $u->Create( Name => 'Membertests'. $$ );
-ok ($id, 'created user') or diag "error: $msg";
-
-my $g = RT::Group->new($RT::SystemUser);
-($id, $msg) = $g->CreateUserDefinedGroup(Name => 'Membertests');
-ok ($id, $msg);
-
-my ($aid, $amsg) =$g->AddMember($u->id);
-ok ($aid, $amsg);
-ok($g->HasMember($u->PrincipalObj),"G has member u");
-
-my $groups = RT::Groups->new($RT::SystemUser);
-$groups->LimitToUserDefinedGroups();
-$groups->WithMember(PrincipalId => $u->id);
-is ($groups->Count , 1,"found the 1 group - " . $groups->Count);
-is ($groups->First->Id , $g->Id, "it's the right one");
-
-
+ my $u = RT::User->new(RT->SystemUser);
+ my ($id, $msg) = $u->Create( Name => 'Membertests'. $$ );
+ ok ($id, 'created user') or diag "error: $msg";
+
+ my $g = RT::Group->new(RT->SystemUser);
+ ($id, $msg) = $g->CreateUserDefinedGroup(Name => 'Membertests');
+ ok ($id, $msg);
+
+ my ($aid, $amsg) =$g->AddMember($u->id);
+ ok ($aid, $amsg);
+ ok($g->HasMember($u->PrincipalObj),"G has member u");
+
+ my $groups = RT::Groups->new(RT->SystemUser);
+ $groups->LimitToUserDefinedGroups();
+ $groups->WithMember(PrincipalId => $u->id);
+ is ($groups->Count , 1,"found the 1 group - " . $groups->Count);
+ is ($groups->First->Id , $g->Id, "it's the right one");
}
-{
- no warnings qw/redefine once/;
+no warnings qw/redefine once/;
-my $q = RT::Queue->new($RT::SystemUser);
+my $q = RT::Queue->new(RT->SystemUser);
my ($id, $msg) =$q->Create( Name => 'GlobalACLTest');
ok ($id, $msg);
-my $testuser = RT::User->new($RT::SystemUser);
+my $testuser = RT::User->new(RT->SystemUser);
($id,$msg) = $testuser->Create(Name => 'JustAnAdminCc');
ok ($id,$msg);
-my $global_admin_cc = RT::Group->new($RT::SystemUser);
+my $global_admin_cc = RT::Group->new(RT->SystemUser);
$global_admin_cc->LoadSystemRoleGroup('AdminCc');
ok($global_admin_cc->id, "Found the global admincc group");
-my $groups = RT::Groups->new($RT::SystemUser);
+my $groups = RT::Groups->new(RT->SystemUser);
$groups->WithRight(Right => 'OwnTicket', Object => $q);
is($groups->Count, 1);
-($id, $msg) = $global_admin_cc->PrincipalObj->GrantRight(Right =>'OwnTicket', Object=> $RT::System);
+($id, $msg) = $global_admin_cc->PrincipalObj->GrantRight(Right =>'OwnTicket', Object=> RT->System);
ok ($id,$msg);
ok (!$testuser->HasRight(Object => $q, Right => 'OwnTicket') , "The test user does not have the right to own tickets in the test queue");
($id, $msg) = $q->AddWatcher(Type => 'AdminCc', PrincipalId => $testuser->id);
ok($id,$msg);
ok ($testuser->HasRight(Object => $q, Right => 'OwnTicket') , "The test user does have the right to own tickets now. thank god.");
-$groups = RT::Groups->new($RT::SystemUser);
+$groups = RT::Groups->new(RT->SystemUser);
$groups->WithRight(Right => 'OwnTicket', Object => $q);
ok ($id,$msg);
is($groups->Count, 3);
-my $RTxGroup = RT::Group->new($RT::SystemUser);
+my $RTxGroup = RT::Group->new(RT->SystemUser);
($id, $msg) = $RTxGroup->CreateUserDefinedGroup( Name => 'RTxGroup', Description => "RTx extension group");
ok ($id,$msg);
is ($RTxGroup->id, $id, "group loaded");
@@ -90,7 +76,7 @@ my $RTxSysObj = {};
bless $RTxSysObj, 'RTx::System';
*RTx::System::Id = sub { 1; };
*RTx::System::id = *RTx::System::Id;
-my $ace = RT::Record->new($RT::SystemUser);
+my $ace = RT::Record->new(RT->SystemUser);
$ace->Table('ACL');
$ace->_BuildTableAttributes unless ($RT::Record::_TABLE_ATTR->{ref($ace)});
($id, $msg) = $ace->Create( PrincipalId => $RTxGroup->id, PrincipalType => 'Group', RightName => 'RTxGroupRight', ObjectType => 'RTx::System', ObjectId => 1);
@@ -101,19 +87,19 @@ bless $RTxObj, 'RTx::System::Record';
*RTx::System::Record::Id = sub { 4; };
*RTx::System::Record::id = *RTx::System::Record::Id;
-$groups = RT::Groups->new($RT::SystemUser);
+$groups = RT::Groups->new(RT->SystemUser);
$groups->WithRight(Right => 'RTxGroupRight', Object => $RTxSysObj);
is($groups->Count, 1, "RTxGroupRight found for RTxSysObj");
-$groups = RT::Groups->new($RT::SystemUser);
+$groups = RT::Groups->new(RT->SystemUser);
$groups->WithRight(Right => 'RTxGroupRight', Object => $RTxObj);
is($groups->Count, 0, "RTxGroupRight not found for RTxObj");
-$groups = RT::Groups->new($RT::SystemUser);
+$groups = RT::Groups->new(RT->SystemUser);
$groups->WithRight(Right => 'RTxGroupRight', Object => $RTxObj, EquivObjects => [ $RTxSysObj ]);
is($groups->Count, 1, "RTxGroupRight found for RTxObj using EquivObjects");
-$ace = RT::Record->new($RT::SystemUser);
+$ace = RT::Record->new(RT->SystemUser);
$ace->Table('ACL');
$ace->_BuildTableAttributes unless ($RT::Record::_TABLE_ATTR->{ref($ace)});
($id, $msg) = $ace->Create( PrincipalId => $RTxGroup->id, PrincipalType => 'Group', RightName => 'RTxGroupRight', ObjectType => 'RTx::System::Record', ObjectId => 5 );
@@ -123,17 +109,10 @@ my $RTxObj2 = {};
bless $RTxObj2, 'RTx::System::Record';
*RTx::System::Record::Id = sub { 5; };
-$groups = RT::Groups->new($RT::SystemUser);
+$groups = RT::Groups->new(RT->SystemUser);
$groups->WithRight(Right => 'RTxGroupRight', Object => $RTxObj2);
is($groups->Count, 1, "RTxGroupRight found for RTxObj2");
-$groups = RT::Groups->new($RT::SystemUser);
+$groups = RT::Groups->new(RT->SystemUser);
$groups->WithRight(Right => 'RTxGroupRight', Object => $RTxObj2, EquivObjects => [ $RTxSysObj ]);
is($groups->Count, 1, "RTxGroupRight found for RTxObj2");
-
-
-
-
-}
-
-1;
diff --git a/rt/t/api/has_rights.t b/rt/t/api/has_rights.t
new file mode 100644
index 000000000..990fc0185
--- /dev/null
+++ b/rt/t/api/has_rights.t
@@ -0,0 +1,43 @@
+use RT::Test nodata => 1, tests => 9;
+
+use strict;
+use warnings;
+
+my $queue = RT::Test->load_or_create_queue( Name => 'A' );
+ok $queue && $queue->id, 'loaded or created queue_a';
+my $qid = $queue->id;
+
+my $user = RT::Test->load_or_create_user(
+ Name => 'user',
+ Password => 'password',
+ EmailAddress => 'test@example.com',
+);
+ok $user && $user->id, 'loaded or created user';
+
+{
+ cleanup();
+ RT::Test->set_rights(
+ { Principal => 'Everyone', Right => [qw(SeeQueue)] },
+ { Principal => 'Cc', Right => [qw(ShowTicket)] },
+ );
+ my ($t) = RT::Test->create_tickets(
+ { Queue => $queue->id },
+ { },
+ );
+ my $rights = $user->PrincipalObj->HasRights( Object => $t );
+ is_deeply( $rights, { SeeQueue => 1 }, 'got it' );
+
+ ($t) = RT::Test->create_tickets(
+ { Queue => $queue->id },
+ { Cc => $user->EmailAddress },
+ );
+ ok($t->Cc->HasMember( $user->id ), 'user is cc');
+ $rights = $user->PrincipalObj->HasRights( Object => $t );
+ is_deeply( $rights, { SeeQueue => 1, ShowTicket => 1 }, 'got it' )
+}
+
+sub cleanup {
+ RT::Test->delete_tickets( "Queue = $qid" );
+ RT::Test->delete_queue_watchers( $queue );
+};
+
diff --git a/rt/t/api/i18n.t b/rt/t/api/i18n.t
index 17d71b761..831532b90 100644
--- a/rt/t/api/i18n.t
+++ b/rt/t/api/i18n.t
@@ -2,7 +2,7 @@
use strict;
use warnings;
use RT;
-use RT::Test tests => 9;
+use RT::Test nodb => 1, tests => 9;
{
@@ -27,4 +27,3 @@ is($en->encoding , 'utf-8', "The encoding ".$en->encoding." is 'utf-8'");
}
-1;
diff --git a/rt/t/api/i18n_guess.t b/rt/t/api/i18n_guess.t
new file mode 100644
index 000000000..139ec1acd
--- /dev/null
+++ b/rt/t/api/i18n_guess.t
@@ -0,0 +1,71 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 16;
+
+use Encode qw(encode);
+
+use constant HAS_ENCODE_GUESS => do { local $@; eval { require Encode::Guess; 1 } };
+use constant HAS_ENCODE_DETECT => do { local $@; eval { require Encode::Detect::Detector; 1 } };
+
+my $string = "\x{442}\x{435}\x{441}\x{442} \x{43f}\x{43e}\x{434}\x{434}\x{435}\x{440}\x{436}\x{43a}\x{430}";
+
+sub guess {
+ local $Test::Builder::Level = $Test::Builder::Level + 1;
+ is( RT::I18N::_GuessCharset( Encode::encode($_[0], $_[1]) ), $_[2] || $_[0], "$_[0] guesses as @{[$_[2]||$_[0]]}" );
+}
+
+RT->Config->Set(EmailInputEncodings => qw(*));
+SKIP: {
+ skip "No Encode::Detect", 3 unless HAS_ENCODE_DETECT;
+ guess('utf-8', $string);
+ guess('cp1251', $string);
+ guess('koi8-r', $string);
+}
+
+RT->Config->Set(EmailInputEncodings => qw(UTF-8 cp1251 koi8-r));
+SKIP: {
+ skip "No Encode::Guess", 4 unless HAS_ENCODE_GUESS;
+ guess('utf-8', $string);
+ guess('cp1251', $string);
+ guess('windows-1251', $string, 'cp1251');
+ {
+ local $TODO = "Encode::Guess can't distinguish cp1251 from koi8-r";
+ guess('koi8-r', $string);
+ }
+}
+
+RT->Config->Set(EmailInputEncodings => qw(UTF-8 koi8-r cp1251));
+SKIP: {
+ skip "No Encode::Guess", 3 unless HAS_ENCODE_GUESS;
+ guess('utf-8', $string);
+ guess('koi8-r', $string);
+ {
+ local $TODO = "Encode::Guess can't distinguish cp1251 from koi8-r";
+ guess('cp1251', $string);
+ }
+}
+
+# windows-1251 is an alias for cp1251, post load check cleanups array for us
+RT->Config->Set(EmailInputEncodings => qw(UTF-8 windows-1251 koi8-r));
+RT->Config->PostLoadCheck;
+SKIP: {
+ skip "No Encode::Guess", 3 unless HAS_ENCODE_GUESS;
+ guess('utf-8', $string);
+ guess('cp1251', $string);
+ {
+ local $TODO = "Encode::Guess can't distinguish cp1251 from koi8-r";
+ guess('koi8-r', $string);
+ }
+}
+
+RT->Config->Set(EmailInputEncodings => qw(* UTF-8 cp1251 koi8-r));
+SKIP: {
+ skip "No Encode::Detect", 3 unless HAS_ENCODE_DETECT;
+ guess('utf-8', $string);
+ guess('cp1251', $string);
+ guess('koi8-r', $string);
+}
+
diff --git a/rt/t/api/link.t b/rt/t/api/link.t
index eac9ae29a..a9e54a716 100644
--- a/rt/t/api/link.t
+++ b/rt/t/api/link.t
@@ -1,13 +1,12 @@
-
use strict;
use warnings;
-use RT::Test tests => 77;
+use RT::Test nodata => 1, tests => 84;
use RT::Test::Web;
+use Test::Warn;
use RT::Link;
-my $link = RT::Link->new($RT::SystemUser);
-
+my $link = RT::Link->new(RT->SystemUser);
ok (ref $link);
isa_ok( $link, 'RT::Link');
@@ -18,29 +17,37 @@ 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 $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(
+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";
{
+ my ($status, $msg);
clean_links();
- my ($status, $msg) = $parent->AddLink;
+
+ warning_like {
+ ($status, $msg) = $parent->AddLink;
+ } qr/Base or Target must be specified/, "warned about linking a ticket to itself";
ok(!$status, "didn't create a link: $msg");
- ($status, $msg) = $parent->AddLink( Base => $parent->id );
+ warning_like {
+ ($status, $msg) = $parent->AddLink( Base => $parent->id );
+ } qr/Can't link a ticket to itself/, "warned about linking a ticket to itself";
ok(!$status, "didn't create a link: $msg");
- ($status, $msg) = $parent->AddLink( Base => $parent->id, Type => 'HasMember' );
+ warning_like {
+ ($status, $msg) = $parent->AddLink( Base => $parent->id, Type => 'HasMember' );
+ } qr/Can't link a ticket to itself/, "warned about linking a ticket to itself";
ok(!$status, "didn't create a link: $msg");
}
@@ -197,8 +204,39 @@ ok $cid, 'created a ticket #'. $cid or diag "error: $msg";
;
}
+{
+ clean_links();
+ $child->SetStatus('deleted');
+
+ my ($status, $msg) = $parent->AddLink(
+ Type => 'MemberOf', Base => $child->id,
+ );
+ ok(!$status, "can't link to deleted ticket: $msg");
+
+ $child->SetStatus('new');
+ ($status, $msg) = $parent->AddLink(
+ Type => 'MemberOf', Base => $child->id,
+ );
+ ok($status, "created a link: $msg");
+
+ $child->SetStatus('deleted');
+ my $children = $parent->Members;
+ $children->RedoSearch;
+
+ my $total = 0;
+ $total++ while $children->Next;
+ is( $total, 0, 'Next skips deleted tickets' );
+
+ is( @{ $children->ItemsArrayRef },
+ 0, 'ItemsArrayRef skips deleted tickets' );
+
+ # back to active status
+ $child->SetStatus('new');
+}
+
sub clean_links {
- my $links = RT::Links->new( $RT::SystemUser );
+ my $links = RT::Links->new( RT->SystemUser );
+ $links->UnLimit;
while ( my $link = $links->Next ) {
my ($status, $msg) = $link->Delete;
$RT::Logger->error("Couldn't delete a link: $msg")
@@ -206,4 +244,3 @@ sub clean_links {
}
}
-1;
diff --git a/rt/t/api/password-types.t b/rt/t/api/password-types.t
index 267a6ede4..5f253d51e 100644
--- a/rt/t/api/password-types.t
+++ b/rt/t/api/password-types.t
@@ -5,27 +5,37 @@ use warnings;
use RT::Test;
use Digest::MD5;
+my $default = "sha512";
+
my $root = RT::User->new(RT->SystemUser);
$root->Load("root");
-# Salted truncated SHA-256
+# Salted SHA-512 (default)
my $old = $root->__Value("Password");
-is(length($old), 40, "Stored as truncated salted SHA-256");
+like($old, qr/^\!$default\!/, "Stored as salted $default");
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");
+like($root->__Value("Password"), qr/^\!$default\!/, "And is now upgraded to salted $default");
# 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");
+like($root->__Value("Password"), qr/^\!$default\!/, "And is now upgraded to salted $default");
# 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");
+like($root->__Value("Password"), qr/^\!$default\!/, "And is now upgraded to salted $default");
+# Salted truncated SHA-256
+my $trunc = MIME::Base64::encode_base64(
+ "salt" . substr(Digest::SHA::sha256("salt".Digest::MD5::md5("secret")),0,26),
+ ""
+);
+$root->_Set( Field => "Password", Value => $trunc);
+ok($root->IsPassword("secret"), "Unsalted MD5 base64 works");
+like($root->__Value("Password"), qr/^\!$default\!/, "And is now upgraded to salted $default");
diff --git a/rt/t/api/queue.t b/rt/t/api/queue.t
index 44d5cafce..07b8ed479 100644
--- a/rt/t/api/queue.t
+++ b/rt/t/api/queue.t
@@ -2,7 +2,7 @@
use strict;
use warnings;
use RT;
-use RT::Test tests => 24;
+use RT::Test nodata => 1, tests => 24;
{
@@ -14,7 +14,7 @@ use RT::Queue;
{
-my $q = RT::Queue->new($RT::SystemUser);
+my $q = RT::Queue->new(RT->SystemUser);
is($q->IsValidStatus('new'), 1, 'New is a valid status');
is($q->IsValidStatus('f00'), 0, 'f00 is not a valid status');
@@ -23,7 +23,7 @@ is($q->IsValidStatus('f00'), 0, 'f00 is not a valid status');
{
-my $q = RT::Queue->new($RT::SystemUser);
+my $q = RT::Queue->new(RT->SystemUser);
is($q->IsActiveStatus('new'), 1, 'New is a Active status');
is($q->IsActiveStatus('rejected'), 0, 'Rejected is an inactive status');
is($q->IsActiveStatus('f00'), 0, 'f00 is not a Active status');
@@ -33,7 +33,7 @@ is($q->IsActiveStatus('f00'), 0, 'f00 is not a Active status');
{
-my $q = RT::Queue->new($RT::SystemUser);
+my $q = RT::Queue->new(RT->SystemUser);
is($q->IsInactiveStatus('new'), 0, 'New is a Active status');
is($q->IsInactiveStatus('rejected'), 1, 'rejeected is an Inactive status');
is($q->IsInactiveStatus('f00'), 0, 'f00 is not a Active status');
@@ -43,7 +43,7 @@ is($q->IsInactiveStatus('f00'), 0, 'f00 is not a Active status');
{
-my $queue = RT::Queue->new($RT::SystemUser);
+my $queue = RT::Queue->new(RT->SystemUser);
my ($id, $val) = $queue->Create( Name => 'Test1');
ok($id, $val);
@@ -55,10 +55,10 @@ ok(!$id, $val);
{
-my $Queue = RT::Queue->new($RT::SystemUser);
+my $Queue = RT::Queue->new(RT->SystemUser);
my ($id, $msg) = $Queue->Create(Name => "Foo");
ok ($id, "Foo $id was created");
-ok(my $group = RT::Group->new($RT::SystemUser));
+ok(my $group = RT::Group->new(RT->SystemUser));
ok($group->LoadQueueRoleGroup(Queue => $id, Type=> 'Requestor'));
ok ($group->Id, "Found the requestors object for this Queue");
@@ -67,7 +67,7 @@ ok ($group->Id, "Found the requestors object for this Queue");
ok ($status, "Added bob at fsck.com as a requestor") or diag "error: $msg";
}
-ok(my $bob = RT::User->new($RT::SystemUser), "Creating a bob rt::user");
+ok(my $bob = RT::User->new(RT->SystemUser), "Creating a bob rt::user");
$bob->LoadByEmail('bob@fsck.com');
ok($bob->Id, "Found the bob rt user");
ok ($Queue->IsWatcher(Type => 'Cc', PrincipalId => $bob->PrincipalId), "The Queue actually has bob at fsck.com as a requestor");
@@ -79,14 +79,13 @@ ok ($Queue->IsWatcher(Type => 'Cc', PrincipalId => $bob->PrincipalId), "The Queu
"The Queue no longer has bob at fsck.com as a requestor");
}
-$group = RT::Group->new($RT::SystemUser);
+$group = RT::Group->new(RT->SystemUser);
ok($group->LoadQueueRoleGroup(Queue => $id, Type=> 'Cc'));
ok ($group->Id, "Found the cc object for this Queue");
-$group = RT::Group->new($RT::SystemUser);
+$group = RT::Group->new(RT->SystemUser);
ok($group->LoadQueueRoleGroup(Queue => $id, Type=> 'AdminCc'));
ok ($group->Id, "Found the AdminCc object for this Queue");
}
-1;
diff --git a/rt/t/api/record.t b/rt/t/api/record.t
index 6bf1af81e..4b6b0b89c 100644
--- a/rt/t/api/record.t
+++ b/rt/t/api/record.t
@@ -14,8 +14,8 @@ ok (require RT::Record);
{
-my $ticket = RT::Ticket->new($RT::SystemUser);
-my $group = RT::Group->new($RT::SystemUser);
+my $ticket = RT::Ticket->new(RT->SystemUser);
+my $group = RT::Group->new(RT->SystemUser);
is($ticket->ObjectTypeStr, 'Ticket', "Ticket returns correct typestring");
is($group->ObjectTypeStr, 'Group', "Group returns correct typestring");
@@ -24,14 +24,14 @@ is($group->ObjectTypeStr, 'Group', "Group returns correct typestring");
{
-my $t1 = RT::Ticket->new($RT::SystemUser);
+my $t1 = RT::Ticket->new(RT->SystemUser);
my ($id, $trans, $msg) = $t1->Create(Subject => 'DepTest1', Queue => 'general');
ok($id, "Created dep test 1 - $msg");
-my $t2 = RT::Ticket->new($RT::SystemUser);
+my $t2 = RT::Ticket->new(RT->SystemUser);
(my $id2, $trans, my $msg2) = $t2->Create(Subject => 'DepTest2', Queue => 'general');
ok($id2, "Created dep test 2 - $msg2");
-my $t3 = RT::Ticket->new($RT::SystemUser);
+my $t3 = RT::Ticket->new(RT->SystemUser);
(my $id3, $trans, my $msg3) = $t3->Create(Subject => 'DepTest3', Queue => 'general', Type => 'approval');
ok($id3, "Created dep test 3 - $msg3");
my ($addid, $addmsg);
@@ -40,7 +40,7 @@ ok ($addid, $addmsg);
ok (($addid, $addmsg) =$t1->AddLink( Type => 'DependsOn', Target => $t3->id));
ok ($addid, $addmsg);
-my $link = RT::Link->new($RT::SystemUser);
+my $link = RT::Link->new(RT->SystemUser);
(my $rv, $msg) = $link->Load($addid);
ok ($rv, $msg);
is ($link->LocalTarget , $t3->id, "Link LocalTarget is correct");
@@ -52,19 +52,18 @@ ok ($t1->HasUnresolvedDependencies( Type => 'approval' ), "Ticket ".$t1->Id." ha
ok (!$t2->HasUnresolvedDependencies, "Ticket ".$t2->Id." has no unresolved deps");
;
-my ($rid, $rmsg)= $t1->Resolve();
+my ($rid, $rmsg)= $t1->SetStatus('resolved');
ok(!$rid, $rmsg);
-my ($rid2, $rmsg2) = $t2->Resolve();
+my ($rid2, $rmsg2) = $t2->SetStatus('resolved');
ok ($rid2, $rmsg2);
-($rid, $rmsg)= $t1->Resolve();
+($rid, $rmsg)= $t1->SetStatus('resolved');
ok(!$rid, $rmsg);
-my ($rid3,$rmsg3) = $t3->Resolve;
+my ($rid3,$rmsg3) = $t3->SetStatus('resolved');
ok ($rid3,$rmsg3);
-($rid, $rmsg)= $t1->Resolve();
+($rid, $rmsg)= $t1->SetStatus('resolved');
ok($rid, $rmsg);
}
-1;
diff --git a/rt/t/api/reminders.t b/rt/t/api/reminders.t
index fd1c6a69f..b035fa8de 100644
--- a/rt/t/api/reminders.t
+++ b/rt/t/api/reminders.t
@@ -10,7 +10,7 @@ use RT::Test tests => 20;
# Create test queues
use_ok ('RT::Queue');
-ok(my $testqueue = RT::Queue->new($RT::SystemUser), 'Instantiate RT::Queue');
+ok(my $testqueue = RT::Queue->new(RT->SystemUser), 'Instantiate RT::Queue');
ok($testqueue->Create( Name => 'reminders tests'), 'Create new queue: reminders tests');
isnt($testqueue->Id , 0, 'Success creating queue');
@@ -20,10 +20,10 @@ isnt($testqueue->Id , 0, 'Success creating queue');
# Create test ticket
use_ok('RT::Ticket');
-my $u = RT::User->new($RT::SystemUser);
+my $u = RT::User->new(RT->SystemUser);
$u->Load("root");
ok ($u->Id, "Found the root user");
-ok(my $t = RT::Ticket->new($RT::SystemUser), 'Instantiate RT::Ticket');
+ok(my $t = RT::Ticket->new(RT->SystemUser), 'Instantiate RT::Ticket');
ok(my ($id, $msg) = $t->Create( Queue => $testqueue->Id,
Subject => 'Testing',
Owner => $u->Id
@@ -31,7 +31,7 @@ ok(my ($id, $msg) = $t->Create( Queue => $testqueue->Id,
isnt($id , 0, 'Success creating ticket');
# Add reminder
-my $due_obj = RT::Date->new( $RT::SystemUser );
+my $due_obj = RT::Date->new( RT->SystemUser );
$due_obj->SetToNow;
ok(my ( $add_id, $add_msg, $txnid ) = $t->Reminders->Add(
Subject => 'TestReminder',
@@ -85,4 +85,4 @@ while ( my $reminder = $reminders->Next ) {
is($r_resolved, 1, 'Reminder resolved');
}
-1;
+
diff --git a/rt/t/api/rights.t b/rt/t/api/rights.t
index a38bcea0c..a1795ca0a 100644
--- a/rt/t/api/rights.t
+++ b/rt/t/api/rights.t
@@ -47,14 +47,14 @@
#
# END BPS TAGGED BLOCK }}}
-use RT::Test tests => 30;
+use RT::Test nodata => 1, tests => 30;
use strict;
use warnings;
# clear all global right
{
- my $acl = RT::ACL->new($RT::SystemUser);
+ my $acl = RT::ACL->new(RT->SystemUser);
$acl->Limit( FIELD => 'RightName', OPERATOR => '!=', VALUE => 'SuperUser' );
$acl->LimitToObject( $RT::System );
while( my $ace = $acl->Next ) {
@@ -81,11 +81,11 @@ ok $user && $user->id, 'loaded or created user';
}
{
- my $group = RT::Group->new( $RT::SystemUser );
+ my $group = RT::Group->new( RT->SystemUser );
ok( $group->LoadQueueRoleGroup( Queue => $queue->id, Type=> 'Owner' ),
"load queue owners role group"
);
- my $ace = RT::ACE->new( $RT::SystemUser );
+ my $ace = RT::ACE->new( RT->SystemUser );
my ($ace_id, $msg) = $group->PrincipalObj->GrantRight(
Right => 'ReplyToTicket', Object => $queue
);
@@ -101,10 +101,10 @@ ok $user && $user->id, 'loaded or created user';
my $ticket;
{
# new ticket
- $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket = RT::Ticket->new(RT->SystemUser);
my ($ticket_id) = $ticket->Create( Queue => $queue->id, Subject => 'test');
ok( $ticket_id, 'new ticket created' );
- is( $ticket->Owner, $RT::Nobody->Id, 'owner of the new ticket is nobody' );
+ is( $ticket->Owner, RT->Nobody->Id, 'owner of the new ticket is nobody' );
ok( !$user->HasRight( Right => 'OwnTicket', Object => $ticket ),
"user can't reply to ticket"
@@ -136,11 +136,11 @@ my $ticket;
{
# Testing of EquivObjects
- my $group = RT::Group->new( $RT::SystemUser );
+ my $group = RT::Group->new( RT->SystemUser );
ok( $group->LoadQueueRoleGroup( Queue => $queue->id, Type=> 'AdminCc' ),
"load queue AdminCc role group"
);
- my $ace = RT::ACE->new( $RT::SystemUser );
+ my $ace = RT::ACE->new( RT->SystemUser );
my ($ace_id, $msg) = $group->PrincipalObj->GrantRight(
Right => 'ModifyTicket', Object => $queue
);
@@ -165,7 +165,7 @@ my $ticket;
my $ticket2;
{
- $ticket2 = RT::Ticket->new($RT::SystemUser);
+ $ticket2 = RT::Ticket->new(RT->SystemUser);
my ($id) = $ticket2->Create( Queue => $queue->id, Subject => 'test2');
ok( $id, 'new ticket created' );
ok( !$user->HasRight( Right => 'ModifyTicket', Object => $ticket2 ),
diff --git a/rt/t/api/rights_show_ticket.t b/rt/t/api/rights_show_ticket.t
index 3e1d0740f..62f62c422 100644
--- a/rt/t/api/rights_show_ticket.t
+++ b/rt/t/api/rights_show_ticket.t
@@ -1,6 +1,6 @@
#!/usr/bin/perl -w
-use RT::Test tests => 264;
+use RT::Test nodata => 1, tests => 264;
use strict;
use warnings;
@@ -228,7 +228,7 @@ sub create_tickets_set{
my @res;
foreach my $q ($queue_a, $queue_b) {
foreach my $n (1 .. 2) {
- my $ticket = RT::Ticket->new( $RT::SystemUser );
+ my $ticket = RT::Ticket->new( RT->SystemUser );
my ($tid) = $ticket->Create(
Queue => $q->id, Subject => $q->Name .' - '. $n
);
@@ -239,24 +239,8 @@ sub create_tickets_set{
return @res;
}
-sub cleanup { delete_tickets(); delete_watchers() };
-
-sub delete_tickets {
- my $tickets = RT::Tickets->new( $RT::SystemUser );
- $tickets->FromSQL( "Queue = $qa_id OR Queue = $qb_id" );
- while ( my $ticket = $tickets->Next ) {
- $ticket->Delete;
- }
-}
-
-sub delete_watchers {
- foreach my $q ($queue_a, $queue_b) {
- foreach my $u ($user_a, $user_b) {
- foreach my $t (qw(Cc AdminCc) ) {
- $q->DeleteWatcher( Type => $t, PrincipalId => $u->id )
- if $q->IsWatcher( Type => $t, PrincipalId => $u->id );
- }
- }
- }
-}
+sub cleanup {
+ RT::Test->delete_tickets( "Queue = $qa_id OR Queue = $qb_id" );
+ RT::Test->delete_queue_watchers( $queue_a, $queue_b );
+};
diff --git a/rt/t/api/rt.t b/rt/t/api/rt.t
index 3c06b5848..51c776250 100644
--- a/rt/t/api/rt.t
+++ b/rt/t/api/rt.t
@@ -2,17 +2,16 @@
use strict;
use warnings;
use RT;
-use RT::Test tests => 4;
+use RT::Test nodata => 1, tests => 4;
{
-is ($RT::Nobody->Name() , 'Nobody', "Nobody is nobody");
-isnt ($RT::Nobody->Name() , 'root', "Nobody isn't named root");
-is ($RT::SystemUser->Name() , 'RT_System', "The system user is RT_System");
-isnt ($RT::SystemUser->Name() , 'noname', "The system user isn't noname");
+is (RT->Nobody->Name() , 'Nobody', "Nobody is nobody");
+isnt (RT->Nobody->Name() , 'root', "Nobody isn't named root");
+is (RT->SystemUser->Name() , 'RT_System', "The system user is RT_System");
+isnt (RT->SystemUser->Name() , 'noname', "The system user isn't noname");
}
-1;
diff --git a/rt/t/api/rtname.t b/rt/t/api/rtname.t
new file mode 100644
index 000000000..ef6092bb2
--- /dev/null
+++ b/rt/t/api/rtname.t
@@ -0,0 +1,34 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+use RT::Test nodata => 1, tests => 9;
+
+use RT::Interface::Email;
+
+# normal use case, regexp set to rtname
+RT->Config->Set( rtname => "site" );
+RT->Config->Set( EmailSubjectTagRegex => qr/site/ );
+RT->Config->Set( rtname => undef );
+is(RT::Interface::Email::ParseTicketId("[site #123] test"), 123);
+is(RT::Interface::Email::ParseTicketId("[othersite #123] test"), undef);
+
+# oops usecase, where the regexp is scragged
+RT->Config->Set( rtname => "site" );
+RT->Config->Set( EmailSubjectTagRegex => undef );
+is(RT::Interface::Email::ParseTicketId("[site #123] test"), 123);
+is(RT::Interface::Email::ParseTicketId("[othersite #123] test"), undef);
+
+# set to a simple regexp. NOTE: we no longer match "site"
+RT->Config->Set( rtname => "site");
+RT->Config->Set( EmailSubjectTagRegex => qr/newsite/);
+is(RT::Interface::Email::ParseTicketId("[site #123] test"), undef);
+is(RT::Interface::Email::ParseTicketId("[newsite #123] test"), 123);
+
+# set to a more complex regexp
+RT->Config->Set( rtname => "site" );
+RT->Config->Set( EmailSubjectTagRegex => qr/newsite|site/ );
+is(RT::Interface::Email::ParseTicketId("[site #123] test"), 123);
+is(RT::Interface::Email::ParseTicketId("[newsite #123] test"), 123);
+is(RT::Interface::Email::ParseTicketId("[othersite #123] test"), undef);
+
diff --git a/rt/t/api/safe-run-child-util.t b/rt/t/api/safe-run-child-util.t
new file mode 100644
index 000000000..b29e97177
--- /dev/null
+++ b/rt/t/api/safe-run-child-util.t
@@ -0,0 +1,201 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 35;
+use Test::Warn;
+
+use RT::Util qw(safe_run_child);
+use POSIX qw//;
+
+is_handle_ok();
+
+{
+ my $res = safe_run_child { return 1 };
+ is $res, 1, "correct return value";
+ is_handle_ok();
+}
+
+# test context
+{
+ my $context;
+ my $sub = sub {
+ if ( wantarray ) {
+ $context = 'array'; return 1, 2, 3;
+ } elsif ( defined wantarray ) {
+ $context = 'scalar'; return 'foo';
+ } elsif ( !wantarray ) {
+ $context = 'void'; return;
+ }
+ };
+ is_deeply [ safe_run_child { $sub->(@_) } ], [1, 2, 3];
+ is $context, 'array';
+ is_handle_ok();
+
+ is scalar safe_run_child {$sub->(@_)}, 'foo';
+ is $context, 'scalar';
+ is_handle_ok();
+
+ safe_run_child {$sub->(@_)};
+ is $context, 'void';
+ is_handle_ok();
+}
+
+# fork+child returns
+{
+ my $res = safe_run_child {
+ if (fork) { wait; return 'parent' }
+
+ open my $fh, '>', RT::Test->temp_directory .'/tttt';
+ print $fh "child";
+ close $fh;
+
+ return 'child';
+ };
+ is $res, 'parent', "correct return value";
+ is( RT::Test->file_content([RT::Test->temp_directory, 'tttt'], unlink => 1 ),
+ 'child',
+ 'correct file content',
+ );
+ is_handle_ok();
+}
+
+# fork+child dies
+{
+ warning_like {
+ my $res = safe_run_child {
+ if (fork) { wait; return 'parent' }
+
+ open my $fh, '>', RT::Test->temp_directory .'/tttt';
+ print $fh "child";
+ close $fh;
+
+ die 'child';
+ };
+ is $res, 'parent', "correct return value";
+ is( RT::Test->file_content([RT::Test->temp_directory, 'tttt'], unlink => 1 ),
+ 'child',
+ 'correct file content',
+ );
+ } qr/System Error: child/;
+ is_handle_ok();
+}
+
+# fork+child exits
+{
+ my $res = safe_run_child {
+ if (fork) { wait; return 'parent' }
+
+ open my $fh, '>', RT::Test->temp_directory .'/tttt';
+ print $fh "child";
+ close $fh;
+
+ exit 0;
+ };
+ is $res, 'parent', "correct return value";
+ is( RT::Test->file_content([RT::Test->temp_directory, 'tttt'], unlink => 1 ),
+ 'child',
+ 'correct file content',
+ );
+ is_handle_ok();
+}
+
+# parent dies
+{
+ my $res = eval { safe_run_child { die 'parent'; } };
+ is $res, undef, "correct return value";
+ like $@, qr'System Error: parent', "correct error message value";
+ is_handle_ok();
+}
+
+# fork+exec
+{
+ my $script = RT::Test->temp_directory .'/true.pl';
+ open my $fh, '>', $script;
+ print $fh <<END;
+#!$^X
+
+open my \$fh, '>', '$script.res';
+print \$fh "child";
+close \$fh;
+
+exit 0;
+END
+ close $fh;
+ chmod 0777, $script;
+
+ my $res = safe_run_child {
+ if (fork) { wait; return 'parent' }
+ exec $script;
+ };
+ is $res, 'parent', "correct return value";
+ is( RT::Test->file_content([$script .'.res'], unlink => 1 ),
+ 'child',
+ 'correct file content',
+ );
+ is_handle_ok();
+}
+
+# fork+parent that doesn't wait()
+{
+ require Time::HiRes;
+ my $start = Time::HiRes::time();
+ my $pid;
+
+ # Set up a poor man's semaphore
+ my $all_set = 0;
+ $SIG{USR1} = sub {$all_set++};
+
+ my $res = safe_run_child {
+ if ($pid = fork) { return 'parent' }
+
+ open my $fh, '>', RT::Test->temp_directory .'/first';
+ print $fh "child";
+ close $fh;
+ # Signal that the first file is now all set; we need to do this
+ # to avoid a race condition
+ kill POSIX::SIGUSR1(), getppid();
+
+ sleep 5;
+
+ open $fh, '>', RT::Test->temp_directory .'/second';
+ print $fh "child";
+ close $fh;
+
+ exit 0;
+ };
+ ok( Time::HiRes::time() - $start < 5, "Didn't wait until child finished" );
+
+ # Wait for up to 3 seconds to get signaled that the child has made
+ # the file (the USR1 will break out of the sleep()). This _should_
+ # be immediate, but there's a race between the parent and child
+ # here, since there's no wait()'ing. There's still a tiny race
+ # where the signal could come in betwene the $all_set check and the
+ # sleep, but that just means we sleep for 3 seconds uselessly.
+ sleep 3 unless $all_set;
+
+ is $res, 'parent', "correct return value";
+ is( RT::Test->file_content([RT::Test->temp_directory, 'first'], unlink => 1 ),
+ 'child',
+ 'correct file content',
+ );
+ ok( not(-f RT::Test->temp_directory.'/second'), "Second file does not exist yet");
+ is_handle_ok();
+
+ ok(waitpid($pid,0), "Waited until child finished to reap");
+ is( RT::Test->file_content([RT::Test->temp_directory, 'second'], unlink => 1 ),
+ 'child',
+ 'correct file content',
+ );
+ is_handle_ok();
+}
+
+sub is_handle_ok {
+ local $Test::Builder::Level = $Test::Builder::Level + 1;
+ my $test = $RT::Handle->dbh->selectall_arrayref(
+ "SELECT id FROM Users WHERE Name = 'Nobody'"
+ );
+ ok $test && $test->[0][0], "selected, DB is there";
+}
+
diff --git a/rt/t/api/savedsearch.t b/rt/t/api/savedsearch.t
new file mode 100644
index 000000000..0aa67eeda
--- /dev/null
+++ b/rt/t/api/savedsearch.t
@@ -0,0 +1,181 @@
+use strict;
+use warnings;
+BEGIN { $ENV{'LANG'} = 'C' }
+
+use RT::Test tests => 27;
+
+use_ok('RT::SavedSearch');
+use_ok('RT::SavedSearches');
+
+use Test::Warn;
+
+# Set up some infrastructure. These calls are tested elsewhere.
+
+my $searchuser = RT::User->new(RT->SystemUser);
+my ($ret, $msg) = $searchuser->Create(Name => 'searchuser'.$$,
+ Privileged => 1,
+ EmailAddress => "searchuser\@p$$.example.com",
+ RealName => 'Search user');
+ok($ret, "created searchuser: $msg");
+$searchuser->PrincipalObj->GrantRight(Right => 'LoadSavedSearch');
+$searchuser->PrincipalObj->GrantRight(Right => 'CreateSavedSearch');
+$searchuser->PrincipalObj->GrantRight(Right => 'ModifySelf');
+
+# This is the group whose searches searchuser should be able to see.
+my $ingroup = RT::Group->new(RT->SystemUser);
+$ingroup->CreateUserDefinedGroup(Name => 'searchgroup1'.$$);
+$ingroup->AddMember($searchuser->Id);
+$searchuser->PrincipalObj->GrantRight(Right => 'EditSavedSearches',
+ Object => $ingroup);
+$searchuser->PrincipalObj->GrantRight(Right => 'ShowSavedSearches',
+ Object => $ingroup);
+
+# This is the group whose searches searchuser should not be able to see.
+my $outgroup = RT::Group->new(RT->SystemUser);
+$outgroup->CreateUserDefinedGroup(Name => 'searchgroup2'.$$);
+$outgroup->AddMember(RT->SystemUser->Id);
+
+my $queue = RT::Queue->new(RT->SystemUser);
+$queue->Create(Name => 'SearchQueue'.$$);
+$searchuser->PrincipalObj->GrantRight(Right => 'SeeQueue', Object => $queue);
+$searchuser->PrincipalObj->GrantRight(Right => 'ShowTicket', Object => $queue);
+$searchuser->PrincipalObj->GrantRight(Right => 'OwnTicket', Object => $queue);
+
+
+my $ticket = RT::Ticket->new(RT->SystemUser);
+$ticket->Create(Queue => $queue->Id,
+ Requestor => [ $searchuser->Name ],
+ Owner => $searchuser,
+ Subject => 'saved search test');
+
+
+# Now start the search madness.
+my $curruser = RT::CurrentUser->new($searchuser);
+my $format = '\' <b><a href="/Ticket/Display.html?id=__id__">__id__</a></b>/TITLE:#\',
+\'<b><a href="/Ticket/Display.html?id=__id__">__Subject__</a></b>/TITLE:Subject\',
+\'__Status__\',
+\'__QueueName__\',
+\'__OwnerName__\',
+\'__Priority__\',
+\'__NEWLINE__\',
+\'\',
+\'<small>__Requestors__</small>\',
+\'<small>__CreatedRelative__</small>\',
+\'<small>__ToldRelative__</small>\',
+\'<small>__LastUpdatedRelative__</small>\',
+\'<small>__TimeLeft__</small>\'';
+
+my $mysearch = RT::SavedSearch->new($curruser);
+($ret, $msg) = $mysearch->Save(Privacy => 'RT::User-' . $searchuser->Id,
+ Type => 'Ticket',
+ Name => 'owned by me',
+ SearchParams => {'Format' => $format,
+ 'Query' => "Owner = '"
+ . $searchuser->Name
+ . "'"});
+ok($ret, "mysearch was created");
+
+
+my $groupsearch = RT::SavedSearch->new($curruser);
+($ret, $msg) = $groupsearch->Save(Privacy => 'RT::Group-' . $ingroup->Id,
+ Type => 'Ticket',
+ Name => 'search queue',
+ SearchParams => {'Format' => $format,
+ 'Query' => "Queue = '"
+ . $queue->Name . "'"});
+ok($ret, "groupsearch was created");
+
+my $othersearch = RT::SavedSearch->new($curruser);
+($ret, $msg) = $othersearch->Save(Privacy => 'RT::Group-' . $outgroup->Id,
+ Type => 'Ticket',
+ Name => 'searchuser requested',
+ SearchParams => {'Format' => $format,
+ 'Query' =>
+ "Requestor.Name LIKE 'search'"});
+ok(!$ret, "othersearch NOT created");
+like($msg, qr/Failed to load object for/, "...for the right reason");
+
+$othersearch = RT::SavedSearch->new(RT->SystemUser);
+($ret, $msg) = $othersearch->Save(Privacy => 'RT::Group-' . $outgroup->Id,
+ Type => 'Ticket',
+ Name => 'searchuser requested',
+ SearchParams => {'Format' => $format,
+ 'Query' =>
+ "Requestor.Name LIKE 'search'"});
+ok($ret, "othersearch created by systemuser");
+
+# Now try to load some searches.
+
+# This should work.
+my $loadedsearch1 = RT::SavedSearch->new($curruser);
+$loadedsearch1->Load('RT::User-'.$curruser->Id, $mysearch->Id);
+is($loadedsearch1->Id, $mysearch->Id, "Loaded mysearch");
+like($loadedsearch1->GetParameter('Query'), qr/Owner/,
+ "Retrieved query of mysearch");
+# Check through the other accessor methods.
+is($loadedsearch1->Privacy, 'RT::User-' . $curruser->Id,
+ "Privacy of mysearch correct");
+is($loadedsearch1->Name, 'owned by me', "Name of mysearch correct");
+is($loadedsearch1->Type, 'Ticket', "Type of mysearch correct");
+
+# See if it can be used to search for tickets.
+my $tickets = RT::Tickets->new($curruser);
+$tickets->FromSQL($loadedsearch1->GetParameter('Query'));
+is($tickets->Count, 1, "Found a ticket");
+
+# This should fail -- wrong object.
+# my $loadedsearch2 = RT::SavedSearch->new($curruser);
+# $loadedsearch2->Load('RT::User-'.$curruser->Id, $groupsearch->Id);
+# isnt($loadedsearch2->Id, $othersearch->Id, "Didn't load groupsearch as mine");
+# ...but this should succeed.
+my $loadedsearch3 = RT::SavedSearch->new($curruser);
+$loadedsearch3->Load('RT::Group-'.$ingroup->Id, $groupsearch->Id);
+is($loadedsearch3->Id, $groupsearch->Id, "Loaded groupsearch");
+like($loadedsearch3->GetParameter('Query'), qr/Queue/,
+ "Retrieved query of groupsearch");
+# Can it get tickets?
+$tickets = RT::Tickets->new($curruser);
+$tickets->FromSQL($loadedsearch3->GetParameter('Query'));
+is($tickets->Count, 1, "Found a ticket");
+
+# This should fail -- no permission.
+my $loadedsearch4 = RT::SavedSearch->new($curruser);
+
+warning_like {
+ $loadedsearch4->Load($othersearch->Privacy, $othersearch->Id);
+} qr/Could not load object RT::Group-\d+ when loading search/;
+
+isnt($loadedsearch4->Id, $othersearch->Id, "Did not load othersearch");
+
+# Try to update an existing search.
+$loadedsearch1->Update( SearchParams => {'Format' => $format,
+ 'Query' => "Queue = '" . $queue->Name . "'" } );
+like($loadedsearch1->GetParameter('Query'), qr/Queue/,
+ "Updated mysearch parameter");
+is($loadedsearch1->Type, 'Ticket', "mysearch is still for tickets");
+is($loadedsearch1->Privacy, 'RT::User-'.$curruser->Id,
+ "mysearch still belongs to searchuser");
+like($mysearch->GetParameter('Query'), qr/Queue/, "other mysearch object updated");
+
+
+## Right ho. Test the pseudo-collection object.
+
+my $genericsearch = RT::SavedSearch->new($curruser);
+$genericsearch->Save(Name => 'generic search',
+ Type => 'all',
+ SearchParams => {'Query' => "Queue = 'General'"});
+
+my $ticketsearches = RT::SavedSearches->new($curruser);
+$ticketsearches->LimitToPrivacy('RT::User-'.$curruser->Id, 'Ticket');
+is($ticketsearches->Count, 1, "Found searchuser's ticket searches");
+
+my $allsearches = RT::SavedSearches->new($curruser);
+$allsearches->LimitToPrivacy('RT::User-'.$curruser->Id);
+is($allsearches->Count, 2, "Found all searchuser's searches");
+
+# Delete a search.
+($ret, $msg) = $genericsearch->Delete;
+ok($ret, "Deleted genericsearch");
+$allsearches->LimitToPrivacy('RT::User-'.$curruser->Id);
+is($allsearches->Count, 1, "Found all searchuser's searches after deletion");
+
diff --git a/rt/t/api/scrip.t b/rt/t/api/scrip.t
index 9d97e7344..eb543476b 100644
--- a/rt/t/api/scrip.t
+++ b/rt/t/api/scrip.t
@@ -10,11 +10,11 @@ use RT::Test tests => 25;
ok (require RT::Scrip);
-my $q = RT::Queue->new($RT::SystemUser);
+my $q = RT::Queue->new(RT->SystemUser);
$q->Create(Name => 'ScripTest');
ok($q->Id, "Created a scriptest queue");
-my $s1 = RT::Scrip->new($RT::SystemUser);
+my $s1 = RT::Scrip->new(RT->SystemUser);
my ($val, $msg) =$s1->Create( Queue => $q->Id,
ScripAction => 'User Defined',
ScripCondition => 'User Defined',
@@ -25,7 +25,7 @@ my ($val, $msg) =$s1->Create( Queue => $q->Id,
);
ok($val,$msg);
-my $ticket = RT::Ticket->new($RT::SystemUser);
+my $ticket = RT::Ticket->new(RT->SystemUser);
my ($tv,$ttv,$tm) = $ticket->Create(Queue => $q->Id,
Subject => "hair on fire",
);
@@ -34,7 +34,7 @@ ok($tv, $tm);
is ($ticket->Priority , '87', "Ticket priority is set right");
-my $ticket2 = RT::Ticket->new($RT::SystemUser);
+my $ticket2 = RT::Ticket->new(RT->SystemUser);
my ($t2v,$t2tv,$t2m) = $ticket2->Create(Queue => $q->Id,
Subject => "hair in water",
);
@@ -117,5 +117,3 @@ isnt ($ticket2->Priority , '87', "Ticket priority is set right");
ok( $scrip->Delete, 'delete the scrip' );
}
-
-1;
diff --git a/rt/t/api/scrip_order.t b/rt/t/api/scrip_order.t
index 9738db9bc..22d3f21d1 100644
--- a/rt/t/api/scrip_order.t
+++ b/rt/t/api/scrip_order.t
@@ -6,14 +6,13 @@ use RT;
use RT::Test tests => 7;
-# {{{ test scrip ordering based on description
-my $scrip_queue = RT::Queue->new($RT::SystemUser);
+my $scrip_queue = RT::Queue->new(RT->SystemUser);
my ($queue_id, $msg) = $scrip_queue->Create( Name => "ScripOrdering-$$",
Description => 'Test scrip ordering by description' );
ok($queue_id, "Created scrip-ordering test queue? ".$msg);
-my $priority_ten_scrip = RT::Scrip->new($RT::SystemUser);
+my $priority_ten_scrip = RT::Scrip->new(RT->SystemUser);
(my $id, $msg) = $priority_ten_scrip->Create(
Description => "10 set priority $$",
Queue => $queue_id,
@@ -26,7 +25,7 @@ my $priority_ten_scrip = RT::Scrip->new($RT::SystemUser);
);
ok($id, "Created priority-10 scrip? ".$msg);
-my $priority_five_scrip = RT::Scrip->new($RT::SystemUser);
+my $priority_five_scrip = RT::Scrip->new(RT->SystemUser);
($id, $msg) = $priority_ten_scrip->Create(
Description => "05 set priority $$",
Queue => $queue_id,
@@ -39,7 +38,7 @@ my $priority_five_scrip = RT::Scrip->new($RT::SystemUser);
);
ok($id, "Created priority-5 scrip? ".$msg);
-my $ticket = RT::Ticket->new($RT::SystemUser);
+my $ticket = RT::Ticket->new(RT->SystemUser);
($id, $msg) = $ticket->Create(
Queue => $queue_id,
Requestor => 'order@example.com',
@@ -51,6 +50,4 @@ isnt($ticket->Priority , 0, "Ticket shouldn't be priority 0");
isnt($ticket->Priority , 5, "Ticket shouldn't be priority 5");
is ($ticket->Priority , 10, "Ticket should be priority 10");
-# }}}
-1;
diff --git a/rt/t/api/searchbuilder.t b/rt/t/api/searchbuilder.t
index cb118906c..8562bfc2b 100644
--- a/rt/t/api/searchbuilder.t
+++ b/rt/t/api/searchbuilder.t
@@ -15,7 +15,7 @@ ok (require RT::SearchBuilder);
{
use_ok('RT::Queues');
-ok(my $queues = RT::Queues->new($RT::SystemUser), 'Created a queues object');
+ok(my $queues = RT::Queues->new(RT->SystemUser), 'Created a queues object');
ok( $queues->UnLimit(),'Unlimited the result set of the queues object');
my $items = $queues->ItemsArrayRef();
my @items = @{$items};
@@ -37,4 +37,3 @@ is_deeply(\@items_ids, \@sorted_ids, "ItemsArrayRef sorts alphabetically by name
}
-1;
diff --git a/rt/t/api/squish.t b/rt/t/api/squish.t
new file mode 100644
index 000000000..59615368f
--- /dev/null
+++ b/rt/t/api/squish.t
@@ -0,0 +1,16 @@
+use strict;
+use warnings;
+use RT;
+use RT::Test nodb => 1, tests => 7;
+
+use RT::Squish;
+
+my $squish = RT::Squish->new();
+for my $method ( qw/Content ModifiedTime ModifiedTimeString Key/ ) {
+ can_ok($squish, $method);
+}
+like( $squish->Key, qr/[a-f0-9]{32}/, 'Key is like md5' );
+ok( (time()-$squish->ModifiedTime) <= 2, 'ModifiedTime' );
+
+use RT::Squish::CSS;
+can_ok('RT::Squish::CSS', 'Style');
diff --git a/rt/t/api/system.t b/rt/t/api/system.t
index 3077115c7..f1100d332 100644
--- a/rt/t/api/system.t
+++ b/rt/t/api/system.t
@@ -2,12 +2,12 @@
use strict;
use warnings;
use RT;
-use RT::Test tests => 7;
+use RT::Test nodata => 1, tests => 7;
{
-my $s = RT::System->new($RT::SystemUser);
+my $s = RT::System->new(RT->SystemUser);
my $rights = $s->AvailableRights;
ok ($rights, "Rights defined");
ok ($rights->{'AdminUsers'},"AdminUsers right found");
@@ -30,4 +30,3 @@ is ($sys->id, 1);
}
-1;
diff --git a/rt/t/api/template-insert.t b/rt/t/api/template-insert.t
index 47bbd790c..1bf5fc390 100644
--- a/rt/t/api/template-insert.t
+++ b/rt/t/api/template-insert.t
@@ -12,7 +12,7 @@ use RT::Test tests => 7;
# This tiny little test script triggers an interaction bug between DBD::Oracle 1.16, SB 1.15 and RT 3.4
use_ok('RT::Template');
-my $template = RT::Template->new($RT::SystemUser);
+my $template = RT::Template->new(RT->SystemUser);
isa_ok($template, 'RT::Template');
my ($val,$msg) = $template->Create(Queue => 1,
diff --git a/rt/t/api/template-simple.t b/rt/t/api/template-simple.t
new file mode 100644
index 000000000..bbdebb31f
--- /dev/null
+++ b/rt/t/api/template-simple.t
@@ -0,0 +1,275 @@
+use strict;
+use warnings;
+use RT;
+use RT::Test tests => 231;
+use Test::Warn;
+
+my $queue = RT::Queue->new(RT->SystemUser);
+$queue->Load("General");
+
+my $ticket_cf = RT::CustomField->new(RT->SystemUser);
+$ticket_cf->Create(
+ Name => 'Department',
+ Queue => '0',
+ Type => 'FreeformSingle',
+);
+
+my $txn_cf = RT::CustomField->new(RT->SystemUser);
+$txn_cf->Create(
+ Name => 'Category',
+ LookupType => RT::Transaction->CustomFieldLookupType,
+ Type => 'FreeformSingle',
+);
+$txn_cf->AddToObject($queue);
+
+my $ticket = RT::Ticket->new(RT->SystemUser);
+my ($id, $msg) = $ticket->Create(
+ Subject => "template testing",
+ Queue => "General",
+ Owner => 'root@localhost',
+ Requestor => ["dom\@example.com"],
+ "CustomField-" . $txn_cf->id => "Special",
+);
+ok($id, "Created ticket: $msg");
+my $txn = $ticket->Transactions->First;
+
+$ticket->AddCustomFieldValue(
+ Field => 'Department',
+ Value => 'Coolio',
+);
+
+TemplateTest(
+ Content => "\ntest",
+ PerlOutput => "test",
+ SimpleOutput => "test",
+);
+
+TemplateTest(
+ Content => "\ntest { 5 * 5 }",
+ PerlOutput => "test 25",
+ SimpleOutput => "test { 5 * 5 }",
+);
+
+TemplateTest(
+ Content => "\ntest { \$Requestor }",
+ PerlOutput => "test dom\@example.com",
+ SimpleOutput => "test dom\@example.com",
+);
+
+TemplateTest(
+ Content => "\ntest { \$TicketSubject }",
+ PerlOutput => "test ",
+ SimpleOutput => "test template testing",
+);
+
+SimpleTemplateTest(
+ Content => "\ntest { \$TicketQueueId }",
+ Output => "test 1",
+);
+
+SimpleTemplateTest(
+ Content => "\ntest { \$TicketQueueName }",
+ Output => "test General",
+);
+
+SimpleTemplateTest(
+ Content => "\ntest { \$TicketOwnerId }",
+ Output => "test 12",
+);
+
+SimpleTemplateTest(
+ Content => "\ntest { \$TicketOwnerName }",
+ Output => "test root",
+);
+
+SimpleTemplateTest(
+ Content => "\ntest { \$TicketOwnerEmailAddress }",
+ Output => "test root\@localhost",
+);
+
+SimpleTemplateTest(
+ Content => "\ntest { \$TicketStatus }",
+ Output => "test new",
+);
+
+SimpleTemplateTest(
+ Content => "\ntest #{ \$TicketId }",
+ Output => "test #" . $ticket->id,
+);
+
+SimpleTemplateTest(
+ Content => "\ntest { \$TicketCFDepartment }",
+ Output => "test Coolio",
+);
+
+SimpleTemplateTest(
+ Content => "\ntest #{ \$TransactionId }",
+ Output => "test #" . $txn->id,
+);
+
+SimpleTemplateTest(
+ Content => "\ntest { \$TransactionType }",
+ Output => "test Create",
+);
+
+SimpleTemplateTest(
+ Content => "\ntest { \$TransactionCFCategory }",
+ Output => "test Special",
+);
+
+SimpleTemplateTest(
+ Content => "\ntest { \$TicketDelete }",
+ Output => "test { \$TicketDelete }",
+);
+
+SimpleTemplateTest(
+ Content => "\ntest { \$Nonexistent }",
+ Output => "test { \$Nonexistent }",
+);
+
+warning_like {
+ TemplateTest(
+ Content => "\ntest { \$Ticket->Nonexistent }",
+ PerlOutput => undef,
+ SimpleOutput => "test { \$Ticket->Nonexistent }",
+ );
+} qr/RT::Ticket::Nonexistent Unimplemented/;
+
+warning_like {
+ TemplateTest(
+ Content => "\ntest { \$Nonexistent->Nonexistent }",
+ PerlOutput => undef,
+ SimpleOutput => "test { \$Nonexistent->Nonexistent }",
+ );
+} qr/Can't call method "Nonexistent" on an undefined value/;
+
+TemplateTest(
+ Content => "\ntest { \$Ticket->OwnerObj->Name }",
+ PerlOutput => "test root",
+ SimpleOutput => "test { \$Ticket->OwnerObj->Name }",
+);
+
+warning_like {
+ TemplateTest(
+ Content => "\ntest { *!( }",
+ SyntaxError => 1,
+ PerlOutput => undef,
+ SimpleOutput => "test { *!( }",
+ );
+} qr/Template parsing error: syntax error/;
+
+TemplateTest(
+ Content => "\ntest { \$rtname ",
+ SyntaxError => 1,
+ PerlOutput => undef,
+ SimpleOutput => undef,
+);
+
+is($ticket->Status, 'new', "test setup");
+SimpleTemplateTest(
+ Content => "\ntest { \$Ticket->SetStatus('resolved') }",
+ Output => "test { \$Ticket->SetStatus('resolved') }",
+);
+is($ticket->Status, 'new', "simple templates can't call ->SetStatus");
+
+# Make sure changing the template's type works
+my $template = RT::Template->new(RT->SystemUser);
+$template->Create(
+ Name => "type chameleon",
+ Type => "Perl",
+ Content => "\ntest { 10 * 7 }",
+);
+ok($id = $template->id, "Created template");
+$template->Parse;
+is($template->MIMEObj->stringify_body, "test 70", "Perl output");
+
+$template = RT::Template->new(RT->SystemUser);
+$template->Load($id);
+is($template->Name, "type chameleon");
+
+$template->SetType('Simple');
+$template->Parse;
+is($template->MIMEObj->stringify_body, "test { 10 * 7 }", "Simple output");
+
+$template = RT::Template->new(RT->SystemUser);
+$template->Load($id);
+is($template->Name, "type chameleon");
+
+$template->SetType('Perl');
+$template->Parse;
+is($template->MIMEObj->stringify_body, "test 70", "Perl output");
+
+undef $ticket;
+
+my $counter = 0;
+sub IndividualTemplateTest {
+ local $Test::Builder::Level = $Test::Builder::Level + 1;
+
+ my %args = (
+ Name => "Test-" . ++$counter,
+ Type => "Perl",
+ @_,
+ );
+
+ my $t = RT::Template->new(RT->SystemUser);
+ $t->Create(
+ Name => $args{Name},
+ Type => $args{Type},
+ Content => $args{Content},
+ );
+
+ ok($t->id, "Created $args{Type} template");
+ is($t->Name, $args{Name}, "$args{Type} template name");
+ is($t->Content, $args{Content}, "$args{Type} content");
+ is($t->Type, $args{Type}, "template type");
+
+ # this should never blow up!
+ my ($ok, $msg) = $t->CompileCheck;
+
+ # we don't need to syntax check simple templates since if you mess them up
+ # it's safe to just use the input directly as the template's output
+ if ($args{SyntaxError} && $args{Type} eq 'Perl') {
+ ok(!$ok, "got a syntax error");
+ }
+ else {
+ ok($ok, $msg);
+ }
+
+ ($ok, $msg) = $t->Parse(
+ TicketObj => $ticket,
+ TransactionObj => $txn,
+ );
+ if (defined $args{Output}) {
+ ok($ok, $msg);
+ is($t->MIMEObj->stringify_body, $args{Output}, "$args{Type} template's output");
+ }
+ else {
+ ok(!$ok, "expected a failure");
+ }
+}
+
+sub TemplateTest {
+ local $Test::Builder::Level = $Test::Builder::Level + 1;
+ my %args = @_;
+
+ for my $type ('Perl', 'Simple') {
+ next if $args{"Skip$type"};
+
+ IndividualTemplateTest(
+ %args,
+ Type => $type,
+ Output => $args{$type . 'Output'},
+ );
+ }
+}
+
+sub SimpleTemplateTest {
+ local $Test::Builder::Level = $Test::Builder::Level + 1;
+ my %args = @_;
+
+ IndividualTemplateTest(
+ %args,
+ Type => 'Simple',
+ );
+}
+
diff --git a/rt/t/api/template.t b/rt/t/api/template.t
index 1612b8ffd..2fadede38 100644
--- a/rt/t/api/template.t
+++ b/rt/t/api/template.t
@@ -14,13 +14,12 @@ ok(require RT::Template);
{
-my $t = RT::Template->new($RT::SystemUser);
+my $t = RT::Template->new(RT->SystemUser);
$t->Create(Name => "Foo", Queue => 1);
-my $t2 = RT::Template->new($RT::Nobody);
+my $t2 = RT::Template->new(RT->Nobody);
$t2->Load($t->Id);
ok($t2->QueueObj->id, "Got the template's queue objet");
}
-1;
diff --git a/rt/t/api/ticket.t b/rt/t/api/ticket.t
index 2ca0997bd..92c8a85df 100644
--- a/rt/t/api/ticket.t
+++ b/rt/t/api/ticket.t
@@ -8,11 +8,11 @@ use RT::Test tests => 87;
{
use_ok ('RT::Queue');
-ok(my $testqueue = RT::Queue->new($RT::SystemUser));
+ok(my $testqueue = RT::Queue->new(RT->SystemUser));
ok($testqueue->Create( Name => 'ticket tests'));
isnt($testqueue->Id , 0);
use_ok('RT::CustomField');
-ok(my $testcf = RT::CustomField->new($RT::SystemUser));
+ok(my $testcf = RT::CustomField->new(RT->SystemUser));
my ($ret, $cmsg) = $testcf->Create( Name => 'selectmulti',
Queue => $testqueue->id,
Type => 'SelectMultiple');
@@ -34,10 +34,10 @@ is($testcf->Values->Count , 3);
use_ok('RT::Ticket');
-my $u = RT::User->new($RT::SystemUser);
+my $u = RT::User->new(RT->SystemUser);
$u->Load("root");
ok ($u->Id, "Found the root user");
-ok(my $t = RT::Ticket->new($RT::SystemUser));
+ok(my $t = RT::Ticket->new(RT->SystemUser));
ok(my ($id, $msg) = $t->Create( Queue => $testqueue->Id,
Subject => 'Testing',
Owner => $u->Id
@@ -56,13 +56,13 @@ ok(my ($cfdv, $cfdm) = $t->DeleteCustomFieldValue(Field => $testcf->Id,
isnt ($cfdv , 0, "Deleted a custom field value: $cfdm");
is($t->CustomFieldValues($testcf->Id)->Count , 0);
-ok(my $t2 = RT::Ticket->new($RT::SystemUser));
+ok(my $t2 = RT::Ticket->new(RT->SystemUser));
ok($t2->Load($id));
is($t2->Subject, 'Testing');
is($t2->QueueObj->Id, $testqueue->id);
is($t2->OwnerObj->Id, $u->Id);
-my $t3 = RT::Ticket->new($RT::SystemUser);
+my $t3 = RT::Ticket->new(RT->SystemUser);
my ($id3, $msg3) = $t3->Create( Queue => $testqueue->Id,
Subject => 'Testing',
Owner => $u->Id);
@@ -93,7 +93,7 @@ ok(require RT::Ticket, "Loading the RT::Ticket library");
{
-my $t = RT::Ticket->new($RT::SystemUser);
+my $t = RT::Ticket->new(RT->SystemUser);
ok( $t->Create(Queue => 'General', Due => '2002-05-21 00:00:00', ReferredToBy => 'http://www.cpan.org', RefersTo => 'http://fsck.com', Subject => 'This is a subject'), "Ticket Created");
@@ -107,19 +107,19 @@ is ($t->ResolvedObj->Unix, 0, "It hasn't been resolved - ". $t->ResolvedObj->Uni
{
-my $ticket = RT::Ticket->new($RT::SystemUser);
+my $ticket = RT::Ticket->new(RT->SystemUser);
my ($id, $msg) = $ticket->Create(Subject => "Foo",
- Owner => $RT::SystemUser->Id,
+ Owner => RT->SystemUser->Id,
Status => 'open',
Requestor => ['jesse@example.com'],
Queue => '1'
);
ok ($id, "Ticket $id was created");
-ok(my $group = RT::Group->new($RT::SystemUser));
+ok(my $group = RT::Group->new(RT->SystemUser));
ok($group->LoadTicketRoleGroup(Ticket => $id, Type=> 'Requestor'));
ok ($group->Id, "Found the requestors object for this ticket");
-ok(my $jesse = RT::User->new($RT::SystemUser), "Creating a jesse rt::user");
+ok(my $jesse = RT::User->new(RT->SystemUser), "Creating a jesse rt::user");
$jesse->LoadByEmail('jesse@example.com');
ok($jesse->Id, "Found the jesse rt user");
@@ -127,7 +127,7 @@ ok($jesse->Id, "Found the jesse rt user");
ok ($ticket->IsWatcher(Type => 'Requestor', PrincipalId => $jesse->PrincipalId), "The ticket actually has jesse at fsck.com as a requestor");
ok (my ($add_id, $add_msg) = $ticket->AddWatcher(Type => 'Requestor', Email => 'bob@fsck.com'), "Added bob at fsck.com as a requestor");
ok ($add_id, "Add succeeded: ($add_msg)");
-ok(my $bob = RT::User->new($RT::SystemUser), "Creating a bob rt::user");
+ok(my $bob = RT::User->new(RT->SystemUser), "Creating a bob rt::user");
$bob->LoadByEmail('bob@fsck.com');
ok($bob->Id, "Found the bob rt user");
ok ($ticket->IsWatcher(Type => 'Requestor', PrincipalId => $bob->PrincipalId), "The ticket actually has bob at fsck.com as a requestor");
@@ -135,23 +135,23 @@ ok ( ($add_id, $add_msg) = $ticket->DeleteWatcher(Type =>'Requestor', Email => '
ok (!$ticket->IsWatcher(Type => 'Requestor', PrincipalId => $bob->PrincipalId), "The ticket no longer has bob at fsck.com as a requestor");
-$group = RT::Group->new($RT::SystemUser);
+$group = RT::Group->new(RT->SystemUser);
ok($group->LoadTicketRoleGroup(Ticket => $id, Type=> 'Cc'));
ok ($group->Id, "Found the cc object for this ticket");
-$group = RT::Group->new($RT::SystemUser);
+$group = RT::Group->new(RT->SystemUser);
ok($group->LoadTicketRoleGroup(Ticket => $id, Type=> 'AdminCc'));
ok ($group->Id, "Found the AdminCc object for this ticket");
-$group = RT::Group->new($RT::SystemUser);
+$group = RT::Group->new(RT->SystemUser);
ok($group->LoadTicketRoleGroup(Ticket => $id, Type=> 'Owner'));
ok ($group->Id, "Found the Owner object for this ticket");
-ok($group->HasMember($RT::SystemUser->UserObj->PrincipalObj), "the owner group has the member 'RT_System'");
+ok($group->HasMember(RT->SystemUser->UserObj->PrincipalObj), "the owner group has the member 'RT_System'");
}
{
-my $t = RT::Ticket->new($RT::SystemUser);
+my $t = RT::Ticket->new(RT->SystemUser);
ok($t->Create(Queue => 'general', Subject => 'SquelchTest', SquelchMailTo => 'nobody@example.com'));
my @returned = $t->SquelchMailTo();
@@ -189,15 +189,15 @@ is($#returned, -1, "The ticket has no squelched recipients". join(',',@returned)
{
-my $t1 = RT::Ticket->new($RT::SystemUser);
+my $t1 = RT::Ticket->new(RT->SystemUser);
$t1->Create ( Subject => 'Merge test 1', Queue => 'general', Requestor => 'merge1@example.com');
my $t1id = $t1->id;
-my $t2 = RT::Ticket->new($RT::SystemUser);
+my $t2 = RT::Ticket->new(RT->SystemUser);
$t2->Create ( Subject => 'Merge test 2', Queue => 'general', Requestor => 'merge2@example.com');
my $t2id = $t2->id;
my ($msg, $val) = $t1->MergeInto($t2->id);
ok ($msg,$val);
-$t1 = RT::Ticket->new($RT::SystemUser);
+$t1 = RT::Ticket->new(RT->SystemUser);
is ($t1->id, undef, "ok. we've got a blank ticket1");
$t1->Load($t1id);
@@ -211,16 +211,16 @@ is ($t1->Requestors->MembersObj->Count, 2);
{
-my $root = RT::User->new($RT::SystemUser);
+my $root = RT::User->new(RT->SystemUser);
$root->Load('root');
ok ($root->Id, "Loaded the root user");
-my $t = RT::Ticket->new($RT::SystemUser);
+my $t = RT::Ticket->new(RT->SystemUser);
$t->Load(1);
$t->SetOwner('root');
is ($t->OwnerObj->Name, 'root' , "Root owns the ticket");
$t->Steal();
-is ($t->OwnerObj->id, $RT::SystemUser->id , "SystemUser owns the ticket");
-my $txns = RT::Transactions->new($RT::SystemUser);
+is ($t->OwnerObj->id, RT->SystemUser->id , "SystemUser owns the ticket");
+my $txns = RT::Transactions->new(RT->SystemUser);
$txns->OrderBy(FIELD => 'id', ORDER => 'DESC');
$txns->Limit(FIELD => 'ObjectId', VALUE => '1');
$txns->Limit(FIELD => 'ObjectType', VALUE => 'RT::Ticket');
@@ -228,14 +228,14 @@ $txns->Limit(FIELD => 'Type', OPERATOR => '!=', VALUE => 'EmailRecord');
my $steal = $txns->First;
is($steal->OldValue , $root->Id , "Stolen from root");
-is($steal->NewValue , $RT::SystemUser->Id , "Stolen by the systemuser");
+is($steal->NewValue , RT->SystemUser->Id , "Stolen by the systemuser");
}
{
-my $tt = RT::Ticket->new($RT::SystemUser);
+my $tt = RT::Ticket->new(RT->SystemUser);
my ($id, $tid, $msg)= $tt->Create(Queue => 'general',
Subject => 'test');
ok($id, $msg);
@@ -254,4 +254,3 @@ ok(!$id,$msg);
}
-1;
diff --git a/rt/t/api/tickets.t b/rt/t/api/tickets.t
index 9148a8899..cabb00e50 100644
--- a/rt/t/api/tickets.t
+++ b/rt/t/api/tickets.t
@@ -8,7 +8,7 @@ use RT::Test tests => 16;
{
ok (require RT::Tickets);
-ok( my $testtickets = RT::Tickets->new( $RT::SystemUser ) );
+ok( my $testtickets = RT::Tickets->new( RT->SystemUser ) );
ok( $testtickets->LimitStatus( VALUE => 'deleted' ) );
# Should be zero until 'allow_deleted_search'
is( $testtickets->Count , 0 );
@@ -22,45 +22,45 @@ is( $testtickets->Count , 0 );
# by requestor name.
my ($id,$msg);
-my $u1 = RT::User->new($RT::SystemUser);
+my $u1 = RT::User->new(RT->SystemUser);
($id, $msg) = $u1->Create( Name => 'RequestorTestOne', EmailAddress => 'rqtest1@example.com');
ok ($id,$msg);
-my $u2 = RT::User->new($RT::SystemUser);
+my $u2 = RT::User->new(RT->SystemUser);
($id, $msg) = $u2->Create( Name => 'RequestorTestTwo', EmailAddress => 'rqtest2@example.com');
ok ($id,$msg);
-my $t1 = RT::Ticket->new($RT::SystemUser);
+my $t1 = RT::Ticket->new(RT->SystemUser);
my ($trans);
($id,$trans,$msg) =$t1->Create (Queue => 'general', Subject => 'Requestor test one', Requestor => [$u1->EmailAddress]);
ok ($id, $msg);
-my $t2 = RT::Ticket->new($RT::SystemUser);
+my $t2 = RT::Ticket->new(RT->SystemUser);
($id,$trans,$msg) =$t2->Create (Queue => 'general', Subject => 'Requestor test one', Requestor => [$u2->EmailAddress]);
ok ($id, $msg);
-my $t3 = RT::Ticket->new($RT::SystemUser);
+my $t3 = RT::Ticket->new(RT->SystemUser);
($id,$trans,$msg) =$t3->Create (Queue => 'general', Subject => 'Requestor test one', Requestor => [$u2->EmailAddress, $u1->EmailAddress]);
ok ($id, $msg);
-my $tix1 = RT::Tickets->new($RT::SystemUser);
+my $tix1 = RT::Tickets->new(RT->SystemUser);
$tix1->FromSQL('Requestor.EmailAddress LIKE "rqtest1" OR Requestor.EmailAddress LIKE "rqtest2"');
is ($tix1->Count, 3);
-my $tix2 = RT::Tickets->new($RT::SystemUser);
+my $tix2 = RT::Tickets->new(RT->SystemUser);
$tix2->FromSQL('Requestor.Name LIKE "TestOne" OR Requestor.Name LIKE "TestTwo"');
is ($tix2->Count, 3);
-my $tix3 = RT::Tickets->new($RT::SystemUser);
+my $tix3 = RT::Tickets->new(RT->SystemUser);
$tix3->FromSQL('Requestor.EmailAddress LIKE "rqtest1"');
is ($tix3->Count, 2);
-my $tix4 = RT::Tickets->new($RT::SystemUser);
+my $tix4 = RT::Tickets->new(RT->SystemUser);
$tix4->FromSQL('Requestor.Name LIKE "TestOne" ');
is ($tix4->Count, 2);
@@ -69,12 +69,12 @@ is ($tix4->Count, 2);
# There's no way to differentiate "one requestor name that matches foo and bar"
# and "two requestors, one matching foo and one matching bar"
-# my $tix5 = RT::Tickets->new($RT::SystemUser);
+# my $tix5 = RT::Tickets->new(RT->SystemUser);
# $tix5->FromSQL('Requestor.Name LIKE "TestOne" AND Requestor.Name LIKE "TestTwo"');
#
# is ($tix5->Count, 1);
#
-# my $tix6 = RT::Tickets->new($RT::SystemUser);
+# my $tix6 = RT::Tickets->new(RT->SystemUser);
# $tix6->FromSQL('Requestor.EmailAddress LIKE "rqtest1" AND Requestor.EmailAddress LIKE "rqtest2"');
#
# is ($tix6->Count, 1);
@@ -85,7 +85,7 @@ is ($tix4->Count, 2);
{
-my $t1 = RT::Ticket->new($RT::SystemUser);
+my $t1 = RT::Ticket->new(RT->SystemUser);
$t1->Create(Queue => 'general', Subject => "LimitWatchers test", Requestors => \['requestor1@example.com']);
@@ -94,11 +94,10 @@ $t1->Create(Queue => 'general', Subject => "LimitWatchers test", Requestors => \
{
# We assume that we've got some tickets hanging around from before.
-ok( my $unlimittickets = RT::Tickets->new( $RT::SystemUser ) );
+ok( my $unlimittickets = RT::Tickets->new( RT->SystemUser ) );
ok( $unlimittickets->UnLimit );
ok( $unlimittickets->Count > 0, "UnLimited tickets object should return tickets" );
}
-1;
diff --git a/rt/t/api/tickets_overlay_sql.t b/rt/t/api/tickets_overlay_sql.t
index 5bc614077..9f91111df 100644
--- a/rt/t/api/tickets_overlay_sql.t
+++ b/rt/t/api/tickets_overlay_sql.t
@@ -1,13 +1,9 @@
-
-use RT;
-use RT::Test tests => 19;
-
-{
-
-use RT::Tickets;
use strict;
+use warnings;
+use RT::Test tests => 20, config => 'Set( %FullTextSearch, Enable => 1 );';
+use Test::Warn;
-my $tix = RT::Tickets->new($RT::SystemUser);
+my $tix = RT::Tickets->new(RT->SystemUser);
{
my $query = "Status = 'open'";
my ($status, $msg) = $tix->FromSQL($query);
@@ -18,7 +14,7 @@ my $tix = RT::Tickets->new($RT::SystemUser);
my (@created,%created);
my $string = 'subject/content SQL test';
{
- my $t = RT::Ticket->new($RT::SystemUser);
+ my $t = RT::Ticket->new(RT->SystemUser);
ok( $t->Create(Queue => 'General', Subject => $string), "Ticket Created");
$created{ $t->Id }++; push @created, $t->Id;
}
@@ -30,7 +26,7 @@ my $string = 'subject/content SQL test';
Data => [ $string ],
);
- my $t = RT::Ticket->new($RT::SystemUser);
+ my $t = RT::Ticket->new(RT->SystemUser);
ok( $t->Create( Queue => 'General',
Requestor => 'jesse@example.com',
Subject => 'another ticket',
@@ -74,7 +70,7 @@ diag "Make sure we don't barf on invalid input for IS / IS NOT";
unlike $tix->BuildSelectQuery, qr/foobar/, "didn't find foobar in the select";
like $tix->BuildSelectQuery, qr/Subject IS NULL/, "found right clause";
- my ($status, $msg) = $tix->FromSQL("Subject IS NOT 'foobar'");
+ ($status, $msg) = $tix->FromSQL("Subject IS NOT 'foobar'");
ok ($status, "valid query") or diag("error: $msg");
is $tix->Count, 2, "found two tickets";
unlike $tix->BuildSelectQuery, qr/foobar/, "didn't find foobar in the select";
@@ -82,15 +78,16 @@ diag "Make sure we don't barf on invalid input for IS / IS NOT";
}
{
- my ($status, $msg) = $tix->FromSQL("Requestor.Signature LIKE 'foo'");
- ok (!$status, "invalid query - Signature not valid") or diag("error: $msg");
+ my ($status, $msg);
- my ($status, $msg) = $tix->FromSQL("Requestor.EmailAddress LIKE 'jesse'");
+ warning_like {
+ ($status, $msg) = $tix->FromSQL("Requestor.Signature LIKE 'foo'");
+ } qr/Invalid watcher subfield: 'Signature'/;
+ ok(!$status, "invalid query - Signature not valid") or diag("error: $msg");
+
+ ($status, $msg) = $tix->FromSQL("Requestor.EmailAddress LIKE 'jesse'");
ok ($status, "valid query") or diag("error: $msg");
is $tix->Count, 1, "found one ticket";
like $tix->First->Subject, qr/another ticket/, "found the right ticket";
}
-}
-
-1;
diff --git a/rt/t/api/txn_content.t b/rt/t/api/txn_content.t
index 0f5d78ca9..392b6a73b 100644
--- a/rt/t/api/txn_content.t
+++ b/rt/t/api/txn_content.t
@@ -3,7 +3,7 @@ use strict;
use RT::Test tests => 3;
use MIME::Entity;
-my $ticket = RT::Ticket->new($RT::SystemUser);
+my $ticket = RT::Ticket->new(RT->SystemUser);
my $mime = MIME::Entity->build(
From => 'test@example.com',
Type => 'text/html',
diff --git a/rt/t/api/uri-fsck_com_rt.t b/rt/t/api/uri-fsck_com_rt.t
index d62e58022..18bee7db2 100644
--- a/rt/t/api/uri-fsck_com_rt.t
+++ b/rt/t/api/uri-fsck_com_rt.t
@@ -4,9 +4,9 @@ use RT;
use RT::Test tests => 8;
use_ok("RT::URI::fsck_com_rt");
-my $uri = RT::URI::fsck_com_rt->new($RT::SystemUser);
+my $uri = RT::URI::fsck_com_rt->new(RT->SystemUser);
-my $t1 = RT::Ticket->new($RT::SystemUser);
+my $t1 = RT::Ticket->new(RT->SystemUser);
my ($id,$trans,$msg) =$t1->Create (Queue => 'general', Subject => 'Requestor test one', );
ok ($id, $msg);
@@ -20,9 +20,8 @@ ok ($uri->isa('RT::Base'), "It's an RT::Base");
is ($uri->LocalURIPrefix , 'fsck.com-rt://'.RT->Config->Get('Organization'));
-my $ticket = RT::Ticket->new($RT::SystemUser);
+my $ticket = RT::Ticket->new(RT->SystemUser);
$ticket->Load(1);
$uri = RT::URI::fsck_com_rt->new($ticket->CurrentUser);
is($uri->LocalURIPrefix. "/ticket/1" , $uri->URIForObject($ticket));
-1;
diff --git a/rt/t/api/uri-t.t b/rt/t/api/uri-t.t
index 4695629bb..61b3e1761 100644
--- a/rt/t/api/uri-t.t
+++ b/rt/t/api/uri-t.t
@@ -3,12 +3,12 @@ use warnings;
use RT;
use RT::Test tests => 6;
-my $t1 = RT::Ticket->new($RT::SystemUser);
+my $t1 = RT::Ticket->new(RT->SystemUser);
my ($id,$trans,$msg) =$t1->Create (Queue => 'general', Subject => 'Requestor test one', );
ok ($id, $msg);
use_ok("RT::URI::t");
-my $uri = RT::URI::t->new($RT::SystemUser);
+my $uri = RT::URI::t->new(RT->SystemUser);
ok(ref($uri), "URI object exists");
my $uristr = "t:1";
@@ -18,4 +18,3 @@ is($uri->Object->Id, 1, "Object loaded has correct ID");
is($uri->URI, 'fsck.com-rt://'.RT->Config->Get('Organization').'/ticket/1',
"URI object has correct URI string");
-1;
diff --git a/rt/t/api/user.t b/rt/t/api/user.t
index 25cf74773..e6b891f73 100644
--- a/rt/t/api/user.t
+++ b/rt/t/api/user.t
@@ -2,7 +2,7 @@
use strict;
use warnings;
use RT;
-use RT::Test tests => 108;
+use RT::Test tests => 111;
{
@@ -16,38 +16,38 @@ ok(require RT::User);
# Make sure we can create a user
-my $u1 = RT::User->new($RT::SystemUser);
+my $u1 = RT::User->new(RT->SystemUser);
is(ref($u1), 'RT::User');
my ($id, $msg) = $u1->Create(Name => 'CreateTest1'.$$, EmailAddress => $$.'create-test-1@example.com');
ok ($id, "Creating user CreateTest1 - " . $msg );
# Make sure we can't create a second user with the same name
-my $u2 = RT::User->new($RT::SystemUser);
+my $u2 = RT::User->new(RT->SystemUser);
($id, $msg) = $u2->Create(Name => 'CreateTest1'.$$, EmailAddress => $$.'create-test-2@example.com');
ok (!$id, $msg);
# Make sure we can't create a second user with the same EmailAddress address
-my $u3 = RT::User->new($RT::SystemUser);
+my $u3 = RT::User->new(RT->SystemUser);
($id, $msg) = $u3->Create(Name => 'CreateTest2'.$$, EmailAddress => $$.'create-test-1@example.com');
ok (!$id, $msg);
# Make sure we can create a user with no EmailAddress address
-my $u4 = RT::User->new($RT::SystemUser);
+my $u4 = RT::User->new(RT->SystemUser);
($id, $msg) = $u4->Create(Name => 'CreateTest3'.$$);
ok ($id, $msg);
# make sure we can create a second user with no EmailAddress address
-my $u5 = RT::User->new($RT::SystemUser);
+my $u5 = RT::User->new(RT->SystemUser);
($id, $msg) = $u5->Create(Name => 'CreateTest4'.$$);
ok ($id, $msg);
# make sure we can create a user with a blank EmailAddress address
-my $u6 = RT::User->new($RT::SystemUser);
+my $u6 = RT::User->new(RT->SystemUser);
($id, $msg) = $u6->Create(Name => 'CreateTest6'.$$, EmailAddress => '');
ok ($id, $msg);
# make sure we can create a second user with a blankEmailAddress address
-my $u7 = RT::User->new($RT::SystemUser);
+my $u7 = RT::User->new(RT->SystemUser);
($id, $msg) = $u7->Create(Name => 'CreateTest7'.$$, EmailAddress => '');
ok ($id, $msg);
@@ -59,19 +59,27 @@ ok ($id, $msg);
ok ($id, $msg);
is_empty ($u7->EmailAddress);
+# back to something, so we can set undef next successfully
+($id,$msg) = $u7->SetEmailAddress('foo@bar'.$$);
+ok ($id, $msg);
+
+($id,$msg) = $u7->SetEmailAddress(undef);
+ok ($id, $msg);
+is_empty ($u7->EmailAddress);
+
RT->Config->Set('ValidateUserEmailAddresses' => 1);
# Make sur we can't create a user with multiple email adresses separated by comma
-my $u8 = RT::User->new($RT::SystemUser);
+my $u8 = RT::User->new(RT->SystemUser);
($id, $msg) = $u8->Create(Name => 'CreateTest8'.$$, EmailAddress => $$.'create-test-81@example.com, '.$$.'create-test-82@example.com');
ok (!$id, $msg);
# Make sur we can't create a user with multiple email adresses separated by space
-my $u9 = RT::User->new($RT::SystemUser);
+my $u9 = RT::User->new(RT->SystemUser);
($id, $msg) = $u9->Create(Name => 'CreateTest9'.$$, EmailAddress => $$.'create-test-91@example.com '.$$.'create-test-92@example.com');
ok (!$id, $msg);
# Make sur we can't create a user with invalid email address
-my $u10 = RT::User->new($RT::SystemUser);
+my $u10 = RT::User->new(RT->SystemUser);
($id, $msg) = $u10->Create(Name => 'CreateTest10'.$$, EmailAddress => $$.'create-test10}@[.com');
ok (!$id, $msg);
RT->Config->Set('ValidateUserEmailAddresses' => undef);
@@ -81,7 +89,7 @@ RT->Config->Set('ValidateUserEmailAddresses' => undef);
{
-ok(my $user = RT::User->new($RT::SystemUser));
+ok(my $user = RT::User->new(RT->SystemUser));
ok($user->Load('root'), "Loaded user 'root'");
ok($user->Privileged, "User 'root' is privileged");
ok(my ($v,$m) = $user->SetPrivileged(0));
@@ -96,7 +104,7 @@ ok($user->Privileged, "User 'root' is privileged again");
{
-ok(my $u = RT::User->new($RT::SystemUser));
+ok(my $u = RT::User->new(RT->SystemUser));
ok($u->Load(1), "Loaded the first user");
is($u->PrincipalObj->ObjectId , 1, "user 1 is the first principal");
is($u->PrincipalObj->PrincipalType, 'User' , "Principal 1 is a user, not a group");
@@ -106,7 +114,7 @@ is($u->PrincipalObj->PrincipalType, 'User' , "Principal 1 is a user, not a group
{
-my $root = RT::User->new($RT::SystemUser);
+my $root = RT::User->new(RT->SystemUser);
$root->Load('root');
ok($root->Id, "Found the root user");
my $rootq = RT::Queue->new($root);
@@ -115,7 +123,7 @@ ok($rootq->Id, "Loaded the first queue");
ok ($rootq->CurrentUser->HasRight(Right=> 'CreateTicket', Object => $rootq), "Root can create tickets");
-my $new_user = RT::User->new($RT::SystemUser);
+my $new_user = RT::User->new(RT->SystemUser);
my ($id, $msg) = $new_user->Create(Name => 'ACLTest'.$$);
ok ($id, "Created a new user for acl test $msg");
@@ -140,13 +148,13 @@ ok (!$q->CurrentUser->HasRight(Right => 'CreateTicket', Object => $q), "The user
# Create a ticket in the queue
-my $new_tick = RT::Ticket->new($RT::SystemUser);
+my $new_tick = RT::Ticket->new(RT->SystemUser);
my ($tickid, $tickmsg) = $new_tick->Create(Subject=> 'ACL Test', Queue => 'General');
ok($tickid, "Created ticket: $tickid");
# Make sure the user doesn't have the right to modify tickets in the queue
ok (!$new_user->HasRight( Object => $new_tick, Right => 'ModifyTicket'), "User can't modify the ticket without group membership");
# Create a new group
-my $group = RT::Group->new($RT::SystemUser);
+my $group = RT::Group->new(RT->SystemUser);
$group->CreateUserDefinedGroup(Name => 'ACLTest'.$$);
ok($group->Id, "Created a new group Ok");
# Grant a group the right to modify tickets in a queue
@@ -166,12 +174,12 @@ ok ($did,"Deleted the group member: $dmsg");
ok (!$new_user->HasRight( Object => $new_tick, Right => 'ModifyTicket'), "User can't modify the ticket without group membership");
-my $q_as_system = RT::Queue->new($RT::SystemUser);
+my $q_as_system = RT::Queue->new(RT->SystemUser);
$q_as_system->Load(1);
ok($q_as_system->Id, "Loaded the first queue");
# Create a ticket in the queue
-my $new_tick2 = RT::Ticket->new($RT::SystemUser);
+my $new_tick2 = RT::Ticket->new(RT->SystemUser);
(my $tick2id, $tickmsg) = $new_tick2->Create(Subject=> 'ACL Test 2', Queue =>$q_as_system->Id);
ok($tick2id, "Created ticket: $tick2id");
is($new_tick2->QueueObj->id, $q_as_system->Id, "Created a new ticket in queue 1");
@@ -181,7 +189,7 @@ is($new_tick2->QueueObj->id, $q_as_system->Id, "Created a new ticket in queue 1"
ok (!$new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can't modify the ticket without group membership");
# Create a subgroup
-my $subgroup = RT::Group->new($RT::SystemUser);
+my $subgroup = RT::Group->new(RT->SystemUser);
$subgroup->CreateUserDefinedGroup(Name => 'Subgrouptest'.$$);
ok($subgroup->Id, "Created a new group ".$subgroup->Id."Ok");
#Add the subgroup as a subgroup of the group
@@ -210,7 +218,6 @@ ok (!$new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User
ok ($id,$msg);
ok ($new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can modify the ticket without group membership");
-# }}}
my ($usrid, $usrmsg) = $subgroup->DeleteMember($new_user->PrincipalId);
@@ -222,7 +229,6 @@ ok (!$new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User
ok(($gv,$gm) = $group->PrincipalObj->RevokeRight( Object => $q, Right => 'ModifyTicket'),"Granted the group the right to modify tickets");
ok($gv,"revoke succeeed - $gm");
-# {{{ Test the user's right to modify a ticket as a _queue_ admincc for a right granted at the _queue_ level
# Grant queue admin cc the right to modify ticket in the queue
ok(my ($qv,$qm) = $q_as_system->AdminCc->PrincipalObj->GrantRight( Object => $q_as_system, Right => 'ModifyTicket'),"Granted the queue adminccs the right to modify tickets");
@@ -240,9 +246,7 @@ ok (my ($del_id, $del_msg) = $q_as_system->DeleteWatcher(Type => 'AdminCc', Prin
# Make sure the user doesn't have the right to modify tickets in the queue
ok (!$new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can't modify the ticket without group membership");
-# }}}
-# {{{ Test the user's right to modify a ticket as a _ticket_ admincc with the right granted at the _queue_ level
# Add the user as a ticket admincc
ok (my( $uadd_id, $uadd_msg) = $new_tick2->AddWatcher(Type => 'AdminCc', PrincipalId => $new_user->PrincipalId) , "Added the new user as a queue admincc");
@@ -262,11 +266,9 @@ ok (!$new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User
ok(my ($rqv,$rqm) = $q_as_system->AdminCc->PrincipalObj->RevokeRight( Object => $q_as_system, Right => 'ModifyTicket'),"Revokeed the queue adminccs the right to modify tickets");
ok($rqv, "Revoked the right successfully - $rqm");
-# }}}
-# {{{ Test the user's right to modify a ticket as a _queue_ admincc for a right granted at the _system_ level
# Before we start Make sure the user does not have the right to modify tickets in the queue
ok (!$new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can not modify the ticket without it being granted");
@@ -294,9 +296,7 @@ ok (($del_id, $del_msg) = $q_as_system->DeleteWatcher(Type => 'AdminCc', Princip
ok (!$new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can't modify the ticket without group membership");
ok (!$new_user->HasRight( Object => $new_tick2->QueueObj, Right => 'ModifyTicket'), "User can't modify tickets in the queue without group membership");
-# }}}
-# {{{ Test the user's right to modify a ticket as a _ticket_ admincc with the right granted at the _queue_ level
ok (!$new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can not modify the ticket without being an admincc");
ok (!$new_user->HasRight( Object => $new_tick2->QueueObj, Right => 'ModifyTicket'), "User can not modify tickets in the queue obj without being an admincc");
@@ -322,7 +322,6 @@ ok (!$new_user->HasRight( Object => $new_tick2->QueueObj, Right => 'ModifyTicket
ok(($rqv,$rqm) = $q_as_system->AdminCc->PrincipalObj->RevokeRight( Object => $RT::System, Right => 'ModifyTicket'),"Revokeed the queue adminccs the right to modify tickets");
ok($rqv, "Revoked the right successfully - $rqm");
-# }}}
@@ -336,4 +335,3 @@ ok($rqv, "Revoked the right successfully - $rqm");
}
-1;
diff --git a/rt/t/api/users.t b/rt/t/api/users.t
index d1ff174e1..1f3a48770 100644
--- a/rt/t/api/users.t
+++ b/rt/t/api/users.t
@@ -1,37 +1,31 @@
-
use strict;
use warnings;
-use RT;
-use RT::Test tests => 11;
-
-
-{
+use RT::Test tests => 10;
-ok(require RT::Users);
-
-
-}
+RT::System->AddRights(
+ 'RTxUserRight' => 'Just a right for testing rights',
+);
{
no warnings qw(redefine once);
-ok(my $users = RT::Users->new($RT::SystemUser));
-$users->WhoHaveRight(Object =>$RT::System, Right =>'SuperUser');
+ok(my $users = RT::Users->new(RT->SystemUser));
+$users->WhoHaveRight(Object => RT->System, Right =>'SuperUser');
is($users->Count , 1, "There is one privileged superuser - Found ". $users->Count );
# TODO: this wants more testing
-my $RTxUser = RT::User->new($RT::SystemUser);
+my $RTxUser = RT::User->new(RT->SystemUser);
my ($id, $msg) = $RTxUser->Create( Name => 'RTxUser', Comments => "RTx extension user", Privileged => 1);
ok ($id,$msg);
-my $group = RT::Group->new($RT::SystemUser);
+my $group = RT::Group->new(RT->SystemUser);
$group->LoadACLEquivalenceGroup($RTxUser->PrincipalObj);
my $RTxSysObj = {};
bless $RTxSysObj, 'RTx::System';
*RTx::System::Id = sub { 1; };
*RTx::System::id = *RTx::System::Id;
-my $ace = RT::Record->new($RT::SystemUser);
+my $ace = RT::Record->new(RT->SystemUser);
$ace->Table('ACL');
$ace->_BuildTableAttributes unless ($RT::Record::_TABLE_ATTR->{ref($ace)});
($id, $msg) = $ace->Create( PrincipalId => $group->id, PrincipalType => 'Group', RightName => 'RTxUserRight', ObjectType => 'RTx::System', ObjectId => 1 );
@@ -42,19 +36,19 @@ bless $RTxObj, 'RTx::System::Record';
*RTx::System::Record::Id = sub { 4; };
*RTx::System::Record::id = *RTx::System::Record::Id;
-$users = RT::Users->new($RT::SystemUser);
+$users = RT::Users->new(RT->SystemUser);
$users->WhoHaveRight(Right => 'RTxUserRight', Object => $RTxSysObj);
is($users->Count, 1, "RTxUserRight found for RTxSysObj");
-$users = RT::Users->new($RT::SystemUser);
+$users = RT::Users->new(RT->SystemUser);
$users->WhoHaveRight(Right => 'RTxUserRight', Object => $RTxObj);
is($users->Count, 0, "RTxUserRight not found for RTxObj");
-$users = RT::Users->new($RT::SystemUser);
+$users = RT::Users->new(RT->SystemUser);
$users->WhoHaveRight(Right => 'RTxUserRight', Object => $RTxObj, EquivObjects => [ $RTxSysObj ]);
is($users->Count, 1, "RTxUserRight found for RTxObj using EquivObjects");
-$ace = RT::Record->new($RT::SystemUser);
+$ace = RT::Record->new(RT->SystemUser);
$ace->Table('ACL');
$ace->_BuildTableAttributes unless ($RT::Record::_TABLE_ATTR->{ref($ace)});
($id, $msg) = $ace->Create( PrincipalId => $group->id, PrincipalType => 'Group', RightName => 'RTxUserRight', ObjectType => 'RTx::System::Record', ObjectId => 5 );
@@ -65,11 +59,11 @@ bless $RTxObj2, 'RTx::System::Record';
*RTx::System::Record::Id = sub { 5; };
*RTx::System::Record::id = sub { 5; };
-$users = RT::Users->new($RT::SystemUser);
+$users = RT::Users->new(RT->SystemUser);
$users->WhoHaveRight(Right => 'RTxUserRight', Object => $RTxObj2);
is($users->Count, 1, "RTxUserRight found for RTxObj2");
-$users = RT::Users->new($RT::SystemUser);
+$users = RT::Users->new(RT->SystemUser);
$users->WhoHaveRight(Right => 'RTxUserRight', Object => $RTxObj2, EquivObjects => [ $RTxSysObj ]);
is($users->Count, 1, "RTxUserRight found for RTxObj2");
@@ -77,4 +71,3 @@ is($users->Count, 1, "RTxUserRight found for RTxObj2");
}
-1;
diff --git a/rt/t/api/versions_sorter.t b/rt/t/api/versions_sorter.t
new file mode 100644
index 000000000..b2ec547a0
--- /dev/null
+++ b/rt/t/api/versions_sorter.t
@@ -0,0 +1,22 @@
+#!/usr/bin/perl -w
+
+use RT::Test nodata => 1, tests => 3;
+
+use strict;
+use warnings;
+
+sub is_right_sorting {
+ my @order = @_;
+ my @tmp = sort { int(rand(3)) - 1 } @order;
+
+ is_deeply(
+ [ sort RT::Handle::cmp_version @tmp ],
+ \@order,
+ 'test sorting of ('. join(' ', @tmp) .')'
+ );
+}
+
+is_right_sorting(qw(1 2 3));
+is_right_sorting(qw(1.1 1.2 1.3 2.0 2.1));
+is_right_sorting(qw(4.0.0a1 4.0.0alpha2 4.0.0b1 4.0.0beta2 4.0.0pre1 4.0.0pre2 4.0.0rc1 4.0.0rc2 4.0.0));
+
diff --git a/rt/t/api/web-config.t b/rt/t/api/web-config.t
new file mode 100644
index 000000000..fb2b36242
--- /dev/null
+++ b/rt/t/api/web-config.t
@@ -0,0 +1,163 @@
+use strict;
+use warnings;
+use RT;
+use RT::Test nodb => 1, tests => 89;
+
+sub no_warnings_ok {
+ local $Test::Builder::Level = $Test::Builder::Level + 1;
+
+ my $option = shift;
+ my $value = shift;
+ my $name = shift;
+
+ is(warnings_from($option => $value), 0, $name);
+}
+
+sub one_warning_like {
+ local $Test::Builder::Level = $Test::Builder::Level + 1;
+
+ my $option = shift;
+ my $value = shift;
+ my $regex = shift;
+ my $name = shift;
+
+ my @w = warnings_from($option => $value);
+ is(@w, 1);
+ like($w[0], $regex, $name);
+}
+
+
+sub warnings_from {
+ my $option = shift;
+ my $value = shift;
+
+ my @warnings;
+ local $SIG{__WARN__} = sub {
+ push @warnings, $_[0];
+ };
+
+ RT->Config->Set($option => $value);
+ RT->Config->PostLoadCheck;
+
+ return @warnings;
+}
+
+# WebPath
+no_warnings_ok(WebPath => '');
+no_warnings_ok(WebPath => '/foo');
+no_warnings_ok(WebPath => '/foo/bar');
+
+one_warning_like(WebPath => '/foo/', qr/The WebPath config option requires no trailing slash/);
+
+one_warning_like(WebPath => 'foo', qr/The WebPath config option requires a leading slash/);
+
+my @w = warnings_from(WebPath => 'foo/');
+is(@w, 2);
+like($w[0], qr/The WebPath config option requires no trailing slash/);
+like($w[1], qr/The WebPath config option requires a leading slash/);
+
+one_warning_like(WebPath => '/foo/bar/', qr/The WebPath config option requires no trailing slash/);
+
+one_warning_like(WebPath => 'foo/bar', qr/The WebPath config option requires a leading slash/);
+
+@w = warnings_from(WebPath => 'foo/bar/');
+is(@w, 2);
+like($w[0], qr/The WebPath config option requires no trailing slash/);
+like($w[1], qr/The WebPath config option requires a leading slash/);
+
+one_warning_like(WebPath => '/', qr{For the WebPath config option, use the empty string instead of /});
+
+# reinstate a valid WebPath for other tests
+no_warnings_ok(WebPath => '/rt');
+
+# WebDomain
+no_warnings_ok(WebDomain => 'example.com');
+no_warnings_ok(WebDomain => 'rt.example.com');
+no_warnings_ok(WebDomain => 'localhost');
+
+one_warning_like(WebDomain => '', qr{You must set the WebDomain config option});
+
+one_warning_like(WebDomain => 'http://rt.example.com', qr{The WebDomain config option must not contain a scheme \(http://\)});
+
+one_warning_like(WebDomain => 'https://rt.example.com', qr{The WebDomain config option must not contain a scheme \(https://\)});
+
+one_warning_like(WebDomain => 'rt.example.com/path', qr{The WebDomain config option must not contain a path \(/path\)});
+
+one_warning_like(WebDomain => 'rt.example.com/path/more', qr{The WebDomain config option must not contain a path \(/path/more\)});
+
+one_warning_like(WebDomain => 'rt.example.com:80', qr{The WebDomain config option must not contain a port \(80\)});
+
+# reinstate a valid WebDomain for other tests
+no_warnings_ok(WebDomain => 'rt.example.com');
+
+# WebPort
+no_warnings_ok(WebDomain => 80);
+no_warnings_ok(WebDomain => 443);
+no_warnings_ok(WebDomain => 8888);
+
+one_warning_like(WebPort => '', qr{You must set the WebPort config option});
+
+one_warning_like(WebPort => 3.14, qr{The WebPort config option must be an integer});
+
+one_warning_like(WebPort => 'wha?', qr{The WebPort config option must be an integer});
+
+# reinstate a valid WebDomain for other tests
+no_warnings_ok(WebPort => 443);
+
+# WebBaseURL
+no_warnings_ok(WebBaseURL => 'http://rt.example.com');
+no_warnings_ok(WebBaseURL => 'HTTP://rt.example.com', 'uppercase scheme is okay');
+no_warnings_ok(WebBaseURL => 'http://rt.example.com:8888', 'nonstandard port is okay');
+no_warnings_ok(WebBaseURL => 'https://rt.example.com:8888', 'nonstandard port with https is okay');
+
+one_warning_like(WebBaseURL => '', qr{You must set the WebBaseURL config option});
+
+one_warning_like(WebBaseURL => 'rt.example.com', qr{The WebBaseURL config option must contain a scheme});
+
+one_warning_like(WebBaseURL => 'xtp://rt.example.com', qr{The WebBaseURL config option must contain a scheme \(http or https\)});
+
+one_warning_like(WebBaseURL => 'http://rt.example.com/', qr{The WebBaseURL config option requires no trailing slash});
+
+one_warning_like(WebBaseURL => 'http://rt.example.com/rt', qr{The WebBaseURL config option must not contain a path \(/rt\)});
+
+@w = warnings_from(WebBaseURL => 'http://rt.example.com/rt/');
+is(@w, 2);
+like($w[0], qr{The WebBaseURL config option requires no trailing slash});
+like($w[1], qr{The WebBaseURL config option must not contain a path \(/rt/\)});
+
+one_warning_like(WebBaseURL => 'http://rt.example.com/rt/ir', qr{The WebBaseURL config option must not contain a path \(/rt/ir\)});
+
+@w = warnings_from(WebBaseURL => 'http://rt.example.com/rt/ir/');
+is(@w, 2);
+like($w[0], qr{The WebBaseURL config option requires no trailing slash});
+like($w[1], qr{The WebBaseURL config option must not contain a path \(/rt/ir/\)});
+
+# reinstate a valid WebBaseURL for other tests
+no_warnings_ok(WebBaseURL => 'http://rt.example.com');
+
+# WebURL
+no_warnings_ok(WebURL => 'http://rt.example.com/');
+no_warnings_ok(WebURL => 'HTTP://rt.example.com/', 'uppercase scheme is okay');
+no_warnings_ok(WebURL => 'http://example.com/rt/');
+no_warnings_ok(WebURL => 'http://example.com/rt/ir/');
+no_warnings_ok(WebURL => 'http://rt.example.com:8888/', 'nonstandard port is okay');
+no_warnings_ok(WebURL => 'https://rt.example.com:8888/', 'nonstandard port with https is okay');
+
+one_warning_like(WebURL => '', qr{You must set the WebURL config option});
+
+@w = warnings_from(WebURL => 'rt.example.com');
+is(@w, 2);
+like($w[0], qr{The WebURL config option must contain a scheme});
+like($w[1], qr{The WebURL config option requires a trailing slash});
+
+one_warning_like(WebURL => 'http://rt.example.com', qr{The WebURL config option requires a trailing slash});
+
+one_warning_like(WebURL => 'xtp://example.com/rt/', qr{The WebURL config option must contain a scheme \(http or https\)});
+
+one_warning_like(WebURL => 'http://rt.example.com/rt', qr{The WebURL config option requires a trailing slash});
+
+one_warning_like(WebURL => 'http://rt.example.com/rt/ir', qr{The WebURL config option requires a trailing slash});
+
+# reinstate a valid WebURL for other tests
+no_warnings_ok(WebURL => 'http://rt.example.com/rt/');
+