first pass RT4 merge, RT#13852
[freeside.git] / rt / t / api / savedsearch.t
1 use strict;
2 use warnings;
3 BEGIN { $ENV{'LANG'} = 'C' }
4
5 use RT::Test tests => 27;
6
7 use_ok('RT::SavedSearch');
8 use_ok('RT::SavedSearches');
9
10 use Test::Warn;
11
12 # Set up some infrastructure.  These calls are tested elsewhere.
13
14 my $searchuser = RT::User->new(RT->SystemUser);
15 my ($ret, $msg) = $searchuser->Create(Name => 'searchuser'.$$,
16                     Privileged => 1,
17                     EmailAddress => "searchuser\@p$$.example.com",
18                     RealName => 'Search user');
19 ok($ret, "created searchuser: $msg");
20 $searchuser->PrincipalObj->GrantRight(Right => 'LoadSavedSearch');
21 $searchuser->PrincipalObj->GrantRight(Right => 'CreateSavedSearch');
22 $searchuser->PrincipalObj->GrantRight(Right => 'ModifySelf');
23
24 # This is the group whose searches searchuser should be able to see.
25 my $ingroup = RT::Group->new(RT->SystemUser);
26 $ingroup->CreateUserDefinedGroup(Name => 'searchgroup1'.$$);
27 $ingroup->AddMember($searchuser->Id);
28 $searchuser->PrincipalObj->GrantRight(Right => 'EditSavedSearches',
29                                       Object => $ingroup);
30 $searchuser->PrincipalObj->GrantRight(Right => 'ShowSavedSearches',
31                                       Object => $ingroup);
32
33 # This is the group whose searches searchuser should not be able to see.
34 my $outgroup = RT::Group->new(RT->SystemUser);
35 $outgroup->CreateUserDefinedGroup(Name => 'searchgroup2'.$$);
36 $outgroup->AddMember(RT->SystemUser->Id);
37
38 my $queue = RT::Queue->new(RT->SystemUser);
39 $queue->Create(Name => 'SearchQueue'.$$);
40 $searchuser->PrincipalObj->GrantRight(Right => 'SeeQueue', Object => $queue);
41 $searchuser->PrincipalObj->GrantRight(Right => 'ShowTicket', Object => $queue);
42 $searchuser->PrincipalObj->GrantRight(Right => 'OwnTicket', Object => $queue);
43
44
45 my $ticket = RT::Ticket->new(RT->SystemUser);
46 $ticket->Create(Queue => $queue->Id,
47                 Requestor => [ $searchuser->Name ],
48                 Owner => $searchuser,
49                 Subject => 'saved search test');
50
51
52 # Now start the search madness.
53 my $curruser = RT::CurrentUser->new($searchuser);
54 my $format = '\'   <b><a href="/Ticket/Display.html?id=__id__">__id__</a></b>/TITLE:#\',
55 \'<b><a href="/Ticket/Display.html?id=__id__">__Subject__</a></b>/TITLE:Subject\',
56 \'__Status__\',
57 \'__QueueName__\',
58 \'__OwnerName__\',
59 \'__Priority__\',
60 \'__NEWLINE__\',
61 \'\',
62 \'<small>__Requestors__</small>\',
63 \'<small>__CreatedRelative__</small>\',
64 \'<small>__ToldRelative__</small>\',
65 \'<small>__LastUpdatedRelative__</small>\',
66 \'<small>__TimeLeft__</small>\'';
67
68 my $mysearch = RT::SavedSearch->new($curruser);
69 ($ret, $msg) = $mysearch->Save(Privacy => 'RT::User-' . $searchuser->Id,
70                                Type => 'Ticket',
71                                Name => 'owned by me',
72                                SearchParams => {'Format' => $format,
73                                                 'Query' => "Owner = '" 
74                                                     . $searchuser->Name 
75                                                     . "'"});
76 ok($ret, "mysearch was created");
77
78
79 my $groupsearch = RT::SavedSearch->new($curruser);
80 ($ret, $msg) = $groupsearch->Save(Privacy => 'RT::Group-' . $ingroup->Id,
81                                   Type => 'Ticket',
82                                   Name => 'search queue',
83                                   SearchParams => {'Format' => $format,
84                                                    'Query' => "Queue = '"
85                                                        . $queue->Name . "'"});
86 ok($ret, "groupsearch was created");
87
88 my $othersearch = RT::SavedSearch->new($curruser);
89 ($ret, $msg) = $othersearch->Save(Privacy => 'RT::Group-' . $outgroup->Id,
90                                   Type => 'Ticket',
91                                   Name => 'searchuser requested',
92                                   SearchParams => {'Format' => $format,
93                                                    'Query' => 
94                                                        "Requestor.Name LIKE 'search'"});
95 ok(!$ret, "othersearch NOT created");
96 like($msg, qr/Failed to load object for/, "...for the right reason");
97
98 $othersearch = RT::SavedSearch->new(RT->SystemUser);
99 ($ret, $msg) = $othersearch->Save(Privacy => 'RT::Group-' . $outgroup->Id,
100                                   Type => 'Ticket',
101                                   Name => 'searchuser requested',
102                                   SearchParams => {'Format' => $format,
103                                                    'Query' => 
104                                                        "Requestor.Name LIKE 'search'"});
105 ok($ret, "othersearch created by systemuser");
106
107 # Now try to load some searches.
108
109 # This should work.
110 my $loadedsearch1 = RT::SavedSearch->new($curruser);
111 $loadedsearch1->Load('RT::User-'.$curruser->Id, $mysearch->Id);
112 is($loadedsearch1->Id, $mysearch->Id, "Loaded mysearch");
113 like($loadedsearch1->GetParameter('Query'), qr/Owner/, 
114      "Retrieved query of mysearch");
115 # Check through the other accessor methods.
116 is($loadedsearch1->Privacy, 'RT::User-' . $curruser->Id,
117    "Privacy of mysearch correct");
118 is($loadedsearch1->Name, 'owned by me', "Name of mysearch correct");
119 is($loadedsearch1->Type, 'Ticket', "Type of mysearch correct");
120
121 # See if it can be used to search for tickets.
122 my $tickets = RT::Tickets->new($curruser);
123 $tickets->FromSQL($loadedsearch1->GetParameter('Query'));
124 is($tickets->Count, 1, "Found a ticket");
125
126 # This should fail -- wrong object.
127 # my $loadedsearch2 = RT::SavedSearch->new($curruser);
128 # $loadedsearch2->Load('RT::User-'.$curruser->Id, $groupsearch->Id);
129 # isnt($loadedsearch2->Id, $othersearch->Id, "Didn't load groupsearch as mine");
130 # ...but this should succeed.
131 my $loadedsearch3 = RT::SavedSearch->new($curruser);
132 $loadedsearch3->Load('RT::Group-'.$ingroup->Id, $groupsearch->Id);
133 is($loadedsearch3->Id, $groupsearch->Id, "Loaded groupsearch");
134 like($loadedsearch3->GetParameter('Query'), qr/Queue/,
135      "Retrieved query of groupsearch");
136 # Can it get tickets?
137 $tickets = RT::Tickets->new($curruser);
138 $tickets->FromSQL($loadedsearch3->GetParameter('Query'));
139 is($tickets->Count, 1, "Found a ticket");
140
141 # This should fail -- no permission.
142 my $loadedsearch4 = RT::SavedSearch->new($curruser);
143
144 warning_like {
145     $loadedsearch4->Load($othersearch->Privacy, $othersearch->Id);
146 } qr/Could not load object RT::Group-\d+ when loading search/;
147
148 isnt($loadedsearch4->Id, $othersearch->Id, "Did not load othersearch");
149
150 # Try to update an existing search.
151 $loadedsearch1->Update( SearchParams => {'Format' => $format,
152                         'Query' => "Queue = '" . $queue->Name . "'" } );
153 like($loadedsearch1->GetParameter('Query'), qr/Queue/,
154      "Updated mysearch parameter");
155 is($loadedsearch1->Type, 'Ticket', "mysearch is still for tickets");
156 is($loadedsearch1->Privacy, 'RT::User-'.$curruser->Id,
157    "mysearch still belongs to searchuser");
158 like($mysearch->GetParameter('Query'), qr/Queue/, "other mysearch object updated");
159
160
161 ## Right ho.  Test the pseudo-collection object.
162
163 my $genericsearch = RT::SavedSearch->new($curruser);
164 $genericsearch->Save(Name => 'generic search',
165                      Type => 'all',
166                      SearchParams => {'Query' => "Queue = 'General'"});
167
168 my $ticketsearches = RT::SavedSearches->new($curruser);
169 $ticketsearches->LimitToPrivacy('RT::User-'.$curruser->Id, 'Ticket');
170 is($ticketsearches->Count, 1, "Found searchuser's ticket searches");
171
172 my $allsearches = RT::SavedSearches->new($curruser);
173 $allsearches->LimitToPrivacy('RT::User-'.$curruser->Id);
174 is($allsearches->Count, 2, "Found all searchuser's searches");
175
176 # Delete a search.
177 ($ret, $msg) = $genericsearch->Delete;
178 ok($ret, "Deleted genericsearch");
179 $allsearches->LimitToPrivacy('RT::User-'.$curruser->Id);
180 is($allsearches->Count, 1, "Found all searchuser's searches after deletion");
181