import rt 3.8.9
[freeside.git] / rt / lib / t / regression / 14linking.t
1 use Test::More  tests => '70';
2 use_ok('RT');
3 use_ok('RT::Ticket');
4 use_ok('RT::ScripConditions');
5 use_ok('RT::ScripActions');
6 use_ok('RT::Template');
7 use_ok('RT::Scrips');
8 use_ok('RT::Scrip');
9 RT::LoadConfig();
10 RT::Init();
11
12 use File::Temp qw/tempfile/;
13 my ($fh, $filename) = tempfile( UNLINK => 1, SUFFIX => '.rt');
14 my $link_scrips_orig = $RT::LinkTransactionsRun1Scrip;
15 my $link_acl_chacks_orig = $RT::StrictLinkACL;
16 $RT::LinkTransactionsRun1Scrip = 1;
17 $RT::StrictLinkACL = 1;
18
19 my $condition = RT::ScripCondition->new( $RT::SystemUser );
20 $condition->Load('User Defined');
21 ok($condition->id);
22 my $action = RT::ScripAction->new( $RT::SystemUser );
23 $action->Load('User Defined');
24 ok($action->id);
25 my $template = RT::Template->new( $RT::SystemUser );
26 $template->Load('Blank');
27 ok($template->id);
28
29 my $q1 = RT::Queue->new($RT::SystemUser);
30 my ($id,$msg) = $q1->Create(Name => "LinkTest1.$$");
31 ok ($id,$msg);
32 my $q2 = RT::Queue->new($RT::SystemUser);
33 ($id,$msg) = $q2->Create(Name => "LinkTest2.$$");
34 ok ($id,$msg);
35
36 my $commit_code = <<END;
37 open(FILE, "<$filename");
38 my \$data = <FILE>;
39 chomp \$data;
40 close FILE;
41 open(FILE, ">$filename");
42 if (\$self->TransactionObj->Type eq 'AddLink') {
43     print FILE \$data+1, "\n";
44 }
45 else {
46     print FILE \$data-1, "\n";
47 }
48 close FILE;
49 1;
50 END
51
52 my $Scrips = RT::Scrips->new( $RT::SystemUser );
53 $Scrips->UnLimit;
54 while ( my $Scrip = $Scrips->Next ) {
55     $Scrip->Delete if $Scrip->Description =~ /Add or Delete Link \d+/;
56 }
57
58
59 my $scrip = RT::Scrip->new($RT::SystemUser);
60 ($id,$msg) = $scrip->Create( Description => "Add or Delete Link $$",
61                           ScripCondition => $condition->id,
62                           ScripAction    => $action->id,
63                           Template       => $template->id,
64                           Stage          => 'TransactionCreate',
65                           Queue          => 0,
66                   CustomIsApplicableCode => '$self->TransactionObj->Type =~ /(Add|Delete)Link/;',
67                        CustomPrepareCode => '1;',
68                        CustomCommitCode  => $commit_code,
69                            );
70 ok($id, "Scrip created");
71
72 my $u1 = RT::User->new($RT::SystemUser);
73 ($id,$msg) = $u1->Create(Name => "LinkTestUser.$$");
74 ok ($id,$msg);
75
76 my $creator = RT::CurrentUser->new($u1->id);
77
78 ($id,$msg) = $u1->PrincipalObj->GrantRight ( Object => $q1, Right => 'CreateTicket');
79 ok ($id,$msg);
80
81 diag('Create tickets without rights to link') if $ENV{'TEST_VERBOSE'};
82 {
83     # on q2 we have no rights, yet
84     my $parent = RT::Ticket->new( $RT::SystemUser );
85     ($id,$tid,$msg) = $parent->Create( Subject => 'Link test 1', Queue => $q2->id );
86     ok($id,$msg);
87     my $child = RT::Ticket->new( $creator );
88     ($id,$tid,$msg) = $child->Create( Subject => 'Link test 1', Queue => $q1->id, MemberOf => $parent->id );
89     ok($id,$msg);
90     $child->CurrentUser( $RT::SystemUser );
91     is($child->_Links('Base')->Count, 0, 'link was not created, no permissions');
92     is($child->_Links('Target')->Count, 0, 'link was not create, no permissions');
93 }
94
95 diag('Create tickets with rights checks on one end of a link') if $ENV{'TEST_VERBOSE'};
96 {
97     # on q2 we have no rights, but use checking one only on thing
98     local $RT::StrictLinkACL = 0;
99     my $parent = RT::Ticket->new( $RT::SystemUser );
100     ($id,$tid,$msg) = $parent->Create( Subject => 'Link test 1', Queue => $q2->id );
101     ok($id,$msg);
102     my $child = RT::Ticket->new( $creator );
103     ($id,$tid,$msg) = $child->Create( Subject => 'Link test 1', Queue => $q1->id, MemberOf => $parent->id );
104     ok($id,$msg);
105     $child->CurrentUser( $RT::SystemUser );
106     is($child->_Links('Base')->Count, 1, 'link was created');
107     is($child->_Links('Target')->Count, 0, 'link was created only one');
108     # no scrip run on second ticket accroding to config option
109     is(link_count($filename), 0, "scrips ok"); 
110 }
111
112 ($id,$msg) = $u1->PrincipalObj->GrantRight ( Object => $q1, Right => 'ModifyTicket');
113 ok ($id,$msg);
114
115 diag('try to add link without rights') if $ENV{'TEST_VERBOSE'};
116 {
117     # on q2 we have no rights, yet
118     my $parent = RT::Ticket->new( $RT::SystemUser );
119     ($id,$tid,$msg) = $parent->Create( Subject => 'Link test 1', Queue => $q2->id );
120     ok($id,$msg);
121     my $child = RT::Ticket->new( $creator );
122     ($id,$tid,$msg) = $child->Create( Subject => 'Link test 1', Queue => $q1->id );
123     ok($id,$msg);
124     my ($id, $msg) = $child->AddLink(Type => 'MemberOf', Target => $parent->id);
125     ok(!$id, $msg);
126     is(link_count($filename), 0, "scrips ok");
127     $child->CurrentUser( $RT::SystemUser );
128     is($child->_Links('Base')->Count, 0, 'link was not created, no permissions');
129     is($child->_Links('Target')->Count, 0, 'link was not create, no permissions');
130 }
131
132 diag('add link with rights only on base') if $ENV{'TEST_VERBOSE'};
133 {
134     # on q2 we have no rights, but use checking one only on thing
135     local $RT::StrictLinkACL = 0;
136     my $parent = RT::Ticket->new( $RT::SystemUser );
137     ($id,$tid,$msg) = $parent->Create( Subject => 'Link test 1', Queue => $q2->id );
138     ok($id,$msg);
139     my $child = RT::Ticket->new( $creator );
140     ($id,$tid,$msg) = $child->Create( Subject => 'Link test 1', Queue => $q1->id );
141     ok($id,$msg);
142     my ($id, $msg) = $child->AddLink(Type => 'MemberOf', Target => $parent->id);
143     ok($id, $msg);
144     is(link_count($filename), 1, "scrips ok");
145     $child->CurrentUser( $RT::SystemUser );
146     is($child->_Links('Base')->Count, 1, 'link was created');
147     is($child->_Links('Target')->Count, 0, 'link was created only one');
148     $child->CurrentUser( $creator );
149
150     # turn off feature and try to delete link, we should fail
151     $RT::StrictLinkACL = 1;
152     my ($id, $msg) = $child->AddLink(Type => 'MemberOf', Target => $parent->id);
153     ok(!$id, $msg);
154     is(link_count($filename), 1, "scrips ok");
155     $child->CurrentUser( $RT::SystemUser );
156     $child->_Links('Base')->_DoCount;
157     is($child->_Links('Base')->Count, 1, 'link was not deleted');
158     $child->CurrentUser( $creator );
159
160     # try to delete link, we should success as feature is active
161     $RT::StrictLinkACL = 0;
162     my ($id, $msg) = $child->DeleteLink(Type => 'MemberOf', Target => $parent->id);
163     ok($id, $msg);
164     is(link_count($filename), 0, "scrips ok");
165     $child->CurrentUser( $RT::SystemUser );
166     $child->_Links('Base')->_DoCount;
167     is($child->_Links('Base')->Count, 0, 'link was deleted');
168 }
169
170 my $tid;
171 my $ticket = RT::Ticket->new( $creator);
172 ok($ticket->isa('RT::Ticket'));
173 ($id,$tid, $msg) = $ticket->Create(Subject => 'Link test 1', Queue => $q1->id);
174 ok ($id,$msg);
175
176 diag('try link to itself') if $ENV{'TEST_VERBOSE'};
177 {
178     my ($id, $msg) = $ticket->AddLink(Type => 'RefersTo', Target => $ticket->id);
179     ok(!$id, $msg);
180     is(link_count($filename), 0, "scrips ok");
181 }
182
183 my $ticket2 = RT::Ticket->new($RT::SystemUser);
184 ($id, $tid, $msg) = $ticket2->Create(Subject => 'Link test 2', Queue => $q2->id);
185 ok ($id, $msg);
186 ($id,$msg) =$ticket->AddLink(Type => 'RefersTo', Target => $ticket2->id);
187 ok(!$id,$msg);
188 ok(link_count($filename) == 0, "scrips ok");
189
190 ($id,$msg) = $u1->PrincipalObj->GrantRight ( Object => $q2, Right => 'CreateTicket');
191 ok ($id,$msg);
192 ($id,$msg) = $u1->PrincipalObj->GrantRight ( Object => $q2, Right => 'ModifyTicket');
193 ok ($id,$msg);
194 ($id,$msg) =$ticket->AddLink(Type => 'RefersTo', Target => $ticket2->id);
195 ok($id,$msg);
196 ok(link_count($filename) == 1, "scrips ok");
197 ($id,$msg) =$ticket->AddLink(Type => 'RefersTo', Target => -1);
198 ok(!$id,$msg);
199 ok(link_count($filename) == 1, "scrips ok");
200 ($id,$msg) = $ticket->AddLink(Type => 'RefersTo', Target => $ticket2->id);
201 ok($id,$msg);
202 is(link_count($filename), 1, "scrips ok");
203
204 my $transactions = $ticket2->Transactions;
205 $transactions->Limit( FIELD => 'Type', VALUE => 'AddLink' );
206 ok( $transactions->Count == 1, "Transaction found in other ticket" );
207 ok( $transactions->First->Field eq 'ReferredToBy');
208 ok( $transactions->First->NewValue eq $ticket->URI );
209
210 ($id,$msg) =$ticket->DeleteLink(Type => 'RefersTo', Target => $ticket2->id);
211 ok($id,$msg);
212 ok(link_count($filename) == 0, "scrips ok");
213 $transactions = $ticket2->Transactions;
214 $transactions->Limit( FIELD => 'Type', VALUE => 'DeleteLink' );
215 ok( $transactions->Count == 1, "Transaction found in other ticket" );
216 ok( $transactions->First->Field eq 'ReferredToBy');
217 ok( $transactions->First->OldValue eq $ticket->URI );
218
219 $RT::LinkTransactionsRun1Scrip = 0;
220
221 ($id,$msg) =$ticket->AddLink(Type => 'RefersTo', Target => $ticket2->id);
222 ok($id,$msg);
223 ok(link_count($filename) == 2, "scrips ok");
224 ($id,$msg) =$ticket->DeleteLink(Type => 'RefersTo', Target => $ticket2->id);
225 ok($id,$msg);
226 ok(link_count($filename) == 0, "scrips ok");
227
228 # restore
229 $RT::LinkTransactionsRun1Scrip = $link_scrips_orig;
230 $RT::StrictLinkACL = $link_acl_checks_orig;
231
232 exit(0);
233
234 sub link_count {
235
236     my $file = shift;
237     open(FILE, "<$file");
238     my $data = <FILE>;
239     chomp $data;
240     return $data + 0;
241     close FILE;
242
243 }