5 use RT::Test tests => 158;
7 my ($baseurl, $agent) =RT::Test->started_ok;
8 ok( $agent->login, 'log in' );
10 my $q = RT::Queue->new($RT::SystemUser);
12 my $ip_cf = RT::CustomField->new($RT::SystemUser);
14 my ($val,$msg) = $ip_cf->Create(Name => 'IP', Type =>'IPAddressRange', LookupType => 'RT::Queue-RT::Ticket');
17 $ip_cf->AddToObject($q);
21 diag "load and check basic properties of the IP CF" if $ENV{'TEST_VERBOSE'};
23 my $cfs = RT::CustomFields->new( $RT::SystemUser );
24 $cfs->Limit( FIELD => 'Name', VALUE => 'IP' );
25 is( $cfs->Count, 1, "found one CF with name 'IP'" );
28 is( $cf->Type, 'IPAddressRange', 'type check' );
29 is( $cf->LookupType, 'RT::Queue-RT::Ticket', 'lookup type check' );
30 ok( !$cf->MaxValues, "unlimited number of values" );
31 ok( !$cf->Disabled, "not disabled" );
34 diag "check that CF applies to queue General" if $ENV{'TEST_VERBOSE'};
36 my $cfs = $q->TicketCustomFields;
37 $cfs->Limit( FIELD => 'id', VALUE => $cf->id, ENTRYAGGREGATOR => 'AND' );
38 is( $cfs->Count, 1, 'field applies to queue' );
42 'abcd:' x 7 . 'abcd' => 'abcd:' x 7 . 'abcd',
43 '034:' x 7 . '034' => '0034:' x 7 . '0034',
44 'abcd::' => 'abcd:' . '0000:' x 6 . '0000',
45 '::abcd' => '0000:' x 7 . 'abcd',
46 'abcd::034' => 'abcd:' . '0000:' x 6 . '0034',
47 'abcd::192.168.1.1' => 'abcd:' . '0000:' x 5 . 'c0a8:0101',
48 '::192.168.1.1' => '0000:' x 6 . 'c0a8:0101',
49 '::' => '0000:' x 7 . '0000',
52 diag "create a ticket via web and set IP" if $ENV{'TEST_VERBOSE'};
54 for my $ip ( keys %valid ) {
55 ok $agent->goto_create_ticket($q), "go to create ticket";
56 my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
58 form_name => 'TicketCreate',
65 $agent->content_like( qr/$valid{$ip}/, "IP on the page" );
66 my ($id) = $agent->content =~ /Ticket (\d+) created/;
67 ok( $id, "created ticket $id" );
69 my $ticket = RT::Ticket->new($RT::SystemUser);
71 ok( $ticket->id, 'loaded ticket' );
72 is( $ticket->FirstCustomFieldValue('IP'), $valid{$ip},
77 diag "create a ticket via web with CIDR" if $ENV{'TEST_VERBOSE'};
79 my $val = 'abcd:034::/31';
80 ok $agent->goto_create_ticket($q), "go to create ticket";
81 my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
83 form_name => 'TicketCreate',
90 my ($id) = $agent->content =~ /Ticket (\d+) created/;
91 ok( $id, "created ticket $id" );
93 my $ticket = RT::Ticket->new($RT::SystemUser);
95 ok( $ticket->id, 'loaded ticket' );
97 $ticket->FirstCustomFieldValue('IP'),
98 'abcd:0034:0000:0000:0000:0000:0000:0000-abcd:0035:ffff:ffff:ffff:ffff:ffff:ffff',
103 diag "create a ticket and edit IP field using Edit page" if $ENV{'TEST_VERBOSE'};
105 my $val = 'abcd' . ':abcd' x 7;
106 ok $agent->goto_create_ticket($q), "go to create ticket";
108 form_name => 'TicketCreate',
109 fields => { Subject => 'test ip', }
112 my ($id) = $agent->content =~ /Ticket (\d+) created/;
113 ok( $id, "created ticket $id" );
114 my $cf_field = "Object-RT::Ticket-$id-CustomField-$cf_id-Values";
116 $agent->follow_link_ok( { text => 'Basics', n => "1" },
117 "Followed 'Basics' link" );
118 $agent->form_name('TicketModify');
120 is( $agent->value($cf_field), '', 'IP is empty' );
121 $agent->field( $cf_field => $val );
122 $agent->click('SubmitTicket');
124 $agent->content_contains( $val, "IP on the page" );
126 my $ticket = RT::Ticket->new($RT::SystemUser);
128 ok( $ticket->id, 'loaded ticket' );
129 is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
131 diag "set IP with spaces around" if $ENV{'TEST_VERBOSE'};
132 $agent->follow_link_ok( { text => 'Basics', n => "1" },
133 "Followed 'Basics' link" );
134 $agent->form_name('TicketModify');
135 is( $agent->value($cf_field), $val, 'IP is in input box' );
136 $val = 'bbcd' . ':abcd' x 7;
137 $agent->field( $cf_field => " $val " );
138 $agent->click('SubmitTicket');
140 $agent->content_contains( $val, "IP on the page" );
142 $ticket = RT::Ticket->new($RT::SystemUser);
144 ok( $ticket->id, 'loaded ticket' );
145 is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
147 diag "replace IP with a range" if $ENV{'TEST_VERBOSE'};
148 $agent->follow_link_ok( { text => 'Basics', n => "1" },
149 "Followed 'Basics' link" );
150 $agent->form_name('TicketModify');
151 is( $agent->value($cf_field), $val, 'IP is in input box' );
152 $val = 'abcd' . ':0000' x 7 . '-' . 'abcd' . ':ffff' x 7;
153 $agent->field( $cf_field => 'abcd::/16' );
154 $agent->click('SubmitTicket');
156 $agent->content_contains( $val, "IP on the page" );
158 $ticket = RT::Ticket->new($RT::SystemUser);
160 ok( $ticket->id, 'loaded ticket' );
161 is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
163 diag "delete range, add another range using CIDR" if $ENV{'TEST_VERBOSE'};
164 $agent->follow_link_ok( { text => 'Basics', n => "1" },
165 "Followed 'Basics' link" );
166 $agent->form_name('TicketModify');
167 is( $agent->value($cf_field), $val, 'IP is in input box' );
168 $val = 'bb00' . ':0000' x 7 . '-' . 'bbff' . ':ffff' x 7;
169 $agent->field( $cf_field => $val );
170 $agent->click('SubmitTicket');
172 $agent->content_contains( $val, "IP on the page" );
174 $ticket = RT::Ticket->new($RT::SystemUser);
176 ok( $ticket->id, 'loaded ticket' );
177 is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
180 diag "check that we parse correct IPs only" if $ENV{'TEST_VERBOSE'};
183 my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
185 ( 'abcd:', 'efgh', 'abcd:' x 8 . 'abcd', 'abcd::abcd::abcd' );
186 for my $invalid (@invalid) {
187 ok $agent->goto_create_ticket($q), "go to create ticket";
189 form_name => 'TicketCreate',
191 Subject => 'test ip',
192 $cf_field => $invalid,
196 $agent->content_like( qr/can not be parsed as an IP address range/,
197 'ticket fails to create' );
202 diag "search tickets by IP" if $ENV{'TEST_VERBOSE'};
204 my $val = 'abcd::/16';
205 ok $agent->goto_create_ticket($q), "go to create ticket";
206 my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
208 form_name => 'TicketCreate',
210 Subject => 'test ip',
215 my ($id) = $agent->content =~ /Ticket (\d+) created/;
216 ok( $id, "created ticket $id" );
218 my $ticket = RT::Ticket->new($RT::SystemUser);
220 ok( $ticket->id, 'loaded ticket' );
222 my $tickets = RT::Tickets->new($RT::SystemUser);
223 $tickets->FromSQL("id = $id AND CF.{IP} = 'abcd::/16'");
224 ok( $tickets->Count, "found tickets" );
226 $ticket->FirstCustomFieldValue('IP'),
227 'abcd:0000:0000:0000:0000:0000:0000:0000-abcd:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
232 diag "search tickets by IP range" if $ENV{'TEST_VERBOSE'};
234 my $val = 'abcd:ef00::/24';
235 ok $agent->goto_create_ticket($q), "go to create ticket";
236 my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
238 form_name => 'TicketCreate',
240 Subject => 'test ip',
245 my ($id) = $agent->content =~ /Ticket (\d+) created/;
246 ok( $id, "created ticket $id" );
248 my $ticket = RT::Ticket->new($RT::SystemUser);
250 ok( $ticket->id, 'loaded ticket' );
252 my $tickets = RT::Tickets->new( $RT::SystemUser );
253 $tickets->FromSQL("id = $id AND CF.{IP} =
254 'abcd:ef::-abcd:efff:ffff:ffff:ffff:ffff:ffff:ffff'");
255 ok( $tickets->Count, "found tickets" );
258 $ticket->FirstCustomFieldValue('IP'),
259 'abcd:ef00:0000:0000:0000:0000:0000:0000-abcd:efff:ffff:ffff:ffff:ffff:ffff:ffff',
264 diag "create two tickets with different IPs and check several searches" if $ENV{'TEST_VERBOSE'};
266 ok $agent->goto_create_ticket($q), "go to create ticket";
267 my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
268 my $first_ip = 'cbcd' . ':0000' x 7;
269 my $second_ip = 'cbdd' . ':0000' x 7;
271 form_name => 'TicketCreate',
273 Subject => 'test ip',
274 $cf_field => $first_ip,
278 my ($id1) = $agent->content =~ /Ticket (\d+) created/;
279 ok( $id1, "created first ticket $id1" );
281 ok $agent->goto_create_ticket($q), "go to create ticket";
283 form_name => 'TicketCreate',
285 Subject => 'test ip',
286 $cf_field => $second_ip,
290 my ($id2) = $agent->content =~ /Ticket (\d+) created/;
291 ok( $id2, "created second ticket $id2" );
293 my $tickets = RT::Tickets->new( $RT::SystemUser );
294 $tickets->FromSQL("id = $id1 OR id = $id2");
295 is( $tickets->Count, 2, "found both tickets by 'id = x OR y'" );
298 $tickets = RT::Tickets->new( $RT::SystemUser );
299 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '$first_ip'");
300 is( $tickets->Count, 1, "found one ticket" );
301 is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip, "correct value" );
302 $tickets = RT::Tickets->new( $RT::SystemUser );
303 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '$second_ip'");
304 is( $tickets->Count, 1, "found one ticket" );
305 is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip, "correct value" );
307 # IP/32 - one address
308 $tickets = RT::Tickets->new( $RT::SystemUser );
309 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'cbcd::/16'");
310 is( $tickets->Count, 1, "found one ticket" );
311 is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip, "correct value" );
312 $tickets = RT::Tickets->new( $RT::SystemUser );
313 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'cbdd::/16'");
314 is( $tickets->Count, 1, "found one ticket" );
315 is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip, "correct value" );
318 $tickets = RT::Tickets->new( $RT::SystemUser );
320 "(id = $id1 OR id = $id2) AND CF.{IP} = '$first_ip-cbcf::'"
322 is( $tickets->Count, 1, "found one ticket" );
323 is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip, "correct value" );
324 $tickets = RT::Tickets->new( $RT::SystemUser );
326 "(id = $id1 OR id = $id2) AND CF.{IP} = '$second_ip-cbdf::'");
327 is( $tickets->Count, 1, "found one ticket" );
328 is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip, "correct value" );
330 # IP range, with start IP greater than end
331 $tickets = RT::Tickets->new( $RT::SystemUser );
332 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} =
333 'cbcf::-$first_ip'");
334 is( $tickets->Count, 1, "found one ticket" );
335 is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip,, "correct value" );
336 $tickets = RT::Tickets->new( $RT::SystemUser );
337 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'cbdf::-$second_ip'");
338 is( $tickets->Count, 1, "found one ticket" );
339 is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip, "correct value" );
342 $tickets = RT::Tickets->new( $RT::SystemUser );
343 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'cbcd::/12'");
344 is( $tickets->Count, 1, "found one ticket" );
345 is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip, "correct value" );
346 $tickets = RT::Tickets->new( $RT::SystemUser );
347 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'cbdd::/12'");
348 is( $tickets->Count, 1, "found one ticket" );
349 is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip, "correct value" );
351 # IP is not in CIDR/24
352 $tickets = RT::Tickets->new( $RT::SystemUser );
353 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} != 'cbcd::/12'");
354 is( $tickets->Count, 1, "found one ticket" );
355 is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip,, "correct value" );
356 $tickets = RT::Tickets->new( $RT::SystemUser );
357 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} != 'cbdd::/12'");
358 is( $tickets->Count, 1, "found one ticket" );
359 is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip, "correct value" );
362 $tickets = RT::Tickets->new( $RT::SystemUser );
363 $tickets->FromSQL("(id = $id1 OR id = $id2) AND "
364 ."(CF.{IP} = 'cbcd::/12' OR CF.{IP} = 'cbdd::/12')");
365 is( $tickets->Count, 2, "found both tickets" );
368 diag "create two tickets with different IP ranges and check several searches" if $ENV{'TEST_VERBOSE'};
370 ok $agent->goto_create_ticket($q), "go to create ticket";
371 my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
373 form_name => 'TicketCreate',
375 Subject => 'test ip',
376 $cf_field => 'ddcd::/16',
380 my ($id1) = $agent->content =~ /Ticket (\d+) created/;
381 ok( $id1, "created first ticket $id1" );
383 ok $agent->goto_create_ticket($q), "go to create ticket";
385 form_name => 'TicketCreate',
387 Subject => 'test ip',
388 $cf_field => 'edcd::/16',
392 my ($id2) = $agent->content =~ /Ticket (\d+) created/;
393 ok( $id2, "created ticket $id2" );
395 my $tickets = RT::Tickets->new( $RT::SystemUser );
396 $tickets->FromSQL("id = $id1 OR id = $id2");
397 is( $tickets->Count, 2, "found both tickets by 'id = x OR y'" );
400 $tickets = RT::Tickets->new( $RT::SystemUser );
401 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd::'");
402 is( $tickets->Count, 1, "found one ticket" );
403 is( $tickets->First->id, $id1, "correct value" );
404 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd:abcd::'");
405 is( $tickets->Count, 1, "found one ticket" );
406 is( $tickets->First->id, $id1, "correct value" );
407 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd:ffff::'");
408 is( $tickets->Count, 1, "found one ticket" );
409 is( $tickets->First->id, $id1, "correct value" );
410 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'edcd::abcd'");
411 is( $tickets->Count, 1, "found one ticket" );
412 is( $tickets->First->id, $id2, "correct value" );
413 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'edcd::ffff'");
414 is( $tickets->Count, 1, "found one ticket" );
415 is( $tickets->First->id, $id2, "correct value" );
417 "(id = $id1 OR id = $id2) AND CF.{IP} = 'edcd:ffff:ffff:ffff:ffff:ffff:ffff:ffff'"
419 is( $tickets->Count, 1, "found one ticket" );
420 is( $tickets->First->id, $id2, "correct value" );
422 # IP/32 - one address
423 $tickets = RT::Tickets->new( $RT::SystemUser );
424 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd::/32'");
425 is( $tickets->Count, 1, "found one ticket" );
426 is( $tickets->First->id, $id1, "correct value" );
427 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'edcd::/32'");
428 is( $tickets->Count, 1, "found one ticket" );
429 is( $tickets->First->id, $id2, "correct value" );
431 # IP range, lower than both
432 $tickets = RT::Tickets->new( $RT::SystemUser );
433 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'abcd::/32'");
434 is( $tickets->Count, 0, "didn't finnd ticket" ) or diag "but found ". $tickets->First->id;
436 # IP range, intersect with the first range
438 "(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcc::-ddcd:ab::'"
440 is( $tickets->Count, 1, "found one ticket" );
441 is( $tickets->First->id, $id1, "correct value" );
443 # IP range, equal to the first range
444 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd::/16'");
445 is( $tickets->Count, 1, "found one ticket" );
446 is( $tickets->First->id, $id1, "correct value" );
448 # IP range, lay inside the first range
449 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd:ab::'");
450 is( $tickets->Count, 1, "found one ticket" );
451 is( $tickets->First->id, $id1, "correct value" );
453 # IP range, intersect with the ranges
454 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcc::-edcd:ab::'");
455 is( $tickets->Count, 2, "found both tickets" );
457 # IP range, equal to range from the starting IP of the first ticket to the ending IP of the second
459 "(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd::-edcd:ffff:ffff:ffff:ffff:ffff:ffff:ffff'"
461 is( $tickets->Count, 2, "found both tickets" );
463 # IP range, has the both ranges inside it
464 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'd000::/2'");
465 is( $tickets->Count, 2, "found both tickets" );
467 # IP range, greater than both
468 $tickets = RT::Tickets->new( $RT::SystemUser );
469 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ffff::/16'");
470 is( $tickets->Count, 0, "didn't find ticket" ) or diag "but found ". $tickets->First->id;