summaryrefslogtreecommitdiff
path: root/rt/t/customfields
diff options
context:
space:
mode:
Diffstat (limited to 'rt/t/customfields')
-rw-r--r--rt/t/customfields/access_via_queue.t30
-rw-r--r--rt/t/customfields/api.t221
-rw-r--r--rt/t/customfields/combo_cascade.t37
-rw-r--r--rt/t/customfields/date_search.t119
-rw-r--r--rt/t/customfields/datetime_search.t141
-rw-r--r--rt/t/customfields/external.t56
-rw-r--r--rt/t/customfields/ip.t285
-rw-r--r--rt/t/customfields/iprange.t469
-rw-r--r--rt/t/customfields/iprangev6.t474
-rw-r--r--rt/t/customfields/ipv6.t252
-rw-r--r--rt/t/customfields/pattern.t44
-rw-r--r--rt/t/customfields/single_values.t37
-rw-r--r--rt/t/customfields/sort_order.t20
-rw-r--r--rt/t/customfields/transaction.t60
14 files changed, 2219 insertions, 26 deletions
diff --git a/rt/t/customfields/access_via_queue.t b/rt/t/customfields/access_via_queue.t
index c291860ea..690e177df 100644
--- a/rt/t/customfields/access_via_queue.t
+++ b/rt/t/customfields/access_via_queue.t
@@ -3,7 +3,7 @@
use strict;
use warnings;
-use RT::Test tests => 35;
+use RT::Test nodata => 1, tests => 37;
use RT::Ticket;
use RT::CustomField;
@@ -11,11 +11,11 @@ my $queue_name = "CFSortQueue-$$";
my $queue = RT::Test->load_or_create_queue( Name => $queue_name );
ok($queue && $queue->id, "$queue_name - test queue creation");
-diag "create a CF\n" if $ENV{TEST_VERBOSE};
+diag "create a CF";
my $cf_name = "Rights$$";
my $cf;
{
- $cf = RT::CustomField->new( $RT::SystemUser );
+ $cf = RT::CustomField->new( RT->SystemUser );
my ($ret, $msg) = $cf->Create(
Name => $cf_name,
Queue => $queue->id,
@@ -98,7 +98,7 @@ ok( RT::Test->set_rights(
my ($baseurl, $m) = RT::Test->started_ok;
ok $m->login( tester => 'password' ), 'logged in';
-diag "check that we have no the CF on the create" if $ENV{'TEST_VERBOSE'};
+diag "check that we don't have the cf on create";
{
$m->submit_form(
form_name => "CreateTicketInQueue",
@@ -115,46 +115,46 @@ diag "check that we have no the CF on the create" if $ENV{'TEST_VERBOSE'};
);
my ($tid) = ($m->content =~ /Ticket (\d+) created/i);
ok $tid, "created a ticket succesfully";
- $m->content_unlike(qr/$cf_name/, "don't see CF");
+ $m->content_lacks($cf_name, "don't see CF");
- $m->follow_link( text => 'Custom Fields' );
- $form = $m->form_number(3);
+ $m->follow_link( id => 'page-basics');
+ $form = $m->form_name('TicketModify');
$cf_field = "Object-RT::Ticket-$tid-CustomField-". $cf->id ."-Value";
ok !$form->find_input( $cf_field ), 'no form field on the page';
}
-diag "check that we see CF as Cc" if $ENV{'TEST_VERBOSE'};
+diag "check that we see CF as Cc";
{
my $ticket = RT::Ticket->new( $tester );
my ($tid, $msg) = $ticket->Create( Queue => $queue, Subject => 'test', Cc => $tester->id );
ok $tid, "created ticket";
ok $m->goto_ticket( $tid ), "opened ticket";
- $m->content_like(qr/$cf_name/, "see CF");
+ $m->content_contains($cf_name, "see CF");
}
-diag "check that owner can see and edit CF" if $ENV{'TEST_VERBOSE'};
+diag "check that owner can see and edit CF";
{
my $ticket = RT::Ticket->new( $tester );
my ($tid, $msg) = $ticket->Create( Queue => $queue, Subject => 'test', Cc => $tester->id, Owner => $tester->id );
ok $tid, "created ticket";
ok $m->goto_ticket( $tid ), "opened ticket";
- $m->content_like(qr/$cf_name/, "see CF");
+ $m->content_contains($cf_name, "see CF");
- $m->follow_link( text => 'Custom Fields' );
- my $form = $m->form_number(3);
+ $m->follow_link( id => 'page-basics');
+ my $form = $m->form_name('TicketModify');
my $cf_field = "Object-RT::Ticket-$tid-CustomField-". $cf->id ."-Value";
ok $form->find_input( $cf_field ), 'form field on the page';
$m->submit_form(
- form_number => 3,
+ form_name => 'TicketModify',
fields => {
$cf_field => "changed cf",
},
);
ok $m->goto_ticket( $tid ), "opened ticket";
- $m->content_like(qr/$cf_name/, "changed cf");
+ $m->content_contains($cf_name, "changed cf");
}
diff --git a/rt/t/customfields/api.t b/rt/t/customfields/api.t
new file mode 100644
index 000000000..d739a572d
--- /dev/null
+++ b/rt/t/customfields/api.t
@@ -0,0 +1,221 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings FATAL => 'all';
+
+use RT::Test nodata => 1, tests => 139;
+
+# Before we get going, ditch all object_cfs; this will remove
+# all custom fields systemwide;
+my $object_cfs = RT::ObjectCustomFields->new(RT->SystemUser);
+$object_cfs->UnLimit();
+while (my $ocf = $object_cfs->Next) {
+ $ocf->Delete();
+}
+
+
+my $queue = RT::Queue->new( RT->SystemUser );
+$queue->Create( Name => 'RecordCustomFields-'.$$ );
+ok ($queue->id, "Created the queue");
+
+my $queue2 = RT::Queue->new( RT->SystemUser );
+$queue2->Create( Name => 'RecordCustomFields2' );
+
+my $ticket = RT::Ticket->new( RT->SystemUser );
+$ticket->Create(
+ Queue => $queue->Id,
+ Requestor => 'root@localhost',
+ Subject => 'RecordCustomFields1',
+);
+
+my $cfs = $ticket->CustomFields;
+is( $cfs->Count, 0 );
+
+# Check that record has no any CF values yet {{{
+my $cfvs = $ticket->CustomFieldValues;
+is( $cfvs->Count, 0 );
+is( $ticket->FirstCustomFieldValue, undef );
+
+my $local_cf1 = RT::CustomField->new( RT->SystemUser );
+$local_cf1->Create( Name => 'RecordCustomFields1-'.$$, Type => 'SelectSingle', Queue => $queue->id );
+$local_cf1->AddValue( Name => 'RecordCustomFieldValues11' );
+$local_cf1->AddValue( Name => 'RecordCustomFieldValues12' );
+
+my $local_cf2 = RT::CustomField->new( RT->SystemUser );
+$local_cf2->Create( Name => 'RecordCustomFields2-'.$$, Type => 'SelectSingle', Queue => $queue->id );
+$local_cf2->AddValue( Name => 'RecordCustomFieldValues21' );
+$local_cf2->AddValue( Name => 'RecordCustomFieldValues22' );
+
+my $global_cf3 = RT::CustomField->new( RT->SystemUser );
+$global_cf3->Create( Name => 'RecordCustomFields3-'.$$, Type => 'SelectSingle', Queue => 0 );
+$global_cf3->AddValue( Name => 'RecordCustomFieldValues31' );
+$global_cf3->AddValue( Name => 'RecordCustomFieldValues32' );
+
+my $local_cf4 = RT::CustomField->new( RT->SystemUser );
+$local_cf4->Create( Name => 'RecordCustomFields4', Type => 'SelectSingle', Queue => $queue2->id );
+$local_cf4->AddValue( Name => 'RecordCustomFieldValues41' );
+$local_cf4->AddValue( Name => 'RecordCustomFieldValues42' );
+
+
+my @custom_fields = ($local_cf1, $local_cf2, $global_cf3);
+
+
+$cfs = $ticket->CustomFields;
+is( $cfs->Count, 3 );
+
+# Check that record has no any CF values yet {{{
+$cfvs = $ticket->CustomFieldValues;
+is( $cfvs->Count, 0 );
+is( $ticket->FirstCustomFieldValue, undef );
+
+# CF with ID -1 shouldnt exist at all
+$cfvs = $ticket->CustomFieldValues( -1 );
+is( $cfvs->Count, 0 );
+is( $ticket->FirstCustomFieldValue( -1 ), undef );
+
+$cfvs = $ticket->CustomFieldValues( 'SomeUnexpedCustomFieldName' );
+is( $cfvs->Count, 0 );
+is( $ticket->FirstCustomFieldValue( 'SomeUnexpedCustomFieldName' ), undef );
+
+for (@custom_fields) {
+ $cfvs = $ticket->CustomFieldValues( $_->id );
+ is( $cfvs->Count, 0 );
+
+ $cfvs = $ticket->CustomFieldValues( $_->Name );
+ is( $cfvs->Count, 0 );
+ is( $ticket->FirstCustomFieldValue( $_->id ), undef );
+ is( $ticket->FirstCustomFieldValue( $_->Name ), undef );
+}
+
+# try to add field value with fields that do not exist {{{
+my ($status, $msg) = $ticket->AddCustomFieldValue( Field => -1 , Value => 'foo' );
+ok(!$status, "shouldn't add value" );
+($status, $msg) = $ticket->AddCustomFieldValue( Field => 'SomeUnexpedCustomFieldName' , Value => 'foo' );
+ok(!$status, "shouldn't add value" );
+
+SKIP: {
+
+ skip "TODO: We want fields that are not allowed to set unexpected values", 10;
+ for (@custom_fields) {
+ ($status, $msg) = $ticket->AddCustomFieldValue( Field => $_ , Value => 'SomeUnexpectedCFValue' );
+ ok( !$status, 'value doesn\'t exist');
+
+ ($status, $msg) = $ticket->AddCustomFieldValue( Field => $_->id , Value => 'SomeUnexpectedCFValue' );
+ ok( !$status, 'value doesn\'t exist');
+
+ ($status, $msg) = $ticket->AddCustomFieldValue( Field => $_->Name , Value => 'SomeUnexpectedCFValue' );
+ ok( !$status, 'value doesn\'t exist');
+ }
+
+ # Let check that we did not add value to be sure
+ # using only FirstCustomFieldValue sub because
+ # we checked other variants allready
+ for (@custom_fields) {
+ is( $ticket->FirstCustomFieldValue( $_->id ), undef );
+ }
+
+}
+# Add some values to our custom fields
+for (@custom_fields) {
+ # this should be tested elsewhere
+ $_->AddValue( Name => 'Foo' );
+ $_->AddValue( Name => 'Bar' );
+}
+
+my $test_add_delete_cycle = sub {
+ my $cb = shift;
+ for (@custom_fields) {
+ ($status, $msg) = $ticket->AddCustomFieldValue( Field => $cb->($_) , Value => 'Foo' );
+ ok( $status, "message: $msg");
+ }
+
+ # does it exist?
+ $cfvs = $ticket->CustomFieldValues;
+ is( $cfvs->Count, 3, "We found all three custom fields on our ticket" );
+ for (@custom_fields) {
+ $cfvs = $ticket->CustomFieldValues( $_->id );
+ is( $cfvs->Count, 1 , "we found one custom field when searching by id");
+
+ $cfvs = $ticket->CustomFieldValues( $_->Name );
+ is( $cfvs->Count, 1 , " We found one custom field when searching by name for " . $_->Name);
+ is( $ticket->FirstCustomFieldValue( $_->id ), 'Foo' , "first value by id is foo");
+ is( $ticket->FirstCustomFieldValue( $_->Name ), 'Foo' , "first value by name is foo");
+ }
+ # because our CFs are SingleValue then new value addition should override
+ for (@custom_fields) {
+ ($status, $msg) = $ticket->AddCustomFieldValue( Field => $_ , Value => 'Bar' );
+ ok( $status, "message: $msg");
+ }
+ $cfvs = $ticket->CustomFieldValues;
+ is( $cfvs->Count, 3 );
+ for (@custom_fields) {
+ $cfvs = $ticket->CustomFieldValues( $_->id );
+ is( $cfvs->Count, 1 );
+
+ $cfvs = $ticket->CustomFieldValues( $_->Name );
+ is( $cfvs->Count, 1 );
+ is( $ticket->FirstCustomFieldValue( $_->id ), 'Bar' );
+ is( $ticket->FirstCustomFieldValue( $_->Name ), 'Bar' );
+ }
+ # delete it
+ for (@custom_fields ) {
+ ($status, $msg) = $ticket->DeleteCustomFieldValue( Field => $_ , Value => 'Bar' );
+ ok( $status, "Deleted a custom field value 'Bar' for field ".$_->id.": $msg");
+ }
+ $cfvs = $ticket->CustomFieldValues;
+ is( $cfvs->Count, 0, "The ticket (".$ticket->id.") no longer has any custom field values" );
+ for (@custom_fields) {
+ $cfvs = $ticket->CustomFieldValues( $_->id );
+ is( $cfvs->Count, 0, $ticket->id." has no values for cf ".$_->id );
+
+ $cfvs = $ticket->CustomFieldValues( $_->Name );
+ is( $cfvs->Count, 0 , $ticket->id." has no values for cf '".$_->Name. "'" );
+ is( $ticket->FirstCustomFieldValue( $_->id ), undef , "There is no first custom field value when loading by id" );
+ is( $ticket->FirstCustomFieldValue( $_->Name ), undef, "There is no first custom field value when loading by Name" );
+ }
+};
+
+# lets test cycle via CF id
+$test_add_delete_cycle->( sub { return $_[0]->id } );
+# lets test cycle via CF object reference
+$test_add_delete_cycle->( sub { return $_[0] } );
+
+$ticket->AddCustomFieldValue( Field => $local_cf2->id , Value => 'Baz' );
+$ticket->AddCustomFieldValue( Field => $global_cf3->id , Value => 'Baz' );
+# now if we ask for cf values on RecordCustomFields4 we should not get any
+$cfvs = $ticket->CustomFieldValues( 'RecordCustomFields4' );
+is( $cfvs->Count, 0, "No custom field values for non-Queue cf" );
+is( $ticket->FirstCustomFieldValue( 'RecordCustomFields4' ), undef, "No first custom field value for non-Queue cf" );
+
+{
+ my $cfname = $global_cf3->Name;
+ ($status, $msg) = $global_cf3->SetDisabled(1);
+ ok($status, "Disabled CF named $cfname");
+
+ my $load = RT::CustomField->new( RT->SystemUser );
+ $load->LoadByName( Name => $cfname);
+ ok($load->Id, "Loaded CF named $cfname");
+ is($load->Id, $global_cf3->Id, "Can load disabled CFs");
+
+ my $dup = RT::CustomField->new( RT->SystemUser );
+ $dup->Create( Name => $cfname, Type => 'SelectSingle', Queue => 0 );
+ ok($dup->Id, "Created CF with duplicate name");
+
+ $load->LoadByName( Name => $cfname);
+ is($load->Id, $dup->Id, "Loading by name gets non-disabled first");
+
+ $dup->SetDisabled(1);
+ $global_cf3->SetDisabled(0);
+
+ $load->LoadByName( Name => $cfname);
+ is($load->Id, $global_cf3->Id, "Loading by name gets non-disabled first, even with order swapped");
+}
+
+#SKIP: {
+# skip "TODO: should we add CF values to objects via CF Name?", 48;
+# names are not unique
+ # lets test cycle via CF Name
+# $test_add_delete_cycle->( sub { return $_[0]->Name } );
+#}
+
+
diff --git a/rt/t/customfields/combo_cascade.t b/rt/t/customfields/combo_cascade.t
new file mode 100644
index 000000000..28eee4527
--- /dev/null
+++ b/rt/t/customfields/combo_cascade.t
@@ -0,0 +1,37 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+
+use RT::Test nodata => 1, tests => 11;
+
+my $q = RT::Queue->new($RT::SystemUser);
+works($q->Create(Name => "CF-Pattern-".$$));
+
+my $cf = RT::CustomField->new($RT::SystemUser);
+my @cf_args = (Name => $q->Name, Type => 'Combobox', Queue => $q->id);
+
+works($cf->Create(@cf_args));
+
+# Set some CFVs with Category markers
+
+my $t = RT::Ticket->new($RT::SystemUser);
+my ($id,undef,$msg) = $t->Create(Queue => $q->id, Subject => 'CF Test');
+works($id,$msg);
+
+sub add_works {
+ works(
+ $cf->AddValue(Name => $_[0], Description => $_[0], Category => $_[1])
+ );
+};
+
+add_works('value1', '1. Category A');
+add_works('value2');
+add_works('value3', '1.1. A-sub one');
+add_works('value4', '1.2. A-sub two');
+add_works('value5', '');
+
+my $cfv = $cf->Values->First;
+is($cfv->Category, '1. Category A');
+works($cfv->SetCategory('1. Category AAA'));
+is($cfv->Category, '1. Category AAA');
+
diff --git a/rt/t/customfields/date_search.t b/rt/t/customfields/date_search.t
new file mode 100644
index 000000000..b425b9e36
--- /dev/null
+++ b/rt/t/customfields/date_search.t
@@ -0,0 +1,119 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use RT::Test nodata => 1, tests => 13;
+
+my $q = RT::Queue->new(RT->SystemUser);
+ok( $q->Create( Name => 'DateCFTest' . $$ ), 'create queue' );
+
+my $cf = RT::CustomField->new(RT->SystemUser);
+ok(
+ $cf->Create(
+ Name => 'date-' . $$,
+ Type => 'Date',
+ MaxValues => 1,
+ LookupType => RT::Ticket->CustomFieldLookupType,
+ ),
+ 'create cf date'
+);
+ok( $cf->AddToObject($q), 'date cf apply to queue' );
+
+my $ticket = RT::Ticket->new(RT->SystemUser);
+
+ok(
+ $ticket->Create(
+ Queue => $q->id,
+ Subject => 'Test',
+ 'CustomField-' . $cf->id => '2010-05-04',
+ ),
+ 'create ticket with cf set to 2010-05-04'
+);
+
+is( $ticket->CustomFieldValues->First->Content, '2010-05-04', 'date in db is' );
+
+{
+
+ my $tickets = RT::Tickets->new(RT->SystemUser);
+ $tickets->LimitCustomField(
+ CUSTOMFIELD => $cf->id,
+ OPERATOR => '=',
+ VALUE => '2010-05-04',
+ );
+ is( $tickets->Count, 1, 'found the ticket with exact date: 2010-05-04' );
+
+}
+
+{
+ my $tickets = RT::Tickets->new(RT->SystemUser);
+ $tickets->LimitCustomField(
+ CUSTOMFIELD => $cf->id,
+ OPERATOR => '>',
+ VALUE => '2010-05-03',
+ );
+
+ is( $tickets->Count, 1, 'found ticket with > 2010-05-03' );
+}
+
+{
+ my $tickets = RT::Tickets->new(RT->SystemUser);
+ $tickets->LimitCustomField(
+ CUSTOMFIELD => $cf->id,
+ OPERATOR => '<',
+ VALUE => '2010-05-05',
+ );
+
+ is( $tickets->Count, 1, 'found ticket with < 2010-05-05' );
+}
+
+{
+
+ my $tickets = RT::Tickets->new(RT->SystemUser);
+ $tickets->LimitCustomField(
+ CUSTOMFIELD => $cf->id,
+ OPERATOR => '=',
+ VALUE => '2010-05-05',
+ );
+
+ is( $tickets->Count, 0, 'did not find the ticket with = 2010-05-05' );
+}
+
+{
+
+ my $tickets = RT::Tickets->new(RT->SystemUser);
+ $tickets->LimitCustomField(
+ CUSTOMFIELD => $cf->id,
+ OPERATOR => '<',
+ VALUE => '2010-05-03',
+ );
+
+ is( $tickets->Count, 0, 'did not find the ticket with < 2010-05-03' );
+}
+
+{
+
+ my $tickets = RT::Tickets->new(RT->SystemUser);
+ $tickets->LimitCustomField(
+ CUSTOMFIELD => $cf->id,
+ OPERATOR => '>',
+ VALUE => '2010-05-05',
+ );
+
+ is( $tickets->Count, 0, 'did not find the ticket with > 2010-05-05' );
+}
+
+$ticket = RT::Ticket->new(RT->SystemUser);
+
+ok(
+ $ticket->Create(
+ Queue => $q->id,
+ Subject => 'Test',
+ 'CustomField-' . $cf->id => '2010-05-04 11:34:56',
+ ),
+ 'create ticket with cf set to 2010-05-04 11:34:56'
+);
+
+is( $ticket->CustomFieldValues->First->Content,
+ '2010-05-04', 'date in db only has date' );
+
diff --git a/rt/t/customfields/datetime_search.t b/rt/t/customfields/datetime_search.t
new file mode 100644
index 000000000..11fe3bc57
--- /dev/null
+++ b/rt/t/customfields/datetime_search.t
@@ -0,0 +1,141 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use RT::Test nodata => 1, tests => 14;
+RT->Config->Set( 'Timezone' => 'EST5EDT' ); # -04:00
+
+my $q = RT::Queue->new(RT->SystemUser);
+ok( $q->Create( Name => 'DateTimeCFTest' . $$ ), 'create queue' );
+
+my $cf = RT::CustomField->new(RT->SystemUser);
+ok(
+ $cf->Create(
+ Name => 'datetime-' . $$,
+ Type => 'DateTime',
+ MaxValues => 1,
+ LookupType => RT::Ticket->CustomFieldLookupType,
+ ),
+ 'create cf datetime'
+);
+ok( $cf->AddToObject($q), 'date cf apply to queue' );
+
+my $ticket = RT::Ticket->new(RT->SystemUser);
+
+ok(
+ $ticket->Create(
+ Queue => $q->id,
+ Subject => 'Test',
+ 'CustomField-' . $cf->id => '2010-05-04 07:00:00',
+ ),
+ 'create ticket with cf set to 2010-05-04 07:00:00( 2010-05-04 11:00:00 with UTC )'
+);
+
+is(
+ $ticket->CustomFieldValues->First->Content,
+ '2010-05-04 11:00:00',
+ 'date in db is in timezone UTC'
+);
+
+{
+
+ my $tickets = RT::Tickets->new(RT->SystemUser);
+ $tickets->LimitCustomField(
+ CUSTOMFIELD => $cf->id,
+ OPERATOR => '=',
+ VALUE => '2010-05-04 07:00:00', # this timezone is server
+ );
+
+ is( $tickets->Count, 1, 'found the ticket with exact date: 2010-05-04 07:00:00' );
+}
+
+{
+
+ # TODO according to the code, if OPERATOR is '=', it means on that day
+ # this will test this behavior
+ my $tickets = RT::Tickets->new(RT->SystemUser);
+ $tickets->LimitCustomField(
+ CUSTOMFIELD => $cf->id,
+ OPERATOR => '=',
+ VALUE => '2010-05-04',
+ );
+
+ is( $tickets->Count, 1, 'found the ticket with rough date: 2010-05-04' );
+}
+
+{
+
+ # TODO according to the code, if OPERATOR is '=', it means on that day
+ # this will test this behavior
+ my $tickets = RT::Tickets->new(RT->SystemUser);
+ $tickets->LimitCustomField(
+ CUSTOMFIELD => $cf->id,
+ OPERATOR => '=',
+ VALUE => '2010-05-05',
+ );
+
+ is( $tickets->Count, 0, 'did not find the ticket with wrong datetime: 2010-05-05' );
+}
+
+my $tickets = RT::Tickets->new( RT->SystemUser );
+$tickets->UnLimit;
+while( my $ticket = $tickets->Next ) {
+ $ticket->Delete();
+}
+
+{
+ ok(
+ $ticket->Create(
+ Queue => $q->id,
+ Subject => 'Test',
+ 'CustomField-' . $cf->id => '2010-06-21 17:00:01',
+ ),
+'create ticket with cf set to 2010-06-21 17:00:01( 2010-06-21 21:00:01 with UTC )'
+ );
+
+ my $shanghai = RT::Test->load_or_create_user(
+ Name => 'shanghai',
+ Timezone => 'Asia/Shanghai',
+ );
+
+ ok(
+ $shanghai->PrincipalObj->GrantRight(
+ Right => 'SuperUser',
+ Object => $RT::System,
+ )
+ );
+
+ my $current_user = RT::CurrentUser->new($shanghai);
+ my $tickets = RT::Tickets->new($current_user);
+ $tickets->LimitCustomField(
+ CUSTOMFIELD => $cf->id,
+ OPERATOR => '=',
+ VALUE => '2010-06-22',
+ );
+ is( $tickets->Count, 1, 'found the ticket with rough datetime: 2010-06-22' );
+
+ $tickets->UnLimit;
+ $tickets->LimitCustomField(
+ CUSTOMFIELD => $cf->id,
+ OPERATOR => '>',
+ VALUE => '2010-06-21',
+ );
+ is( $tickets->Count, 1, 'found the ticket with > 2010-06-21' );
+
+ $tickets->UnLimit;
+ $tickets->LimitCustomField(
+ CUSTOMFIELD => $cf->id,
+ OPERATOR => '<',
+ VALUE => '2010-06-23',
+ );
+ is( $tickets->Count, 1, 'found the ticket with < 2010-06-23' );
+
+ $tickets->UnLimit;
+ $tickets->LimitCustomField(
+ CUSTOMFIELD => $cf->id,
+ OPERATOR => '=',
+ VALUE => '2010-06-22 05:00:01',
+ );
+ is( $tickets->Count, 1, 'found the ticket with = 2010-06-22 01:00:01' );
+}
diff --git a/rt/t/customfields/external.t b/rt/t/customfields/external.t
new file mode 100644
index 000000000..0abf6eca1
--- /dev/null
+++ b/rt/t/customfields/external.t
@@ -0,0 +1,56 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use RT;
+use RT::Test nodata => 1, tests => 11;
+
+sub new (*) {
+ my $class = shift;
+ return $class->new(RT->SystemUser);
+}
+
+use constant VALUES_CLASS => 'RT::CustomFieldValues::Groups';
+RT->Config->Set(CustomFieldValuesSources => VALUES_CLASS);
+
+my $q = new( RT::Queue );
+isa_ok( $q, 'RT::Queue' );
+my ($qid) = $q->Create( Name => "CF-External-". $$ );
+ok( $qid, "created queue" );
+my %arg = ( Name => $q->Name,
+ Type => 'Select',
+ Queue => $q->id,
+ MaxValues => 1,
+ ValuesClass => VALUES_CLASS );
+
+my $cf = new( RT::CustomField );
+isa_ok( $cf, 'RT::CustomField' );
+
+{
+ my ($cfid, $msg) = $cf->Create( %arg );
+ ok( $cfid, "created cf" ) or diag "error: $msg";
+ is( $cf->ValuesClass, VALUES_CLASS, "right values class" );
+ ok( $cf->IsExternalValues, "custom field has external values" );
+}
+
+{
+ # create at least on group for the tests
+ my $group = RT::Group->new( RT->SystemUser );
+ my ($ret, $msg) = $group->CreateUserDefinedGroup( Name => $q->Name );
+ ok $ret, 'created group' or diag "error: $msg";
+}
+
+{
+ my $values = $cf->Values;
+ isa_ok( $values, VALUES_CLASS );
+ ok( $values->Count, "we have values" );
+ my ($failure, $count) = (0, 0);
+ while( my $value = $values->Next ) {
+ $count++;
+ $failure = 1 unless $value->Name;
+ }
+ ok( !$failure, "all values have name" );
+ is( $values->Count, $count, "count is correct" );
+}
+
diff --git a/rt/t/customfields/ip.t b/rt/t/customfields/ip.t
new file mode 100644
index 000000000..f73e63fa5
--- /dev/null
+++ b/rt/t/customfields/ip.t
@@ -0,0 +1,285 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 73;
+
+my ( $baseurl, $agent ) = RT::Test->started_ok;
+ok( $agent->login, 'log in' );
+
+my $q = RT::Queue->new($RT::SystemUser);
+$q->Load('General');
+my $ip_cf = RT::CustomField->new($RT::SystemUser);
+
+my ( $val, $msg ) = $ip_cf->Create(
+ Name => 'IP',
+ Type => 'IPAddress',
+ LookupType => 'RT::Queue-RT::Ticket'
+);
+ok( $val, $msg );
+my $cf_id = $val;
+$ip_cf->AddToObject($q);
+use_ok('RT');
+
+my $cf;
+diag "load and check basic properties of the IP CF" if $ENV{'TEST_VERBOSE'};
+{
+ my $cfs = RT::CustomFields->new($RT::SystemUser);
+ $cfs->Limit( FIELD => 'Name', VALUE => 'IP' );
+ is( $cfs->Count, 1, "found one CF with name 'IP'" );
+
+ $cf = $cfs->First;
+ is( $cf->Type, 'IPAddress', 'type check' );
+ is( $cf->LookupType, 'RT::Queue-RT::Ticket', 'lookup type check' );
+ ok( !$cf->MaxValues, "unlimited number of values" );
+ ok( !$cf->Disabled, "not disabled" );
+}
+
+diag "check that CF applies to queue General" if $ENV{'TEST_VERBOSE'};
+{
+ my $cfs = $q->TicketCustomFields;
+ $cfs->Limit( FIELD => 'id', VALUE => $cf->id, ENTRYAGGREGATOR => 'AND' );
+ is( $cfs->Count, 1, 'field applies to queue' );
+}
+
+diag "create a ticket via web and set IP" if $ENV{'TEST_VERBOSE'};
+{
+ my $val = '192.168.20.1';
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => $val,
+ }
+ );
+
+ $agent->content_contains( $val, "IP on the page" );
+ my ($id) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id, "created ticket $id" );
+
+ my $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+ is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
+}
+
+diag "create a ticket and edit IP field using Edit page"
+ if $ENV{'TEST_VERBOSE'};
+{
+ my $val = '172.16.0.1';
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => { Subject => 'test ip', }
+ );
+
+ my ($id) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id, "created ticket $id" );
+ my $cf_field = "Object-RT::Ticket-$id-CustomField-$cf_id-Values";
+
+ $agent->follow_link_ok( { text => 'Basics', n => "1" },
+ "Followed 'Basics' link" );
+ $agent->form_name('TicketModify');
+
+ is( $agent->value($cf_field), '', 'IP is empty' );
+ $agent->field( $cf_field => $val );
+ $agent->click('SubmitTicket');
+
+ $agent->content_contains( $val, "IP on the page" );
+
+ my $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+ is( $ticket->FirstCustomFieldValue('IP'), '172.16.0.1' );
+
+ diag "set IP with spaces around" if $ENV{'TEST_VERBOSE'};
+ $val = " 172.16.0.2 \n ";
+ $agent->follow_link_ok( { text => 'Basics', n => "1" },
+ "Followed 'Basics' link" );
+ $agent->form_name('TicketModify');
+ is( $agent->value($cf_field), '172.16.0.1', 'IP is in input box' );
+ $agent->field( $cf_field => $val );
+ $agent->click('SubmitTicket');
+
+ $agent->content_contains( '172.16.0.2', "IP on the page" );
+
+ $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+ is( $ticket->FirstCustomFieldValue('IP'),
+ '172.16.0.2', 'correct value' );
+}
+
+diag "check that we parse correct IPs only" if $ENV{'TEST_VERBOSE'};
+{
+
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ for my $valid (qw/1.0.0.0 255.255.255.255/) {
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => $valid,
+ }
+ );
+
+ my ($id) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id, "created ticket $id" );
+ my $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ is( $ticket->id, $id, 'loaded ticket' );
+
+ is( $ticket->FirstCustomFieldValue('IP'),
+ $valid, 'correct value' );
+ }
+
+ for my $invalid (qw{255.255.255.256 355.255.255.255 8.13.8/8.13.0/1.0}) {
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => $invalid,
+ }
+ );
+
+ $agent->content_contains( 'can not be parsed as an IP address',
+ 'ticket fails to create' );
+ }
+
+}
+
+diag "search tickets by IP" if $ENV{'TEST_VERBOSE'};
+{
+ my $val = '172.16.1.1';
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => $val,
+ }
+ );
+
+ my ($id) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id, "created ticket $id" );
+
+ my $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+
+ my $tickets = RT::Tickets->new($RT::SystemUser);
+ $tickets->FromSQL("id = $id AND CF.{IP} = '172.16.1.1'");
+ ok( $tickets->Count, "found tickets" );
+}
+
+diag "create two tickets with different IPs and check several searches"
+ if $ENV{'TEST_VERBOSE'};
+{
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => '192.168.21.10',
+ }
+ );
+
+ my ($id1) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id1, "created first ticket $id1" );
+
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => '192.168.22.10',
+ }
+ );
+
+ my ($id2) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id2, "created second ticket $id2" );
+
+ my $tickets = RT::Tickets->new($RT::SystemUser);
+ $tickets->FromSQL("id = $id1 OR id = $id2");
+ is( $tickets->Count, 2, "found both tickets by 'id = x OR y'" );
+
+ # IP
+ $tickets = RT::Tickets->new($RT::SystemUser);
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.10'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'),
+ '192.168.21.10', "correct value" );
+ $tickets = RT::Tickets->new($RT::SystemUser);
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.22.10'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'),
+ '192.168.22.10', "correct value" );
+
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} <= '192.168.21.10'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'),
+ '192.168.21.10', "correct value" );
+ $tickets = RT::Tickets->new($RT::SystemUser);
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} >= '192.168.22.10'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'),
+ '192.168.22.10', "correct value" );
+
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} > '192.168.22.10'");
+ is( $tickets->Count, 0, "no tickets found" );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} < '192.168.21.10'");
+ is( $tickets->Count, 0, "no tickets found" );
+
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} < '192.168.22.10'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'),
+ '192.168.21.10', "correct value" );
+
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} > '192.168.21.10'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'),
+ '192.168.22.10', "correct value" );
+}
+
+diag "create a ticket with an IP of 10.0.0.1 and search for doesn't match '10.0.0.'."
+ if $ENV{'TEST_VERBOSE'};
+{
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'local',
+ $cf_field => '10.0.0.1',
+ }
+ );
+
+ my ($id) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id, "created first ticket $id" );
+
+ my $tickets = RT::Tickets->new($RT::SystemUser);
+ $tickets->FromSQL("id=$id AND CF.{IP} NOT LIKE '10.0.0.'");
+
+ SKIP: {
+ skip "partical ip parse causes ambiguity", 1;
+ is( $tickets->Count, 0, "should not have found the ticket" );
+ }
+}
+
+
+diag "test the operators in search page" if $ENV{'TEST_VERBOSE'};
+{
+ $agent->get_ok( $baseurl . "/Search/Build.html?Query=Queue='General'" );
+ $agent->content_contains('CF.{IP}', 'got CF.{IP}');
+ my $form = $agent->form_name('BuildQuery');
+ my $op = $form->find_input("'CF.{IP}'Op");
+ ok( $op, "found 'CF.{IP}'Op" );
+ is_deeply( [ $op->possible_values ], [ '=', '!=', '<', '>' ], 'op values' );
+}
diff --git a/rt/t/customfields/iprange.t b/rt/t/customfields/iprange.t
new file mode 100644
index 000000000..118d23c88
--- /dev/null
+++ b/rt/t/customfields/iprange.t
@@ -0,0 +1,469 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 133;
+
+my ($baseurl, $agent) =RT::Test->started_ok;
+ok( $agent->login, 'log in' );
+
+my $q = RT::Queue->new($RT::SystemUser);
+$q->Load('General');
+my $ip_cf = RT::CustomField->new($RT::SystemUser);
+
+my ($val,$msg) = $ip_cf->Create(Name => 'IP', Type =>'IPAddressRange', LookupType => 'RT::Queue-RT::Ticket');
+ok($val,$msg);
+my $cf_id = $val;
+$ip_cf->AddToObject($q);
+use_ok('RT');
+
+my $cf;
+diag "load and check basic properties of the IP CF" if $ENV{'TEST_VERBOSE'};
+{
+ my $cfs = RT::CustomFields->new( $RT::SystemUser );
+ $cfs->Limit( FIELD => 'Name', VALUE => 'IP' );
+ is( $cfs->Count, 1, "found one CF with name 'IP'" );
+
+ $cf = $cfs->First;
+ is( $cf->Type, 'IPAddressRange', 'type check' );
+ is( $cf->LookupType, 'RT::Queue-RT::Ticket', 'lookup type check' );
+ ok( !$cf->MaxValues, "unlimited number of values" );
+ ok( !$cf->Disabled, "not disabled" );
+}
+
+diag "check that CF applies to queue General" if $ENV{'TEST_VERBOSE'};
+{
+ my $cfs = $q->TicketCustomFields;
+ $cfs->Limit( FIELD => 'id', VALUE => $cf->id, ENTRYAGGREGATOR => 'AND' );
+ is( $cfs->Count, 1, 'field applies to queue' );
+}
+
+diag "create a ticket via web and set IP" if $ENV{'TEST_VERBOSE'};
+{
+ my $val = '192.168.20.1';
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => $val,
+ }
+ );
+
+ $agent->content_like( qr/\Q$val/, "IP on the page" );
+ my ($id) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id, "created ticket $id" );
+
+ my $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+ is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
+}
+
+diag "create a ticket via web with CIDR" if $ENV{'TEST_VERBOSE'};
+{
+ my $val = '172.16.20/31';
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => $val,
+ }
+ );
+
+ my ($id) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id, "created ticket $id" );
+
+ my $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+ is( $ticket->FirstCustomFieldValue('IP'), '172.16.20.0-172.16.20.1', 'correct value' );
+}
+
+diag "create a ticket and edit IP field using Edit page" if $ENV{'TEST_VERBOSE'};
+{
+ my $val = '172.16.0.1';
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => { Subject => 'test ip', }
+ );
+
+ my ($id) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id, "created ticket $id" );
+ my $cf_field = "Object-RT::Ticket-$id-CustomField-$cf_id-Values";
+
+ $agent->follow_link_ok( { text => 'Basics', n => "1" },
+ "Followed 'Basics' link" );
+ $agent->form_name('TicketModify');
+
+ like( $agent->value($cf_field), qr/^\s*$/, 'IP is empty' );
+ $agent->field( $cf_field => $val );
+ $agent->click('SubmitTicket');
+
+ $agent->content_like( qr/\Q$val/, "IP on the page" );
+
+ my $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+ is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
+
+ diag "set IP with spaces around" if $ENV{'TEST_VERBOSE'};
+ $val = " 172.16.0.2 \n ";
+ $agent->follow_link_ok( { text => 'Basics', n => "1" },
+ "Followed 'Basics' link" );
+ $agent->form_name('TicketModify');
+ like( $agent->value($cf_field),
+ qr/^\s*\Q172.16.0.1\E\s*$/, 'IP is in input box' );
+ $agent->field( $cf_field => $val );
+ $agent->click('SubmitTicket');
+
+ $agent->content_like( qr/\Q172.16.0.2/, "IP on the page" );
+
+ $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+ is( $ticket->FirstCustomFieldValue('IP'), '172.16.0.2', 'correct value' );
+
+ diag "replace IP with a range" if $ENV{'TEST_VERBOSE'};
+ $val = '172.16.0.0-172.16.0.255';
+ $agent->follow_link_ok( { text => 'Basics', n => "1" },
+ "Followed 'Basics' link" );
+ $agent->form_name('TicketModify');
+ like( $agent->value($cf_field),
+ qr/^\s*\Q172.16.0.2\E\s*$/, 'IP is in input box' );
+ $agent->field( $cf_field => $val );
+ $agent->click('SubmitTicket');
+
+ $agent->content_like( qr/\Q$val/, "IP on the page" );
+
+ $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+ is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
+
+ diag "delete range, add another range using CIDR" if $ENV{'TEST_VERBOSE'};
+ $val = '172.16/16';
+ $agent->follow_link_ok( { text => 'Basics', n => "1" },
+ "Followed 'Basics' link" );
+ $agent->form_name('TicketModify');
+ is( $agent->value($cf_field),
+ '172.16.0.0-172.16.0.255', 'IP is in input box' );
+ $agent->field( $cf_field => $val );
+ $agent->click('SubmitTicket');
+
+ $agent->content_like( qr/\Q$val/, "IP on the page" );
+
+ $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+ is( $ticket->FirstCustomFieldValue('IP'),
+ '172.16.0.0-172.16.255.255', 'correct value' );
+}
+
+diag "check that we parse correct IPs only" if $ENV{'TEST_VERBOSE'};
+{
+
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ for my $valid (qw/1.0.0.0 255.255.255.255/) {
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => $valid,
+ }
+ );
+
+ my ($id) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id, "created ticket $id" );
+ my $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ is( $ticket->id, $id, 'loaded ticket' );
+
+ is( $ticket->FirstCustomFieldValue('IP'), $valid, 'correct value' );
+ }
+
+ for my $invalid (qw{255.255.255.256 355.255.255.255 8.13.8/8.13.0/1.0}) {
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => $invalid,
+ }
+ );
+
+ $agent->content_like( qr/can not be parsed as an IP address range/, 'ticket fails to create' );
+ }
+
+}
+
+diag "search tickets by IP" if $ENV{'TEST_VERBOSE'};
+{
+ my $val = '172.16.1/31';
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => $val,
+ }
+ );
+
+ my ($id) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id, "created ticket $id" );
+
+ my $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+
+ my $tickets = RT::Tickets->new($RT::SystemUser);
+ $tickets->FromSQL("id = $id AND CF.{IP} = '172.16.1.1'");
+ ok( $tickets->Count, "found tickets" );
+
+ is( $ticket->FirstCustomFieldValue('IP'),
+ '172.16.1.0-172.16.1.1', 'correct value' );
+}
+
+diag "search tickets by IP range" if $ENV{'TEST_VERBOSE'};
+{
+ my $val = '172.16.2/26';
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => $val,
+ }
+ );
+
+ my ($id) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id, "created ticket $id" );
+
+ my $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+
+ my $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("id = $id AND CF.{IP} = '172.16.2.0-172.16.2.255'");
+ ok( $tickets->Count, "found tickets" );
+
+ is( $ticket->FirstCustomFieldValue('IP'),
+ '172.16.2.0-172.16.2.63', 'correct value' );
+}
+
+diag "create two tickets with different IPs and check several searches" if $ENV{'TEST_VERBOSE'};
+{
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => '192.168.21.10',
+ }
+ );
+
+ my ($id1) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id1, "created first ticket $id1" );
+
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => '192.168.22.10',
+ }
+ );
+
+ my ($id2) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id2, "created second ticket $id2" );
+
+ my $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("id = $id1 OR id = $id2");
+ is( $tickets->Count, 2, "found both tickets by 'id = x OR y'" );
+
+ # IP
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.10'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.21.10', "correct value" );
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.22.10'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.22.10', "correct value" );
+
+ # IP/32 - one address
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.10/32'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.21.10', "correct value" );
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.22.10/32'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.22.10', "correct value" );
+
+ # IP range
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.0-192.168.21.255'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.21.10', "correct value" );
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.22.0-192.168.22.255'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.22.10', "correct value" );
+
+ # IP range, with start IP greater than end
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.255-192.168.21.0'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.21.10', "correct value" );
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.22.255-192.168.22.0'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.22.10', "correct value" );
+
+ # CIDR/24
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.0/24'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.21.10', "correct value" );
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.22.0/24'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.22.10', "correct value" );
+
+ # IP is not in CIDR/24
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} != '192.168.21.0/24'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.22.10', "correct value" );
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} != '192.168.22.0/24'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), '192.168.21.10', "correct value" );
+
+ # CIDR or CIDR
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND "
+ ."(CF.{IP} = '192.168.21.0/24' OR CF.{IP} = '192.168.22.0/24')");
+ is( $tickets->Count, 2, "found both tickets" );
+}
+
+diag "create two tickets with different IP ranges and check several searches" if $ENV{'TEST_VERBOSE'};
+{
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => '192.168.21.0-192.168.21.127',
+ }
+ );
+
+ my ($id1) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id1, "created first ticket $id1" );
+
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => '192.168.21.128-192.168.21.255',
+ }
+ );
+
+ my ($id2) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id2, "created ticket $id2" );
+
+ my $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("id = $id1 OR id = $id2");
+ is( $tickets->Count, 2, "found both tickets by 'id = x OR y'" );
+
+ # IP
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.0'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id1, "correct value" );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.64'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id1, "correct value" );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.127'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id1, "correct value" );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.128'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id2, "correct value" );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.191'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id2, "correct value" );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.255'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id2, "correct value" );
+
+ # IP/32 - one address
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.63/32'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id1, "correct value" );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.191/32'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id2, "correct value" );
+
+ # IP range, lower than both
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.20.0-192.168.20.255'");
+ is( $tickets->Count, 0, "didn't finnd ticket" ) or diag "but found ". $tickets->First->id;
+
+ # IP range, intersect with the first range
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.20.0-192.168.21.63'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id1, "correct value" );
+
+ # IP range, equal to the first range
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.0-192.168.21.127'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id1, "correct value" );
+
+ # IP range, lay inside the first range
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.31-192.168.21.63'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id1, "correct value" );
+
+ # IP range, intersect with the ranges
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.31-192.168.21.191'");
+ is( $tickets->Count, 2, "found both tickets" );
+
+ # IP range, equal to range from the starting IP of the first ticket to the ending IP of the second
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.21.0-192.168.21.255'");
+ is( $tickets->Count, 2, "found both tickets" );
+
+ # IP range, has the both ranges inside it
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168/16'");
+ is( $tickets->Count, 2, "found both tickets" );
+
+ # IP range, greater than both
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '192.168.22/24'");
+ is( $tickets->Count, 0, "didn't find ticket" ) or diag "but found ". $tickets->First->id;
+}
+
+
+diag "test the operators in search page" if $ENV{'TEST_VERBOSE'};
+{
+ $agent->get_ok( $baseurl . "/Search/Build.html?Query=Queue='General'" );
+ $agent->content_contains('CF.{IP}', 'got CF.{IP}');
+ my $form = $agent->form_name('BuildQuery');
+ my $op = $form->find_input("'CF.{IP}'Op");
+ ok( $op, "found 'CF.{IP}'Op" );
+ is_deeply( [ $op->possible_values ], [ '=', '!=', '<', '>' ], 'op values' );
+}
+
diff --git a/rt/t/customfields/iprangev6.t b/rt/t/customfields/iprangev6.t
new file mode 100644
index 000000000..d823dd6e3
--- /dev/null
+++ b/rt/t/customfields/iprangev6.t
@@ -0,0 +1,474 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 158;
+
+my ($baseurl, $agent) =RT::Test->started_ok;
+ok( $agent->login, 'log in' );
+
+my $q = RT::Queue->new($RT::SystemUser);
+$q->Load('General');
+my $ip_cf = RT::CustomField->new($RT::SystemUser);
+
+my ($val,$msg) = $ip_cf->Create(Name => 'IP', Type =>'IPAddressRange', LookupType => 'RT::Queue-RT::Ticket');
+ok($val,$msg);
+my $cf_id = $val;
+$ip_cf->AddToObject($q);
+use_ok('RT');
+
+my $cf;
+diag "load and check basic properties of the IP CF" if $ENV{'TEST_VERBOSE'};
+{
+ my $cfs = RT::CustomFields->new( $RT::SystemUser );
+ $cfs->Limit( FIELD => 'Name', VALUE => 'IP' );
+ is( $cfs->Count, 1, "found one CF with name 'IP'" );
+
+ $cf = $cfs->First;
+ is( $cf->Type, 'IPAddressRange', 'type check' );
+ is( $cf->LookupType, 'RT::Queue-RT::Ticket', 'lookup type check' );
+ ok( !$cf->MaxValues, "unlimited number of values" );
+ ok( !$cf->Disabled, "not disabled" );
+}
+
+diag "check that CF applies to queue General" if $ENV{'TEST_VERBOSE'};
+{
+ my $cfs = $q->TicketCustomFields;
+ $cfs->Limit( FIELD => 'id', VALUE => $cf->id, ENTRYAGGREGATOR => 'AND' );
+ is( $cfs->Count, 1, 'field applies to queue' );
+}
+
+my %valid = (
+ 'abcd:' x 7 . 'abcd' => 'abcd:' x 7 . 'abcd',
+ '034:' x 7 . '034' => '0034:' x 7 . '0034',
+ 'abcd::' => 'abcd:' . '0000:' x 6 . '0000',
+ '::abcd' => '0000:' x 7 . 'abcd',
+ 'abcd::034' => 'abcd:' . '0000:' x 6 . '0034',
+ 'abcd::192.168.1.1' => 'abcd:' . '0000:' x 5 . 'c0a8:0101',
+ '::192.168.1.1' => '0000:' x 6 . 'c0a8:0101',
+ '::' => '0000:' x 7 . '0000',
+);
+
+diag "create a ticket via web and set IP" if $ENV{'TEST_VERBOSE'};
+{
+ for my $ip ( keys %valid ) {
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => $ip,
+ }
+ );
+
+ $agent->content_like( qr/$valid{$ip}/, "IP on the page" );
+ my ($id) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id, "created ticket $id" );
+
+ my $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+ is( $ticket->FirstCustomFieldValue('IP'), $valid{$ip},
+ 'correct value' );
+ }
+}
+
+diag "create a ticket via web with CIDR" if $ENV{'TEST_VERBOSE'};
+{
+ my $val = 'abcd:034::/31';
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => $val,
+ }
+ );
+
+ my ($id) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id, "created ticket $id" );
+
+ my $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+ is(
+ $ticket->FirstCustomFieldValue('IP'),
+'abcd:0034:0000:0000:0000:0000:0000:0000-abcd:0035:ffff:ffff:ffff:ffff:ffff:ffff',
+ 'correct value'
+ );
+}
+
+diag "create a ticket and edit IP field using Edit page" if $ENV{'TEST_VERBOSE'};
+{
+ my $val = 'abcd' . ':abcd' x 7;
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => { Subject => 'test ip', }
+ );
+
+ my ($id) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id, "created ticket $id" );
+ my $cf_field = "Object-RT::Ticket-$id-CustomField-$cf_id-Values";
+
+ $agent->follow_link_ok( { text => 'Basics', n => "1" },
+ "Followed 'Basics' link" );
+ $agent->form_name('TicketModify');
+
+ is( $agent->value($cf_field), '', 'IP is empty' );
+ $agent->field( $cf_field => $val );
+ $agent->click('SubmitTicket');
+
+ $agent->content_contains( $val, "IP on the page" );
+
+ my $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+ is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
+
+ diag "set IP with spaces around" if $ENV{'TEST_VERBOSE'};
+ $agent->follow_link_ok( { text => 'Basics', n => "1" },
+ "Followed 'Basics' link" );
+ $agent->form_name('TicketModify');
+ is( $agent->value($cf_field), $val, 'IP is in input box' );
+ $val = 'bbcd' . ':abcd' x 7;
+ $agent->field( $cf_field => " $val " );
+ $agent->click('SubmitTicket');
+
+ $agent->content_contains( $val, "IP on the page" );
+
+ $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+ is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
+
+ diag "replace IP with a range" if $ENV{'TEST_VERBOSE'};
+ $agent->follow_link_ok( { text => 'Basics', n => "1" },
+ "Followed 'Basics' link" );
+ $agent->form_name('TicketModify');
+ is( $agent->value($cf_field), $val, 'IP is in input box' );
+ $val = 'abcd' . ':0000' x 7 . '-' . 'abcd' . ':ffff' x 7;
+ $agent->field( $cf_field => 'abcd::/16' );
+ $agent->click('SubmitTicket');
+
+ $agent->content_contains( $val, "IP on the page" );
+
+ $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+ is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
+
+ diag "delete range, add another range using CIDR" if $ENV{'TEST_VERBOSE'};
+ $agent->follow_link_ok( { text => 'Basics', n => "1" },
+ "Followed 'Basics' link" );
+ $agent->form_name('TicketModify');
+ is( $agent->value($cf_field), $val, 'IP is in input box' );
+ $val = 'bb00' . ':0000' x 7 . '-' . 'bbff' . ':ffff' x 7;
+ $agent->field( $cf_field => $val );
+ $agent->click('SubmitTicket');
+
+ $agent->content_contains( $val, "IP on the page" );
+
+ $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+ is( $ticket->FirstCustomFieldValue('IP'), $val, 'correct value' );
+}
+
+diag "check that we parse correct IPs only" if $ENV{'TEST_VERBOSE'};
+{
+
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ my @invalid =
+ ( 'abcd:', 'efgh', 'abcd:' x 8 . 'abcd', 'abcd::abcd::abcd' );
+ for my $invalid (@invalid) {
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => $invalid,
+ }
+ );
+
+ $agent->content_like( qr/can not be parsed as an IP address range/,
+ 'ticket fails to create' );
+ }
+
+}
+
+diag "search tickets by IP" if $ENV{'TEST_VERBOSE'};
+{
+ my $val = 'abcd::/16';
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => $val,
+ }
+ );
+
+ my ($id) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id, "created ticket $id" );
+
+ my $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+
+ my $tickets = RT::Tickets->new($RT::SystemUser);
+ $tickets->FromSQL("id = $id AND CF.{IP} = 'abcd::/16'");
+ ok( $tickets->Count, "found tickets" );
+ is(
+ $ticket->FirstCustomFieldValue('IP'),
+'abcd:0000:0000:0000:0000:0000:0000:0000-abcd:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
+ 'correct value'
+ );
+}
+
+diag "search tickets by IP range" if $ENV{'TEST_VERBOSE'};
+{
+ my $val = 'abcd:ef00::/24';
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => $val,
+ }
+ );
+
+ my ($id) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id, "created ticket $id" );
+
+ my $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+
+ my $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("id = $id AND CF.{IP} =
+ 'abcd:ef::-abcd:efff:ffff:ffff:ffff:ffff:ffff:ffff'");
+ ok( $tickets->Count, "found tickets" );
+
+ is(
+ $ticket->FirstCustomFieldValue('IP'),
+'abcd:ef00:0000:0000:0000:0000:0000:0000-abcd:efff:ffff:ffff:ffff:ffff:ffff:ffff',
+ 'correct value'
+ );
+}
+
+diag "create two tickets with different IPs and check several searches" if $ENV{'TEST_VERBOSE'};
+{
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ my $first_ip = 'cbcd' . ':0000' x 7;
+ my $second_ip = 'cbdd' . ':0000' x 7;
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => $first_ip,
+ }
+ );
+
+ my ($id1) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id1, "created first ticket $id1" );
+
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => $second_ip,
+ }
+ );
+
+ my ($id2) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id2, "created second ticket $id2" );
+
+ my $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("id = $id1 OR id = $id2");
+ is( $tickets->Count, 2, "found both tickets by 'id = x OR y'" );
+
+ # IP
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '$first_ip'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip, "correct value" );
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = '$second_ip'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip, "correct value" );
+
+ # IP/32 - one address
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'cbcd::/16'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip, "correct value" );
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'cbdd::/16'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip, "correct value" );
+
+ # IP range
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL(
+ "(id = $id1 OR id = $id2) AND CF.{IP} = '$first_ip-cbcf::'"
+ );
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip, "correct value" );
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL(
+ "(id = $id1 OR id = $id2) AND CF.{IP} = '$second_ip-cbdf::'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip, "correct value" );
+
+ # IP range, with start IP greater than end
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} =
+ 'cbcf::-$first_ip'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip,, "correct value" );
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'cbdf::-$second_ip'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip, "correct value" );
+
+ # CIDR/12
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'cbcd::/12'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip, "correct value" );
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'cbdd::/12'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip, "correct value" );
+
+ # IP is not in CIDR/24
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} != 'cbcd::/12'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), $second_ip,, "correct value" );
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} != 'cbdd::/12'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'), $first_ip, "correct value" );
+
+ # CIDR or CIDR
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND "
+ ."(CF.{IP} = 'cbcd::/12' OR CF.{IP} = 'cbdd::/12')");
+ is( $tickets->Count, 2, "found both tickets" );
+}
+
+diag "create two tickets with different IP ranges and check several searches" if $ENV{'TEST_VERBOSE'};
+{
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => 'ddcd::/16',
+ }
+ );
+
+ my ($id1) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id1, "created first ticket $id1" );
+
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => 'edcd::/16',
+ }
+ );
+
+ my ($id2) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id2, "created ticket $id2" );
+
+ my $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("id = $id1 OR id = $id2");
+ is( $tickets->Count, 2, "found both tickets by 'id = x OR y'" );
+
+ # IP
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd::'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id1, "correct value" );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd:abcd::'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id1, "correct value" );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd:ffff::'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id1, "correct value" );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'edcd::abcd'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id2, "correct value" );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'edcd::ffff'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id2, "correct value" );
+ $tickets->FromSQL(
+"(id = $id1 OR id = $id2) AND CF.{IP} = 'edcd:ffff:ffff:ffff:ffff:ffff:ffff:ffff'"
+ );
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id2, "correct value" );
+
+ # IP/32 - one address
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd::/32'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id1, "correct value" );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'edcd::/32'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id2, "correct value" );
+
+ # IP range, lower than both
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'abcd::/32'");
+ is( $tickets->Count, 0, "didn't finnd ticket" ) or diag "but found ". $tickets->First->id;
+
+ # IP range, intersect with the first range
+ $tickets->FromSQL(
+ "(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcc::-ddcd:ab::'"
+ );
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id1, "correct value" );
+
+ # IP range, equal to the first range
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd::/16'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id1, "correct value" );
+
+ # IP range, lay inside the first range
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd:ab::'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->id, $id1, "correct value" );
+
+ # IP range, intersect with the ranges
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcc::-edcd:ab::'");
+ is( $tickets->Count, 2, "found both tickets" );
+
+ # IP range, equal to range from the starting IP of the first ticket to the ending IP of the second
+ $tickets->FromSQL(
+ "(id = $id1 OR id = $id2) AND CF.{IP} = 'ddcd::-edcd:ffff:ffff:ffff:ffff:ffff:ffff:ffff'"
+ );
+ is( $tickets->Count, 2, "found both tickets" );
+
+ # IP range, has the both ranges inside it
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'd000::/2'");
+ is( $tickets->Count, 2, "found both tickets" );
+
+ # IP range, greater than both
+ $tickets = RT::Tickets->new( $RT::SystemUser );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'ffff::/16'");
+ is( $tickets->Count, 0, "didn't find ticket" ) or diag "but found ". $tickets->First->id;
+}
+
+
diff --git a/rt/t/customfields/ipv6.t b/rt/t/customfields/ipv6.t
new file mode 100644
index 000000000..09c4d30d0
--- /dev/null
+++ b/rt/t/customfields/ipv6.t
@@ -0,0 +1,252 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 102;
+
+my ( $baseurl, $agent ) = RT::Test->started_ok;
+ok( $agent->login, 'log in' );
+
+my $q = RT::Queue->new($RT::SystemUser);
+$q->Load('General');
+my $ip_cf = RT::CustomField->new($RT::SystemUser);
+
+my ( $val, $msg ) = $ip_cf->Create(
+ Name => 'IP',
+ Type => 'IPAddress',
+ LookupType => 'RT::Queue-RT::Ticket'
+);
+ok( $val, $msg );
+my $cf_id = $val;
+$ip_cf->AddToObject($q);
+use_ok('RT');
+
+my $cf;
+diag "load and check basic properties of the IP CF" if $ENV{'TEST_VERBOSE'};
+{
+ my $cfs = RT::CustomFields->new($RT::SystemUser);
+ $cfs->Limit( FIELD => 'Name', VALUE => 'IP' );
+ is( $cfs->Count, 1, "found one CF with name 'IP'" );
+
+ $cf = $cfs->First;
+ is( $cf->Type, 'IPAddress', 'type check' );
+ is( $cf->LookupType, 'RT::Queue-RT::Ticket', 'lookup type check' );
+ ok( !$cf->MaxValues, "unlimited number of values" );
+ ok( !$cf->Disabled, "not disabled" );
+}
+
+diag "check that CF applies to queue General" if $ENV{'TEST_VERBOSE'};
+{
+ my $cfs = $q->TicketCustomFields;
+ $cfs->Limit( FIELD => 'id', VALUE => $cf->id, ENTRYAGGREGATOR => 'AND' );
+ is( $cfs->Count, 1, 'field applies to queue' );
+}
+
+my %valid = (
+ 'abcd:' x 7 . 'abcd' => 'abcd:' x 7 . 'abcd',
+ '034:' x 7 . '034' => '0034:' x 7 . '0034',
+ 'abcd::' => 'abcd:' . '0000:' x 6 . '0000',
+ '::abcd' => '0000:' x 7 . 'abcd',
+ 'abcd::034' => 'abcd:' . '0000:' x 6 . '0034',
+ 'abcd::192.168.1.1' => 'abcd:' . '0000:' x 5 . 'c0a8:0101',
+ '::192.168.1.1' => '0000:' x 6 . 'c0a8:0101',
+ '::' => '0000:' x 7 . '0000',
+);
+
+diag "create a ticket via web and set IP" if $ENV{'TEST_VERBOSE'};
+{
+ for my $ip ( keys %valid ) {
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => $ip,
+ }
+ );
+
+ $agent->content_contains( $valid{$ip}, "IP on the page" );
+ my ($id) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id, "created ticket $id" );
+
+ my $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+ is( $ticket->FirstCustomFieldValue('IP'), $valid{$ip},
+ 'correct value' );
+
+ my $tickets = RT::Tickets->new($RT::SystemUser);
+ $tickets->FromSQL("id = $id AND CF.{IP} = '$ip'");
+ ok( $tickets->Count, "found tickets" );
+ }
+}
+
+diag "create a ticket and edit IP field using Edit page"
+ if $ENV{'TEST_VERBOSE'};
+
+{
+ my $ip = 'abcd::034';
+
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => { Subject => 'test ip', }
+ );
+
+ my ($id) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id, "created ticket $id" );
+ my $cf_field = "Object-RT::Ticket-$id-CustomField-$cf_id-Values";
+
+ $agent->follow_link_ok( { text => 'Basics', n => "1" },
+ "Followed 'Basics' link" );
+ $agent->form_name('TicketModify');
+
+ is( $agent->value($cf_field), '', 'IP is empty' );
+ $agent->field( $cf_field => $valid{$ip} );
+ $agent->click('SubmitTicket');
+
+ $agent->content_contains( $valid{$ip}, "IP on the page" );
+
+ my $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+ my $values = $ticket->CustomFieldValues('IP');
+ is( $ticket->FirstCustomFieldValue('IP'), $valid{$ip}, 'correct value' );
+
+ diag "set IP with spaces around" if $ENV{'TEST_VERBOSE'};
+ my $new_ip = '::3141';
+ my $new_value = '0000:' x 7 . '3141';
+
+ $agent->follow_link_ok( { text => 'Basics', n => "1" },
+ "Followed 'Basics' link" );
+ $agent->form_name('TicketModify');
+ is( $agent->value($cf_field), $valid{$ip}, 'IP is in input box' );
+ $agent->field( $cf_field => $new_ip );
+ $agent->click('SubmitTicket');
+
+ $agent->content_contains( $new_value, "IP on the page" );
+
+ $ticket = RT::Ticket->new($RT::SystemUser);
+ $ticket->Load($id);
+ ok( $ticket->id, 'loaded ticket' );
+ is( $ticket->FirstCustomFieldValue('IP'), $new_value, 'correct value' );
+}
+
+diag "check that we parse correct IPs only" if $ENV{'TEST_VERBOSE'};
+{
+
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ my @invalid =
+ ( 'abcd:', 'efgh', 'abcd:' x 8 . 'abcd', 'abcd::abcd::abcd' );
+ for my $invalid (@invalid) {
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => $invalid,
+ }
+ );
+
+ $agent->content_contains( 'can not be parsed as an IP address',
+ 'ticket fails to create' );
+ }
+}
+
+diag "create two tickets with different IPs and check several searches"
+ if $ENV{'TEST_VERBOSE'};
+{
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => 'abcd::',
+ }
+ );
+
+ my ($id1) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id1, "created first ticket $id1" );
+
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'test ip',
+ $cf_field => 'bbcd::',
+ }
+ );
+
+ my ($id2) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id2, "created second ticket $id2" );
+
+ my $tickets = RT::Tickets->new($RT::SystemUser);
+ $tickets->FromSQL("id = $id1 OR id = $id2");
+ is( $tickets->Count, 2, "found both tickets by 'id = x OR y'" );
+
+ # IP
+ $tickets = RT::Tickets->new($RT::SystemUser);
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'abcd::'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'),
+ 'abcd' . ':0000' x 7, "correct value" );
+ $tickets = RT::Tickets->new($RT::SystemUser);
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} = 'bbcd::'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'),
+ 'bbcd' . ':0000' x 7, "correct value" );
+
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} <= 'abcd::'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'),
+ 'abcd' . ':0000' x 7, "correct value" );
+ $tickets = RT::Tickets->new($RT::SystemUser);
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} >= 'bbcd::'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'),
+ 'bbcd' . ':0000' x 7, "correct value" );
+
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} > 'bbcd::'");
+ is( $tickets->Count, 0, "no tickets found" );
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} < 'abcd::'");
+ is( $tickets->Count, 0, "no tickets found" );
+
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} < 'bbcd::'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'),
+ 'abcd' . ':0000' x 7, "correct value" );
+
+ $tickets->FromSQL("(id = $id1 OR id = $id2) AND CF.{IP} > 'abcd::'");
+ is( $tickets->Count, 1, "found one ticket" );
+ is( $tickets->First->FirstCustomFieldValue('IP'),
+ 'bbcd' . ':0000' x 7, "correct value" );
+}
+
+diag "create a ticket with an IP of abcd:23:: and search for doesn't match 'abcd:23'."
+ if $ENV{'TEST_VERBOSE'};
+{
+ ok $agent->goto_create_ticket($q), "go to create ticket";
+ my $cf_field = "Object-RT::Ticket--CustomField-$cf_id-Values";
+ $agent->submit_form(
+ form_name => 'TicketCreate',
+ fields => {
+ Subject => 'local',
+ $cf_field => 'abcd:23::',
+ }
+ );
+
+ my ($id) = $agent->content =~ /Ticket (\d+) created/;
+ ok( $id, "created first ticket $id" );
+
+ my $tickets = RT::Tickets->new($RT::SystemUser);
+ $tickets->FromSQL("id=$id AND CF.{IP} NOT LIKE 'abcd:23'");
+
+ SKIP: {
+ skip "partical ip parse can causes ambiguity", 1;
+ is( $tickets->Count, 0, "should not have found the ticket" );
+ }
+}
+
diff --git a/rt/t/customfields/pattern.t b/rt/t/customfields/pattern.t
new file mode 100644
index 000000000..7d1090fa7
--- /dev/null
+++ b/rt/t/customfields/pattern.t
@@ -0,0 +1,44 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+
+use RT;
+use RT::Test nodata => 1, tests => 17;
+
+my $q = RT::Queue->new($RT::SystemUser);
+works($q->Create(Name => "CF-Pattern-".$$));
+
+my $cf = RT::CustomField->new($RT::SystemUser);
+my @cf_args = (Name => $q->Name, Type => 'Freeform', Queue => $q->id, MaxValues => 1);
+
+fails($cf->Create(@cf_args, Pattern => ')))bad!regex((('));
+works($cf->Create(@cf_args, Pattern => 'good regex'));
+
+my $t = RT::Ticket->new($RT::SystemUser);
+my ($id,undef,$msg) = $t->Create(Queue => $q->id, Subject => 'CF Test');
+works($id,$msg);
+
+# OK, I'm thoroughly brain washed by HOP at this point now...
+sub cnt { $t->CustomFieldValues($cf->id)->Count };
+sub add { $t->AddCustomFieldValue(Field => $cf->id, Value => $_[0]) };
+sub del { $t->DeleteCustomFieldValue(Field => $cf->id, Value => $_[0]) };
+
+is(cnt(), 0, "No values yet");
+fails(add('not going to match'));
+is(cnt(), 0, "No values yet");
+works(add('here is a good regex'));
+is(cnt(), 1, "Value filled");
+fails(del('here is a good regex'));
+is(cnt(), 1, "Single CF - Value _not_ deleted");
+
+$cf->SetMaxValues(0); # Unlimited MaxValues
+
+works(del('here is a good regex'));
+is(cnt(), 0, "Multiple CF - Value deleted");
+
+fails($cf->SetPattern('(?{ "insert evil code here" })'));
+works($cf->SetPattern('(?!)')); # reject everything
+fails(add(''));
+fails(add('...'));
+
+undef $t;
diff --git a/rt/t/customfields/single_values.t b/rt/t/customfields/single_values.t
new file mode 100644
index 000000000..15a00163c
--- /dev/null
+++ b/rt/t/customfields/single_values.t
@@ -0,0 +1,37 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+
+use RT;
+use RT::Test nodata => 1, tests => 8;
+
+
+
+my $q = RT::Queue->new(RT->SystemUser);
+my ($id,$msg) =$q->Create(Name => "CF-Single-".$$);
+ok($id,$msg);
+
+my $cf = RT::CustomField->new(RT->SystemUser);
+($id,$msg) = $cf->Create(Name => 'Single-'.$$, Type => 'Select', MaxValues => '1', Queue => $q->id);
+ok($id,$msg);
+
+
+($id,$msg) =$cf->AddValue(Name => 'First');
+ok($id,$msg);
+
+($id,$msg) =$cf->AddValue(Name => 'Second');
+ok($id,$msg);
+
+
+my $t = RT::Ticket->new(RT->SystemUser);
+($id,undef,$msg) = $t->Create(Queue => $q->id,
+ Subject => 'CF Test');
+
+ok($id,$msg);
+is($t->CustomFieldValues($cf->id)->Count, 0, "No values yet");
+$t->AddCustomFieldValue(Field => $cf->id, Value => 'First');
+is($t->CustomFieldValues($cf->id)->Count, 1, "One now");
+
+$t->AddCustomFieldValue(Field => $cf->id, Value => 'Second');
+is($t->CustomFieldValues($cf->id)->Count, 1, "Still one");
+
diff --git a/rt/t/customfields/sort_order.t b/rt/t/customfields/sort_order.t
index c5c808ceb..2453a7cc8 100644
--- a/rt/t/customfields/sort_order.t
+++ b/rt/t/customfields/sort_order.t
@@ -3,7 +3,7 @@
use strict;
use warnings;
-use RT::Test tests => 18;
+use RT::Test tests => 20;
use RT::Ticket;
use RT::CustomField;
@@ -11,10 +11,10 @@ my $queue_name = "CFSortQueue-$$";
my $queue = RT::Test->load_or_create_queue( Name => $queue_name );
ok($queue && $queue->id, "$queue_name - test queue creation");
-diag "create multiple CFs: B, A and C" if $ENV{TEST_VERBOSE};
+diag "create multiple CFs: B, A and C";
my @cfs = ();
{
- my $cf = RT::CustomField->new( $RT::SystemUser );
+ my $cf = RT::CustomField->new( RT->SystemUser );
my ($ret, $msg) = $cf->Create(
Name => "CF B",
Queue => $queue->id,
@@ -24,7 +24,7 @@ my @cfs = ();
push @cfs, $cf;
}
{
- my $cf = RT::CustomField->new( $RT::SystemUser );
+ my $cf = RT::CustomField->new( RT->SystemUser );
my ($ret, $msg) = $cf->Create(
Name => "CF A",
Queue => $queue->id,
@@ -34,7 +34,7 @@ my @cfs = ();
push @cfs, $cf;
}
{
- my $cf = RT::CustomField->new( $RT::SystemUser );
+ my $cf = RT::CustomField->new( RT->SystemUser );
my ($ret, $msg) = $cf->Create(
Name => "CF C",
Queue => $queue->id,
@@ -47,12 +47,11 @@ my @cfs = ();
my ($baseurl, $m) = RT::Test->started_ok;
ok $m->login( root => 'password' ), 'logged in';
-diag "reorder CFs: C, A and B" if $ENV{TEST_VERBOSE};
+diag "reorder CFs: C, A and B";
{
$m->get( '/Admin/Queues/' );
$m->follow_link_ok( {text => $queue->id} );
- $m->follow_link_ok( {text => 'Ticket Custom Fields'} );
-
+ $m->follow_link_ok( {id => 'page-ticket-custom-fields'} );
my @tmp = ($m->content =~ /(CF [ABC])/g);
is_deeply(\@tmp, ['CF B', 'CF A', 'CF C']);
@@ -64,7 +63,7 @@ diag "reorder CFs: C, A and B" if $ENV{TEST_VERBOSE};
is_deeply(\@tmp, ['CF C', 'CF A', 'CF B']);
}
-diag "check ticket create, display and edit pages" if $ENV{TEST_VERBOSE};
+diag "check ticket create, display and edit pages";
{
$m->submit_form(
form_name => "CreateTicketInQueue",
@@ -83,8 +82,7 @@ diag "check ticket create, display and edit pages" if $ENV{TEST_VERBOSE};
@tmp = ($m->content =~ /(CF [ABC])/g);
is_deeply(\@tmp, ['CF C', 'CF A', 'CF B']);
-
- $m->follow_link_ok( {text => 'Custom Fields'} );
+ $m->follow_link_ok( {id => 'page-basics'});
@tmp = ($m->content =~ /(CF [ABC])/g);
is_deeply(\@tmp, ['CF C', 'CF A', 'CF B']);
diff --git a/rt/t/customfields/transaction.t b/rt/t/customfields/transaction.t
new file mode 100644
index 000000000..22f8459eb
--- /dev/null
+++ b/rt/t/customfields/transaction.t
@@ -0,0 +1,60 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+use Data::Dumper;
+
+use RT::Test nodata => 1, tests => 14;
+use_ok('RT');
+use_ok('RT::Transactions');
+
+
+my $q = RT::Queue->new(RT->SystemUser);
+my ($id,$msg) = $q->Create( Name => 'TxnCFTest'.$$);
+ok($id,$msg);
+
+my $cf = RT::CustomField->new(RT->SystemUser);
+($id,$msg) = $cf->Create(Name => 'Txnfreeform-'.$$, Type => 'Freeform', MaxValues => '0', LookupType => RT::Transaction->CustomFieldLookupType );
+
+ok($id,$msg);
+
+($id,$msg) = $cf->AddToObject($q);
+
+ok($id,$msg);
+
+
+my $ticket = RT::Ticket->new(RT->SystemUser);
+
+my $transid;
+($id,$transid, $msg) = $ticket->Create(Queue => $q->id,
+ Subject => 'TxnCF test',
+ );
+ok($id,$msg);
+
+my $trans = RT::Transaction->new(RT->SystemUser);
+$trans->Load($transid);
+
+is($trans->ObjectId,$id);
+is ($trans->ObjectType, 'RT::Ticket');
+is ($trans->Type, 'Create');
+my $txncfs = $trans->CustomFields;
+is ($txncfs->Count, 1, "We have one custom field");
+my $txn_cf = $txncfs->First;
+is ($txn_cf->id, $cf->id, "It's the right custom field");
+my $values = $trans->CustomFieldValues($txn_cf->id);
+is ($values->Count, 0, "It has no values");
+
+# Old API
+my %cf_updates = ( 'CustomField-'.$cf->id => 'Testing');
+$trans->UpdateCustomFields( ARGSRef => \%cf_updates);
+
+ $values = $trans->CustomFieldValues($txn_cf->id);
+is ($values->Count, 1, "It has one value");
+
+# New API
+
+$trans->UpdateCustomFields( 'CustomField-'.$cf->id => 'Test two');
+ $values = $trans->CustomFieldValues($txn_cf->id);
+is ($values->Count, 2, "it has two values");
+
+# TODO ok(0, "Should updating custom field values remove old values?");