rt 4.0.21 (RT#13852)
[freeside.git] / rt / t / customfields / iprange.t
1
2 use strict;
3 use warnings;
4
5 use RT::Test tests => 133;
6
7 my ($baseurl, $agent) =RT::Test->started_ok;
8 ok( $agent->login, 'log in' );
9
10 my $q = RT::Queue->new($RT::SystemUser);
11 $q->Load('General');
12 my $ip_cf = RT::CustomField->new($RT::SystemUser);
13         
14 my ($val,$msg) = $ip_cf->Create(Name => 'IP', Type =>'IPAddressRange', LookupType => 'RT::Queue-RT::Ticket');
15 ok($val,$msg);
16 my $cf_id = $val;
17 $ip_cf->AddToObject($q);
18 use_ok('RT');
19
20 my $cf;
21 diag "load and check basic properties of the IP CF" if $ENV{'TEST_VERBOSE'};
22 {
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'" );
26
27     $cf = $cfs->First;
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" );
32 }
33
34 diag "check that CF applies to queue General" if $ENV{'TEST_VERBOSE'};
35 {
36     my $cfs = $q->TicketCustomFields;
37     $cfs->Limit( FIELD => 'id', VALUE => $cf->id, ENTRYAGGREGATOR => 'AND' );
38     is( $cfs->Count, 1, 'field applies to queue' );
39 }
40
41 diag "create a ticket via web and set IP" if $ENV{'TEST_VERBOSE'};
42 {
43     my $val = '192.168.20.1';
44     ok $agent->goto_create_ticket($q), "go to create ticket";
45     my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
46     $agent->submit_form(
47         form_name => 'TicketCreate',
48         fields    => {
49             Subject                                       => 'test ip',
50             $cf_field => $val,
51         }
52     );
53
54     $agent->content_like( qr/\Q$val/, "IP on the page" );
55     my ($id) = $agent->content =~ /Ticket (\d+) created/;
56     ok( $id, "created ticket $id" );
57
58     my $ticket = RT::Ticket->new($RT::SystemUser);
59     $ticket->Load($id);
60     ok( $ticket->id, 'loaded ticket' );
61     is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
62 }
63
64 diag "create a ticket via web with CIDR" if $ENV{'TEST_VERBOSE'};
65 {
66     my $val = '172.16.20/31';
67     ok $agent->goto_create_ticket($q), "go to create ticket";
68     my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
69     $agent->submit_form(
70         form_name => 'TicketCreate',
71         fields    => {
72             Subject                                       => 'test ip',
73             $cf_field => $val,
74         }
75     );
76
77     my ($id) = $agent->content =~ /Ticket (\d+) created/;
78     ok( $id, "created ticket $id" );
79
80     my $ticket = RT::Ticket->new($RT::SystemUser);
81     $ticket->Load($id);
82     ok( $ticket->id, 'loaded ticket' );
83     is( $ticket->FirstCustomFieldValue('IP'), '172.16.20.0-172.16.20.1', 'correct value' );
84 }
85
86 diag "create a ticket and edit IP field using Edit page" if $ENV{'TEST_VERBOSE'};
87 {
88     my $val = '172.16.0.1';
89     ok $agent->goto_create_ticket($q), "go to create ticket";
90     $agent->submit_form(
91         form_name => 'TicketCreate',
92         fields    => { Subject => 'test ip', }
93     );
94
95     my ($id) = $agent->content =~ /Ticket (\d+) created/;
96     ok( $id, "created ticket $id" );
97     my $cf_field = "Object-RT::Ticket-$id-CustomField-$cf_id-Values";
98
99     $agent->follow_link_ok( { text => 'Basics', n => "1" },
100         "Followed 'Basics' link" );
101     $agent->form_name('TicketModify');
102
103     like( $agent->value($cf_field), qr/^\s*$/, 'IP is empty' );
104     $agent->field( $cf_field => $val );
105     $agent->click('SubmitTicket');
106
107     $agent->content_like( qr/\Q$val/, "IP on the page" );
108
109     my $ticket = RT::Ticket->new($RT::SystemUser);
110     $ticket->Load($id);
111     ok( $ticket->id, 'loaded ticket' );
112     is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
113
114     diag "set IP with spaces around" if $ENV{'TEST_VERBOSE'};
115     $val = "  172.16.0.2  \n  ";
116     $agent->follow_link_ok( { text => 'Basics', n => "1" },
117         "Followed 'Basics' link" );
118     $agent->form_name('TicketModify');
119     like( $agent->value($cf_field),
120         qr/^\s*\Q172.16.0.1\E\s*$/, 'IP is in input box' );
121     $agent->field( $cf_field => $val );
122     $agent->click('SubmitTicket');
123
124     $agent->content_like( qr/\Q172.16.0.2/, "IP on the page" );
125
126     $ticket = RT::Ticket->new($RT::SystemUser);
127     $ticket->Load($id);
128     ok( $ticket->id, 'loaded ticket' );
129     is( $ticket->FirstCustomFieldValue('IP'), '172.16.0.2', 'correct value' );
130
131     diag "replace IP with a range" if $ENV{'TEST_VERBOSE'};
132     $val = '172.16.0.0-172.16.0.255';
133     $agent->follow_link_ok( { text => 'Basics', n => "1" },
134         "Followed 'Basics' link" );
135     $agent->form_name('TicketModify');
136     like( $agent->value($cf_field),
137         qr/^\s*\Q172.16.0.2\E\s*$/, 'IP is in input box' );
138     $agent->field( $cf_field => $val );
139     $agent->click('SubmitTicket');
140
141     $agent->content_like( qr/\Q$val/, "IP on the page" );
142
143     $ticket = RT::Ticket->new($RT::SystemUser);
144     $ticket->Load($id);
145     ok( $ticket->id, 'loaded ticket' );
146     is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
147
148     diag "delete range, add another range using CIDR" if $ENV{'TEST_VERBOSE'};
149     $val = '172.16/16';
150     $agent->follow_link_ok( { text => 'Basics', n => "1" },
151         "Followed 'Basics' link" );
152     $agent->form_name('TicketModify');
153     is( $agent->value($cf_field),
154         '172.16.0.0-172.16.0.255', 'IP is in input box' );
155     $agent->field( $cf_field => $val );
156     $agent->click('SubmitTicket');
157
158     $agent->content_like( qr/\Q$val/, "IP on the page" );
159
160     $ticket = RT::Ticket->new($RT::SystemUser);
161     $ticket->Load($id);
162     ok( $ticket->id, 'loaded ticket' );
163     is( $ticket->FirstCustomFieldValue('IP'),
164         '172.16.0.0-172.16.255.255', 'correct value' );
165 }
166
167 diag "check that we parse correct IPs only" if $ENV{'TEST_VERBOSE'};
168 {
169
170     my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
171     for my $valid (qw/1.0.0.0 255.255.255.255/) {
172         ok $agent->goto_create_ticket($q), "go to create ticket";
173         $agent->submit_form(
174             form_name => 'TicketCreate',
175             fields    => {
176                 Subject   => 'test ip',
177                 $cf_field => $valid,
178             }
179         );
180
181         my ($id) = $agent->content =~ /Ticket (\d+) created/;
182         ok( $id, "created ticket $id" );
183         my $ticket = RT::Ticket->new($RT::SystemUser);
184         $ticket->Load($id);
185         is( $ticket->id, $id, 'loaded ticket' );
186
187         is( $ticket->FirstCustomFieldValue('IP'), $valid, 'correct value' );
188     }
189
190     for my $invalid (qw{255.255.255.256 355.255.255.255 8.13.8/8.13.0/1.0}) {
191         ok $agent->goto_create_ticket($q), "go to create ticket";
192         $agent->submit_form(
193             form_name => 'TicketCreate',
194             fields    => {
195                 Subject   => 'test ip',
196                 $cf_field => $invalid,
197             }
198         );
199
200         $agent->content_like( qr/is not a valid IP address range/, 'ticket fails to create' );
201     }
202
203 }
204
205 diag "search tickets by IP" if $ENV{'TEST_VERBOSE'};
206 {
207     my $val = '172.16.1/31';
208     ok $agent->goto_create_ticket($q), "go to create ticket";
209     my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
210     $agent->submit_form(
211         form_name => 'TicketCreate',
212         fields    => {
213             Subject   => 'test ip',
214             $cf_field => $val,
215         }
216     );
217
218     my ($id) = $agent->content =~ /Ticket (\d+) created/;
219     ok( $id, "created ticket $id" );
220
221     my $ticket = RT::Ticket->new($RT::SystemUser);
222     $ticket->Load($id);
223     ok( $ticket->id, 'loaded ticket' );
224
225     my $tickets = RT::Tickets->new($RT::SystemUser);
226     $tickets->FromSQL("id = $id AND CF.{IP} = '172.16.1.1'");
227     ok( $tickets->Count, "found tickets" );
228
229     is( $ticket->FirstCustomFieldValue('IP'),
230         '172.16.1.0-172.16.1.1', 'correct value' );
231 }
232
233 diag "search tickets by IP range" if $ENV{'TEST_VERBOSE'};
234 {
235     my $val = '172.16.2/26';
236     ok $agent->goto_create_ticket($q), "go to create ticket";
237     my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
238     $agent->submit_form(
239         form_name => 'TicketCreate',
240         fields    => {
241             Subject   => 'test ip',
242             $cf_field => $val,
243         }
244     );
245
246     my ($id) = $agent->content =~ /Ticket (\d+) created/;
247     ok( $id, "created ticket $id" );
248
249     my $ticket = RT::Ticket->new($RT::SystemUser);
250     $ticket->Load($id);
251     ok( $ticket->id, 'loaded ticket' );
252
253     my $tickets = RT::Tickets->new( $RT::SystemUser );
254     $tickets->FromSQL("id = $id AND CF.{IP} = '172.16.2.0-172.16.2.255'");
255     ok( $tickets->Count, "found tickets" );
256
257     is( $ticket->FirstCustomFieldValue('IP'),
258         '172.16.2.0-172.16.2.63', 'correct value' );
259 }
260
261 diag "create two tickets with different IPs and check several searches" if $ENV{'TEST_VERBOSE'};
262 {
263     ok $agent->goto_create_ticket($q), "go to create ticket";
264     my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
265     $agent->submit_form(
266         form_name => 'TicketCreate',
267         fields    => {
268             Subject   => 'test ip',
269             $cf_field => '192.168.21.10',
270         }
271     );
272
273     my ($id1) = $agent->content =~ /Ticket (\d+) created/;
274     ok( $id1, "created first ticket $id1" );
275
276     ok $agent->goto_create_ticket($q), "go to create ticket";
277     $agent->submit_form(
278         form_name => 'TicketCreate',
279         fields    => {
280             Subject   => 'test ip',
281             $cf_field => '192.168.22.10',
282         }
283     );
284
285     my ($id2) = $agent->content =~ /Ticket (\d+) created/;
286     ok( $id2, "created second ticket $id2" );
287
288     my $tickets = RT::Tickets->new( $RT::SystemUser );
289     $tickets->FromSQL("id = $id1 OR id = $id2");
290     is( $tickets->Count, 2, "found both tickets by 'id = x OR y'" );
291
292     # IP
293     $tickets = RT::Tickets->new( $RT::SystemUser );
294     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.10'");
295     is( $tickets->Count, 1, "found one ticket" );
296     is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.21.10', "correct value" );
297     $tickets = RT::Tickets->new( $RT::SystemUser );
298     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.22.10'");
299     is( $tickets->Count, 1, "found one ticket" );
300     is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.22.10', "correct value" );
301
302     # IP/32 - one address
303     $tickets = RT::Tickets->new( $RT::SystemUser );
304     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.10/32'");
305     is( $tickets->Count, 1, "found one ticket" );
306     is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.21.10', "correct value" );
307     $tickets = RT::Tickets->new( $RT::SystemUser );
308     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.22.10/32'");
309     is( $tickets->Count, 1, "found one ticket" );
310     is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.22.10', "correct value" );
311
312     # IP range
313     $tickets = RT::Tickets->new( $RT::SystemUser );
314     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.0-192.168.21.255'");
315     is( $tickets->Count, 1, "found one ticket" );
316     is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.21.10', "correct value" );
317     $tickets = RT::Tickets->new( $RT::SystemUser );
318     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.22.0-192.168.22.255'");
319     is( $tickets->Count, 1, "found one ticket" );
320     is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.22.10', "correct value" );
321
322     # IP range, with start IP greater than end
323     $tickets = RT::Tickets->new( $RT::SystemUser );
324     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.255-192.168.21.0'");
325     is( $tickets->Count, 1, "found one ticket" );
326     is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.21.10', "correct value" );
327     $tickets = RT::Tickets->new( $RT::SystemUser );
328     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.22.255-192.168.22.0'");
329     is( $tickets->Count, 1, "found one ticket" );
330     is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.22.10', "correct value" );
331
332     # CIDR/24
333     $tickets = RT::Tickets->new( $RT::SystemUser );
334     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.0/24'");
335     is( $tickets->Count, 1, "found one ticket" );
336     is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.21.10', "correct value" );
337     $tickets = RT::Tickets->new( $RT::SystemUser );
338     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.22.0/24'");
339     is( $tickets->Count, 1, "found one ticket" );
340     is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.22.10', "correct value" );
341
342     # IP is not in CIDR/24
343     $tickets = RT::Tickets->new( $RT::SystemUser );
344     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} != '192.168.21.0/24'");
345     is( $tickets->Count, 1, "found one ticket" );
346     is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.22.10', "correct value" );
347     $tickets = RT::Tickets->new( $RT::SystemUser );
348     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} != '192.168.22.0/24'");
349     is( $tickets->Count, 1, "found one ticket" );
350     is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.21.10', "correct value" );
351
352     # CIDR or CIDR
353     $tickets = RT::Tickets->new( $RT::SystemUser );
354     $tickets->FromSQL("(id = $id1 OR id = $id2) AND "
355         ."(CF.{IP} = '192.168.21.0/24' OR CF.{IP} = '192.168.22.0/24')");
356     is( $tickets->Count, 2, "found both tickets" );
357 }
358
359 diag "create two tickets with different IP ranges and check several searches" if $ENV{'TEST_VERBOSE'};
360 {
361     ok $agent->goto_create_ticket($q), "go to create ticket";
362     my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
363     $agent->submit_form(
364         form_name => 'TicketCreate',
365         fields    => {
366             Subject   => 'test ip',
367             $cf_field => '192.168.21.0-192.168.21.127',
368         }
369     );
370
371     my ($id1) = $agent->content =~ /Ticket (\d+) created/;
372     ok( $id1, "created first ticket $id1" );
373
374     ok $agent->goto_create_ticket($q), "go to create ticket";
375     $agent->submit_form(
376         form_name => 'TicketCreate',
377         fields    => {
378             Subject   => 'test ip',
379             $cf_field => '192.168.21.128-192.168.21.255',
380         }
381     );
382
383     my ($id2) = $agent->content =~ /Ticket (\d+) created/;
384     ok( $id2, "created ticket $id2" );
385
386     my $tickets = RT::Tickets->new( $RT::SystemUser );
387     $tickets->FromSQL("id = $id1 OR id = $id2");
388     is( $tickets->Count, 2, "found both tickets by 'id = x OR y'" );
389
390     # IP
391     $tickets = RT::Tickets->new( $RT::SystemUser );
392     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.0'");
393     is( $tickets->Count, 1, "found one ticket" );
394     is( $tickets->First->id, $id1, "correct value" );
395     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.64'");
396     is( $tickets->Count, 1, "found one ticket" );
397     is( $tickets->First->id, $id1, "correct value" );
398     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.127'");
399     is( $tickets->Count, 1, "found one ticket" );
400     is( $tickets->First->id, $id1, "correct value" );
401     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.128'");
402     is( $tickets->Count, 1, "found one ticket" );
403     is( $tickets->First->id, $id2, "correct value" );
404     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.191'");
405     is( $tickets->Count, 1, "found one ticket" );
406     is( $tickets->First->id, $id2, "correct value" );
407     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.255'");
408     is( $tickets->Count, 1, "found one ticket" );
409     is( $tickets->First->id, $id2, "correct value" );
410
411     # IP/32 - one address
412     $tickets = RT::Tickets->new( $RT::SystemUser );
413     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.63/32'");
414     is( $tickets->Count, 1, "found one ticket" );
415     is( $tickets->First->id, $id1, "correct value" );
416     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.191/32'");
417     is( $tickets->Count, 1, "found one ticket" );
418     is( $tickets->First->id, $id2, "correct value" );
419
420     # IP range, lower than both
421     $tickets = RT::Tickets->new( $RT::SystemUser );
422     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.20.0-192.168.20.255'");
423     is( $tickets->Count, 0, "didn't finnd ticket" ) or diag "but found ". $tickets->First->id;
424
425     # IP range, intersect with the first range
426     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.20.0-192.168.21.63'");
427     is( $tickets->Count, 1, "found one ticket" );
428     is( $tickets->First->id, $id1, "correct value" );
429
430     # IP range, equal to the first range
431     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.0-192.168.21.127'");
432     is( $tickets->Count, 1, "found one ticket" );
433     is( $tickets->First->id, $id1, "correct value" );
434
435     # IP range, lay inside the first range
436     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.31-192.168.21.63'");
437     is( $tickets->Count, 1, "found one ticket" );
438     is( $tickets->First->id, $id1, "correct value" );
439
440     # IP range, intersect with the ranges
441     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.31-192.168.21.191'");
442     is( $tickets->Count, 2, "found both tickets" );
443
444     # IP range, equal to range from the starting IP of the first ticket to the ending IP of the second
445     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.0-192.168.21.255'");
446     is( $tickets->Count, 2, "found both tickets" );
447
448     # IP range, has the both ranges inside it
449     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168/16'");
450     is( $tickets->Count, 2, "found both tickets" );
451
452     # IP range, greater than both
453     $tickets = RT::Tickets->new( $RT::SystemUser );
454     $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.22/24'");
455     is( $tickets->Count, 0, "didn't find ticket" ) or diag "but found ". $tickets->First->id;
456 }
457
458
459 diag "test the operators in search page" if $ENV{'TEST_VERBOSE'};
460 {
461     $agent->get_ok( $baseurl . "/Search/Build.html?Query=Queue='General'" );
462     $agent->content_contains('CF.{IP}', 'got CF.{IP}');
463     my $form = $agent->form_name('BuildQuery');
464     my $op = $form->find_input("'CF.{IP}'Op");
465     ok( $op, "found 'CF.{IP}'Op" );
466     is_deeply( [ $op->possible_values ], [ '=', '!=', '<', '>' ], 'op values' );
467 }
468