5 use RT::Test tests => '101';
8 use_ok('RT::ScripConditions');
9 use_ok('RT::ScripActions');
10 use_ok('RT::Template');
15 use File::Temp qw/tempfile/;
16 my ($fh, $filename) = tempfile( UNLINK => 1, SUFFIX => '.rt');
17 my $link_scrips_orig = RT->Config->Get( 'LinkTransactionsRun1Scrip' );
18 RT->Config->Set( 'LinkTransactionsRun1Scrip', 1 );
20 my $link_acl_checks_orig = RT->Config->Get( 'StrictLinkACL' );
21 RT->Config->Set( 'StrictLinkACL', 1);
23 my $condition = RT::ScripCondition->new( $RT::SystemUser );
24 $condition->Load('User Defined');
26 my $action = RT::ScripAction->new( $RT::SystemUser );
27 $action->Load('User Defined');
29 my $template = RT::Template->new( $RT::SystemUser );
30 $template->Load('Blank');
33 my $q1 = RT::Queue->new($RT::SystemUser);
34 my ($id,$msg) = $q1->Create(Name => "LinkTest1.$$");
36 my $q2 = RT::Queue->new($RT::SystemUser);
37 ($id,$msg) = $q2->Create(Name => "LinkTest2.$$");
40 my $commit_code = <<END;
41 open( my \$file, '<', "$filename" ) or die "couldn't open $filename";
46 \$RT::Logger->debug("Data is \$data");
48 open( \$file, '>', "$filename" ) or die "couldn't open $filename";
49 if (\$self->TransactionObj->Type eq 'AddLink') {
50 \$RT::Logger->debug("AddLink");
51 print \$file \$data+1, "\n";
53 elsif (\$self->TransactionObj->Type eq 'DeleteLink') {
54 \$RT::Logger->debug("DeleteLink");
55 print \$file \$data-1, "\n";
58 \$RT::Logger->error("THIS SHOULDN'T HAPPEN");
65 my $Scrips = RT::Scrips->new( $RT::SystemUser );
67 while ( my $Scrip = $Scrips->Next ) {
68 $Scrip->Delete if $Scrip->Description and $Scrip->Description =~ /Add or Delete Link \d+/;
72 my $scrip = RT::Scrip->new($RT::SystemUser);
73 ($id,$msg) = $scrip->Create( Description => "Add or Delete Link $$",
74 ScripCondition => $condition->id,
75 ScripAction => $action->id,
76 Template => $template->id,
77 Stage => 'TransactionCreate',
79 CustomIsApplicableCode => '$self->TransactionObj->Type =~ /(Add|Delete)Link/;',
80 CustomPrepareCode => '1;',
81 CustomCommitCode => $commit_code,
83 ok($id, "Scrip created");
85 my $u1 = RT::User->new($RT::SystemUser);
86 ($id,$msg) = $u1->Create(Name => "LinkTestUser.$$");
89 # grant ShowTicket right to allow count transactions
90 ($id,$msg) = $u1->PrincipalObj->GrantRight ( Object => $q1, Right => 'ShowTicket');
92 ($id,$msg) = $u1->PrincipalObj->GrantRight ( Object => $q2, Right => 'ShowTicket');
94 ($id,$msg) = $u1->PrincipalObj->GrantRight ( Object => $q1, Right => 'CreateTicket');
97 my $creator = RT::CurrentUser->new($u1->id);
99 diag('Create tickets without rights to link') if $ENV{'TEST_VERBOSE'};
101 # on q2 we have no rights, yet
102 my $parent = RT::Ticket->new( $RT::SystemUser );
103 my ($id,$tid,$msg) = $parent->Create( Subject => 'Link test 1', Queue => $q2->id );
105 my $child = RT::Ticket->new( $creator );
106 ($id,$tid,$msg) = $child->Create( Subject => 'Link test 1', Queue => $q1->id, MemberOf => $parent->id );
108 $child->CurrentUser( $RT::SystemUser );
109 is($child->_Links('Base')->Count, 0, 'link was not created, no permissions');
110 is($child->_Links('Target')->Count, 0, 'link was not create, no permissions');
113 diag('Create tickets with rights checks on one end of a link') if $ENV{'TEST_VERBOSE'};
115 # on q2 we have no rights, but use checking one only on thing
116 RT->Config->Set( StrictLinkACL => 0 );
117 my $parent = RT::Ticket->new( $RT::SystemUser );
118 my ($id,$tid,$msg) = $parent->Create( Subject => 'Link test 1', Queue => $q2->id );
120 my $child = RT::Ticket->new( $creator );
121 ($id,$tid,$msg) = $child->Create( Subject => 'Link test 1', Queue => $q1->id, MemberOf => $parent->id );
123 $child->CurrentUser( $RT::SystemUser );
124 is($child->_Links('Base')->Count, 1, 'link was created');
125 is($child->_Links('Target')->Count, 0, 'link was created only one');
126 # no scrip run on second ticket accroding to config option
127 is(link_count($filename), undef, "scrips ok");
128 RT->Config->Set( StrictLinkACL => 1 );
131 ($id,$msg) = $u1->PrincipalObj->GrantRight ( Object => $q1, Right => 'ModifyTicket');
134 diag('try to add link without rights') if $ENV{'TEST_VERBOSE'};
136 # on q2 we have no rights, yet
137 my $parent = RT::Ticket->new( $RT::SystemUser );
138 my ($id,$tid,$msg) = $parent->Create( Subject => 'Link test 1', Queue => $q2->id );
140 my $child = RT::Ticket->new( $creator );
141 ($id,$tid,$msg) = $child->Create( Subject => 'Link test 1', Queue => $q1->id );
143 ($id, $msg) = $child->AddLink(Type => 'MemberOf', Target => $parent->id);
145 is(link_count($filename), undef, "scrips ok");
146 $child->CurrentUser( $RT::SystemUser );
147 is($child->_Links('Base')->Count, 0, 'link was not created, no permissions');
148 is($child->_Links('Target')->Count, 0, 'link was not create, no permissions');
151 diag('add link with rights only on base') if $ENV{'TEST_VERBOSE'};
153 # on q2 we have no rights, but use checking one only on thing
154 RT->Config->Set( StrictLinkACL => 0 );
155 my $parent = RT::Ticket->new( $RT::SystemUser );
156 my ($id,$tid,$msg) = $parent->Create( Subject => 'Link test 1', Queue => $q2->id );
158 my $child = RT::Ticket->new( $creator );
159 ($id,$tid,$msg) = $child->Create( Subject => 'Link test 1', Queue => $q1->id );
161 ($id, $msg) = $child->AddLink(Type => 'MemberOf', Target => $parent->id);
163 is(link_count($filename), 1, "scrips ok");
164 $child->CurrentUser( $RT::SystemUser );
165 is($child->_Links('Base')->Count, 1, 'link was created');
166 is($child->_Links('Target')->Count, 0, 'link was created only one');
167 $child->CurrentUser( $creator );
169 # turn off feature and try to delete link, we should fail
170 RT->Config->Set( StrictLinkACL => 1 );
171 ($id, $msg) = $child->AddLink(Type => 'MemberOf', Target => $parent->id);
173 is(link_count($filename), 1, "scrips ok");
174 $child->CurrentUser( $RT::SystemUser );
175 $child->_Links('Base')->_DoCount;
176 is($child->_Links('Base')->Count, 1, 'link was not deleted');
177 $child->CurrentUser( $creator );
179 # try to delete link, we should success as feature is active
180 RT->Config->Set( StrictLinkACL => 0 );
181 ($id, $msg) = $child->DeleteLink(Type => 'MemberOf', Target => $parent->id);
183 is(link_count($filename), 0, "scrips ok");
184 $child->CurrentUser( $RT::SystemUser );
185 $child->_Links('Base')->_DoCount;
186 is($child->_Links('Base')->Count, 0, 'link was deleted');
187 RT->Config->Set( StrictLinkACL => 1 );
191 my $ticket = RT::Ticket->new( $creator);
192 ok($ticket->isa('RT::Ticket'));
193 ($id,$tid, $msg) = $ticket->Create(Subject => 'Link test 1', Queue => $q1->id);
196 diag('try link to itself') if $ENV{'TEST_VERBOSE'};
198 my ($id, $msg) = $ticket->AddLink(Type => 'RefersTo', Target => $ticket->id);
200 is(link_count($filename), 0, "scrips ok");
203 my $ticket2 = RT::Ticket->new($RT::SystemUser);
204 ($id, $tid, $msg) = $ticket2->Create(Subject => 'Link test 2', Queue => $q2->id);
206 ($id,$msg) =$ticket->AddLink(Type => 'RefersTo', Target => $ticket2->id);
208 is(link_count($filename), 0, "scrips ok");
210 ($id,$msg) = $u1->PrincipalObj->GrantRight ( Object => $q2, Right => 'CreateTicket');
212 ($id,$msg) = $u1->PrincipalObj->GrantRight ( Object => $q2, Right => 'ModifyTicket');
214 ($id,$msg) = $ticket->AddLink(Type => 'RefersTo', Target => $ticket2->id);
216 is(link_count($filename), 1, "scrips ok");
217 ($id,$msg) = $ticket->AddLink(Type => 'RefersTo', Target => -1);
219 ($id,$msg) = $ticket->AddLink(Type => 'RefersTo', Target => $ticket2->id);
221 is(link_count($filename), 1, "scrips ok");
223 my $transactions = $ticket2->Transactions;
224 $transactions->Limit( FIELD => 'Type', VALUE => 'AddLink' );
225 is( $transactions->Count, 1, "Transaction found in other ticket" );
226 is( $transactions->First->Field , 'ReferredToBy');
227 is( $transactions->First->NewValue , $ticket->URI );
229 ($id,$msg) = $ticket->DeleteLink(Type => 'RefersTo', Target => $ticket2->id);
231 is(link_count($filename), 0, "scrips ok");
232 $transactions = $ticket2->Transactions;
233 $transactions->Limit( FIELD => 'Type', VALUE => 'DeleteLink' );
234 is( $transactions->Count, 1, "Transaction found in other ticket" );
235 is( $transactions->First->Field , 'ReferredToBy');
236 is( $transactions->First->OldValue , $ticket->URI );
238 RT->Config->Set( LinkTransactionsRun1Scrip => 0 );
240 ($id,$msg) =$ticket->AddLink(Type => 'RefersTo', Target => $ticket2->id);
242 is(link_count($filename), 2, "scrips ok");
243 ($id,$msg) =$ticket->DeleteLink(Type => 'RefersTo', Target => $ticket2->id);
245 is(link_count($filename), 0, "scrips ok");
247 # tests for silent behaviour
248 ($id,$msg) = $ticket->AddLink(Type => 'RefersTo', Target => $ticket2->id, Silent => 1);
250 is(link_count($filename), 0, "scrips ok");
252 my $transactions = $ticket->Transactions;
253 $transactions->Limit( FIELD => 'Type', VALUE => 'AddLink' );
254 is( $transactions->Count, 2, "Still two txns on the base" );
256 $transactions = $ticket2->Transactions;
257 $transactions->Limit( FIELD => 'Type', VALUE => 'AddLink' );
258 is( $transactions->Count, 2, "Still two txns on the target" );
261 ($id,$msg) =$ticket->DeleteLink(Type => 'RefersTo', Target => $ticket2->id, Silent => 1);
263 is(link_count($filename), 0, "scrips ok");
265 ($id,$msg) = $ticket->AddLink(Type => 'RefersTo', Target => $ticket2->id, SilentBase => 1);
267 is(link_count($filename), 1, "scrips ok");
269 my $transactions = $ticket->Transactions;
270 $transactions->Limit( FIELD => 'Type', VALUE => 'AddLink' );
271 is( $transactions->Count, 2, "still five txn on the base" );
273 $transactions = $ticket2->Transactions;
274 $transactions->Limit( FIELD => 'Type', VALUE => 'AddLink' );
275 is( $transactions->Count, 3, "+1 txn on the target" );
278 ($id,$msg) =$ticket->DeleteLink(Type => 'RefersTo', Target => $ticket2->id, SilentBase => 1);
280 is(link_count($filename), 0, "scrips ok");
282 ($id,$msg) = $ticket->AddLink(Type => 'RefersTo', Target => $ticket2->id, SilentTarget => 1);
284 is(link_count($filename), 1, "scrips ok");
286 my $transactions = $ticket->Transactions;
287 $transactions->Limit( FIELD => 'Type', VALUE => 'AddLink' );
288 is( $transactions->Count, 3, "+1 txn on the base" );
290 $transactions = $ticket2->Transactions;
291 $transactions->Limit( FIELD => 'Type', VALUE => 'AddLink' );
292 is( $transactions->Count, 3, "three txns on the target" );
294 ($id,$msg) =$ticket->DeleteLink(Type => 'RefersTo', Target => $ticket2->id, SilentTarget => 1);
296 is(link_count($filename), 0, "scrips ok");
300 RT->Config->Set( LinkTransactionsRun1Scrip => $link_scrips_orig );
301 RT->Config->Set( StrictLinkACL => $link_acl_checks_orig );
304 my $Scrips = RT::Scrips->new( $RT::SystemUser );
305 $Scrips->Limit( FIELD => 'Description', OPERATOR => 'STARTSWITH', VALUE => 'Add or Delete Link ');
306 while ( my $s = $Scrips->Next ) { $s->Delete };
310 my $link = RT::Link->new( $RT::SystemUser );
311 ($id,$msg) = $link->Create( Base => $ticket->URI, Target => $ticket2->URI, Type => 'MyLinkType' );
313 ok($link->LocalBase == $ticket->id, "LocalBase set correctly");
314 ok($link->LocalTarget == $ticket2->id, "LocalTarget set correctly");
318 *RT::NotTicket::Id = sub { return $$ };
319 *RT::NotTicket::id = \&RT::NotTicket::Id;
323 package RT::URI::not_ticket;
326 @ISA = qw/RT::URI::base/;
328 sub Object { return bless {}, 'RT::NotTicket'; }
331 my $orig_getresolver = \&RT::URI::_GetResolver;
333 no warnings 'redefine';
334 *RT::URI::_GetResolver = sub {
338 $scheme =~ s/(\.|-)/_/g;
340 my $module = "RT::URI::$scheme";
341 $resolver = $module->new($self->CurrentUser);
344 $self->{'resolver'} = $resolver;
346 $self->{'resolver'} = RT::URI::base->new($self->CurrentUser);
351 ($id,$msg) = $link->Create( Base => "not_ticket::$RT::Organization/notticket/$$", Target => $ticket2->URI, Type => 'MyLinkType' );
353 ok($link->LocalBase == 0, "LocalBase set correctly");
354 ok($link->LocalTarget == $ticket2->id, "LocalTarget set correctly");
356 ($id,$msg) = $link->Create( Target => "not_ticket::$RT::Organization/notticket/$$", Base => $ticket->URI, Type => 'MyLinkType' );
358 ok($link->LocalTarget == 0, "LocalTarget set correctly");
359 ok($link->LocalBase == $ticket->id, "LocalBase set correctly");
361 ($id,$msg) = $link->Create(
362 Target => "not_ticket::$RT::Organization/notticket/1$$",
363 Base => "not_ticket::$RT::Organization/notticket/$$",
364 Type => 'MyLinkType' );
367 ok($link->LocalTarget == 0, "LocalTarget set correctly");
368 ok($link->LocalBase == 0, "LocalBase set correctly");
370 # restore _GetResolver
372 no warnings 'redefine';
373 *RT::URI::_GetResolver = $orig_getresolver;
378 open ( my $fh, '<', $file ) or die "couldn't open $file";
382 return undef unless $data;