6 use RT::Test tests => 158;
8 my ($baseurl, $agent) =RT::Test->started_ok;
9 ok( $agent->login, 'log in' );
11 my $q = RT::Queue->new($RT::SystemUser);
13 my $ip_cf = RT::CustomField->new($RT::SystemUser);
15 my ($val,$msg) = $ip_cf->Create(Name => 'IP', Type =>'IPAddressRange', LookupType => 'RT::Queue-RT::Ticket');
18 $ip_cf->AddToObject($q);
22 diag "load and check basic properties of the IP CF" if $ENV{'TEST_VERBOSE'};
24 my $cfs = RT::CustomFields->new( $RT::SystemUser );
25 $cfs->Limit( FIELD => 'Name', VALUE => 'IP' );
26 is( $cfs->Count, 1, "found one CF with name 'IP'" );
29 is( $cf->Type, 'IPAddressRange', 'type check' );
30 is( $cf->LookupType, 'RT::Queue-RT::Ticket', 'lookup type check' );
31 ok( !$cf->MaxValues, "unlimited number of values" );
32 ok( !$cf->Disabled, "not disabled" );
35 diag "check that CF applies to queue General" if $ENV{'TEST_VERBOSE'};
37 my $cfs = $q->TicketCustomFields;
38 $cfs->Limit( FIELD => 'id', VALUE => $cf->id, ENTRYAGGREGATOR => 'AND' );
39 is( $cfs->Count, 1, 'field applies to queue' );
43 'abcd:' x 7 . 'abcd' => 'abcd:' x 7 . 'abcd',
44 '034:' x 7 . '034' => '0034:' x 7 . '0034',
45 'abcd::' => 'abcd:' . '0000:' x 6 . '0000',
46 '::abcd' => '0000:' x 7 . 'abcd',
47 'abcd::034' => 'abcd:' . '0000:' x 6 . '0034',
48 'abcd::192.168.1.1' => 'abcd:' . '0000:' x 5 . 'c0a8:0101',
49 '::192.168.1.1' => '0000:' x 6 . 'c0a8:0101',
50 '::' => '0000:' x 7 . '0000',
53 diag "create a ticket via web and set IP" if $ENV{'TEST_VERBOSE'};
55 for my $ip ( keys %valid ) {
56 ok $agent->goto_create_ticket($q), "go to create ticket";
57 my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
59 form_name => 'TicketCreate',
66 $agent->content_like( qr/$valid{$ip}/, "IP on the page" );
67 my ($id) = $agent->content =~ /Ticket (\d+) created/;
68 ok( $id, "created ticket $id" );
70 my $ticket = RT::Ticket->new($RT::SystemUser);
72 ok( $ticket->id, 'loaded ticket' );
73 is( $ticket->FirstCustomFieldValue('IP'), $valid{$ip},
78 diag "create a ticket via web with CIDR" if $ENV{'TEST_VERBOSE'};
80 my $val = 'abcd:034::/31';
81 ok $agent->goto_create_ticket($q), "go to create ticket";
82 my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
84 form_name => 'TicketCreate',
91 my ($id) = $agent->content =~ /Ticket (\d+) created/;
92 ok( $id, "created ticket $id" );
94 my $ticket = RT::Ticket->new($RT::SystemUser);
96 ok( $ticket->id, 'loaded ticket' );
98 $ticket->FirstCustomFieldValue('IP'),
99 'abcd:0034:0000:0000:0000:0000:0000:0000-abcd:0035:ffff:ffff:ffff:ffff:ffff:ffff',
104 diag "create a ticket and edit IP field using Edit page" if $ENV{'TEST_VERBOSE'};
106 my $val = 'abcd' . ':abcd' x 7;
107 ok $agent->goto_create_ticket($q), "go to create ticket";
109 form_name => 'TicketCreate',
110 fields => { Subject => 'test ip', }
113 my ($id) = $agent->content =~ /Ticket (\d+) created/;
114 ok( $id, "created ticket $id" );
115 my $cf_field = "Object-RT::Ticket-$id-CustomField-$cf_id-Values";
117 $agent->follow_link_ok( { text => 'Basics', n => "1" },
118 "Followed 'Basics' link" );
119 $agent->form_name('TicketModify');
121 is( $agent->value($cf_field), '', 'IP is empty' );
122 $agent->field( $cf_field => $val );
123 $agent->click('SubmitTicket');
125 $agent->content_contains( $val, "IP on the page" );
127 my $ticket = RT::Ticket->new($RT::SystemUser);
129 ok( $ticket->id, 'loaded ticket' );
130 is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
132 diag "set IP with spaces around" if $ENV{'TEST_VERBOSE'};
133 $agent->follow_link_ok( { text => 'Basics', n => "1" },
134 "Followed 'Basics' link" );
135 $agent->form_name('TicketModify');
136 is( $agent->value($cf_field), $val, 'IP is in input box' );
137 $val = 'bbcd' . ':abcd' x 7;
138 $agent->field( $cf_field => " $val " );
139 $agent->click('SubmitTicket');
141 $agent->content_contains( $val, "IP on the page" );
143 $ticket = RT::Ticket->new($RT::SystemUser);
145 ok( $ticket->id, 'loaded ticket' );
146 is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
148 diag "replace IP with a range" if $ENV{'TEST_VERBOSE'};
149 $agent->follow_link_ok( { text => 'Basics', n => "1" },
150 "Followed 'Basics' link" );
151 $agent->form_name('TicketModify');
152 is( $agent->value($cf_field), $val, 'IP is in input box' );
153 $val = 'abcd' . ':0000' x 7 . '-' . 'abcd' . ':ffff' x 7;
154 $agent->field( $cf_field => 'abcd::/16' );
155 $agent->click('SubmitTicket');
157 $agent->content_contains( $val, "IP on the page" );
159 $ticket = RT::Ticket->new($RT::SystemUser);
161 ok( $ticket->id, 'loaded ticket' );
162 is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
164 diag "delete range, add another range using CIDR" if $ENV{'TEST_VERBOSE'};
165 $agent->follow_link_ok( { text => 'Basics', n => "1" },
166 "Followed 'Basics' link" );
167 $agent->form_name('TicketModify');
168 is( $agent->value($cf_field), $val, 'IP is in input box' );
169 $val = 'bb00' . ':0000' x 7 . '-' . 'bbff' . ':ffff' x 7;
170 $agent->field( $cf_field => $val );
171 $agent->click('SubmitTicket');
173 $agent->content_contains( $val, "IP on the page" );
175 $ticket = RT::Ticket->new($RT::SystemUser);
177 ok( $ticket->id, 'loaded ticket' );
178 is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
181 diag "check that we parse correct IPs only" if $ENV{'TEST_VERBOSE'};
184 my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
186 ( 'abcd:', 'efgh', 'abcd:' x 8 . 'abcd', 'abcd::abcd::abcd' );
187 for my $invalid (@invalid) {
188 ok $agent->goto_create_ticket($q), "go to create ticket";
190 form_name => 'TicketCreate',
192 Subject => 'test ip',
193 $cf_field => $invalid,
197 $agent->content_like( qr/can not be parsed as an IP address range/,
198 'ticket fails to create' );
203 diag "search tickets by IP" if $ENV{'TEST_VERBOSE'};
205 my $val = 'abcd::/16';
206 ok $agent->goto_create_ticket($q), "go to create ticket";
207 my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
209 form_name => 'TicketCreate',
211 Subject => 'test ip',
216 my ($id) = $agent->content =~ /Ticket (\d+) created/;
217 ok( $id, "created ticket $id" );
219 my $ticket = RT::Ticket->new($RT::SystemUser);
221 ok( $ticket->id, 'loaded ticket' );
223 my $tickets = RT::Tickets->new($RT::SystemUser);
224 $tickets->FromSQL("id = $id AND CF.{IP} = 'abcd::/16'");
225 ok( $tickets->Count, "found tickets" );
227 $ticket->FirstCustomFieldValue('IP'),
228 'abcd:0000:0000:0000:0000:0000:0000:0000-abcd:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
233 diag "search tickets by IP range" if $ENV{'TEST_VERBOSE'};
235 my $val = 'abcd:ef00::/24';
236 ok $agent->goto_create_ticket($q), "go to create ticket";
237 my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
239 form_name => 'TicketCreate',
241 Subject => 'test ip',
246 my ($id) = $agent->content =~ /Ticket (\d+) created/;
247 ok( $id, "created ticket $id" );
249 my $ticket = RT::Ticket->new($RT::SystemUser);
251 ok( $ticket->id, 'loaded ticket' );
253 my $tickets = RT::Tickets->new( $RT::SystemUser );
254 $tickets->FromSQL("id = $id AND CF.{IP} =
255 'abcd:ef::-abcd:efff:ffff:ffff:ffff:ffff:ffff:ffff'");
256 ok( $tickets->Count, "found tickets" );
259 $ticket->FirstCustomFieldValue('IP'),
260 'abcd:ef00:0000:0000:0000:0000:0000:0000-abcd:efff:ffff:ffff:ffff:ffff:ffff:ffff',
265 diag "create two tickets with different IPs and check several searches" if $ENV{'TEST_VERBOSE'};
267 ok $agent->goto_create_ticket($q), "go to create ticket";
268 my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
269 my $first_ip = 'cbcd' . ':0000' x 7;
270 my $second_ip = 'cbdd' . ':0000' x 7;
272 form_name => 'TicketCreate',
274 Subject => 'test ip',
275 $cf_field => $first_ip,
279 my ($id1) = $agent->content =~ /Ticket (\d+) created/;
280 ok( $id1, "created first ticket $id1" );
282 ok $agent->goto_create_ticket($q), "go to create ticket";
284 form_name => 'TicketCreate',
286 Subject => 'test ip',
287 $cf_field => $second_ip,
291 my ($id2) = $agent->content =~ /Ticket (\d+) created/;
292 ok( $id2, "created second ticket $id2" );
294 my $tickets = RT::Tickets->new( $RT::SystemUser );
295 $tickets->FromSQL("id = $id1 OR id = $id2");
296 is( $tickets->Count, 2, "found both tickets by 'id = x OR y'" );
299 $tickets = RT::Tickets->new( $RT::SystemUser );
300 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '$first_ip'");
301 is( $tickets->Count, 1, "found one ticket" );
302 is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip, "correct value" );
303 $tickets = RT::Tickets->new( $RT::SystemUser );
304 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '$second_ip'");
305 is( $tickets->Count, 1, "found one ticket" );
306 is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip, "correct value" );
308 # IP/32 - one address
309 $tickets = RT::Tickets->new( $RT::SystemUser );
310 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'cbcd::/16'");
311 is( $tickets->Count, 1, "found one ticket" );
312 is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip, "correct value" );
313 $tickets = RT::Tickets->new( $RT::SystemUser );
314 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'cbdd::/16'");
315 is( $tickets->Count, 1, "found one ticket" );
316 is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip, "correct value" );
319 $tickets = RT::Tickets->new( $RT::SystemUser );
321 "(id = $id1 OR id = $id2) AND CF.{IP} = '$first_ip-cbcf::'"
323 is( $tickets->Count, 1, "found one ticket" );
324 is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip, "correct value" );
325 $tickets = RT::Tickets->new( $RT::SystemUser );
327 "(id = $id1 OR id = $id2) AND CF.{IP} = '$second_ip-cbdf::'");
328 is( $tickets->Count, 1, "found one ticket" );
329 is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip, "correct value" );
331 # IP range, with start IP greater than end
332 $tickets = RT::Tickets->new( $RT::SystemUser );
333 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} =
334 'cbcf::-$first_ip'");
335 is( $tickets->Count, 1, "found one ticket" );
336 is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip,, "correct value" );
337 $tickets = RT::Tickets->new( $RT::SystemUser );
338 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'cbdf::-$second_ip'");
339 is( $tickets->Count, 1, "found one ticket" );
340 is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip, "correct value" );
343 $tickets = RT::Tickets->new( $RT::SystemUser );
344 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'cbcd::/12'");
345 is( $tickets->Count, 1, "found one ticket" );
346 is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip, "correct value" );
347 $tickets = RT::Tickets->new( $RT::SystemUser );
348 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'cbdd::/12'");
349 is( $tickets->Count, 1, "found one ticket" );
350 is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip, "correct value" );
352 # IP is not in CIDR/24
353 $tickets = RT::Tickets->new( $RT::SystemUser );
354 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} != 'cbcd::/12'");
355 is( $tickets->Count, 1, "found one ticket" );
356 is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip,, "correct value" );
357 $tickets = RT::Tickets->new( $RT::SystemUser );
358 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} != 'cbdd::/12'");
359 is( $tickets->Count, 1, "found one ticket" );
360 is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip, "correct value" );
363 $tickets = RT::Tickets->new( $RT::SystemUser );
364 $tickets->FromSQL("(id = $id1 OR id = $id2) AND "
365 ."(CF.{IP} = 'cbcd::/12' OR CF.{IP} = 'cbdd::/12')");
366 is( $tickets->Count, 2, "found both tickets" );
369 diag "create two tickets with different IP ranges and check several searches" if $ENV{'TEST_VERBOSE'};
371 ok $agent->goto_create_ticket($q), "go to create ticket";
372 my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
374 form_name => 'TicketCreate',
376 Subject => 'test ip',
377 $cf_field => 'ddcd::/16',
381 my ($id1) = $agent->content =~ /Ticket (\d+) created/;
382 ok( $id1, "created first ticket $id1" );
384 ok $agent->goto_create_ticket($q), "go to create ticket";
386 form_name => 'TicketCreate',
388 Subject => 'test ip',
389 $cf_field => 'edcd::/16',
393 my ($id2) = $agent->content =~ /Ticket (\d+) created/;
394 ok( $id2, "created ticket $id2" );
396 my $tickets = RT::Tickets->new( $RT::SystemUser );
397 $tickets->FromSQL("id = $id1 OR id = $id2");
398 is( $tickets->Count, 2, "found both tickets by 'id = x OR y'" );
401 $tickets = RT::Tickets->new( $RT::SystemUser );
402 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd::'");
403 is( $tickets->Count, 1, "found one ticket" );
404 is( $tickets->First->id, $id1, "correct value" );
405 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd:abcd::'");
406 is( $tickets->Count, 1, "found one ticket" );
407 is( $tickets->First->id, $id1, "correct value" );
408 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd:ffff::'");
409 is( $tickets->Count, 1, "found one ticket" );
410 is( $tickets->First->id, $id1, "correct value" );
411 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'edcd::abcd'");
412 is( $tickets->Count, 1, "found one ticket" );
413 is( $tickets->First->id, $id2, "correct value" );
414 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'edcd::ffff'");
415 is( $tickets->Count, 1, "found one ticket" );
416 is( $tickets->First->id, $id2, "correct value" );
418 "(id = $id1 OR id = $id2) AND CF.{IP} = 'edcd:ffff:ffff:ffff:ffff:ffff:ffff:ffff'"
420 is( $tickets->Count, 1, "found one ticket" );
421 is( $tickets->First->id, $id2, "correct value" );
423 # IP/32 - one address
424 $tickets = RT::Tickets->new( $RT::SystemUser );
425 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd::/32'");
426 is( $tickets->Count, 1, "found one ticket" );
427 is( $tickets->First->id, $id1, "correct value" );
428 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'edcd::/32'");
429 is( $tickets->Count, 1, "found one ticket" );
430 is( $tickets->First->id, $id2, "correct value" );
432 # IP range, lower than both
433 $tickets = RT::Tickets->new( $RT::SystemUser );
434 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'abcd::/32'");
435 is( $tickets->Count, 0, "didn't finnd ticket" ) or diag "but found ". $tickets->First->id;
437 # IP range, intersect with the first range
439 "(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcc::-ddcd:ab::'"
441 is( $tickets->Count, 1, "found one ticket" );
442 is( $tickets->First->id, $id1, "correct value" );
444 # IP range, equal to the first range
445 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd::/16'");
446 is( $tickets->Count, 1, "found one ticket" );
447 is( $tickets->First->id, $id1, "correct value" );
449 # IP range, lay inside the first range
450 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd:ab::'");
451 is( $tickets->Count, 1, "found one ticket" );
452 is( $tickets->First->id, $id1, "correct value" );
454 # IP range, intersect with the ranges
455 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcc::-edcd:ab::'");
456 is( $tickets->Count, 2, "found both tickets" );
458 # IP range, equal to range from the starting IP of the first ticket to the ending IP of the second
460 "(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd::-edcd:ffff:ffff:ffff:ffff:ffff:ffff:ffff'"
462 is( $tickets->Count, 2, "found both tickets" );
464 # IP range, has the both ranges inside it
465 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'd000::/2'");
466 is( $tickets->Count, 2, "found both tickets" );
468 # IP range, greater than both
469 $tickets = RT::Tickets->new( $RT::SystemUser );
470 $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ffff::/16'");
471 is( $tickets->Count, 0, "didn't find ticket" ) or diag "but found ". $tickets->First->id;