diff options
Diffstat (limited to 'rt/t/api')
39 files changed, 3760 insertions, 0 deletions
diff --git a/rt/t/api/ace.t b/rt/t/api/ace.t new file mode 100644 index 000000000..4031046d9 --- /dev/null +++ b/rt/t/api/ace.t @@ -0,0 +1,238 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 76; + + +{ + +ok(require RT::ACE); + + +} + +{ + +my $Queue = RT::Queue->new($RT::SystemUser); + +is ($Queue->AvailableRights->{'DeleteTicket'} , 'Delete tickets', "Found the delete ticket right"); +is ($RT::System->AvailableRights->{'SuperUser'}, 'Do anything and everything', "Found the superuser right"); + + + +} + +{ + +use_ok('RT::User'); +my $user_a = RT::User->new($RT::SystemUser); +$user_a->Create( Name => 'DelegationA', Privileged => 1); +ok ($user_a->Id, "Created delegation user a"); + +my $user_b = RT::User->new($RT::SystemUser); +$user_b->Create( Name => 'DelegationB', Privileged => 1); +ok ($user_b->Id, "Created delegation user b"); + + +use_ok('RT::Queue'); +my $q = RT::Queue->new($RT::SystemUser); +$q->Create(Name =>'DelegationTest'); +ok ($q->Id, "Created a delegation test queue"); + + +#------ First, we test whether a user can delegate a right that's been granted to him personally +my ($val, $msg) = $user_a->PrincipalObj->GrantRight(Object => $RT::System, Right => 'AdminOwnPersonalGroups'); +ok($val, $msg); + +($val, $msg) = $user_a->PrincipalObj->GrantRight(Object =>$q, Right => 'OwnTicket'); +ok($val, $msg); + +ok($user_a->HasRight( Object => $RT::System, Right => 'AdminOwnPersonalGroups') ,"user a has the right 'AdminOwnPersonalGroups' directly"); + +my $a_delegates = RT::Group->new($user_a); +$a_delegates->CreatePersonalGroup(Name => 'Delegates'); +ok( $a_delegates->Id ,"user a creates a personal group 'Delegates'"); +ok( $a_delegates->AddMember($user_b->PrincipalId) ,"user a adds user b to personal group 'delegates'"); + +ok( !$user_b->HasRight(Right => 'OwnTicket', Object => $q) ,"user b does not have the right to OwnTicket' in queue 'DelegationTest'"); +ok( $user_a->HasRight(Right => 'OwnTicket', Object => $q) ,"user a has the right to 'OwnTicket' in queue 'DelegationTest'"); +ok(!$user_a->HasRight( Object => $RT::System, Right => 'DelegateRights') ,"user a does not have the right 'delegate rights'"); + + +my $own_ticket_ace = RT::ACE->new($user_a); +my $user_a_equiv_group = RT::Group->new($user_a); +$user_a_equiv_group->LoadACLEquivalenceGroup($user_a->PrincipalObj); +ok ($user_a_equiv_group->Id, "Loaded the user A acl equivalence group"); +my $user_b_equiv_group = RT::Group->new($user_b); +$user_b_equiv_group->LoadACLEquivalenceGroup($user_b->PrincipalObj); +ok ($user_b_equiv_group->Id, "Loaded the user B acl equivalence group"); +$own_ticket_ace->LoadByValues( PrincipalType => 'Group', PrincipalId => $user_a_equiv_group->PrincipalId, Object=>$q, RightName => 'OwnTicket'); + +ok ($own_ticket_ace->Id, "Found the ACE we want to test with for now"); + + +($val, $msg) = $own_ticket_ace->Delegate(PrincipalId => $a_delegates->PrincipalId) ; +ok( !$val ,"user a tries and fails to delegate the right 'ownticket' in queue 'DelegationTest' to personal group 'delegates' - $msg"); + + +($val, $msg) = $user_a->PrincipalObj->GrantRight( Right => 'DelegateRights'); +ok($val, "user a is granted the right to 'delegate rights' - $msg"); + +ok($user_a->HasRight( Object => $RT::System, Right => 'DelegateRights') ,"user a has the right 'DeletgateRights'"); + +($val, $msg) = $own_ticket_ace->Delegate(PrincipalId => $a_delegates->PrincipalId) ; + +ok( $val ,"user a tries and succeeds to delegate the right 'ownticket' in queue 'DelegationTest' to personal group 'delegates' - $msg"); +ok( $user_b->HasRight(Right => 'OwnTicket', Object => $q) ,"user b has the right to own tickets in queue 'DelegationTest'"); +my $delegated_ace = RT::ACE->new($user_a); +$delegated_ace->LoadByValues ( Object => $q, RightName => 'OwnTicket', PrincipalType => 'Group', +PrincipalId => $a_delegates->PrincipalId, DelegatedBy => $user_a->PrincipalId, DelegatedFrom => $own_ticket_ace->Id); +ok ($delegated_ace->Id, "Found the delegated ACE"); + +ok( $a_delegates->DeleteMember($user_b->PrincipalId) ,"user a removes b from pg 'delegates'"); +ok( !$user_b->HasRight(Right => 'OwnTicket', Object => $q) ,"user b does not have the right to own tickets in queue 'DelegationTest'"); +ok( $a_delegates->AddMember($user_b->PrincipalId) ,"user a adds user b to personal group 'delegates'"); +ok( $user_b->HasRight(Right => 'OwnTicket', Object=> $q) ,"user b has the right to own tickets in queue 'DelegationTest'"); +ok( $delegated_ace->Delete ,"user a revokes pg 'delegates' right to 'OwnTickets' in queue 'DelegationTest'"); +ok( ! $user_b->HasRight(Right => 'OwnTicket', Object => $q) ,"user b does not have the right to own tickets in queue 'DelegationTest'"); + +($val, $msg) = $own_ticket_ace->Delegate(PrincipalId => $a_delegates->PrincipalId) ; +ok( $val ,"user a delegates pg 'delegates' right to 'OwnTickets' in queue 'DelegationTest' - $msg"); + +ok( $user_b->HasRight(Right => 'OwnTicket', Object => $q) ,"user b has the right to own tickets in queue 'DelegationTest'"); + +($val, $msg) = $user_a->PrincipalObj->RevokeRight(Object=>$q, Right => 'OwnTicket'); +ok($val, "Revoked user a's right to own tickets in queue 'DelegationTest". $msg); + +ok( !$user_a->HasRight(Right => 'OwnTicket', Object => $q) ,"user a does not have the right to own tickets in queue 'DelegationTest'"); + + ok( !$user_b->HasRight(Right => 'OwnTicket', Object => $q) ,"user b does not have the right to own tickets in queue 'DelegationTest'"); + +($val, $msg) = $user_a->PrincipalObj->GrantRight(Object=>$q, Right => 'OwnTicket'); +ok($val, $msg); + + ok( $user_a->HasRight(Right => 'OwnTicket', Object => $q) ,"user a has the right to own tickets in queue 'DelegationTest'"); + + ok( !$user_b->HasRight(Right => 'OwnTicket', Object => $q) ,"user b does not have the right to own tickets in queue 'DelegationTest'"); + +# {{{ get back to a known clean state +($val, $msg) = $user_a->PrincipalObj->RevokeRight( Object => $q, Right => 'OwnTicket'); +ok($val, "Revoked user a's right to own tickets in queue 'DelegationTest -". $msg); +ok( !$user_a->HasRight(Right => 'OwnTicket', Object => $q) ,"make sure that user a can't own tickets in queue 'DelegationTest'"); +# }}} + + +# {{{ Set up some groups and membership +my $del1 = RT::Group->new($RT::SystemUser); +($val, $msg) = $del1->CreateUserDefinedGroup(Name => 'Del1'); +ok( $val ,"create a group del1 - $msg"); + +my $del2 = RT::Group->new($RT::SystemUser); +($val, $msg) = $del2->CreateUserDefinedGroup(Name => 'Del2'); +ok( $val ,"create a group del2 - $msg"); +($val, $msg) = $del1->AddMember($del2->PrincipalId); +ok( $val,"make del2 a member of del1 - $msg"); + +my $del2a = RT::Group->new($RT::SystemUser); +($val, $msg) = $del2a->CreateUserDefinedGroup(Name => 'Del2a'); +ok( $val ,"create a group del2a - $msg"); +($val, $msg) = $del2->AddMember($del2a->PrincipalId); +ok($val ,"make del2a a member of del2 - $msg"); + +my $del2b = RT::Group->new($RT::SystemUser); +($val, $msg) = $del2b->CreateUserDefinedGroup(Name => 'Del2b'); +ok( $val ,"create a group del2b - $msg"); +($val, $msg) = $del2->AddMember($del2b->PrincipalId); +ok($val ,"make del2b a member of del2 - $msg"); + +($val, $msg) = $del2->AddMember($user_a->PrincipalId) ; +ok($val,"make 'user a' a member of del2 - $msg"); + +($val, $msg) = $del2b->AddMember($user_a->PrincipalId) ; +ok($val,"make 'user a' a member of del2b - $msg"); + +# }}} + +# {{{ Grant a right to a group and make sure that a submember can delegate the right and that it does not get yanked +# when a user is removed as a submember, when they're a submember through another path +($val, $msg) = $del1->PrincipalObj->GrantRight( Object=> $q, Right => 'OwnTicket'); +ok( $val ,"grant del1 the right to 'OwnTicket' in queue 'DelegationTest' - $msg"); + +ok( $user_a->HasRight(Right => 'OwnTicket', Object => $q) ,"make sure that user a can own tickets in queue 'DelegationTest'"); + +my $group_ace= RT::ACE->new($user_a); +$group_ace->LoadByValues( PrincipalType => 'Group', PrincipalId => $del1->PrincipalId, Object => $q, RightName => 'OwnTicket'); + +ok ($group_ace->Id, "Found the ACE we want to test with for now"); + +($val, $msg) = $group_ace->Delegate(PrincipalId => $a_delegates->PrincipalId); + +ok( $val ,"user a tries and succeeds to delegate the right 'ownticket' in queue 'DelegationTest' to personal group 'delegates' - $msg"); +ok( $user_b->HasRight(Right => 'OwnTicket', Object => $q) ,"user b has the right to own tickets in queue 'DelegationTest'"); + + +($val, $msg) = $del2b->DeleteMember($user_a->PrincipalId); +ok( $val ,"remove user a from group del2b - $msg"); +ok( $user_a->HasRight(Right => 'OwnTicket', Object => $q) ,"user a has the right to own tickets in queue 'DelegationTest'"); +ok( $user_b->HasRight(Right => 'OwnTicket', Object => $q) ,"user b has the right to own tickets in queue 'DelegationTest'"); + +# }}} + +# {{{ When a user is removed froom a group by the only path they're in there by, make sure the delegations go away +($val, $msg) = $del2->DeleteMember($user_a->PrincipalId); +ok( $val ,"remove user a from group del2 - $msg"); +ok( !$user_a->HasRight(Right => 'OwnTicket', Object => $q) ,"user a does not have the right to own tickets in queue 'DelegationTest' "); +ok( !$user_b->HasRight(Right => 'OwnTicket', Object => $q) ,"user b does not have the right to own tickets in queue 'DelegationTest' "); +# }}} + +($val, $msg) = $del2->AddMember($user_a->PrincipalId); +ok( $val ,"make user a a member of group del2 - $msg"); + +($val, $msg) = $del2->PrincipalObj->GrantRight(Object=>$q, Right => 'OwnTicket'); +ok($val, "grant the right 'own tickets' in queue 'DelegationTest' to group del2 - $msg"); + +my $del2_right = RT::ACE->new($user_a); +$del2_right->LoadByValues( PrincipalId => $del2->PrincipalId, PrincipalType => 'Group', Object => $q, RightName => 'OwnTicket'); +ok ($del2_right->Id, "Found the right"); + +($val, $msg) = $del2_right->Delegate(PrincipalId => $a_delegates->PrincipalId); +ok( $val ,"user a tries and succeeds to delegate the right 'ownticket' in queue 'DelegationTest' gotten via del2 to personal group 'delegates' - $msg"); + +# They have it via del1 and del2 +ok( $user_b->HasRight(Right => 'OwnTicket', Object => $q) ,"user b has the right to own tickets in queue 'DelegationTest'"); + + +($val, $msg) = $del2->PrincipalObj->RevokeRight(Object=>$q, Right => 'OwnTicket'); +ok($val, "revoke the right 'own tickets' in queue 'DelegationTest' to group del2 - $msg"); +ok( $user_a->HasRight(Right => 'OwnTicket', Object => $q) ,"user a does has the right to own tickets in queue 'DelegationTest' via del1"); +ok( !$user_b->HasRight(Right => 'OwnTicket', Object => $q) ,"user b does not have the right to own tickets in queue 'DelegationTest'"); + +($val, $msg) = $del2->PrincipalObj->GrantRight(Object=>$q, Right => 'OwnTicket'); +ok($val, "grant the right 'own tickets' in queue 'DelegationTest' to group del2 - $msg"); + + +$group_ace= RT::ACE->new($user_a); +$group_ace->LoadByValues( PrincipalType => 'Group', PrincipalId => $del1->PrincipalId, Object=>$q, RightName => 'OwnTicket'); + +ok ($group_ace->Id, "Found the ACE we want to test with for now"); + +($val, $msg) = $group_ace->Delegate(PrincipalId => $a_delegates->PrincipalId); + +ok( $val ,"user a tries and succeeds to delegate the right 'ownticket' in queue 'DelegationTest' to personal group 'delegates' - $msg"); + +ok( $user_b->HasRight(Right => 'OwnTicket', Object => $q) ,"user b has the right to own tickets in queue 'DelegationTest'"); + +($val, $msg) = $del2->DeleteMember($user_a->PrincipalId); +ok( $val ,"remove user a from group del2 - $msg"); + +ok( !$user_a->HasRight(Right => 'OwnTicket', Object => $q) ,"user a does not have the right to own tickets in queue 'DelegationTest'"); + +ok( !$user_b->HasRight(Right => 'OwnTicket', Object => $q) ,"user b does not have the right to own tickets in queue 'DelegationTest'"); + + + + +} + +1; diff --git a/rt/t/api/action-createtickets.t b/rt/t/api/action-createtickets.t new file mode 100644 index 000000000..69ceb8d4d --- /dev/null +++ b/rt/t/api/action-createtickets.t @@ -0,0 +1,240 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 49; + + +{ + +ok (require RT::Action::CreateTickets); +use_ok('RT::Scrip'); +use_ok('RT::Template'); +use_ok('RT::ScripAction'); +use_ok('RT::ScripCondition'); +use_ok('RT::Ticket'); + +my $approvalsq = RT::Queue->new($RT::SystemUser); +$approvalsq->Create(Name => 'Approvals'); +ok ($approvalsq->Id, "Created Approvals test queue"); + + +my $approvals = +'===Create-Ticket: approval +Queue: Approvals +Type: approval +AdminCc: {join ("\nAdminCc: ",@admins) } +Depended-On-By: {$Tickets{"TOP"}->Id} +Refers-To: TOP +Subject: Approval for ticket: {$Tickets{"TOP"}->Id} - {$Tickets{"TOP"}->Subject} +Due: {time + 86400} +Content-Type: text/plain +Content: Your approval is requested for the ticket {$Tickets{"TOP"}->Id}: {$Tickets{"TOP"}->Subject} +Blah +Blah +ENDOFCONTENT +===Create-Ticket: two +Subject: Manager approval. +Depended-On-By: approval +Queue: Approvals +Content-Type: text/plain +Content: +Your minion approved ticket {$Tickets{"TOP"}->Id}. you ok with that? +ENDOFCONTENT +'; + +like ($approvals , qr/Content/, "Read in the approvals template"); + +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); +$q->Create(Name => 'WorkflowTest'); +ok ($q->Id, "Created workflow test queue"); + +my $scrip = RT::Scrip->new($RT::SystemUser); +my ($sval, $smsg) =$scrip->Create( ScripCondition => 'On Transaction', + ScripAction => 'Create Tickets', + Template => 'Approvals', + Queue => $q->Id); +ok ($sval, $smsg); +ok ($scrip->Id, "Created the scrip"); +ok ($scrip->TemplateObj->Id, "Created the scrip template"); +ok ($scrip->ConditionObj->Id, "Created the scrip condition"); +ok ($scrip->ActionObj->Id, "Created the scrip action"); + +my $t = RT::Ticket->new($RT::SystemUser); +my($tid, $ttrans, $tmsg) = $t->Create(Subject => "Sample workflow test", + Owner => "root", + Queue => $q->Id); + +ok ($tid,$tmsg); + +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"); +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); + +# comma-delimited templates +my $commas = <<"EOF"; +id,Queue,Subject,Owner,Content +ticket1,General,"foo, bar",root,blah +ticket2,General,foo bar,root,blah +ticket3,General,foo' bar,root,blah'boo +ticket4,General,foo' bar,,blah'boo +EOF + + +# Comma delimited templates with missing data +my $sparse_commas = <<"EOF"; +id,Queue,Subject,Owner,Requestor +ticket14,General,,,bobby +ticket15,General,,,tommy +ticket16,General,,suzie,tommy +ticket17,General,Foo "bar" baz,suzie,tommy +ticket18,General,'Foo "bar" baz',suzie,tommy +ticket19,General,'Foo bar' baz,suzie,tommy +EOF + + +# tab-delimited templates +my $tabs = <<"EOF"; +id\tQueue\tSubject\tOwner\tContent +ticket10\tGeneral\t"foo' bar"\troot\tblah' +ticket11\tGeneral\tfoo, bar\troot\tblah +ticket12\tGeneral\tfoo' bar\troot\tblah'boo +ticket13\tGeneral\tfoo' bar\t\tblah'boo +EOF + +my %expected; + +$expected{ticket1} = <<EOF; +Queue: General +Subject: foo, bar +Owner: root +Content: blah +ENDOFCONTENT +EOF + +$expected{ticket2} = <<EOF; +Queue: General +Subject: foo bar +Owner: root +Content: blah +ENDOFCONTENT +EOF + +$expected{ticket3} = <<EOF; +Queue: General +Subject: foo' bar +Owner: root +Content: blah'boo +ENDOFCONTENT +EOF + +$expected{ticket4} = <<EOF; +Queue: General +Subject: foo' bar +Owner: +Content: blah'boo +ENDOFCONTENT +EOF + +$expected{ticket10} = <<EOF; +Queue: General +Subject: foo' bar +Owner: root +Content: blah' +ENDOFCONTENT +EOF + +$expected{ticket11} = <<EOF; +Queue: General +Subject: foo, bar +Owner: root +Content: blah +ENDOFCONTENT +EOF + +$expected{ticket12} = <<EOF; +Queue: General +Subject: foo' bar +Owner: root +Content: blah'boo +ENDOFCONTENT +EOF + +$expected{ticket13} = <<EOF; +Queue: General +Subject: foo' bar +Owner: +Content: blah'boo +ENDOFCONTENT +EOF + + +$expected{'ticket14'} = <<EOF; +Queue: General +Subject: +Owner: +Requestor: bobby +EOF +$expected{'ticket15'} = <<EOF; +Queue: General +Subject: +Owner: +Requestor: tommy +EOF +$expected{'ticket16'} = <<EOF; +Queue: General +Subject: +Owner: suzie +Requestor: tommy +EOF +$expected{'ticket17'} = <<EOF; +Queue: General +Subject: Foo "bar" baz +Owner: suzie +Requestor: tommy +EOF +$expected{'ticket18'} = <<EOF; +Queue: General +Subject: Foo "bar" baz +Owner: suzie +Requestor: tommy +EOF +$expected{'ticket19'} = <<EOF; +Queue: General +Subject: 'Foo bar' baz +Owner: suzie +Requestor: tommy +EOF + + + + +$action->Parse(Content =>$commas); +$action->Parse(Content =>$sparse_commas); +$action->Parse(Content => $tabs); + +my %got; +foreach (@{ $action->{'create_tickets'} }) { + $got{$_} = $action->{'templates'}->{$_}; +} + +foreach my $id ( sort keys %expected ) { + ok(exists($got{"create-$id"}), "template exists for $id"); + is($got{"create-$id"}, $expected{$id}, "template is correct for $id"); +} + + +} + +1; diff --git a/rt/t/api/attachment.t b/rt/t/api/attachment.t new file mode 100644 index 000000000..07c46bad0 --- /dev/null +++ b/rt/t/api/attachment.t @@ -0,0 +1,45 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 4; + + +{ + +ok (require RT::Attachment); + + +} + +{ + +my $test1 = "From: jesse"; +my @headers = RT::Attachment->_SplitHeaders($test1); +is ($#headers, 0, $test1 ); + +my $test2 = qq{From: jesse +To: bobby +Subject: foo +}; + +@headers = RT::Attachment->_SplitHeaders($test2); +is ($#headers, 2, "testing a bunch of singline multiple headers" ); + + +my $test3 = qq{From: jesse +To: bobby, + Suzie, + Sally, + Joey: bizzy, +Subject: foo +}; + +@headers = RT::Attachment->_SplitHeaders($test3); +is ($#headers, 2, "testing a bunch of singline multiple headers" ); + + + +} + +1; diff --git a/rt/t/api/attribute-tests.t b/rt/t/api/attribute-tests.t new file mode 100644 index 000000000..90c3ddb7e --- /dev/null +++ b/rt/t/api/attribute-tests.t @@ -0,0 +1,86 @@ +use strict; +use warnings; +use RT; +use RT::Test tests => 34; + + + +my $runid = rand(200); + +my $attribute = "squelch-$runid"; + +ok(require RT::Attributes); + +my $user = RT::User->new($RT::SystemUser); +ok (UNIVERSAL::isa($user, 'RT::User')); +my ($id,$msg) = $user->Create(Name => 'attrtest-'.$runid); +ok ($id, $msg); +ok($user->id, "Created a test user"); + +ok(1, $user->Attributes->BuildSelectQuery); +my $attr = $user->Attributes; +# XXX: Order by id as some tests depend on it +$attr->OrderByCols({ FIELD => 'id' }); + +ok(1, $attr->BuildSelectQuery); + + +ok (UNIVERSAL::isa($attr,'RT::Attributes'), 'got the attributes object'); + +($id, $msg) = $user->AddAttribute(Name => 'TestAttr', Content => 'The attribute has content'); +ok ($id, $msg); +is ($attr->Count,1, " One attr after adding a first one"); + +my $first_attr = $user->FirstAttribute('TestAttr'); +ok($first_attr, "got some sort of attribute"); +isa_ok($first_attr, 'RT::Attribute'); +is($first_attr->Content, 'The attribute has content', "got the right content back"); + +($id, $msg) = $attr->DeleteEntry(Name => $runid); +ok(!$id, "Deleted non-existant entry - $msg"); +is ($attr->Count,1, "1 attr after deleting an empty attr"); + +my @names = $attr->Names; +is ("@names", "TestAttr"); + + +($id, $msg) = $user->AddAttribute(Name => $runid, Content => "First"); +ok($id, $msg); + +my $runid_attr = $user->FirstAttribute($runid); +ok($runid_attr, "got some sort of attribute"); +isa_ok($runid_attr, 'RT::Attribute'); +is($runid_attr->Content, 'First', "got the right content back"); + +is ($attr->Count,2, " Two attrs after adding an attribute named $runid"); +($id, $msg) = $user->AddAttribute(Name => $runid, Content => "Second"); +ok($id, $msg); + +$runid_attr = $user->FirstAttribute($runid); +ok($runid_attr, "got some sort of attribute"); +isa_ok($runid_attr, 'RT::Attribute'); +is($runid_attr->Content, 'First', "got the first content back still"); + +is ($attr->Count,3, " Three attrs after adding a secondvalue to $runid"); +($id, $msg) = $attr->DeleteEntry(Name => $runid, Content => "First"); +ok($id, $msg); +is ($attr->Count,2); + +#$attr->_DoSearch(); +($id, $msg) = $attr->DeleteEntry(Name => $runid, Content => "Second"); +ok($id, $msg); +is ($attr->Count,1); + +#$attr->_DoSearch(); +ok(1, $attr->BuildSelectQuery); +($id, $msg) = $attr->DeleteEntry(Name => "moose"); +ok(!$id, "Deleted non-existant entry - $msg"); +is ($attr->Count,1); + +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 new file mode 100644 index 000000000..cb2626ad8 --- /dev/null +++ b/rt/t/api/attribute.t @@ -0,0 +1,42 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 7; + + +{ + +my $user = $RT::SystemUser; +my ($id, $msg) = $user->AddAttribute(Name => 'SavedSearch', Content => { Query => 'Foo'} ); +ok ($id, $msg); +my $attr = RT::Attribute->new($RT::SystemUser); +$attr->Load($id); +is($attr->Name , 'SavedSearch'); +$attr->SetSubValues( Format => 'baz'); + +my $format = $attr->SubValue('Format'); +is ($format , 'baz'); + +$attr->SetSubValues( Format => 'bar'); +$format = $attr->SubValue('Format'); +is ($format , 'bar'); + +$attr->DeleteAllSubValues(); +$format = $attr->SubValue('Format'); +is ($format, undef); + +$attr->SetSubValues(Format => 'This is a format'); + +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); +($id) = $attr3->Load($id); +is ($id, 0); + + +} + +1; diff --git a/rt/t/api/cf.t b/rt/t/api/cf.t new file mode 100644 index 000000000..98114c93f --- /dev/null +++ b/rt/t/api/cf.t @@ -0,0 +1,224 @@ +#!/usr/bin/perl + +use strict; +use warnings FATAL => 'all'; + +use RT::Test tests => 139; + +# Before we get going, ditch all object_cfs; this will remove +# all custom fields systemwide; +my $object_cfs = RT::ObjectCustomFields->new($RT::SystemUser); +$object_cfs->UnLimit(); +while (my $ocf = $object_cfs->Next) { + $ocf->Delete(); +} + + +my $queue = RT::Queue->new( $RT::SystemUser ); +$queue->Create( Name => 'RecordCustomFields-'.$$ ); +ok ($queue->id, "Created the queue"); + +my $queue2 = RT::Queue->new( $RT::SystemUser ); +$queue2->Create( Name => 'RecordCustomFields2' ); + +my $ticket = RT::Ticket->new( $RT::SystemUser ); +$ticket->Create( + Queue => $queue->Id, + Requestor => 'root@localhost', + Subject => 'RecordCustomFields1', +); + +my $cfs = $ticket->CustomFields; +is( $cfs->Count, 0 ); + +# Check that record has no any CF values yet {{{ +my $cfvs = $ticket->CustomFieldValues; +is( $cfvs->Count, 0 ); +is( $ticket->FirstCustomFieldValue, undef ); + +my $local_cf1 = RT::CustomField->new( $RT::SystemUser ); +$local_cf1->Create( Name => 'RecordCustomFields1-'.$$, Type => 'SelectSingle', Queue => $queue->id ); +$local_cf1->AddValue( Name => 'RecordCustomFieldValues11' ); +$local_cf1->AddValue( Name => 'RecordCustomFieldValues12' ); + +my $local_cf2 = RT::CustomField->new( $RT::SystemUser ); +$local_cf2->Create( Name => 'RecordCustomFields2-'.$$, Type => 'SelectSingle', Queue => $queue->id ); +$local_cf2->AddValue( Name => 'RecordCustomFieldValues21' ); +$local_cf2->AddValue( Name => 'RecordCustomFieldValues22' ); + +my $global_cf3 = RT::CustomField->new( $RT::SystemUser ); +$global_cf3->Create( Name => 'RecordCustomFields3-'.$$, Type => 'SelectSingle', Queue => 0 ); +$global_cf3->AddValue( Name => 'RecordCustomFieldValues31' ); +$global_cf3->AddValue( Name => 'RecordCustomFieldValues32' ); + +my $local_cf4 = RT::CustomField->new( $RT::SystemUser ); +$local_cf4->Create( Name => 'RecordCustomFields4', Type => 'SelectSingle', Queue => $queue2->id ); +$local_cf4->AddValue( Name => 'RecordCustomFieldValues41' ); +$local_cf4->AddValue( Name => 'RecordCustomFieldValues42' ); + + +my @custom_fields = ($local_cf1, $local_cf2, $global_cf3); + + +$cfs = $ticket->CustomFields; +is( $cfs->Count, 3 ); + +# Check that record has no any CF values yet {{{ +$cfvs = $ticket->CustomFieldValues; +is( $cfvs->Count, 0 ); +is( $ticket->FirstCustomFieldValue, undef ); + +# CF with ID -1 shouldnt exist at all +$cfvs = $ticket->CustomFieldValues( -1 ); +is( $cfvs->Count, 0 ); +is( $ticket->FirstCustomFieldValue( -1 ), undef ); + +$cfvs = $ticket->CustomFieldValues( 'SomeUnexpedCustomFieldName' ); +is( $cfvs->Count, 0 ); +is( $ticket->FirstCustomFieldValue( 'SomeUnexpedCustomFieldName' ), undef ); + +for (@custom_fields) { + $cfvs = $ticket->CustomFieldValues( $_->id ); + is( $cfvs->Count, 0 ); + + $cfvs = $ticket->CustomFieldValues( $_->Name ); + is( $cfvs->Count, 0 ); + is( $ticket->FirstCustomFieldValue( $_->id ), undef ); + is( $ticket->FirstCustomFieldValue( $_->Name ), undef ); +} +# }}} + +# try to add field value with fields that do not exist {{{ +my ($status, $msg) = $ticket->AddCustomFieldValue( Field => -1 , Value => 'foo' ); +ok(!$status, "shouldn't add value" ); +($status, $msg) = $ticket->AddCustomFieldValue( Field => 'SomeUnexpedCustomFieldName' , Value => 'foo' ); +ok(!$status, "shouldn't add value" ); +# }}} + +# {{{ +SKIP: { + + skip "TODO: We want fields that are not allowed to set unexpected values", 10; + for (@custom_fields) { + ($status, $msg) = $ticket->AddCustomFieldValue( Field => $_ , Value => 'SomeUnexpectedCFValue' ); + ok( !$status, 'value doesn\'t exist'); + + ($status, $msg) = $ticket->AddCustomFieldValue( Field => $_->id , Value => 'SomeUnexpectedCFValue' ); + ok( !$status, 'value doesn\'t exist'); + + ($status, $msg) = $ticket->AddCustomFieldValue( Field => $_->Name , Value => 'SomeUnexpectedCFValue' ); + ok( !$status, 'value doesn\'t exist'); + } + + # Let check that we did not add value to be sure + # using only FirstCustomFieldValue sub because + # we checked other variants allready + for (@custom_fields) { + is( $ticket->FirstCustomFieldValue( $_->id ), undef ); + } + +} +# Add some values to our custom fields +for (@custom_fields) { + # this should be tested elsewhere + $_->AddValue( Name => 'Foo' ); + $_->AddValue( Name => 'Bar' ); +} + +my $test_add_delete_cycle = sub { + my $cb = shift; + for (@custom_fields) { + ($status, $msg) = $ticket->AddCustomFieldValue( Field => $cb->($_) , Value => 'Foo' ); + ok( $status, "message: $msg"); + } + + # does it exist? + $cfvs = $ticket->CustomFieldValues; + is( $cfvs->Count, 3, "We found all three custom fields on our ticket" ); + for (@custom_fields) { + $cfvs = $ticket->CustomFieldValues( $_->id ); + is( $cfvs->Count, 1 , "we found one custom field when searching by id"); + + $cfvs = $ticket->CustomFieldValues( $_->Name ); + is( $cfvs->Count, 1 , " We found one custom field when searching by name for " . $_->Name); + is( $ticket->FirstCustomFieldValue( $_->id ), 'Foo' , "first value by id is foo"); + is( $ticket->FirstCustomFieldValue( $_->Name ), 'Foo' , "first value by name is foo"); + } + # because our CFs are SingleValue then new value addition should override + for (@custom_fields) { + ($status, $msg) = $ticket->AddCustomFieldValue( Field => $_ , Value => 'Bar' ); + ok( $status, "message: $msg"); + } + $cfvs = $ticket->CustomFieldValues; + is( $cfvs->Count, 3 ); + for (@custom_fields) { + $cfvs = $ticket->CustomFieldValues( $_->id ); + is( $cfvs->Count, 1 ); + + $cfvs = $ticket->CustomFieldValues( $_->Name ); + is( $cfvs->Count, 1 ); + is( $ticket->FirstCustomFieldValue( $_->id ), 'Bar' ); + is( $ticket->FirstCustomFieldValue( $_->Name ), 'Bar' ); + } + # delete it + for (@custom_fields ) { + ($status, $msg) = $ticket->DeleteCustomFieldValue( Field => $_ , Value => 'Bar' ); + ok( $status, "Deleted a custom field value 'Bar' for field ".$_->id.": $msg"); + } + $cfvs = $ticket->CustomFieldValues; + is( $cfvs->Count, 0, "The ticket (".$ticket->id.") no longer has any custom field values" ); + for (@custom_fields) { + $cfvs = $ticket->CustomFieldValues( $_->id ); + is( $cfvs->Count, 0, $ticket->id." has no values for cf ".$_->id ); + + $cfvs = $ticket->CustomFieldValues( $_->Name ); + is( $cfvs->Count, 0 , $ticket->id." has no values for cf '".$_->Name. "'" ); + is( $ticket->FirstCustomFieldValue( $_->id ), undef , "There is no first custom field value when loading by id" ); + is( $ticket->FirstCustomFieldValue( $_->Name ), undef, "There is no first custom field value when loading by Name" ); + } +}; + +# lets test cycle via CF id +$test_add_delete_cycle->( sub { return $_[0]->id } ); +# lets test cycle via CF object reference +$test_add_delete_cycle->( sub { return $_[0] } ); + +$ticket->AddCustomFieldValue( Field => $local_cf2->id , Value => 'Baz' ); +$ticket->AddCustomFieldValue( Field => $global_cf3->id , Value => 'Baz' ); +# now if we ask for cf values on RecordCustomFields4 we should not get any +$cfvs = $ticket->CustomFieldValues( 'RecordCustomFields4' ); +is( $cfvs->Count, 0, "No custom field values for non-Queue cf" ); +is( $ticket->FirstCustomFieldValue( 'RecordCustomFields4' ), undef, "No first custom field value for non-Queue cf" ); + +{ + my $cfname = $global_cf3->Name; + ($status, $msg) = $global_cf3->SetDisabled(1); + ok($status, "Disabled CF named $cfname"); + + my $load = RT::CustomField->new( $RT::SystemUser ); + $load->LoadByName( Name => $cfname); + ok($load->Id, "Loaded CF named $cfname"); + is($load->Id, $global_cf3->Id, "Can load disabled CFs"); + + my $dup = RT::CustomField->new( $RT::SystemUser ); + $dup->Create( Name => $cfname, Type => 'SelectSingle', Queue => 0 ); + ok($dup->Id, "Created CF with duplicate name"); + + $load->LoadByName( Name => $cfname); + is($load->Id, $dup->Id, "Loading by name gets non-disabled first"); + + $dup->SetDisabled(1); + $global_cf3->SetDisabled(0); + + $load->LoadByName( Name => $cfname); + is($load->Id, $global_cf3->Id, "Loading by name gets non-disabled first, even with order swapped"); +} + +#SKIP: { +# skip "TODO: should we add CF values to objects via CF Name?", 48; +# names are not unique + # lets test cycle via CF Name +# $test_add_delete_cycle->( sub { return $_[0]->Name } ); +#} + + diff --git a/rt/t/api/cf_combo_casacade.t b/rt/t/api/cf_combo_casacade.t new file mode 100644 index 000000000..b37345a6a --- /dev/null +++ b/rt/t/api/cf_combo_casacade.t @@ -0,0 +1,46 @@ +#!/usr/bin/perl +use warnings; +use strict; + +use RT::Test tests => 11; + +sub fails { ok(!$_[0], "This should fail: $_[1]") } +sub works { ok($_[0], $_[1] || 'This works') } + +sub new (*) { + my $class = shift; + return $class->new($RT::SystemUser); +} + +my $q = new(RT::Queue); +works($q->Create(Name => "CF-Pattern-".$$)); + +my $cf = new(RT::CustomField); +my @cf_args = (Name => $q->Name, Type => 'Combobox', Queue => $q->id); + +works($cf->Create(@cf_args)); + +# Set some CFVs with Category markers + +my $t = new(RT::Ticket); +my ($id,undef,$msg) = $t->Create(Queue => $q->id, Subject => 'CF Test'); +works($id,$msg); + +sub add_works { + works( + $cf->AddValue(Name => $_[0], Description => $_[0], Category => $_[1]) + ); +}; + +add_works('value1', '1. Category A'); +add_works('value2'); +add_works('value3', '1.1. A-sub one'); +add_works('value4', '1.2. A-sub two'); +add_works('value5', ''); + +my $cfv = $cf->Values->First; +is($cfv->Category, '1. Category A'); +works($cfv->SetCategory('1. Category AAA')); +is($cfv->Category, '1. Category AAA'); + +1; diff --git a/rt/t/api/cf_external.t b/rt/t/api/cf_external.t new file mode 100644 index 000000000..076871240 --- /dev/null +++ b/rt/t/api/cf_external.t @@ -0,0 +1,56 @@ +#!/usr/bin/perl + +use warnings; +use strict; + +use RT; +use RT::Test nodata => 1, tests => 11; + +sub new (*) { + my $class = shift; + return $class->new($RT::SystemUser); +} + +use constant VALUES_CLASS => 'RT::CustomFieldValues::Groups'; + +my $q = new( RT::Queue ); +isa_ok( $q, 'RT::Queue' ); +my ($qid) = $q->Create( Name => "CF-External-". $$ ); +ok( $qid, "created queue" ); +my %arg = ( Name => $q->Name, + Type => 'Select', + Queue => $q->id, + MaxValues => 1, + ValuesClass => VALUES_CLASS ); + +my $cf = new( RT::CustomField ); +isa_ok( $cf, 'RT::CustomField' ); + +{ + my ($cfid) = $cf->Create( %arg ); + ok( $cfid, "created cf" ); + is( $cf->ValuesClass, VALUES_CLASS, "right values class" ); + ok( $cf->IsExternalValues, "custom field has external values" ); +} + +{ + # create at least on group for the tests + my $group = RT::Group->new( $RT::SystemUser ); + my ($ret, $msg) = $group->CreateUserDefinedGroup( Name => $q->Name ); + ok $ret, 'created group' or diag "error: $msg"; +} + +{ + my $values = $cf->Values; + isa_ok( $values, VALUES_CLASS ); + ok( $values->Count, "we have values" ); + my ($failure, $count) = (0, 0); + while( my $value = $values->Next ) { + $count++; + $failure = 1 unless $value->Name; + } + ok( !$failure, "all values have name" ); + is( $values->Count, $count, "count is correct" ); +} + +exit(0); diff --git a/rt/t/api/cf_pattern.t b/rt/t/api/cf_pattern.t new file mode 100644 index 000000000..89db2fea5 --- /dev/null +++ b/rt/t/api/cf_pattern.t @@ -0,0 +1,53 @@ +#!/usr/bin/perl +use warnings; +use strict; + +use RT; +use RT::Test tests => 17; + + +sub fails { ok(!$_[0], "This should fail: $_[1]") } +sub works { ok($_[0], $_[1] || 'This works') } + +sub new (*) { + my $class = shift; + return $class->new($RT::SystemUser); +} + +my $q = new(RT::Queue); +works($q->Create(Name => "CF-Pattern-".$$)); + +my $cf = new(RT::CustomField); +my @cf_args = (Name => $q->Name, Type => 'Freeform', Queue => $q->id, MaxValues => 1); + +fails($cf->Create(@cf_args, Pattern => ')))bad!regex(((')); +works($cf->Create(@cf_args, Pattern => 'good regex')); + +my $t = new(RT::Ticket); +my ($id,undef,$msg) = $t->Create(Queue => $q->id, Subject => 'CF Test'); +works($id,$msg); + +# OK, I'm thoroughly brain washed by HOP at this point now... +sub cnt { $t->CustomFieldValues($cf->id)->Count }; +sub add { $t->AddCustomFieldValue(Field => $cf->id, Value => $_[0]) }; +sub del { $t->DeleteCustomFieldValue(Field => $cf->id, Value => $_[0]) }; + +is(cnt(), 0, "No values yet"); +fails(add('not going to match')); +is(cnt(), 0, "No values yet"); +works(add('here is a good regex')); +is(cnt(), 1, "Value filled"); +fails(del('here is a good regex')); +is(cnt(), 1, "Single CF - Value _not_ deleted"); + +$cf->SetMaxValues(0); # Unlimited MaxValues + +works(del('here is a good regex')); +is(cnt(), 0, "Multiple CF - Value deleted"); + +fails($cf->SetPattern('(?{ "insert evil code here" })')); +works($cf->SetPattern('(?!)')); # reject everything +fails(add('')); +fails(add('...')); + +1; diff --git a/rt/t/api/cf_single_values.t b/rt/t/api/cf_single_values.t new file mode 100644 index 000000000..8e96edd44 --- /dev/null +++ b/rt/t/api/cf_single_values.t @@ -0,0 +1,38 @@ +#!/usr/bin/perl +use warnings; +use strict; + +use RT; +use RT::Test tests => 8; + + + +my $q = RT::Queue->new($RT::SystemUser); +my ($id,$msg) =$q->Create(Name => "CF-Single-".$$); +ok($id,$msg); + +my $cf = RT::CustomField->new($RT::SystemUser); +($id,$msg) = $cf->Create(Name => 'Single-'.$$, Type => 'Select', MaxValues => '1', Queue => $q->id); +ok($id,$msg); + + +($id,$msg) =$cf->AddValue(Name => 'First'); +ok($id,$msg); + +($id,$msg) =$cf->AddValue(Name => 'Second'); +ok($id,$msg); + + +my $t = RT::Ticket->new($RT::SystemUser); +($id,undef,$msg) = $t->Create(Queue => $q->id, + Subject => 'CF Test'); + +ok($id,$msg); +is($t->CustomFieldValues($cf->id)->Count, 0, "No values yet"); +$t->AddCustomFieldValue(Field => $cf->id, Value => 'First'); +is($t->CustomFieldValues($cf->id)->Count, 1, "One now"); + +$t->AddCustomFieldValue(Field => $cf->id, Value => 'Second'); +is($t->CustomFieldValues($cf->id)->Count, 1, "Still one"); + +1; diff --git a/rt/t/api/cf_transaction.t b/rt/t/api/cf_transaction.t new file mode 100644 index 000000000..1ed2ab932 --- /dev/null +++ b/rt/t/api/cf_transaction.t @@ -0,0 +1,60 @@ +#!/usr/bin/perl + +use warnings; +use strict; +use Data::Dumper; + +use RT::Test tests => 14; +use_ok('RT'); +use_ok('RT::Transactions'); + + +my $q = RT::Queue->new($RT::SystemUser); +my ($id,$msg) = $q->Create( Name => 'TxnCFTest'.$$); +ok($id,$msg); + +my $cf = RT::CustomField->new($RT::SystemUser); +($id,$msg) = $cf->Create(Name => 'Txnfreeform-'.$$, Type => 'Freeform', MaxValues => '0', LookupType => RT::Transaction->CustomFieldLookupType ); + +ok($id,$msg); + +($id,$msg) = $cf->AddToObject($q); + +ok($id,$msg); + + +my $ticket = RT::Ticket->new($RT::SystemUser); + +my $transid; +($id,$transid, $msg) = $ticket->Create(Queue => $q->id, + Subject => 'TxnCF test', + ); +ok($id,$msg); + +my $trans = RT::Transaction->new($RT::SystemUser); +$trans->Load($transid); + +is($trans->ObjectId,$id); +is ($trans->ObjectType, 'RT::Ticket'); +is ($trans->Type, 'Create'); +my $txncfs = $trans->CustomFields; +is ($txncfs->Count, 1, "We have one custom field"); +my $txn_cf = $txncfs->First; +is ($txn_cf->id, $cf->id, "It's the right custom field"); +my $values = $trans->CustomFieldValues($txn_cf->id); +is ($values->Count, 0, "It has no values"); + +# Old API +my %cf_updates = ( 'CustomField-'.$cf->id => 'Testing'); +$trans->UpdateCustomFields( ARGSRef => \%cf_updates); + + $values = $trans->CustomFieldValues($txn_cf->id); +is ($values->Count, 1, "It has one value"); + +# New API + +$trans->UpdateCustomFields( 'CustomField-'.$cf->id => 'Test two'); + $values = $trans->CustomFieldValues($txn_cf->id); +is ($values->Count, 2, "it has two values"); + +# TODO ok(0, "Should updating custom field values remove old values?"); diff --git a/rt/t/api/condition-ownerchange.t b/rt/t/api/condition-ownerchange.t new file mode 100644 index 000000000..4c4c49b29 --- /dev/null +++ b/rt/t/api/condition-ownerchange.t @@ -0,0 +1,51 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 11; + + +{ + +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 ($val, $msg) =$s1->Create( Queue => $q->Id, + ScripAction => 'User Defined', + ScripCondition => 'On Owner Change', + CustomIsApplicableCode => '', + CustomPrepareCode => 'return 1', + CustomCommitCode => ' + $self->TicketObj->SetPriority($self->TicketObj->Priority+1); + return(1); + ', + Template => 'Blank' + ); +ok($val,$msg); + +my $ticket = RT::Ticket->new($RT::SystemUser); +my ($tv,$ttv,$tm) = $ticket->Create(Queue => $q->Id, + Subject => "hair on fire", + InitialPriority => '20' + ); +ok($tv, $tm); +ok($ticket->SetOwner('root')); +is ($ticket->Priority , '21', "Ticket priority is set right"); +ok($ticket->Steal); +is ($ticket->Priority , '22', "Ticket priority is set right"); +ok($ticket->Untake); +is ($ticket->Priority , '23', "Ticket priority is set right"); +ok($ticket->Take); +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 new file mode 100644 index 000000000..96789509d --- /dev/null +++ b/rt/t/api/condition-reject.t @@ -0,0 +1,45 @@ +# +# Check that the "On Reject" scrip condition exists and is working +# + +use strict; +use warnings; +use RT; +use RT::Test tests => 7; + + +{ + +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 ($val, $msg) =$s1->Create( Queue => $q->Id, + ScripAction => 'User Defined', + ScripCondition => 'On reject', + CustomIsApplicableCode => '', + CustomPrepareCode => 'return 1', + CustomCommitCode => ' + $self->TicketObj->SetPriority($self->TicketObj->Priority+1); + return(1); + ', + Template => 'Blank' + ); +ok($val,$msg); + +my $ticket = RT::Ticket->new($RT::SystemUser); +my ($tv,$ttv,$tm) = $ticket->Create(Queue => $q->Id, + Subject => "hair on fire", + InitialPriority => '20' + ); +ok($tv, $tm); +ok($ticket->SetStatus('rejected'), "Status set to \"rejected\""); +is ($ticket->Priority , '21', "Condition is true, scrip triggered"); +ok($ticket->SetStatus('open'), "Status set to \"open\""); +is ($ticket->Priority , '21', "Condition is false, scrip skipped"); + +} + +1; diff --git a/rt/t/api/currentuser.t b/rt/t/api/currentuser.t new file mode 100644 index 000000000..c15804824 --- /dev/null +++ b/rt/t/api/currentuser.t @@ -0,0 +1,32 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 8; + + +{ + +ok (require RT::CurrentUser); + + +} + +{ + +ok (my $cu = RT::CurrentUser->new('root')); +ok (my $lh = $cu->LanguageHandle('en-us')); +isnt ($lh, undef, '$lh is defined'); +ok ($lh->isa('Locale::Maketext')); +is ($cu->loc('TEST_STRING'), "Concrete Mixer", "Localized TEST_STRING into English"); +SKIP: { + skip "French localization is not enabled", 2 + unless grep $_ && $_ =~ /^(\*|fr)$/, RT->Config->Get('LexiconLanguages'); + ok ($lh = $cu->LanguageHandle('fr')); + is ($cu->loc('before'), "avant", "Localized TEST_STRING into French"); +} + + +} + +1; diff --git a/rt/t/api/customfield.t b/rt/t/api/customfield.t new file mode 100644 index 000000000..44319c47f --- /dev/null +++ b/rt/t/api/customfield.t @@ -0,0 +1,74 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 29; +use Test::Warn; + + +{ + +use_ok('RT::CustomField'); +ok(my $cf = RT::CustomField->new($RT::SystemUser)); +ok(my ($id, $msg)= $cf->Create( Name => 'TestingCF', + Queue => '0', + SortOrder => '1', + Description => 'A Testing custom field', + Type=> 'SelectSingle'), 'Created a global CustomField'); +isnt($id , 0, 'Global custom field correctly created'); +ok ($cf->SingleValue); +is($cf->Type, 'Select'); +is($cf->MaxValues, 1); + +(my $val, $msg) = $cf->SetMaxValues('0'); +ok($val, $msg); +is($cf->Type, 'Select'); +is($cf->MaxValues, 0); +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_id, $bad_msg)= $cf->Create( Name => 'TestingCF-bad', + Queue => '0', + SortOrder => '1', + Description => 'A Testing custom field with a bogus Type', + Type=> 'SelectSingleton'), 'Created a global CustomField with a bogus type'); +is($bad_id , 0, 'Global custom field correctly decided to not create a cf with a bogus type '); + + +} + +{ + +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')); +isnt($val , 0); +ok (my ($delval, $delmsg) = $cf->DeleteValue($val)); +ok ($delval,"Deleting a cf value: $delmsg"); + + +} + +{ + +ok(my $cf = RT::CustomField->new($RT::SystemUser)); + +warning_like { +ok($cf->ValidateType('SelectSingle')); +} qr/deprecated/; + +warning_like { +ok($cf->ValidateType('SelectMultiple')); +} qr/deprecated/; + +warning_like { +ok(!$cf->ValidateType('SelectFooMultiple')); +} qr/deprecated/; + + +} + +1; diff --git a/rt/t/api/date.t b/rt/t/api/date.t new file mode 100644 index 000000000..bc1446f50 --- /dev/null +++ b/rt/t/api/date.t @@ -0,0 +1,564 @@ +#!/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 warnings; use strict; +use RT::Test tests => $tests; +use RT::User; +use Test::Warn; + +use_ok('RT::Date'); +{ + my $date = RT::Date->new($RT::SystemUser); + isa_ok($date, 'RT::Date', "constructor returned RT::Date oject"); + $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->Config->Set( Timezone => 'UTC' ); +} + +my $current_user; +{ + my $user = RT::User->new($RT::SystemUser); + my($uid, $msg) = $user->Create( + Name => "date_api". rand(200), + Lang => 'en', + Privileged => 1, + ); + ok($uid, "user was created") or diag("error: $msg"); + $current_user = RT::CurrentUser->new($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"); + + $current_user->UserObj->__Set( Field => 'Timezone', Value => 'Europe/Moscow'); + is($current_user->UserObj->Timezone, + 'Europe/Moscow', + "successfuly changed user's timezone"); + 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' ); + is($date->Timezone('server'), + 'Africa/Ouagadougou', + "timezone of the RT server was changed"); + 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, + "successfuly changed user's timezone"); + 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'), + 'UTC', + "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"); + is($date->Timezone('server'), + 'UTC', + "timezone of the server is not defined so UTC"); + + RT->Config->Set( Timezone => 'UTC' ); +} + +{ + 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'), + '1970-01-01 00:00:00', + "don't know format, return ISO format"); + is($date->Get(Format =>'W3CDTF'), + '1970-01-01T00:00:00Z', + "W3CDTF format with defaults"); + is($date->Get(Format =>'RFC2822'), + 'Thu, 1 Jan 1970 00:00:00 +0000', + "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 ); + + is($date->ISO(Time => 0), + '1970-01-01', + "ISO format without time part"); + is($date->W3CDTF(Time => 0), + '1970-01-01', + "W3CDTF format without time part"); + is($date->RFC2822(Time => 0), + 'Thu, 1 Jan 1970', + "RFC2822 format without time part"); + is($date->LocalizedDateTime(Time => 0), + 'Thu, Jan 1, 1970', + "LocalizedDateTime format without time part") if ( $localized_datetime_tests ); + + is($date->ISO(Date => 0), + '00:00:00', + "ISO format without date part"); + is($date->W3CDTF(Date => 0), + '1970-01-01T00:00:00Z', + "W3CDTF format is incorrect without date part"); + is($date->RFC2822(Date => 0), + '00:00:00 +0000', + "RFC2822 format without date part"); + is($date->LocalizedDateTime(Date => 0), + '12:00:00 AM', + "LocalizedDateTime format without date part") if ( $localized_datetime_tests ); + + is($date->ISO(Date => 0, Seconds => 0), + '00:00', + "ISO format without date part and seconds"); + is($date->W3CDTF(Date => 0, Seconds => 0), + '1970-01-01T00:00Z', + "W3CDTF format without seconds, but we ship date part even if Date is false"); + is($date->RFC2822(Date => 0, Seconds => 0), + '00:00 +0000', + "RFC2822 format without date part and seconds"); + + is($date->RFC2822(DayOfWeek => 0), + '1 Jan 1970 00:00:00 +0000', + "RFC2822 format without 'day of week' part"); + is($date->RFC2822(DayOfWeek => 0, Date => 0), + '00:00:00 +0000', + "RFC2822 format without 'day of week' and date parts(corner case test)"); + + is($date->LocalizedDateTime(AbbrDay => 0), + 'Thursday, Jan 1, 1970 12:00:00 AM', + "LocalizedDateTime format without abbreviation of day") if ( $localized_datetime_tests ); + is($date->LocalizedDateTime(AbbrMonth => 0), + 'Thu, January 1, 1970 12:00:00 AM', + "LocalizedDateTime format without abbreviation of month") if ( $localized_datetime_tests ); + is($date->LocalizedDateTime(DateFormat => 'date_format_short'), + '1/1/70 12:00:00 AM', + "LocalizedDateTime format with non default DateFormat") if ( $localized_datetime_tests ); + is($date->LocalizedDateTime(TimeFormat => 'time_format_short'), + 'Thu, Jan 1, 1970 12:00 AM', + "LocalizedDateTime format with non default TimeFormat") if ( $localized_datetime_tests ); + + is($date->Date, + '1970-01-01', + "the default format for the 'Date' method is ISO"); + is($date->Date(Format => 'W3CDTF'), + '1970-01-01', + "'Date' method, W3CDTF format"); + is($date->Date(Format => 'RFC2822'), + 'Thu, 1 Jan 1970', + "'Date' method, RFC2822 format"); + is($date->Date(Time => 1), + '1970-01-01', + "'Date' method doesn't pass through 'Time' argument"); + is($date->Date(Date => 0), + '1970-01-01', + "'Date' method overrides 'Date' argument"); + + is($date->Time, + '00:00:00', + "the default format for the 'Time' method is ISO"); + is($date->Time(Format => 'W3CDTF'), + '1970-01-01T00:00:00Z', + "'Time' method, W3CDTF format, date part is required by w3c doc"); + is($date->Time(Format => 'RFC2822'), + '00:00:00 +0000', + "'Time' method, RFC2822 format"); + is($date->Time(Date => 1), + '00:00:00', + "'Time' method doesn't pass through 'Date' argument"); + is($date->Time(Time => 0), + '00:00:00', + "'Time' method overrides 'Time' argument"); + + is($date->DateTime, + '1970-01-01 00:00:00', + "the default format for the 'DateTime' method is ISO"); + is($date->DateTime(Format =>'W3CDTF'), + '1970-01-01T00:00:00Z', + "'DateTime' method, W3CDTF format"); + is($date->DateTime(Format =>'RFC2822'), + 'Thu, 1 Jan 1970 00:00:00 +0000', + "'DateTime' method, RFC2822 format"); + is($date->DateTime(Date => 0, Time => 0), + '1970-01-01 00:00:00', + "the 'DateTime' method overrides both 'Date' and 'Time' arguments"); +} + + +{ # positive timezone + $current_user->UserObj->__Set( Field => 'Timezone', Value => 'Europe/Moscow'); + my $date = RT::Date->new( $current_user ); + $date->Set( Format => 'ISO', Timezone => 'utc', Value => '2005-01-01 15:10:00' ); + is($date->ISO( Timezone => 'user' ), '2005-01-01 18:10:00', "ISO"); + is($date->W3CDTF( Timezone => 'user' ), '2005-01-01T18:10:00+03:00', "W3C DTF"); + is($date->RFC2822( Timezone => 'user' ), 'Sat, 1 Jan 2005 18:10:00 +0300', "RFC2822"); + + # DST + $date = RT::Date->new( $current_user ); + $date->Set( Format => 'ISO', Timezone => 'utc', Value => '2005-07-01 15:10:00' ); + is($date->ISO( Timezone => 'user' ), '2005-07-01 19:10:00', "ISO"); + is($date->W3CDTF( Timezone => 'user' ), '2005-07-01T19:10:00+04:00', "W3C DTF"); + is($date->RFC2822( Timezone => 'user' ), 'Fri, 1 Jul 2005 19:10:00 +0400', "RFC2822"); +} + +{ # negative timezone + $current_user->UserObj->__Set( Field => 'Timezone', Value => 'America/New_York'); + my $date = RT::Date->new( $current_user ); + $date->Set( Format => 'ISO', Timezone => 'utc', Value => '2005-01-01 15:10:00' ); + is($date->ISO( Timezone => 'user' ), '2005-01-01 10:10:00', "ISO"); + is($date->W3CDTF( Timezone => 'user' ), '2005-01-01T10:10:00-05:00', "W3C DTF"); + is($date->RFC2822( Timezone => 'user' ), 'Sat, 1 Jan 2005 10:10:00 -0500', "RFC2822"); + + # DST + $date = RT::Date->new( $current_user ); + $date->Set( Format => 'ISO', Timezone => 'utc', Value => '2005-07-01 15:10:00' ); + is($date->ISO( Timezone => 'user' ), '2005-07-01 11:10:00', "ISO"); + is($date->W3CDTF( Timezone => 'user' ), '2005-07-01T11:10:00-04:00', "W3C DTF"); + is($date->RFC2822( Timezone => 'user' ), 'Fri, 1 Jul 2005 11:10:00 -0400', "RFC2822"); +} + +warning_like +{ # bad format + my $date = RT::Date->new($RT::SystemUser); + $date->Set( Format => 'bad' ); + is($date->Unix, 0, "bad format"); +} qr'Unknown Date format: bad'; + + +{ # setting value via Unix method + my $date = RT::Date->new($RT::SystemUser); + $date->Unix(1); + is($date->ISO, '1970-01-01 00:00:01', "correct value"); + + foreach (undef, 0, ''){ + $date->Unix(1); + is($date->ISO, '1970-01-01 00:00:01', "correct value"); + + $date->Set(Format => 'unix', Value => $_); + is($date->ISO, '1970-01-01 00:00:00', "Set a date to midnight 1/1/1970 GMT due to wrong call"); + is($date->Unix, 0, "unix is 0 => unset"); + } +} + +my $year = (localtime(time))[5] + 1900; + +{ # set+ISO format + 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/; + is($date->Unix, 0, "date was wrong => unix == 0"); + + # XXX: ISO format has more feature than we suport + # http://www.cl.cam.ac.uk/~mgk25/iso-time.html + + $date->Set(Format => 'ISO', Value => '2005-11-28 15:10:00'); + is($date->ISO, '2005-11-28 15:10:00', "YYYY-DD-MM hh:mm:ss"); + + $date->Set(Format => 'ISO', Value => '2005-11-28 15:10:00+00'); + is($date->ISO, '2005-11-28 15:10:00', "YYYY-DD-MM hh:mm:ss+00"); + + $date->Set(Format => 'ISO', Value => '11-28 15:10:00'); + is($date->ISO, $year .'-11-28 15:10:00', "DD-MM hh:mm:ss"); + + $date->Set(Format => 'ISO', Value => '11-28 15:10:00+00'); + is($date->ISO, $year .'-11-28 15:10:00', "DD-MM hh:mm:ss+00"); + + $date->Set(Format => 'ISO', Value => '20051128151000'); + is($date->ISO, '2005-11-28 15:10:00', "YYYYDDMMhhmmss"); + + $date->Set(Format => 'ISO', Value => '1128151000'); + is($date->ISO, $year .'-11-28 15:10:00', "DDMMhhmmss"); + + $date->Set(Format => 'ISO', Value => '2005112815:10:00'); + is($date->ISO, '2005-11-28 15:10:00', "YYYYDDMMhh:mm:ss"); + + $date->Set(Format => 'ISO', Value => '112815:10:00'); + is($date->ISO, $year .'-11-28 15:10:00', "DDMMhh:mm:ss"); + + $date->Set(Format => 'ISO', Value => '2005-13-28 15:10:00'); + is($date->Unix, 0, "wrong month value"); + + $date->Set(Format => 'ISO', Value => '2005-00-28 15:10:00'); + is($date->Unix, 0, "wrong month value"); + + $date->Set(Format => 'ISO', Value => '1960-01-28 15:10:00'); + is($date->Unix, 0, "too old, we don't support"); +} + +{ # set+datemanip format(Time::ParseDate) + my $date = RT::Date->new($RT::SystemUser); + $date->Set(Format => 'unknown', Value => 'weird date'); + is($date->Unix, 0, "date was wrong"); + + RT->Config->Set( Timezone => 'Europe/Moscow' ); + $date->Set(Format => 'datemanip', Value => '2005-11-28 15:10:00'); + is($date->ISO, '2005-11-28 12:10:00', "YYYY-DD-MM hh:mm:ss"); + + RT->Config->Set( Timezone => 'UTC' ); + $date->Set(Format => 'datemanip', Value => '2005-11-28 15:10:00'); + is($date->ISO, '2005-11-28 15:10:00', "YYYY-DD-MM hh:mm:ss"); + + $current_user->UserObj->__Set( Field => 'Timezone', Value => 'Europe/Moscow'); + $date = RT::Date->new( $current_user ); + $date->Set(Format => 'datemanip', Value => '2005-11-28 15:10:00'); + is($date->ISO, '2005-11-28 12:10:00', "YYYY-DD-MM hh:mm:ss"); +} + +{ # set+unknown format(Time::ParseDate) + my $date = RT::Date->new($RT::SystemUser); + $date->Set(Format => 'unknown', Value => 'weird date'); + is($date->Unix, 0, "date was wrong"); + + RT->Config->Set( Timezone => 'Europe/Moscow' ); + $date->Set(Format => 'unknown', Value => '2005-11-28 15:10:00'); + is($date->ISO, '2005-11-28 12:10:00', "YYYY-DD-MM hh:mm:ss"); + + $date->Set(Format => 'unknown', Value => '2005-11-28 15:10:00', Timezone => 'utc' ); + is($date->ISO, '2005-11-28 15:10:00', "YYYY-DD-MM hh:mm:ss"); + + # test relative dates + { + set_fixed_time("2005-11-28T15:10:00Z"); + $date->Set(Format => 'unknown', Value => 'now'); + is($date->ISO, '2005-11-28 15:10:00', "YYYY-DD-MM hh:mm:ss"); + + $date->Set(Format => 'unknown', Value => '1 day ago'); + is($date->ISO, '2005-11-27 15:10:00', "YYYY-DD-MM hh:mm:ss"); + restore_time(); + } + + RT->Config->Set( Timezone => 'UTC' ); + $date->Set(Format => 'unknown', Value => '2005-11-28 15:10:00'); + is($date->ISO, '2005-11-28 15:10:00', "YYYY-DD-MM hh:mm:ss"); + + $current_user->UserObj->__Set( Field => 'Timezone', Value => 'Europe/Moscow'); + $date = RT::Date->new( $current_user ); + $date->Set(Format => 'unknown', Value => '2005-11-28 15:10:00'); + is($date->ISO, '2005-11-28 12:10:00', "YYYY-DD-MM hh:mm:ss"); + $date->Set(Format => 'unknown', Value => '2005-11-28 15:10:00', Timezone => 'server' ); + is($date->ISO, '2005-11-28 15:10:00', "YYYY-DD-MM hh:mm:ss"); + $date->Set(Format => 'unknown', Value => '2005-11-28 15:10:00', Timezone => 'utc' ); + is($date->ISO, '2005-11-28 15:10:00', "YYYY-DD-MM hh:mm:ss"); +} + +{ # SetToMidnight + my $date = RT::Date->new($RT::SystemUser); + + RT->Config->Set( Timezone => 'Europe/Moscow' ); + $date->Set(Format => 'ISO', Value => '2005-11-28 15:10:00'); + $date->SetToMidnight; + is($date->ISO, '2005-11-28 00:00:00', "default is utc"); + $date->Set(Format => 'ISO', Value => '2005-11-28 15:10:00'); + $date->SetToMidnight(Timezone => 'utc'); + is($date->ISO, '2005-11-28 00:00:00', "utc context"); + $date->Set(Format => 'ISO', Value => '2005-11-28 15:10:00'); + $date->SetToMidnight(Timezone => 'user'); + is($date->ISO, '2005-11-27 21:00:00', "user context, user has no preference, fallback to server"); + $date->Set(Format => 'ISO', Value => '2005-11-28 15:10:00'); + $date->SetToMidnight(Timezone => 'server'); + is($date->ISO, '2005-11-27 21:00:00', "server context"); + + $current_user->UserObj->__Set( Field => 'Timezone', Value => 'Europe/Moscow'); + $date = RT::Date->new( $current_user ); + $date->Set(Format => 'ISO', Value => '2005-11-28 15:10:00'); + $date->SetToMidnight; + is($date->ISO, '2005-11-28 00:00:00', "default is utc"); + $date->Set(Format => 'ISO', Value => '2005-11-28 15:10:00'); + $date->SetToMidnight(Timezone => 'utc'); + is($date->ISO, '2005-11-28 00:00:00', "utc context"); + $date->Set(Format => 'ISO', Value => '2005-11-28 15:10:00'); + $date->SetToMidnight(Timezone => 'user'); + is($date->ISO, '2005-11-27 21:00:00', "user context"); + $date->SetToMidnight(Timezone => 'server'); + is($date->ISO, '2005-11-27 21:00:00', "server context"); + + RT->Config->Set( Timezone => 'UTC' ); +} + +{ # SetToNow + my $date = RT::Date->new($RT::SystemUser); + my $time = time; + $date->SetToNow; + ok($date->Unix >= $time, 'close enough'); + ok($date->Unix < $time+5, 'difference is less than five seconds'); +} + +{ + my $date = RT::Date->new($RT::SystemUser); + + $date->Unix(0); + $date->AddSeconds; + is($date->ISO, '1970-01-01 00:00:00', "nothing changed"); + $date->AddSeconds(0); + is($date->ISO, '1970-01-01 00:00:00', "nothing changed"); + + $date->Unix(0); + $date->AddSeconds(5); + is($date->ISO, '1970-01-01 00:00:05', "added five seconds"); + $date->AddSeconds(-2); + is($date->ISO, '1970-01-01 00:00:03', "substracted two seconds"); + + $date->Unix(0); + $date->AddSeconds(3661); + is($date->ISO, '1970-01-01 01:01:01', "added one hour, minute and a second"); + +# XXX: TODO, doesn't work with Test::Warn +# TODO: { +# local $TODO = "BUG or subject to change Date handling to support unix time <= 0"; +# $date->Unix(0); +# $date->AddSeconds(-2); +# ok($date->Unix > 0); +# } + + $date->Unix(0); + $date->AddDay; + is($date->ISO, '1970-01-02 00:00:00', "added one day"); + $date->AddDays(2); + is($date->ISO, '1970-01-04 00:00:00', "added two days"); + $date->AddDays(-1); + is($date->ISO, '1970-01-03 00:00:00', "substructed one day"); + + $date->Unix(0); + $date->AddDays(31); + is($date->ISO, '1970-02-01 00:00:00', "added one month"); +} + +{ + $current_user->UserObj->__Set( Field => 'Timezone', Value => ''); + my $date = RT::Date->new( $current_user ); + is($date->AsString, "Not set", "AsString returns 'Not set'"); + + RT->Config->Set( DateTimeFormat => ''); + $date->Unix(1); + is($date->AsString, 'Thu Jan 01 00:00:01 1970', "correct string"); + is($date->AsString(Date => 0), '00:00:01', "correct string"); + is($date->AsString(Time => 0), 'Thu Jan 01 1970', "correct string"); + is($date->AsString(Date => 0, Time => 0), 'Thu Jan 01 00:00:01 1970', "invalid input"); + + RT->Config->Set( DateTimeFormat => 'RFC2822' ); + $date->Unix(1); + is($date->AsString, 'Thu, 1 Jan 1970 00:00:01 +0000', "correct string"); + + RT->Config->Set( DateTimeFormat => { Format => 'RFC2822', Seconds => 0 } ); + $date->Unix(1); + is($date->AsString, 'Thu, 1 Jan 1970 00:00 +0000', "correct string"); + is($date->AsString(Seconds => 1), 'Thu, 1 Jan 1970 00:00:01 +0000', "correct string"); +} + +{ # DurationAsString + my $date = RT::Date->new($RT::SystemUser); + + is($date->DurationAsString(1), '1 sec', '1 sec'); + is($date->DurationAsString(59), '59 sec', '59 sec'); + is($date->DurationAsString(60), '1 min', '1 min'); + is($date->DurationAsString(60*119), '119 min', '119 min'); + is($date->DurationAsString(60*60*2-1), '120 min', '120 min'); + is($date->DurationAsString(60*60*2), '2 hours', '2 hours'); + is($date->DurationAsString(60*60*48-1), '48 hours', '48 hours'); + is($date->DurationAsString(60*60*48), '2 days', '2 days'); + is($date->DurationAsString(60*60*24*14-1), '14 days', '14 days'); + is($date->DurationAsString(60*60*24*14), '2 weeks', '2 weeks'); + is($date->DurationAsString(60*60*24*7*8-1), '8 weeks', '8 weeks'); + is($date->DurationAsString(60*60*24*61), '2 months', '2 months'); + is($date->DurationAsString(60*60*24*365-1), '12 months', '12 months'); + is($date->DurationAsString(60*60*24*366), '1 years', '1 years'); + + is($date->DurationAsString(-1), '1 sec ago', '1 sec ago'); +} + +{ # DiffAsString + 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'); + + $date->Unix(2); + is($date->DiffAsString(-1), '', 'no diff, wrong input'); + + 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); + 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); + $date->SetToNow; + my $diff = $date->Diff; + ok($diff <= 0, 'close enought'); + ok($diff > -5, 'close enought'); +} + +{ # AgeAsString + 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); + 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'); + is($date->GetWeekday(-1), 'Sat', '-1 is Saturday'); + is($date->GetWeekday(-7), 'Sun', '-7 is Sunday'); + is($date->GetWeekday(-8), '', '-8 and lesser are invalid'); +} + +{ # GetMonth + 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'); + is($date->GetMonth(-1), 'Dec', '11 is December'); + is($date->GetMonth(-12), 'Jan', '0 is January'); + is($date->GetMonth(-13), '', '-13 and lesser are invalid'); +} + +#TODO: AsString +#TODO: RFC2822, W3CDTF with Timezones + +exit(0); + diff --git a/rt/t/api/emailparser.t b/rt/t/api/emailparser.t new file mode 100644 index 000000000..4807138cc --- /dev/null +++ b/rt/t/api/emailparser.t @@ -0,0 +1,32 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 4; + + +{ + +ok(require RT::EmailParser); + + +} + +{ + +is(RT::EmailParser::IsRTAddress("","rt\@example.com"),1, "Regexp matched rt address" ); +is(RT::EmailParser::IsRTAddress("","frt\@example.com"),undef, "Regexp didn't match non-rt address" ); + + +} + +{ + +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"); + + +} + +1; diff --git a/rt/t/api/group.t b/rt/t/api/group.t new file mode 100644 index 000000000..551d4f1a0 --- /dev/null +++ b/rt/t/api/group.t @@ -0,0 +1,99 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 38; + + +{ + +# {{{ Tests +ok (require RT::Group); + +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); + +ok($ng->LoadUserDefinedGroup('TestGroup'), "Loaded testgroup"); +is($ng->id , $group->id, "Loaded the right group"); + + +ok (($id,$msg) = $ng->AddMember('1'), "Added a member to the group"); +ok($id, $msg); +ok (($id,$msg) = $ng->AddMember('2' ), "Added a member to the group"); +ok($id, $msg); +ok (($id,$msg) = $ng->AddMember('3' ), "Added a member to the group"); +ok($id, $msg); + +# Group 1 now has members 1, 2 ,3 + +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"); +ok($id, $msg); +ok (($id,$msg) = $group_2->AddMember('1' ), "Added member RT_System to the group TestGroup2"); +ok($id, $msg); + +# Group 2 how has 1, g1->{1, 2,3} + +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"); +ok($id, $msg); + +# g3 now has g2->{1, g1->{1,2,3}} + +my $principal_1 = RT::Principal->new($RT::SystemUser); +$principal_1->Load('1'); + +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"); +ok($id, $msg); + +# g3 now has 1, g2->{1, g1->{1,2,3}} + +is($group_3->HasMember($principal_2), undef, "group 3 doesn't have member 2"); +ok($group_3->HasMemberRecursively($principal_2), "group 3 has member 2 recursively"); +ok($ng->HasMember($principal_2) , "group ".$ng->Id." has member 2"); +my ($delid , $delmsg) =$ng->DeleteMember($principal_2->Id); +isnt ($delid ,0, "Sucessfully deleted it-".$delid."-".$delmsg); + +#Gotta reload the group objects, since we've been messing with various internals. +# we shouldn't need to do this. +#$ng->LoadUserDefinedGroup('TestGroup'); +#$group_2->LoadUserDefinedGroup('TestGroup2'); +#$group_3->LoadUserDefinedGroup('TestGroup'); + +# G1 now has 1, 3 +# Group 2 how has 1, g1->{1, 3} +# g3 now has 1, g2->{1, g1->{1, 3}} + +ok(!$ng->HasMember($principal_2) , "group ".$ng->Id." no longer has member 2"); +is($group_3->HasMemberRecursively($principal_2), undef, "group 3 doesn't have member 2"); +is($group_2->HasMemberRecursively($principal_2), undef, "group 2 doesn't have member 2"); +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($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"); + + +} + +1; diff --git a/rt/t/api/groups.t b/rt/t/api/groups.t new file mode 100644 index 000000000..995c844ba --- /dev/null +++ b/rt/t/api/groups.t @@ -0,0 +1,139 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 28; + + +{ + +ok (require RT::Groups); + + +} + +{ + +# 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"); + + +} + +{ + no warnings qw/redefine once/; + +my $q = RT::Queue->new($RT::SystemUser); +my ($id, $msg) =$q->Create( Name => 'GlobalACLTest'); +ok ($id, $msg); + +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); +$global_admin_cc->LoadSystemRoleGroup('AdminCc'); +ok($global_admin_cc->id, "Found the global admincc group"); +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); +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->WithRight(Right => 'OwnTicket', Object => $q); +ok ($id,$msg); +is($groups->Count, 3); + +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"); + +my $RTxSysObj = {}; +bless $RTxSysObj, 'RTx::System'; +*RTx::System::Id = sub { 1; }; +*RTx::System::id = *RTx::System::Id; +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); +ok ($id, "ACL for RTxSysObj created"); + +my $RTxObj = {}; +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->WithRight(Right => 'RTxGroupRight', Object => $RTxSysObj); +is($groups->Count, 1, "RTxGroupRight found for RTxSysObj"); + +$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->WithRight(Right => 'RTxGroupRight', Object => $RTxObj, EquivObjects => [ $RTxSysObj ]); +is($groups->Count, 1, "RTxGroupRight found for RTxObj using EquivObjects"); + +$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 ); +ok ($id, "ACL for RTxObj created"); + +my $RTxObj2 = {}; +bless $RTxObj2, 'RTx::System::Record'; +*RTx::System::Record::Id = sub { 5; }; + +$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->WithRight(Right => 'RTxGroupRight', Object => $RTxObj2, EquivObjects => [ $RTxSysObj ]); +is($groups->Count, 1, "RTxGroupRight found for RTxObj2"); + + + + +} + +1; diff --git a/rt/t/api/i18n.t b/rt/t/api/i18n.t new file mode 100644 index 000000000..17d71b761 --- /dev/null +++ b/rt/t/api/i18n.t @@ -0,0 +1,30 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 9; + + +{ + +use_ok ('RT::I18N'); +ok(RT::I18N->Init); + + +} + +{ + +ok(my $chinese = RT::I18N->get_handle('zh_tw')); +ok(UNIVERSAL::can($chinese, 'maketext')); +like($chinese->maketext('__Content-Type') , qr/utf-8/i, "Found the utf-8 charset for traditional chinese in the string ".$chinese->maketext('__Content-Type')); +is($chinese->encoding , 'utf-8', "The encoding is 'utf-8' -".$chinese->encoding); + +ok(my $en = RT::I18N->get_handle('en')); +ok(UNIVERSAL::can($en, 'maketext')); +is($en->encoding , 'utf-8', "The encoding ".$en->encoding." is 'utf-8'"); + + +} + +1; diff --git a/rt/t/api/link.t b/rt/t/api/link.t new file mode 100644 index 000000000..1fd66bb64 --- /dev/null +++ b/rt/t/api/link.t @@ -0,0 +1,24 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 5; + + +{ + + +use RT::Link; +my $link = RT::Link->new($RT::SystemUser); + + +ok (ref $link); +ok (UNIVERSAL::isa($link, 'RT::Link')); +ok (UNIVERSAL::isa($link, 'RT::Base')); +ok (UNIVERSAL::isa($link, 'RT::Record')); +ok (UNIVERSAL::isa($link, 'DBIx::SearchBuilder::Record')); + + +} + +1; diff --git a/rt/t/api/queue.t b/rt/t/api/queue.t new file mode 100644 index 000000000..44d5cafce --- /dev/null +++ b/rt/t/api/queue.t @@ -0,0 +1,92 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 24; + + +{ + +use RT::Queue; + + +} + +{ + +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'); + + +} + +{ + +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'); + + +} + +{ + +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'); + + +} + +{ + +my $queue = RT::Queue->new($RT::SystemUser); +my ($id, $val) = $queue->Create( Name => 'Test1'); +ok($id, $val); + +($id, $val) = $queue->Create( Name => '66'); +ok(!$id, $val); + + +} + +{ + +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($group->LoadQueueRoleGroup(Queue => $id, Type=> 'Requestor')); +ok ($group->Id, "Found the requestors object for this Queue"); + +{ + my ($status, $msg) = $Queue->AddWatcher(Type => 'Cc', Email => 'bob@fsck.com'); + 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"); +$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"); + +{ + my ($status, $msg) = $Queue->DeleteWatcher(Type =>'Cc', Email => 'bob@fsck.com'); + ok ($status, "Deleted bob from Ccs") or diag "error: $msg"; + ok (!$Queue->IsWatcher(Type => 'Cc', PrincipalId => $bob->PrincipalId), + "The Queue no longer has bob at fsck.com as a requestor"); +} + +$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); +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 new file mode 100644 index 000000000..6bf1af81e --- /dev/null +++ b/rt/t/api/record.t @@ -0,0 +1,70 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 22; + + +{ + +ok (require RT::Record); + + +} + +{ + +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"); + + +} + +{ + +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 $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 $id3, $trans, my $msg3) = $t3->Create(Subject => 'DepTest3', Queue => 'general', Type => 'approval'); +ok($id3, "Created dep test 3 - $msg3"); +my ($addid, $addmsg); +ok (($addid, $addmsg) =$t1->AddLink( Type => 'DependsOn', Target => $t2->id)); +ok ($addid, $addmsg); +ok (($addid, $addmsg) =$t1->AddLink( Type => 'DependsOn', Target => $t3->id)); + +ok ($addid, $addmsg); +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"); +is ($link->LocalBase , $t1->id, "Link LocalBase is correct"); + +ok ($t1->HasUnresolvedDependencies, "Ticket ".$t1->Id." has unresolved deps"); +ok (!$t1->HasUnresolvedDependencies( Type => 'blah' ), "Ticket ".$t1->Id." has no unresolved blahs"); +ok ($t1->HasUnresolvedDependencies( Type => 'approval' ), "Ticket ".$t1->Id." has unresolved approvals"); +ok (!$t2->HasUnresolvedDependencies, "Ticket ".$t2->Id." has no unresolved deps"); +; + +my ($rid, $rmsg)= $t1->Resolve(); +ok(!$rid, $rmsg); +my ($rid2, $rmsg2) = $t2->Resolve(); +ok ($rid2, $rmsg2); +($rid, $rmsg)= $t1->Resolve(); +ok(!$rid, $rmsg); +my ($rid3,$rmsg3) = $t3->Resolve; +ok ($rid3,$rmsg3); +($rid, $rmsg)= $t1->Resolve(); +ok($rid, $rmsg); + + + +} + +1; diff --git a/rt/t/api/reminders.t b/rt/t/api/reminders.t new file mode 100644 index 000000000..fd1c6a69f --- /dev/null +++ b/rt/t/api/reminders.t @@ -0,0 +1,88 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 20; + + +{ + +# Create test queues +use_ok ('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'); + +ok($testqueue->Create( Name => 'reminders tests 2'), 'Create new queue: reminders tests 2'); +isnt($testqueue->Id , 0, 'Success creating queue'); + +# Create test ticket +use_ok('RT::Ticket'); + +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 ($id, $msg) = $t->Create( Queue => $testqueue->Id, + Subject => 'Testing', + Owner => $u->Id + ), 'Create sample ticket'); +isnt($id , 0, 'Success creating ticket'); + +# Add reminder +my $due_obj = RT::Date->new( $RT::SystemUser ); +$due_obj->SetToNow; +ok(my ( $add_id, $add_msg, $txnid ) = $t->Reminders->Add( + Subject => 'TestReminder', + Owner => 'root', + Due => $due_obj->ISO + ), 'Add reminder'); + +# Check that the new Reminder is here +my $reminders = $t->Reminders->Collection; +ok($reminders, 'Loading reminders for this ticket'); +my $found = 0; +while ( my $reminder = $reminders->Next ) { + next unless $found == 0; + $found = 1 if ( $reminder->Subject =~ m/TestReminder/ ); +} + +is($found, 1, 'Reminder successfully added'); + +# Change queue +ok (my ($move_val, $move_msg) = $t->SetQueue('reminders tests 2'), 'Moving ticket from queue "reminders tests" to "reminders tests 2"'); + +is ($t->QueueObj->Name, 'reminders tests 2', 'Ticket successfully moved'); + +# Check that the new reminder is still there and moved to the new queue +$reminders = $t->Reminders->Collection; +ok($reminders, 'Loading reminders for this ticket'); +$found = 0; +my $ok_queue = 0; +while ( my $reminder = $reminders->Next ) { + next unless $found == 0; + if ( $reminder->Subject =~ m/TestReminder/ ) { + $found = 1; + $ok_queue = 1 if ( $reminder->QueueObj->Name eq 'reminders tests 2' ); + } +} +is($found, 1, 'Reminder successfully added'); + +is($ok_queue, 1, 'Reminder automatically moved to new queue'); + +# Resolve reminder +my $r_resolved = 0; +while ( my $reminder = $reminders->Next ) { + if ( $reminder->Subject =~ m/TestReminder/ ) { + if ( $reminder->Status ne 'resolved' ) { + $t->Reminders->Resolve($reminder); + $r_resolved = 1 if ( $reminder->Status eq 'resolved' ); + } + } +} + +is($r_resolved, 1, 'Reminder resolved'); + +} +1; diff --git a/rt/t/api/rights.t b/rt/t/api/rights.t new file mode 100644 index 000000000..7bd332f13 --- /dev/null +++ b/rt/t/api/rights.t @@ -0,0 +1,142 @@ +#!/usr/bin/perl -w +# BEGIN BPS TAGGED BLOCK {{{ +# +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC +# <jesse.com> +# +# (Except where explicitly superseded by other copyright notices) +# +# +# LICENSE: +# +# This work is made available to you under the terms of Version 2 of +# the GNU General Public License. A copy of that license should have +# been provided with this software, but in any event can be snarfed +# from www.gnu.org. +# +# This work is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 or visit their web page on the internet at +# http://www.gnu.org/copyleft/gpl.html. +# +# +# CONTRIBUTION SUBMISSION POLICY: +# +# (The following paragraph is not intended to limit the rights granted +# to you to modify and distribute this software under the terms of +# the GNU General Public License and is only of importance to you if +# you choose to contribute your changes and enhancements to the +# community by submitting them to Best Practical Solutions, LLC.) +# +# By intentionally submitting any modifications, corrections or +# derivatives to this work, or any other work intended for use with +# Request Tracker, to Best Practical Solutions, LLC, you confirm that +# you are the copyright holder for those contributions and you grant +# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, +# royalty-free, perpetual, license to use, copy, create derivative +# works based on those contributions, and sublicense and distribute +# those contributions and any derivatives thereof. +# +# END BPS TAGGED BLOCK }}} + +use RT; +use RT::Test tests => 26; + +use RT::I18N; +use strict; +no warnings 'once'; + +use RT::Queue; +use RT::ACE; +use RT::User; +use RT::Group; +use RT::Ticket; + + +# clear all global right +my $acl = RT::ACL->new($RT::SystemUser); +$acl->Limit( FIELD => 'RightName', OPERATOR => '!=', VALUE => 'SuperUser' ); +$acl->LimitToObject( $RT::System ); +while( my $ace = $acl->Next ) { + $ace->Delete; +} + +my $rand_name = "rights". int rand($$); +# create new queue to be shure we don't mess with rights +my $queue = RT::Queue->new($RT::SystemUser); +my ($queue_id) = $queue->Create( Name => $rand_name); +ok( $queue_id, 'queue created for rights tests' ); + +# new privileged user to check rights +my $user = RT::User->new( $RT::SystemUser ); +my ($user_id) = $user->Create( Name => $rand_name, + EmailAddress => $rand_name .'@localhost', + Privileged => 1, + Password => 'qwe123', + ); +ok( !$user->HasRight( Right => 'OwnTicket', Object => $queue ), "user can't own ticket" ); +ok( !$user->HasRight( Right => 'ReplyToTicket', Object => $queue ), "user can't reply to ticket" ); + +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_id, $msg) = $group->PrincipalObj->GrantRight( Right => 'ReplyToTicket', Object => $queue ); +ok( $ace_id, "Granted queue owners role group with ReplyToTicket right: $msg" ); +ok( $group->PrincipalObj->HasRight( Right => 'ReplyToTicket', Object => $queue ), "role group can reply to ticket" ); +ok( !$user->HasRight( Right => 'ReplyToTicket', Object => $queue ), "user can't reply to ticket" ); + +# new ticket +my $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' ); + +my $status; +($status, $msg) = $user->PrincipalObj->GrantRight( Object => $queue, Right => 'OwnTicket' ); +ok( $status, "successfuly granted right: $msg" ); +ok( $user->HasRight( Right => 'OwnTicket', Object => $queue ), "user can own ticket" ); + +($status, $msg) = $ticket->SetOwner( $user_id ); +ok( $status, "successfuly set owner: $msg" ); +is( $ticket->Owner, $user_id, "set correct owner" ); + +ok( $user->HasRight( Right => 'ReplyToTicket', Object => $ticket ), "user is owner and can reply to ticket" ); + +# Testing of EquivObjects +$group = RT::Group->new( $RT::SystemUser ); +ok( $group->LoadQueueRoleGroup( Queue => $queue_id, Type=> 'AdminCc' ), "load queue AdminCc role group" ); +$ace = RT::ACE->new( $RT::SystemUser ); +($ace_id, $msg) = $group->PrincipalObj->GrantRight( Right => 'ModifyTicket', Object => $queue ); +ok( $ace_id, "Granted queue AdminCc role group with ModifyTicket right: $msg" ); +ok( $group->PrincipalObj->HasRight( Right => 'ModifyTicket', Object => $queue ), "role group can modify ticket" ); +ok( !$user->HasRight( Right => 'ModifyTicket', Object => $ticket ), "user is not AdminCc and can't modify ticket" ); +($status, $msg) = $ticket->AddWatcher(Type => 'AdminCc', PrincipalId => $user->PrincipalId); +ok( $status, "successfuly added user as AdminCc"); +ok( $user->HasRight( Right => 'ModifyTicket', Object => $ticket ), "user is AdminCc and can modify ticket" ); + +my $ticket2 = RT::Ticket->new($RT::SystemUser); +my ($ticket2_id) = $ticket2->Create( Queue => $queue_id, Subject => 'test2'); +ok( $ticket2_id, 'new ticket created' ); +ok( !$user->HasRight( Right => 'ModifyTicket', Object => $ticket2 ), "user is not AdminCc and can't modify ticket2" ); + +# now we can finally test EquivObjects +my $equiv = [ $ticket ]; +ok( $user->HasRight( Right => 'ModifyTicket', Object => $ticket2, EquivObjects => $equiv ), + "user is not AdminCc but can modify ticket2 because of EquivObjects" ); + +# the first a third test below are the same, so they should both pass +my $equiv2 = []; +ok( !$user->HasRight( Right => 'ModifyTicket', Object => $ticket2, EquivObjects => $equiv2 ), + "user is not AdminCc and can't modify ticket2" ); +ok( $user->HasRight( Right => 'ModifyTicket', Object => $ticket, EquivObjects => $equiv2 ), + "user is AdminCc and can modify ticket" ); +ok( !$user->HasRight( Right => 'ModifyTicket', Object => $ticket2, EquivObjects => $equiv2 ), + "user is not AdminCc and can't modify ticket2 (same question different answer)" ); diff --git a/rt/t/api/rt.t b/rt/t/api/rt.t new file mode 100644 index 000000000..3c06b5848 --- /dev/null +++ b/rt/t/api/rt.t @@ -0,0 +1,18 @@ + +use strict; +use warnings; +use RT; +use RT::Test 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"); + + +} + +1; diff --git a/rt/t/api/scrip.t b/rt/t/api/scrip.t new file mode 100644 index 000000000..8e8f96213 --- /dev/null +++ b/rt/t/api/scrip.t @@ -0,0 +1,49 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 7; + + +{ + +ok (require RT::Scrip); + + +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 ($val, $msg) =$s1->Create( Queue => $q->Id, + ScripAction => 'User Defined', + ScripCondition => 'User Defined', + CustomIsApplicableCode => 'if ($self->TicketObj->Subject =~ /fire/) { return (1);} else { return(0)}', + CustomPrepareCode => 'return 1', + CustomCommitCode => '$self->TicketObj->SetPriority("87");', + Template => 'Blank' + ); +ok($val,$msg); + +my $ticket = RT::Ticket->new($RT::SystemUser); +my ($tv,$ttv,$tm) = $ticket->Create(Queue => $q->Id, + Subject => "hair on fire", + ); +ok($tv, $tm); + +is ($ticket->Priority , '87', "Ticket priority is set right"); + + +my $ticket2 = RT::Ticket->new($RT::SystemUser); +my ($t2v,$t2tv,$t2m) = $ticket2->Create(Queue => $q->Id, + Subject => "hair in water", + ); +ok($t2v, $t2m); + +isnt ($ticket2->Priority , '87', "Ticket priority is set right"); + + + +} + +1; diff --git a/rt/t/api/scrip_order.t b/rt/t/api/scrip_order.t new file mode 100644 index 000000000..9738db9bc --- /dev/null +++ b/rt/t/api/scrip_order.t @@ -0,0 +1,56 @@ +#!/usr/bin/perl -w + +use strict; + +use RT; +use RT::Test tests => 7; + + +# {{{ test scrip ordering based on description + +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 $id, $msg) = $priority_ten_scrip->Create( + Description => "10 set priority $$", + Queue => $queue_id, + ScripCondition => 'On Create', + ScripAction => 'User Defined', + CustomPrepareCode => '$RT::Logger->debug("Setting priority to 10..."); return 1;', + CustomCommitCode => '$self->TicketObj->SetPriority(10);', + Template => 'Blank', + Stage => 'TransactionCreate', +); +ok($id, "Created priority-10 scrip? ".$msg); + +my $priority_five_scrip = RT::Scrip->new($RT::SystemUser); +($id, $msg) = $priority_ten_scrip->Create( + Description => "05 set priority $$", + Queue => $queue_id, + ScripCondition => 'On Create', + ScripAction => 'User Defined', + CustomPrepareCode => '$RT::Logger->debug("Setting priority to 5..."); return 1;', + CustomCommitCode => '$self->TicketObj->SetPriority(5);', + Template => 'Blank', + Stage => 'TransactionCreate', +); +ok($id, "Created priority-5 scrip? ".$msg); + +my $ticket = RT::Ticket->new($RT::SystemUser); +($id, $msg) = $ticket->Create( + Queue => $queue_id, + Requestor => 'order@example.com', + Subject => "Scrip order test $$", +); +ok($ticket->id, "Created ticket? id=$id"); + +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 new file mode 100644 index 000000000..cb118906c --- /dev/null +++ b/rt/t/api/searchbuilder.t @@ -0,0 +1,40 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 11; + + +{ + +ok (require RT::SearchBuilder); + + +} + +{ + +use_ok('RT::Queues'); +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}; + +ok($queues->NewItem->_Accessible('Name','read')); +my @sorted = sort {lc($a->Name) cmp lc($b->Name)} @items; +ok (@sorted, "We have an array of queues, sorted". join(',',map {$_->Name} @sorted)); + +ok (@items, "We have an array of queues, raw". join(',',map {$_->Name} @items)); +my @sorted_ids = map {$_->id } @sorted; +my @items_ids = map {$_->id } @items; + +is ($#sorted, $#items); +is ($sorted[0]->Name, $items[0]->Name); +is ($sorted[-1]->Name, $items[-1]->Name); +is_deeply(\@items_ids, \@sorted_ids, "ItemsArrayRef sorts alphabetically by name"); + + + +} + +1; diff --git a/rt/t/api/system.t b/rt/t/api/system.t new file mode 100644 index 000000000..3077115c7 --- /dev/null +++ b/rt/t/api/system.t @@ -0,0 +1,33 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 7; + + +{ + +my $s = RT::System->new($RT::SystemUser); +my $rights = $s->AvailableRights; +ok ($rights, "Rights defined"); +ok ($rights->{'AdminUsers'},"AdminUsers right found"); +ok ($rights->{'CreateTicket'},"CreateTicket right found"); +ok ($rights->{'AdminGroupMembership'},"ModifyGroupMembers right found"); +ok (!$rights->{'CasdasdsreateTicket'},"bogus right not found"); + + + + +} + +{ + +use RT::System; +my $sys = RT::System->new(); +is( $sys->Id, 1); +is ($sys->id, 1); + + +} + +1; diff --git a/rt/t/api/template-insert.t b/rt/t/api/template-insert.t new file mode 100644 index 000000000..47bbd790c --- /dev/null +++ b/rt/t/api/template-insert.t @@ -0,0 +1,26 @@ +#!/usr/bin/perl + +use warnings; +use strict; + + +use RT; +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); + +isa_ok($template, 'RT::Template'); +my ($val,$msg) = $template->Create(Queue => 1, + Name => 'InsertTest', + Content => 'This is template content'); +ok($val,$msg); +is($template->Name, 'InsertTest'); +is($template->Content, 'This is template content', "We created the object right"); +($val, $msg) = $template->SetContent( 'This is new template content'); +ok($val,$msg); +is($template->Content, 'This is new template content', "We managed to _Set_ the content"); diff --git a/rt/t/api/template.t b/rt/t/api/template.t new file mode 100644 index 000000000..1612b8ffd --- /dev/null +++ b/rt/t/api/template.t @@ -0,0 +1,26 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 2; + + +{ + +ok(require RT::Template); + + +} + +{ + +my $t = RT::Template->new($RT::SystemUser); +$t->Create(Name => "Foo", Queue => 1); +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 new file mode 100644 index 000000000..2ca0997bd --- /dev/null +++ b/rt/t/api/ticket.t @@ -0,0 +1,257 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 87; + + +{ + +use_ok ('RT::Queue'); +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)); +my ($ret, $cmsg) = $testcf->Create( Name => 'selectmulti', + Queue => $testqueue->id, + Type => 'SelectMultiple'); +ok($ret,"Created the custom field - ".$cmsg); +($ret,$cmsg) = $testcf->AddValue ( Name => 'Value1', + SortOrder => '1', + Description => 'A testing value'); + +ok($ret, "Added a value - ".$cmsg); + +ok($testcf->AddValue ( Name => 'Value2', + SortOrder => '2', + Description => 'Another testing value')); +ok($testcf->AddValue ( Name => 'Value3', + SortOrder => '3', + Description => 'Yet Another testing value')); + +is($testcf->Values->Count , 3); + +use_ok('RT::Ticket'); + +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 ($id, $msg) = $t->Create( Queue => $testqueue->Id, + Subject => 'Testing', + Owner => $u->Id + )); +isnt($id , 0); +is ($t->OwnerObj->Id , $u->Id, "Root is the ticket owner"); +ok(my ($cfv, $cfm) =$t->AddCustomFieldValue(Field => $testcf->Id, + Value => 'Value1')); +isnt($cfv , 0, "Custom field creation didn't return an error: $cfm"); +is($t->CustomFieldValues($testcf->Id)->Count , 1); +ok($t->CustomFieldValues($testcf->Id)->First && + $t->CustomFieldValues($testcf->Id)->First->Content eq 'Value1'); + +ok(my ($cfdv, $cfdm) = $t->DeleteCustomFieldValue(Field => $testcf->Id, + Value => 'Value1')); +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($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 ($id3, $msg3) = $t3->Create( Queue => $testqueue->Id, + Subject => 'Testing', + Owner => $u->Id); +my ($cfv1, $cfm1) = $t->AddCustomFieldValue(Field => $testcf->Id, + Value => 'Value1'); +isnt($cfv1 , 0, "Adding a custom field to ticket 1 is successful: $cfm"); +my ($cfv2, $cfm2) = $t3->AddCustomFieldValue(Field => $testcf->Id, + Value => 'Value2'); +isnt($cfv2 , 0, "Adding a custom field to ticket 2 is successful: $cfm"); +my ($cfv3, $cfm3) = $t->AddCustomFieldValue(Field => $testcf->Id, + Value => 'Value3'); +isnt($cfv3 , 0, "Adding a custom field to ticket 1 is successful: $cfm"); +is($t->CustomFieldValues($testcf->Id)->Count , 2, + "This ticket has 2 custom field values"); +is($t3->CustomFieldValues($testcf->Id)->Count , 1, + "This ticket has 1 custom field value"); + + +} + +{ + + +ok(require RT::Ticket, "Loading the RT::Ticket library"); + + +} + +{ + +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"); + +ok ( my $id = $t->Id, "Got ticket id"); +like ($t->RefersTo->First->Target , qr/fsck.com/, "Got refers to"); +like ($t->ReferredToBy->First->Base , qr/cpan.org/, "Got referredtoby"); +is ($t->ResolvedObj->Unix, 0, "It hasn't been resolved - ". $t->ResolvedObj->Unix); + + +} + +{ + +my $ticket = RT::Ticket->new($RT::SystemUser); +my ($id, $msg) = $ticket->Create(Subject => "Foo", + 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($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"); +$jesse->LoadByEmail('jesse@example.com'); +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"); +$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"); +ok ( ($add_id, $add_msg) = $ticket->DeleteWatcher(Type =>'Requestor', Email => 'bob@fsck.com'), "Added bob at fsck.com as a requestor"); +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); +ok($group->LoadTicketRoleGroup(Ticket => $id, Type=> 'Cc')); +ok ($group->Id, "Found the cc object for this ticket"); +$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); +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'"); + + +} + +{ + +my $t = RT::Ticket->new($RT::SystemUser); +ok($t->Create(Queue => 'general', Subject => 'SquelchTest', SquelchMailTo => 'nobody@example.com')); + +my @returned = $t->SquelchMailTo(); +is($#returned, 0, "The ticket has one squelched recipients"); + +my ($ret, $msg) = $t->UnsquelchMailTo('nobody@example.com'); +ok($ret, "Removed nobody as a squelched recipient - ".$msg); +@returned = $t->SquelchMailTo(); +is($#returned, -1, "The ticket has no squelched recipients". join(',',@returned)); + + + +@returned = $t->SquelchMailTo('nobody@example.com'); +is($#returned, 0, "The ticket has one squelched recipients"); + +my @names = $t->Attributes->Names; +is(shift @names, 'SquelchMailTo', "The attribute we have is SquelchMailTo"); +@returned = $t->SquelchMailTo('nobody@example.com'); + + +is($#returned, 0, "The ticket has one squelched recipients"); + +@names = $t->Attributes->Names; +is(shift @names, 'SquelchMailTo', "The attribute we have is SquelchMailTo"); + + +($ret, $msg) = $t->UnsquelchMailTo('nobody@example.com'); +ok($ret, "Removed nobody as a squelched recipient - ".$msg); +@returned = $t->SquelchMailTo(); +is($#returned, -1, "The ticket has no squelched recipients". join(',',@returned)); + + + +} + +{ + +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); +$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); +is ($t1->id, undef, "ok. we've got a blank ticket1"); +$t1->Load($t1id); + +is ($t1->id, $t2->id); + +is ($t1->Requestors->MembersObj->Count, 2); + + + +} + +{ + +my $root = RT::User->new($RT::SystemUser); +$root->Load('root'); +ok ($root->Id, "Loaded the root user"); +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); +$txns->OrderBy(FIELD => 'id', ORDER => 'DESC'); +$txns->Limit(FIELD => 'ObjectId', VALUE => '1'); +$txns->Limit(FIELD => 'ObjectType', VALUE => 'RT::Ticket'); +$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"); + + +} + +{ + +my $tt = RT::Ticket->new($RT::SystemUser); +my ($id, $tid, $msg)= $tt->Create(Queue => 'general', + Subject => 'test'); +ok($id, $msg); +is($tt->Status, 'new', "New ticket is created as new"); + +($id, $msg) = $tt->SetStatus('open'); +ok($id, $msg); +like($msg, qr/open/i, "Status message is correct"); +($id, $msg) = $tt->SetStatus('resolved'); +ok($id, $msg); +like($msg, qr/resolved/i, "Status message is correct"); +($id, $msg) = $tt->SetStatus('resolved'); +ok(!$id,$msg); + + + +} + +1; diff --git a/rt/t/api/tickets.t b/rt/t/api/tickets.t new file mode 100644 index 000000000..9148a8899 --- /dev/null +++ b/rt/t/api/tickets.t @@ -0,0 +1,104 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 16; + + +{ + +ok (require RT::Tickets); +ok( my $testtickets = RT::Tickets->new( $RT::SystemUser ) ); +ok( $testtickets->LimitStatus( VALUE => 'deleted' ) ); +# Should be zero until 'allow_deleted_search' +is( $testtickets->Count , 0 ); + + +} + +{ + +# Test to make sure that you can search for tickets by requestor address and +# by requestor name. + +my ($id,$msg); +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); +($id, $msg) = $u2->Create( Name => 'RequestorTestTwo', EmailAddress => 'rqtest2@example.com'); +ok ($id,$msg); + +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); +($id,$trans,$msg) =$t2->Create (Queue => 'general', Subject => 'Requestor test one', Requestor => [$u2->EmailAddress]); +ok ($id, $msg); + + +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); +$tix1->FromSQL('Requestor.EmailAddress LIKE "rqtest1" OR Requestor.EmailAddress LIKE "rqtest2"'); + +is ($tix1->Count, 3); + +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); +$tix3->FromSQL('Requestor.EmailAddress LIKE "rqtest1"'); + +is ($tix3->Count, 2); + +my $tix4 = RT::Tickets->new($RT::SystemUser); +$tix4->FromSQL('Requestor.Name LIKE "TestOne" '); + +is ($tix4->Count, 2); + +# Searching for tickets that have two requestors isn't supported +# 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); +# $tix5->FromSQL('Requestor.Name LIKE "TestOne" AND Requestor.Name LIKE "TestTwo"'); +# +# is ($tix5->Count, 1); +# +# my $tix6 = RT::Tickets->new($RT::SystemUser); +# $tix6->FromSQL('Requestor.EmailAddress LIKE "rqtest1" AND Requestor.EmailAddress LIKE "rqtest2"'); +# +# is ($tix6->Count, 1); + + + +} + +{ + +my $t1 = RT::Ticket->new($RT::SystemUser); +$t1->Create(Queue => 'general', Subject => "LimitWatchers test", Requestors => \['requestor1@example.com']); + + +} + +{ + +# We assume that we've got some tickets hanging around from before. +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 new file mode 100644 index 000000000..798088664 --- /dev/null +++ b/rt/t/api/tickets_overlay_sql.t @@ -0,0 +1,73 @@ + +use RT; +use RT::Test tests => 7; + + +{ + +use RT::Tickets; +use strict; + +my $tix = RT::Tickets->new($RT::SystemUser); +{ + my $query = "Status = 'open'"; + my ($status, $msg) = $tix->FromSQL($query); + ok ($status, "correct query") or diag("error: $msg"); +} + + +my (@created,%created); +my $string = 'subject/content SQL test'; +{ + my $t = RT::Ticket->new($RT::SystemUser); + ok( $t->Create(Queue => 'General', Subject => $string), "Ticket Created"); + $created{ $t->Id }++; push @created, $t->Id; +} + +{ + my $Message = MIME::Entity->build( + Subject => 'this is my subject', + From => 'jesse@example.com', + Data => [ $string ], + ); + + my $t = RT::Ticket->new($RT::SystemUser); + ok( $t->Create( Queue => 'General', + Subject => 'another ticket', + MIMEObj => $Message, + MemberOf => $created[0] + ), + "Ticket Created" + ); + $created{ $t->Id }++; push @created, $t->Id; +} + +{ + my $query = ("Subject LIKE '$string' OR Content LIKE '$string'"); + my ($status, $msg) = $tix->FromSQL($query); + ok ($status, "correct query") or diag("error: $msg"); + + my $count = 0; + while (my $tick = $tix->Next) { + $count++ if $created{ $tick->id }; + } + is ($count, scalar @created, "number of returned tickets same as entered"); +} + +{ + my $query = "id = $created[0] OR MemberOf = $created[0]"; + my ($status, $msg) = $tix->FromSQL($query); + ok ($status, "correct query") or diag("error: $msg"); + + my $count = 0; + while (my $tick = $tix->Next) { + $count++ if $created{ $tick->id }; + } + is ($count, scalar @created, "number of returned tickets same as entered"); +} + + + +} + +1; diff --git a/rt/t/api/uri-fsck_com_rt.t b/rt/t/api/uri-fsck_com_rt.t new file mode 100644 index 000000000..d62e58022 --- /dev/null +++ b/rt/t/api/uri-fsck_com_rt.t @@ -0,0 +1,28 @@ +use strict; +use warnings; +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 $t1 = RT::Ticket->new($RT::SystemUser); +my ($id,$trans,$msg) =$t1->Create (Queue => 'general', Subject => 'Requestor test one', ); +ok ($id, $msg); + +ok(ref($uri)); + +ok (UNIVERSAL::isa($uri,"RT::URI::fsck_com_rt"), "It's an RT::URI::fsck_com_rt"); + +ok ($uri->isa('RT::URI::base'), "It's an RT::URI::base"); +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); +$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 new file mode 100644 index 000000000..4695629bb --- /dev/null +++ b/rt/t/api/uri-t.t @@ -0,0 +1,21 @@ +use strict; +use warnings; +use RT; +use RT::Test tests => 6; + +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); +ok(ref($uri), "URI object exists"); + +my $uristr = "t:1"; +$uri->ParseURI($uristr); +is(ref($uri->Object), "RT::Ticket", "Object loaded is a ticket"); +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 new file mode 100644 index 000000000..25cf74773 --- /dev/null +++ b/rt/t/api/user.t @@ -0,0 +1,339 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 108; + + +{ + +ok(require RT::User); + + +} + +{ + +# Make sure we can create a user + +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); +($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); +($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); +($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); +($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); +($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); +($id, $msg) = $u7->Create(Name => 'CreateTest7'.$$, EmailAddress => ''); +ok ($id, $msg); + +# Can we change the email address away from from ""; +($id,$msg) = $u7->SetEmailAddress('foo@bar'.$$); +ok ($id, $msg); +# can we change the address back to ""; +($id,$msg) = $u7->SetEmailAddress(''); +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); +($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); +($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); +($id, $msg) = $u10->Create(Name => 'CreateTest10'.$$, EmailAddress => $$.'create-test10}@[.com'); +ok (!$id, $msg); +RT->Config->Set('ValidateUserEmailAddresses' => undef); + +} + +{ + + +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)); +is ($v ,1, "Set unprivileged suceeded ($m)"); +ok(!$user->Privileged, "User 'root' is no longer privileged"); +ok(my ($v2,$m2) = $user->SetPrivileged(1)); +is ($v2 ,1, "Set privileged suceeded ($m2"); +ok($user->Privileged, "User 'root' is privileged again"); + + +} + +{ + +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"); + + +} + +{ + +my $root = RT::User->new($RT::SystemUser); +$root->Load('root'); +ok($root->Id, "Found the root user"); +my $rootq = RT::Queue->new($root); +$rootq->Load(1); +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 ($id, $msg) = $new_user->Create(Name => 'ACLTest'.$$); + +ok ($id, "Created a new user for acl test $msg"); + +my $q = RT::Queue->new($new_user); +$q->Load(1); +ok($q->Id, "Loaded the first queue"); + + +ok (!$q->CurrentUser->HasRight(Right => 'CreateTicket', Object => $q), "Some random user doesn't have the right to create tickets"); +ok (my ($gval, $gmsg) = $new_user->PrincipalObj->GrantRight( Right => 'CreateTicket', Object => $q), "Granted the random user the right to create tickets"); +ok ($gval, "Grant succeeded - $gmsg"); + + +ok ($q->CurrentUser->HasRight(Right => 'CreateTicket', Object => $q), "The user can create tickets after we grant him the right"); +ok ( ($gval, $gmsg) = $new_user->PrincipalObj->RevokeRight( Right => 'CreateTicket', Object => $q), "revoked the random user the right to create tickets"); +ok ($gval, "Revocation succeeded - $gmsg"); +ok (!$q->CurrentUser->HasRight(Right => 'CreateTicket', Object => $q), "The user can't create tickets anymore"); + + + + + +# Create a ticket in the queue +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); +$group->CreateUserDefinedGroup(Name => 'ACLTest'.$$); +ok($group->Id, "Created a new group Ok"); +# Grant a group the right to modify tickets in a queue +ok(my ($gv,$gm) = $group->PrincipalObj->GrantRight( Object => $q, Right => 'ModifyTicket'),"Granted the group the right to modify tickets"); +ok($gv,"Grant succeeed - $gm"); +# Add the user to the group +ok( my ($aid, $amsg) = $group->AddMember($new_user->PrincipalId), "Added the member to the group"); +ok ($aid, "Member added to group: $amsg"); +# Make sure the user does have the right to modify tickets in the queue +ok ($new_user->HasRight( Object => $new_tick, Right => 'ModifyTicket'), "User can modify the ticket with group membership"); + + +# Remove the user from the group +ok( my ($did, $dmsg) = $group->DeleteMember($new_user->PrincipalId), "Deleted the member from the group"); +ok ($did,"Deleted the group member: $dmsg"); +# 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"); + + +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 $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"); + + +# make sure that the user can't do this without subgroup membership +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); +$subgroup->CreateUserDefinedGroup(Name => 'Subgrouptest'.$$); +ok($subgroup->Id, "Created a new group ".$subgroup->Id."Ok"); +#Add the subgroup as a subgroup of the group +my ($said, $samsg) = $group->AddMember($subgroup->PrincipalId); +ok ($said, "Added the subgroup as a member of the group"); +# Add the user to a subgroup of the group + +my ($usaid, $usamsg) = $subgroup->AddMember($new_user->PrincipalId); +ok($usaid,"Added the user ".$new_user->Id."to the subgroup"); +# Make sure the user does have the right to modify tickets in the queue +ok ($new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can modify the ticket with subgroup membership"); + +# {{{ Deal with making sure that members of subgroups of a disabled group don't have rights + +($id, $msg) = $group->SetDisabled(1); +ok ($id,$msg); +ok (!$new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can't modify the ticket when the group ".$group->Id. " is disabled"); + ($id, $msg) = $group->SetDisabled(0); +ok($id,$msg); +# Test what happens when we disable the group the user is a member of directly + +($id, $msg) = $subgroup->SetDisabled(1); + ok ($id,$msg); +ok (!$new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can't modify the ticket when the group ".$subgroup->Id. " is disabled"); + ($id, $msg) = $subgroup->SetDisabled(0); + 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); +ok($usrid,"removed the user from the group - $usrmsg"); +# 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"); + +#revoke the right to modify tickets in a queue +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"); +ok($qv, "Granted the right successfully - $qm"); + +# Add the user as a queue admincc +ok (my ($add_id, $add_msg) = $q_as_system->AddWatcher(Type => 'AdminCc', PrincipalId => $new_user->PrincipalId) , "Added the new user as a queue admincc"); +ok ($add_id, "the user is now a queue admincc - $add_msg"); + +# Make sure the user does have the right to modify tickets in the queue +ok ($new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can modify the ticket as an admincc"); +# Remove the user from the role group +ok (my ($del_id, $del_msg) = $q_as_system->DeleteWatcher(Type => 'AdminCc', PrincipalId => $new_user->PrincipalId) , "Deleted the new user as a queue admincc"); + +# 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"); +ok ($add_id, "the user is now a queue admincc - $add_msg"); + +# Make sure the user does have the right to modify tickets in the queue +ok ($new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can modify the ticket as an admincc"); + +# Remove the user from the role group +ok (( $del_id, $del_msg) = $new_tick2->DeleteWatcher(Type => 'AdminCc', PrincipalId => $new_user->PrincipalId) , "Deleted the new user as a queue admincc"); + +# 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"); + + +# Revoke the right to modify ticket in the queue +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"); +ok (!$new_user->HasRight( Object => $new_tick2->QueueObj, Right => 'ModifyTicket'), "User can not modify tickets in the queue without it being granted"); + +# Grant queue admin cc the right to modify ticket in the queue +ok(($qv,$qm) = $q_as_system->AdminCc->PrincipalObj->GrantRight( Object => $RT::System, Right => 'ModifyTicket'),"Granted the queue adminccs the right to modify tickets"); +ok($qv, "Granted the right successfully - $qm"); + +# Make sure the user can't modify the ticket before they're added as a watcher +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 without being an admincc"); + +# Add the user as a queue admincc +ok (($add_id, $add_msg) = $q_as_system->AddWatcher(Type => 'AdminCc', PrincipalId => $new_user->PrincipalId) , "Added the new user as a queue admincc"); +ok ($add_id, "the user is now a queue admincc - $add_msg"); + +# Make sure the user does have the right to modify tickets in the queue +ok ($new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can modify the ticket as an admincc"); +ok ($new_user->HasRight( Object => $new_tick2->QueueObj, Right => 'ModifyTicket'), "User can modify tickets in the queue as an admincc"); +# Remove the user from the role group +ok (($del_id, $del_msg) = $q_as_system->DeleteWatcher(Type => 'AdminCc', PrincipalId => $new_user->PrincipalId) , "Deleted the new user as a queue admincc"); + +# 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"); +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"); + + +# Add the user as a ticket admincc +ok ( ($uadd_id, $uadd_msg) = $new_tick2->AddWatcher(Type => 'AdminCc', PrincipalId => $new_user->PrincipalId) , "Added the new user as a queue admincc"); +ok ($add_id, "the user is now a queue admincc - $add_msg"); + +# Make sure the user does have the right to modify tickets in the queue +ok ($new_user->HasRight( Object => $new_tick2, Right => 'ModifyTicket'), "User can modify the ticket as an admincc"); +ok (!$new_user->HasRight( Object => $new_tick2->QueueObj, Right => 'ModifyTicket'), "User can not modify tickets in the queue obj being only a ticket admincc"); + +# Remove the user from the role group +ok ( ($del_id, $del_msg) = $new_tick2->DeleteWatcher(Type => 'AdminCc', PrincipalId => $new_user->PrincipalId) , "Deleted the new user as a queue admincc"); + +# 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 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"); + + +# Revoke the right to modify ticket in the queue +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"); + +# }}} + + + + +# Grant "privileged users" the system right to create users +# Create a privileged user. +# have that user create another user +# Revoke the right for privileged users to create users +# have the privileged user try to create another user and fail the ACL check + + +} + +1; diff --git a/rt/t/api/users.t b/rt/t/api/users.t new file mode 100644 index 000000000..d1ff174e1 --- /dev/null +++ b/rt/t/api/users.t @@ -0,0 +1,80 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => 11; + + +{ + +ok(require RT::Users); + + +} + +{ + no warnings qw(redefine once); + +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 ($id, $msg) = $RTxUser->Create( Name => 'RTxUser', Comments => "RTx extension user", Privileged => 1); +ok ($id,$msg); + +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); +$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 ); +ok ($id, "ACL for RTxSysObj created"); + +my $RTxObj = {}; +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->WhoHaveRight(Right => 'RTxUserRight', Object => $RTxSysObj); +is($users->Count, 1, "RTxUserRight found for RTxSysObj"); + +$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->WhoHaveRight(Right => 'RTxUserRight', Object => $RTxObj, EquivObjects => [ $RTxSysObj ]); +is($users->Count, 1, "RTxUserRight found for RTxObj using EquivObjects"); + +$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 ); +ok ($id, "ACL for RTxObj created"); + +my $RTxObj2 = {}; +bless $RTxObj2, 'RTx::System::Record'; +*RTx::System::Record::Id = sub { 5; }; +*RTx::System::Record::id = sub { 5; }; + +$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->WhoHaveRight(Right => 'RTxUserRight', Object => $RTxObj2, EquivObjects => [ $RTxSysObj ]); +is($users->Count, 1, "RTxUserRight found for RTxObj2"); + + + +} + +1; |