use strict; use warnings; BEGIN { $ENV{'LANG'} = 'C' } use RT; use RT::User; use RT::Group; use RT::Ticket; use RT::Queue; use RT::Test tests => 27; use_ok('RT::SavedSearch'); use_ok('RT::SavedSearches'); use Test::Warn; # Set up some infrastructure. These calls are tested elsewhere. my $searchuser = RT::User->new($RT::SystemUser); my ($ret, $msg) = $searchuser->Create(Name => 'searchuser'.$$, Privileged => 1, EmailAddress => "searchuser\@p$$.example.com", RealName => 'Search user'); ok($ret, "created searchuser: $msg"); $searchuser->PrincipalObj->GrantRight(Right => 'LoadSavedSearch'); $searchuser->PrincipalObj->GrantRight(Right => 'CreateSavedSearch'); $searchuser->PrincipalObj->GrantRight(Right => 'ModifySelf'); # This is the group whose searches searchuser should be able to see. my $ingroup = RT::Group->new($RT::SystemUser); $ingroup->CreateUserDefinedGroup(Name => 'searchgroup1'.$$); $ingroup->AddMember($searchuser->Id); $searchuser->PrincipalObj->GrantRight(Right => 'EditSavedSearches', Object => $ingroup); $searchuser->PrincipalObj->GrantRight(Right => 'ShowSavedSearches', Object => $ingroup); # This is the group whose searches searchuser should not be able to see. my $outgroup = RT::Group->new($RT::SystemUser); $outgroup->CreateUserDefinedGroup(Name => 'searchgroup2'.$$); $outgroup->AddMember($RT::SystemUser->Id); my $queue = RT::Queue->new($RT::SystemUser); $queue->Create(Name => 'SearchQueue'.$$); $searchuser->PrincipalObj->GrantRight(Right => 'SeeQueue', Object => $queue); $searchuser->PrincipalObj->GrantRight(Right => 'ShowTicket', Object => $queue); $searchuser->PrincipalObj->GrantRight(Right => 'OwnTicket', Object => $queue); my $ticket = RT::Ticket->new($RT::SystemUser); $ticket->Create(Queue => $queue->Id, Requestor => [ $searchuser->Name ], Owner => $searchuser, Subject => 'saved search test'); # Now start the search madness. my $curruser = RT::CurrentUser->new($searchuser); my $format = '\' __id__/TITLE:#\', \'__Subject__/TITLE:Subject\', \'__Status__\', \'__QueueName__\', \'__OwnerName__\', \'__Priority__\', \'__NEWLINE__\', \'\', \'__Requestors__\', \'__CreatedRelative__\', \'__ToldRelative__\', \'__LastUpdatedRelative__\', \'__TimeLeft__\''; my $mysearch = RT::SavedSearch->new($curruser); ($ret, $msg) = $mysearch->Save(Privacy => 'RT::User-' . $searchuser->Id, Type => 'Ticket', Name => 'owned by me', SearchParams => {'Format' => $format, 'Query' => "Owner = '" . $searchuser->Name . "'"}); ok($ret, "mysearch was created"); my $groupsearch = RT::SavedSearch->new($curruser); ($ret, $msg) = $groupsearch->Save(Privacy => 'RT::Group-' . $ingroup->Id, Type => 'Ticket', Name => 'search queue', SearchParams => {'Format' => $format, 'Query' => "Queue = '" . $queue->Name . "'"}); ok($ret, "groupsearch was created"); my $othersearch = RT::SavedSearch->new($curruser); ($ret, $msg) = $othersearch->Save(Privacy => 'RT::Group-' . $outgroup->Id, Type => 'Ticket', Name => 'searchuser requested', SearchParams => {'Format' => $format, 'Query' => "Requestor.Name LIKE 'search'"}); ok(!$ret, "othersearch NOT created"); like($msg, qr/Failed to load object for/, "...for the right reason"); $othersearch = RT::SavedSearch->new($RT::SystemUser); ($ret, $msg) = $othersearch->Save(Privacy => 'RT::Group-' . $outgroup->Id, Type => 'Ticket', Name => 'searchuser requested', SearchParams => {'Format' => $format, 'Query' => "Requestor.Name LIKE 'search'"}); ok($ret, "othersearch created by systemuser"); # Now try to load some searches. # This should work. my $loadedsearch1 = RT::SavedSearch->new($curruser); $loadedsearch1->Load('RT::User-'.$curruser->Id, $mysearch->Id); is($loadedsearch1->Id, $mysearch->Id, "Loaded mysearch"); like($loadedsearch1->GetParameter('Query'), qr/Owner/, "Retrieved query of mysearch"); # Check through the other accessor methods. is($loadedsearch1->Privacy, 'RT::User-' . $curruser->Id, "Privacy of mysearch correct"); is($loadedsearch1->Name, 'owned by me', "Name of mysearch correct"); is($loadedsearch1->Type, 'Ticket', "Type of mysearch correct"); # See if it can be used to search for tickets. my $tickets = RT::Tickets->new($curruser); $tickets->FromSQL($loadedsearch1->GetParameter('Query')); is($tickets->Count, 1, "Found a ticket"); # This should fail -- wrong object. # my $loadedsearch2 = RT::SavedSearch->new($curruser); # $loadedsearch2->Load('RT::User-'.$curruser->Id, $groupsearch->Id); # isnt($loadedsearch2->Id, $othersearch->Id, "Didn't load groupsearch as mine"); # ...but this should succeed. my $loadedsearch3 = RT::SavedSearch->new($curruser); $loadedsearch3->Load('RT::Group-'.$ingroup->Id, $groupsearch->Id); is($loadedsearch3->Id, $groupsearch->Id, "Loaded groupsearch"); like($loadedsearch3->GetParameter('Query'), qr/Queue/, "Retrieved query of groupsearch"); # Can it get tickets? $tickets = RT::Tickets->new($curruser); $tickets->FromSQL($loadedsearch3->GetParameter('Query')); is($tickets->Count, 1, "Found a ticket"); # This should fail -- no permission. my $loadedsearch4 = RT::SavedSearch->new($curruser); warning_like { $loadedsearch4->Load($othersearch->Privacy, $othersearch->Id); } qr/Could not load object RT::Group-\d+ when loading search/; isnt($loadedsearch4->Id, $othersearch->Id, "Did not load othersearch"); # Try to update an existing search. $loadedsearch1->Update( SearchParams => {'Format' => $format, 'Query' => "Queue = '" . $queue->Name . "'" } ); like($loadedsearch1->GetParameter('Query'), qr/Queue/, "Updated mysearch parameter"); is($loadedsearch1->Type, 'Ticket', "mysearch is still for tickets"); is($loadedsearch1->Privacy, 'RT::User-'.$curruser->Id, "mysearch still belongs to searchuser"); like($mysearch->GetParameter('Query'), qr/Queue/, "other mysearch object updated"); ## Right ho. Test the pseudo-collection object. my $genericsearch = RT::SavedSearch->new($curruser); $genericsearch->Save(Name => 'generic search', Type => 'all', SearchParams => {'Query' => "Queue = 'General'"}); my $ticketsearches = RT::SavedSearches->new($curruser); $ticketsearches->LimitToPrivacy('RT::User-'.$curruser->Id, 'Ticket'); is($ticketsearches->Count, 1, "Found searchuser's ticket searches"); my $allsearches = RT::SavedSearches->new($curruser); $allsearches->LimitToPrivacy('RT::User-'.$curruser->Id); is($allsearches->Count, 2, "Found all searchuser's searches"); # Delete a search. ($ret, $msg) = $genericsearch->Delete; ok($ret, "Deleted genericsearch"); $allsearches->LimitToPrivacy('RT::User-'.$curruser->Id); is($allsearches->Count, 1, "Found all searchuser's searches after deletion");