diff options
Diffstat (limited to 'rt/t/api')
33 files changed, 1740 insertions, 284 deletions
diff --git a/rt/t/api/attachment_filename.t b/rt/t/api/attachment_filename.t index 6bfc7072f..aa8acd2d9 100644 --- a/rt/t/api/attachment_filename.t +++ b/rt/t/api/attachment_filename.t @@ -10,18 +10,18 @@ my $mime = MIME::Entity->build( ); $mime->attach( - Path => 'share/html/NoAuth/images/bpslogo.png', + Path => 'share/static/images/bpslogo.png', Type => 'image/png', ); $mime->attach( - Path => 'share/html/NoAuth/images/bpslogo.png', + Path => 'share/static/images/bpslogo.png', Type => 'image/png', Filename => 'bpslogo.png', ); $mime->attach( - Path => 'share/html/NoAuth/images/bpslogo.png', + Path => 'share/static/images/bpslogo.png', Filename => 'images/bpslogo.png', Type => 'image/png', ); diff --git a/rt/t/api/cfsearch.t b/rt/t/api/cfsearch.t index 7a460ce2e..4df6e0af2 100644 --- a/rt/t/api/cfsearch.t +++ b/rt/t/api/cfsearch.t @@ -36,9 +36,9 @@ my $cfvalue1 = 'Foo'; { my ($id, $msg) = $u1->AddCustomFieldValue( - Field => $cfname, - Value => $cfvalue1, - RecordTransaction => 0 ); + Field => $cfname, + Value => $cfvalue1, + RecordTransaction => 0 ); ok( $id, "Adding CF value '$cfvalue1' - " . $msg ); } @@ -51,18 +51,18 @@ my $cfvalue1 = 'Foo'; { my ($id, $msg) = $u1->DeleteCustomFieldValue( - Field => $cfname, - Value => $cfvalue1, - RecordTransaction => 0 ); + Field => $cfname, + Value => $cfvalue1, + RecordTransaction => 0 ); ok( $id, "Deleting CF value - " . $msg ); } my $cfvalue2 = 'Bar'; { my ($id, $msg) = $u1->AddCustomFieldValue( - Field => $cfname, - Value => $cfvalue2, - RecordTransaction => 0 ); + Field => $cfname, + Value => $cfvalue2, + RecordTransaction => 0 ); ok( $id, "Adding second CF value '$cfvalue2' - " . $msg ); } @@ -92,9 +92,9 @@ sub QueryCFValue{ isa_ok( $users, 'RT::Users' ); $users->LimitCustomField( - CUSTOMFIELD => $cf_id, - OPERATOR => "=", - VALUE => $cf_value ); + CUSTOMFIELD => $cf_id, + OPERATOR => "=", + VALUE => $cf_value ); while ( my $filtered_user = $users->Next() ){ my $cf_values = $filtered_user->CustomFieldValues($cf->id); diff --git a/rt/t/api/config.t b/rt/t/api/config.t index 62b77dffa..b87531139 100644 --- a/rt/t/api/config.t +++ b/rt/t/api/config.t @@ -1,7 +1,7 @@ use strict; use warnings; use RT; -use RT::Test nodb => 1, tests => 11; +use RT::Test nodb => 1, tests => undef; use Test::Warn; ok( @@ -39,5 +39,11 @@ my @encodings = qw(utf-8-strict iso-8859-1 ascii); warning_is {RT::Config->PostLoadCheck} "Unknown encoding 'foo' in \@EmailInputEncodings option", 'Correct warning for encoding foo'; +RT::Config->Set( WebDefaultStylesheet => 'non-existent-skin-name' ); +warning_like {RT::Config->PostLoadCheck} qr{rudder}, + 'Correct warning for default stylesheet'; + my @canonical_encodings = RT::Config->Get('EmailInputEncodings'); is_deeply(\@encodings, \@canonical_encodings, 'Got correct encoding list'); + +done_testing;
\ No newline at end of file diff --git a/rt/t/api/cron.t b/rt/t/api/cron.t index 6bd992df3..b16adde82 100644 --- a/rt/t/api/cron.t +++ b/rt/t/api/cron.t @@ -24,10 +24,10 @@ This is a content string with no content.'; my $template_obj = RT::Template->new($CurrentUser); $template_obj->Create(Queue => '0', - Name => 'recordtest', - Description => 'testing Record actions', - Content => $template_content, - ); + Name => 'recordtest', + Description => 'testing Record actions', + Content => $template_content, + ); # Create a queue and some tickets. @@ -36,17 +36,17 @@ my $queue_obj = RT::Queue->new($CurrentUser); ok($ret, 'record test queue creation'); my $ticket1 = RT::Ticket->new($CurrentUser); -my ($id, $tobj, $msg2) = $ticket1->Create(Queue => $queue_obj, - Requestor => ['tara@example.com'], - Subject => 'bork bork bork', - Priority => 22, - ); +my ($id, $tobj, $msg2) = $ticket1->Create(Queue => $queue_obj, + Requestor => ['tara@example.com'], + Subject => 'bork bork bork', + Priority => 22, + ); ok($id, 'record test ticket creation 1'); my $ticket2 = RT::Ticket->new($CurrentUser); ($id, $tobj, $msg2) = $ticket2->Create(Queue => $queue_obj, - Requestor => ['root@localhost'], - Subject => 'hurdy gurdy' - ); + Requestor => ['root@localhost'], + Subject => 'hurdy gurdy' + ); ok($id, 'record test ticket creation 2'); @@ -58,7 +58,7 @@ ok(require RT::Search::FromSQL, "Search::FromSQL loaded"); my $ticketsqlstr = "Requestor.EmailAddress = '" . $CurrentUser->EmailAddress . "' AND Priority > '20'"; my $search = RT::Search::FromSQL->new(Argument => $ticketsqlstr, TicketsObj => RT::Tickets->new($CurrentUser), - ); + ); is(ref($search), 'RT::Search::FromSQL', "search created"); ok($search->Prepare(), "fromsql search run"); my $counter = 0; diff --git a/rt/t/api/customfield.t b/rt/t/api/customfield.t index 6be50bb3a..df8f66df2 100644 --- a/rt/t/api/customfield.t +++ b/rt/t/api/customfield.t @@ -2,72 +2,393 @@ use strict; use warnings; use RT; -use RT::Test nodata => 1, tests => 29; +use RT::Test tests => undef; use Test::Warn; +use_ok('RT::CustomField'); -{ +my $queue = RT::Queue->new( RT->SystemUser ); +$queue->Load( "General" ); +ok( $queue->id, "found the General queue" ); -use_ok('RT::CustomField'); -ok(my $cf = RT::CustomField->new(RT->SystemUser)); -ok(my ($id, $msg)= $cf->Create( Name => 'TestingCF', - Queue => '0', - SortOrder => '1', - Description => 'A Testing custom field', - Type=> 'SelectSingle'), 'Created a global CustomField'); -isnt($id , 0, 'Global custom field correctly created'); -ok ($cf->SingleValue); -is($cf->Type, 'Select'); -is($cf->MaxValues, 1); - -(my $val, $msg) = $cf->SetMaxValues('0'); -ok($val, $msg); -is($cf->Type, 'Select'); -is($cf->MaxValues, 0); -ok(!$cf->SingleValue ); -ok(my ($bogus_val, $bogus_msg) = $cf->SetType('BogusType') , "Trying to set a custom field's type to a bogus type"); -is($bogus_val , 0, "Unable to set a custom field's type to a bogus type"); - -ok(my $bad_cf = RT::CustomField->new(RT->SystemUser)); -ok(my ($bad_id, $bad_msg)= $cf->Create( Name => 'TestingCF-bad', - Queue => '0', - SortOrder => '1', - Description => 'A Testing custom field with a bogus Type', - Type=> 'SelectSingleton'), 'Created a global CustomField with a bogus type'); -is($bad_id , 0, 'Global custom field correctly decided to not create a cf with a bogus type '); - - -} - -{ - -ok(my $cf = RT::CustomField->new(RT->SystemUser)); +my $cf = RT::CustomField->new(RT->SystemUser); +ok($cf, "Have a CustomField object"); + +# Use the old Queue field to set up a ticket CF +my ($ok, $msg) = $cf->Create( + Name => 'TestingCF', + Queue => '0', + Description => 'A Testing custom field', + Type => 'SelectSingle' +); +ok($ok, 'Global custom field correctly created'); +is($cf->Type, 'Select', "Is a select CF"); +ok($cf->SingleValue, "Also a single-value CF"); +is($cf->MaxValues, 1, "...meaning only one value, max"); + +($ok, $msg) = $cf->SetMaxValues('0'); +ok($ok, "Set to infinite values: $msg"); +is($cf->Type, 'Select', "Still a select CF"); +ok( ! $cf->SingleValue, "No longer single-value" ); +is($cf->MaxValues, 0, "...meaning no maximum values"); + +# Test our sanity checking of CF types +($ok, $msg) = $cf->SetType('BogusType'); +ok( ! $ok, "Unable to set a custom field's type to a bogus type: $msg"); + +$cf = RT::CustomField->new(RT->SystemUser); +($ok, $msg) = $cf->Create( + Name => 'TestingCF-bad', + Queue => '0', + SortOrder => '1', + Description => 'A Testing custom field with a bogus Type', + Type=> 'SelectSingleton' +); +ok( ! $ok, "Correctly could not create with bogus type: $msg"); + + +# Deprecated types +warning_like { + ok($cf->ValidateType('SelectSingle'), "ValidateType accepts SelectSingle"); +} qr/deprecated/, "...but warns of deprecation"; + +warning_like { + ok($cf->ValidateType('SelectMultiple'), "ValidateType accepts SelectMultiple"); +} qr/deprecated/, "...but warns of deprecation"; + +warning_like { + ok( ! $cf->ValidateType('SelectFooMultiple'), "ValidateType does not accept SelectFooMultiple"); +} qr/deprecated/, "...and also warns of deprecation"; + + +# Test adding and removing CFVs $cf->Load(1); -is($cf->Id , 1); -ok(my ($val,$msg) = $cf->AddValue(Name => 'foo' , Description => 'TestCFValue', SortOrder => '6')); -isnt($val , 0); -ok (my ($delval, $delmsg) = $cf->DeleteValue($val)); -ok ($delval,"Deleting a cf value: $delmsg"); +($ok, $msg) = $cf->AddValue(Name => 'foo' , Description => 'TestCFValue', SortOrder => '6'); +ok($ok, "Added a new value to the select options"); +($ok, $msg) = $cf->DeleteValue($ok); +ok($ok, "Deleting it again"); + + +# Loading, and context objects +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName( Name => "TestingCF" ); +ok($cf->id, "Load finds it, given just a name" ); +ok( ! $cf->ContextObject, "Did not get a context object"); + +# Old Queue => form should find the global, gain no context object +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => 0); +ok($cf->id, "Load finds it, given a Name and Queue => 0" ); +ok( ! $cf->ContextObject, 'Context object not set when queue is 0'); + +# We don't default to also searching global -- but do pick up a contextobject +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => 1); +ok( ! $cf->id, "Load does not finds it, given a Name and Queue => 1" ); +ok($cf->ContextObject->id, 'Context object is now set'); +# If we IncludeGlobal, we find it +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => 1, IncludeGlobal => 1 ); +ok($cf->id, "Load now finds it, given a Name and Queue => 1 and IncludeGlobal" ); +ok($cf->ContextObject->id, 'Context object is also set'); -} +# The explicit LookupType works +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', LookupType => RT::Ticket->CustomFieldLookupType ); +ok($cf->id, "Load now finds it, given a Name and LookupType" ); +ok( ! $cf->ContextObject, 'No context object gained'); -{ +# The explicit LookupType, ObjectId, and IncludeGlobal -- what most folks want +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', LookupType => RT::Ticket->CustomFieldLookupType, + ObjectId => 1, IncludeGlobal => 1 ); +ok($cf->id, "Load now finds it, given a Name, LookupType, ObjectId, IncludeGlobal" ); +ok($cf->ContextObject->id, 'And gains a context obj'); -ok(my $cf = RT::CustomField->new(RT->SystemUser)); +# Look for a queue by name +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => "General" ); +ok( ! $cf->id, "No IncludeGlobal, so queue by name fails" ); +ok($cf->ContextObject->id, 'But gains a context object'); +# Look for a queue by name, include global +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => "General", IncludeGlobal => 1 ); +ok($cf->id, "By name, and queue name works with IncludeGlobal" ); +ok($cf->ContextObject->id, 'And gains a context object'); + + + +# A bogus Queue gets you no results, but a warning +$cf = RT::CustomField->new( RT->SystemUser ); warning_like { -ok($cf->ValidateType('SelectSingle')); -} qr/deprecated/; + $cf->LoadByName(Name => 'TestingCF', Queue => "Bogus" ); + ok( ! $cf->id, "With a bogus queue name gets no results" ); + ok( ! $cf->ContextObject, 'And also no context object'); +} qr/Failed to load RT::Queue 'Bogus'/, "Generates a warning"; +# Ditto by number which is bogus +$cf = RT::CustomField->new( RT->SystemUser ); warning_like { -ok($cf->ValidateType('SelectMultiple')); -} qr/deprecated/; + $cf->LoadByName(Name => 'TestingCF', Queue => "9000" ); + ok( ! $cf->id, "With a bogus queue number gets no results" ); + ok( ! $cf->ContextObject, 'And also no context object'); +} qr/Failed to load RT::Queue '9000'/, "Generates a warning"; +# But if they also wanted global results, we might have an answer +$cf = RT::CustomField->new( RT->SystemUser ); warning_like { -ok(!$cf->ValidateType('SelectFooMultiple')); -} qr/deprecated/; + $cf->LoadByName(Name => 'TestingCF', Queue => "9000", IncludeGlobal => 1 ); + ok($cf->id, "Bogus queue but IncludeGlobal founds it" ); + ok( ! $cf->ContextObject, 'But no context object'); +} qr/Failed to load RT::Queue '9000'/, "And generates a warning"; + + +# Make it only apply to one queue +$cf->Load(1); +my $ocf = RT::ObjectCustomField->new( RT->SystemUser ); +( $ok, $msg ) = $ocf->LoadByCols( CustomField => $cf->id, ObjectId => 0 ); +ok( $ok, "Found global application of CF" ); +( $ok, $msg ) = $ocf->Delete; +ok( $ok, "...and deleted it"); +( $ok, $msg ) = $ocf->Add( CustomField => $cf->id, ObjectId => 1 ); +ok($ok, "Applied to just queue 1" ); + +# Looking for it globally with Queue => 0 should fail, gain no context object +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => 0); +ok( ! $cf->id, "Load fails to find, given a Name and Queue => 0" ); +ok( ! $cf->ContextObject, 'Context object not set when queue is 0'); + +# Looking it up by Queue => 1 works fine, and gets context object +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => 1); +ok($cf->id, "Load does finds it, given a Name and Queue => 1" ); +ok($cf->ContextObject->id, 'Context object is now set'); + +# Also find it with IncludeGlobal +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => 1, IncludeGlobal => 1 ); +ok($cf->id, "Load also finds it, given a Name and Queue => 1 and IncludeGlobal" ); +ok($cf->ContextObject->id, 'Context object is also set'); + +# The explicit LookupType works +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', LookupType => RT::Ticket->CustomFieldLookupType ); +ok($cf->id, "Load also finds it, given a Name and LookupType" ); +ok( ! $cf->ContextObject, 'But no context object gained'); + +# Explicit LookupType, ObjectId works +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', LookupType => RT::Ticket->CustomFieldLookupType, + ObjectId => 1 ); +ok($cf->id, "Load still finds it, given a Name, LookupType, ObjectId" ); +ok($cf->ContextObject->id, 'And gains a context obj'); + +# Explicit LookupType, ObjectId works +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', LookupType => RT::Ticket->CustomFieldLookupType, + ObjectId => 1, IncludeGlobal => 1 ); +ok($cf->id, "Load also finds it, given a Name, LookupType, ObjectId, and IncludeGlobal" ); +ok($cf->ContextObject->id, 'And gains a context obj'); + +# Look for a queue by name +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => "General" ); +ok($cf->id, "Finds it by queue name" ); +ok($cf->ContextObject->id, 'But gains a context object'); + +# Look for a queue by name, include global +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => "General", IncludeGlobal => 1 ); +ok($cf->id, "By name, and queue name works with IncludeGlobal" ); +ok($cf->ContextObject->id, 'And gains a context object'); + + + + +# Change the lookup type to be a _queue_ CF +($ok, $msg) = $cf->SetLookupType( RT::Queue->CustomFieldLookupType ); +ok($ok, "Changed CF type to be a CF on queues" ); +$ocf = RT::ObjectCustomField->new( RT->SystemUser ); +( $ok, $msg ) = $ocf->Add( CustomField => $cf->id, ObjectId => 0 ); +ok($ok, "Applied globally" ); + +# Just looking by name gets you CFs of any type +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF'); +ok($cf->id, "Find the CF by name, with no queue" ); + +# Queue => 0 means "ticket CF", so doesn't find it +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => 0); +ok( ! $cf->id, "Wrong lookup type to find with Queue => 0" ); + +# Queue => 1 and IncludeGlobal also doesn't find it +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => 0, IncludeGlobal => 1); +ok( ! $cf->id, "Also doesn't find with Queue => 0 and IncludeGlobal" ); + +# Find it with the right LookupType +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', LookupType => RT::Queue->CustomFieldLookupType ); +ok($cf->id, "Found for the right lookup type" ); + +# Found globally +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', LookupType => RT::Queue->CustomFieldLookupType, ObjectId => 0 ); +ok($cf->id, "Found for the right lookup type and ObjectId 0" ); + +# Also works with Queue instead of ObjectId +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', LookupType => RT::Queue->CustomFieldLookupType, Queue => 0 ); +ok($cf->id, "Found for the right lookup type and Queue 0" ); + +# Not found without IncludeGlobal +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', LookupType => RT::Queue->CustomFieldLookupType, ObjectId => 1 ); +ok( ! $cf->id, "Not found for ObjectId 1 and no IncludeGlobal" ); + +# Found with IncludeGlobal +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', LookupType => RT::Queue->CustomFieldLookupType, + ObjectId => 1, IncludeGlobal => 1 ); +ok($cf->id, "Found for ObjectId 1 and IncludeGlobal" ); + +# Found with IncludeGlobal and Queue instead of ObjectId +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', LookupType => RT::Queue->CustomFieldLookupType, + ObjectId => 1, IncludeGlobal => 1 ); +ok($cf->id, "Found for Queue 1 and IncludeGlobal" ); + + + +# Change the lookup type to be a _transaction_ CF +($ok, $msg) = $cf->SetLookupType( RT::Transaction->CustomFieldLookupType ); +ok($ok, "Changed CF type to be a CF on transactions" ); +$ocf = RT::ObjectCustomField->new( RT->SystemUser ); +( $ok, $msg ) = $ocf->Add( CustomField => $cf->id, ObjectId => 0 ); +ok($ok, "Applied globally" ); + +# Just looking by name gets you CFs of any type +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF'); +ok($cf->id, "Find the CF by name, with no queue" ); + +# Queue => 0 means "ticket CF", so doesn't find it +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => 0); +ok( ! $cf->id, "Wrong lookup type to find with Queue => 0" ); + +# Queue => 1 and IncludeGlobal also doesn't find it +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => 0, IncludeGlobal => 1); +ok( ! $cf->id, "Also doesn't find with Queue => 0 and IncludeGlobal" ); + + +# Change the lookup type to be a _user_ CF +$cf->Load(1); +($ok, $msg) = $cf->SetLookupType( RT::User->CustomFieldLookupType ); +ok($ok, "Changed CF type to be a CF on users" ); +$ocf = RT::ObjectCustomField->new( RT->SystemUser ); +( $ok, $msg ) = $ocf->Add( CustomField => $cf->id, ObjectId => 0 ); +ok($ok, "Applied globally" ); + +# Just looking by name gets you CFs of any type +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF'); +ok($cf->id, "Find the CF by name, with no queue" ); + +# Queue => 0 means "ticket CF", so doesn't find it +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => 0); +ok( ! $cf->id, "Wrong lookup type to find with Queue => 0" ); + +# Queue => 1 and IncludeGlobal also doesn't find it +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => 0, IncludeGlobal => 1); +ok( ! $cf->id, "Also doesn't find with Queue => 0 and IncludeGlobal" ); + +# But RT::User->CustomFieldLookupType does +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', LookupType => RT::User->CustomFieldLookupType ); +ok($cf->id, "User lookuptype does" ); + +# Also with an explicit global +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', LookupType => RT::User->CustomFieldLookupType, ObjectId => 0 ); +ok($cf->id, "Also with user CF and explicit global" ); + + + +# Add a second, queue-specific CF to test load order +$cf->Load(1); +($ok, $msg) = $cf->SetLookupType( RT::Ticket->CustomFieldLookupType ); +ok($ok, "Changed CF type back to be a CF on tickets" ); +$ocf = RT::ObjectCustomField->new( RT->SystemUser ); +( $ok, $msg ) = $ocf->Add( CustomField => $cf->id, ObjectId => 0 ); +ok($ok, "Applied globally" ); +($ok, $msg) = $cf->SetDescription( "Global CF" ); +ok($ok, "Changed CF type back to be a CF on tickets" ); + +($ok, $msg) = $cf->Create( + Name => 'TestingCF', + Queue => '1', + Description => 'Queue-specific CF', + Type => 'SelectSingle' +); +ok($ok, "Created second CF successfully"); + +# If passed just a name, you get the first by id +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF' ); +like($cf->Description, qr/Global/, "Gets the first (global) one if just loading by name" ); + +# Ditto if also limited to lookuptype +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', LookupType => RT::Ticket->CustomFieldLookupType ); +like($cf->Description, qr/Global/, "Same, if one adds a LookupType" ); + +# Gets the global with Queue => 0 +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => 0 ); +like($cf->Description, qr/Global/, "Specify Queue => 0 and get global" ); + +# Gets the queue with Queue => 1 +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => 1 ); +like($cf->Description, qr/Queue/, "Specify Queue => 1 and get the queue" ); + +# Gets the queue with Queue => 1 and IncludeGlobal +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => 1, IncludeGlobal => 1 ); +like($cf->Description, qr/Queue/, "Specify Queue => 1 and IncludeGlobal and get the queue" ); + + +# Disable one of them +($ok, $msg) = $cf->SetDisabled(1); +ok($ok, "Disabled the Queue-specific one"); + +# With just a name, prefers the non-disabled +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF' ); +like($cf->Description, qr/Global/, "Prefers non-disabled CFs" ); + +# Still finds the queue one, if asked +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => 1 ); +like($cf->Description, qr/Queue/, "Still loads the disabled queue CF" ); + +# Prefers the global one if IncludeGlobal +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => 1, IncludeGlobal => 1 ); +like($cf->Description, qr/Global/, "Prefers the global one with IncludeGlobal" ); +# IncludeDisabled allows filtering out the disabled one +$cf = RT::CustomField->new( RT->SystemUser ); +$cf->LoadByName(Name => 'TestingCF', Queue => 1, IncludeDisabled => 0 ); +ok( ! $cf->id, "Doesn't find it if IncludeDisabled => 0" ); -} +done_testing; diff --git a/rt/t/api/date.t b/rt/t/api/date.t index 22c6f1b58..dd22943c1 100644 --- a/rt/t/api/date.t +++ b/rt/t/api/date.t @@ -4,7 +4,7 @@ use DateTime; use warnings; use strict; -use RT::Test tests => 175; +use RT::Test tests => undef; use RT::User; use Test::Warn; @@ -57,7 +57,7 @@ my $current_user; is($date->Timezone('user'), 'Europe/Moscow', "in user context still returns user's timezone"); - + $current_user->UserObj->__Set( Field => 'Timezone', Value => ''); is_empty($current_user->UserObj->Timezone, "successfuly changed user's timezone"); @@ -83,6 +83,7 @@ my $current_user; { my $date = RT::Date->new(RT->SystemUser); + is($date->IsSet,0, "new date isn't set"); is($date->Unix, 0, "new date returns 0 in Unix format"); is($date->Get, '1970-01-01 00:00:00', "default is ISO format"); warning_like { @@ -207,6 +208,7 @@ my $current_user; $current_user->UserObj->__Set( Field => 'Timezone', Value => 'Europe/Moscow'); my $date = RT::Date->new( $current_user ); $date->Set( Format => 'ISO', Timezone => 'utc', Value => '2005-01-01 15:10:00' ); + is($date->IsSet,1,"Date has been set"); is($date->ISO( Timezone => 'user' ), '2005-01-01 18:10:00', "ISO"); is($date->W3CDTF( Timezone => 'user' ), '2005-01-01T18:10:00+03:00', "W3C DTF"); is($date->RFC2822( Timezone => 'user' ), 'Sat, 01 Jan 2005 18:10:00 +0300', "RFC2822"); @@ -239,7 +241,7 @@ warning_like { # bad format my $date = RT::Date->new(RT->SystemUser); $date->Set( Format => 'bad' ); - is($date->Unix, 0, "bad format"); + ok(!$date->IsSet, "bad format"); } qr{Unknown Date format: bad}; @@ -248,13 +250,26 @@ warning_like $date->Unix(1); is($date->ISO, '1970-01-01 00:00:01', "correct value"); - foreach (undef, 0, ''){ + foreach (undef, 0, '', -5){ $date->Unix(1); is($date->ISO, '1970-01-01 00:00:01', "correct value"); + is($date->IsSet,1,"Date has been set to a value"); $date->Set(Format => 'unix', Value => $_); is($date->ISO, '1970-01-01 00:00:00', "Set a date to midnight 1/1/1970 GMT due to wrong call"); is($date->Unix, 0, "unix is 0 => unset"); + is($date->IsSet,0,"Date has been unset"); + } + + foreach (undef, 0, '', -5){ + $date->Unix(1); + is($date->ISO, '1970-01-01 00:00:01', "correct value"); + is($date->IsSet,1,"Date has been set to a value"); + + $date->Unix($_); + is($date->ISO, '1970-01-01 00:00:00', "Set a date to midnight 1/1/1970 GMT due to wrong call"); + is($date->Unix, 0, "unix is 0 => unset"); + is($date->IsSet,0,"Date has been unset"); } } @@ -265,7 +280,7 @@ my $year = (localtime(time))[5] + 1900; warning_like { $date->Set(Format => 'ISO', Value => 'weird date'); } qr/Couldn't parse date 'weird date' as a ISO format/; - is($date->Unix, 0, "date was wrong => unix == 0"); + ok(!$date->IsSet, "date was wrong => unix == 0"); # XXX: ISO format has more feature than we suport # http://www.cl.cam.ac.uk/~mgk25/iso-time.html @@ -294,14 +309,18 @@ my $year = (localtime(time))[5] + 1900; $date->Set(Format => 'ISO', Value => '112815:10:00'); is($date->ISO, $year .'-11-28 15:10:00', "DDMMhh:mm:ss"); - $date->Set(Format => 'ISO', Value => '2005-13-28 15:10:00'); - is($date->Unix, 0, "wrong month value"); + warning_like { + $date->Set(Format => 'ISO', Value => '2005-13-28 15:10:00'); + } qr/Invalid date/; + ok(!$date->IsSet, "wrong month value"); - $date->Set(Format => 'ISO', Value => '2005-00-28 15:10:00'); - is($date->Unix, 0, "wrong month value"); + warning_like { + $date->Set(Format => 'ISO', Value => '2005-00-28 15:10:00'); + } qr/Invalid date/; + ok(!$date->IsSet, "wrong month value"); $date->Set(Format => 'ISO', Value => '1960-01-28 15:10:00'); - is($date->Unix, 0, "too old, we don't support"); + ok(!$date->IsSet, "too old, we don't support"); } { # set+datemanip format(Time::ParseDate) @@ -326,7 +345,7 @@ my $year = (localtime(time))[5] + 1900; warnings_like { $date->Set(Format => 'unknown', Value => 'weird date'); } qr{Couldn't parse date 'weird date' by Time::ParseDate}; - is($date->Unix, 0, "date was wrong"); + ok(!$date->IsSet, "date was wrong"); RT->Config->Set( Timezone => 'Europe/Moscow' ); $date->Set(Format => 'unknown', Value => '2005-11-28 15:10:00'); @@ -360,6 +379,34 @@ my $year = (localtime(time))[5] + 1900; is($date->ISO, '2005-11-28 15:10:00', "YYYY-DD-MM hh:mm:ss"); } +{ # 'tomorrow 10am' with TZ + $current_user->UserObj->__Set( Field => 'Timezone', Value => 'Europe/Moscow'); + + set_fixed_time("2012-06-14T15:10:00Z"); # 14th in UTC and Moscow + my $date = RT::Date->new( $current_user ); + $date->Set(Format => 'unknown', Value => 'tomorrow 10am'); + is($date->ISO, '2012-06-15 06:00:00', "YYYY-DD-MM hh:mm:ss"); + + set_fixed_time("2012-06-13T23:10:00Z"); # 13th in UTC and 14th in Moscow + $date = RT::Date->new( $current_user ); + $date->Set(Format => 'unknown', Value => 'tomorrow 10am'); + is($date->ISO, '2012-06-15 06:00:00', "YYYY-DD-MM hh:mm:ss"); + + $current_user->UserObj->__Set( Field => 'Timezone', Value => 'US/Hawaii'); + + set_fixed_time("2012-06-14T20:10:00Z"); # 14th in UTC and Hawaii + $date = RT::Date->new( $current_user ); + $date->Set(Format => 'unknown', Value => 'tomorrow 10am'); + is($date->ISO, '2012-06-15 20:00:00', "YYYY-DD-MM hh:mm:ss"); + + set_fixed_time("2012-06-15T05:10:00Z"); # 15th in UTC and 14th in Hawaii + $date = RT::Date->new( $current_user ); + $date->Set(Format => 'unknown', Value => 'tomorrow 10am'); + is($date->ISO, '2012-06-15 20:00:00', "YYYY-DD-MM hh:mm:ss"); + + restore_time(); +} + { # SetToMidnight my $date = RT::Date->new(RT->SystemUser); @@ -475,11 +522,11 @@ my $year = (localtime(time))[5] + 1900; { # DurationAsString my $date = RT::Date->new(RT->SystemUser); - is($date->DurationAsString(1), '1 sec', '1 sec'); - is($date->DurationAsString(59), '59 sec', '59 sec'); - is($date->DurationAsString(60), '1 min', '1 min'); - is($date->DurationAsString(60*119), '119 min', '119 min'); - is($date->DurationAsString(60*60*2-1), '120 min', '120 min'); + is($date->DurationAsString(1), '1 second', '1 sec'); + is($date->DurationAsString(59), '59 seconds', '59 sec'); + is($date->DurationAsString(60), '1 minute', '1 min'); + is($date->DurationAsString(60*119), '119 minutes', '119 min'); + is($date->DurationAsString(60*60*2-1), '120 minutes', '120 min'); is($date->DurationAsString(60*60*2), '2 hours', '2 hours'); is($date->DurationAsString(60*60*48-1), '48 hours', '48 hours'); is($date->DurationAsString(60*60*48), '2 days', '2 days'); @@ -488,9 +535,9 @@ my $year = (localtime(time))[5] + 1900; is($date->DurationAsString(60*60*24*7*8-1), '8 weeks', '8 weeks'); is($date->DurationAsString(60*60*24*61), '2 months', '2 months'); is($date->DurationAsString(60*60*24*365-1), '12 months', '12 months'); - is($date->DurationAsString(60*60*24*366), '1 years', '1 years'); + is($date->DurationAsString(60*60*24*366), '1 year', '1 year'); - is($date->DurationAsString(-1), '1 sec ago', '1 sec ago'); + is($date->DurationAsString(-1), '1 second ago', '1 sec ago'); } { # DiffAsString @@ -502,13 +549,13 @@ my $year = (localtime(time))[5] + 1900; $date->Unix(2); is($date->DiffAsString(-1), '', 'no diff, wrong input'); - is($date->DiffAsString(3), '1 sec ago', 'diff: 1 sec ago'); - is($date->DiffAsString(1), '1 sec', 'diff: 1 sec'); + is($date->DiffAsString(3), '1 second ago', 'diff: 1 sec ago'); + is($date->DiffAsString(1), '1 second', 'diff: 1 sec'); my $ndate = RT::Date->new(RT->SystemUser); is($date->DiffAsString($ndate), '', 'no diff, wrong input'); $ndate->Unix(3); - is($date->DiffAsString($ndate), '1 sec ago', 'diff: 1 sec ago'); + is($date->DiffAsString($ndate), '1 second ago', 'diff: 1 sec ago'); } { # Diff @@ -523,7 +570,7 @@ my $year = (localtime(time))[5] + 1900; my $date = RT::Date->new(RT->SystemUser); $date->SetToNow; my $diff = $date->AgeAsString; - like($diff, qr/^(0 sec|[1-5] sec ago)$/, 'close enought'); + like($diff, qr/^(0 seconds|(1 second|[2-5] seconds) ago)$/, 'close enought'); } { # GetWeekday @@ -550,15 +597,16 @@ my $year = (localtime(time))[5] + 1900; # set unknown format: edge cases my $date = RT::Date->new(RT->SystemUser); $date->Set( Value => 0, Format => 'unknown' ); - is( $date->Unix(), 0, "unix is 0 with Value => 0, Format => 'unknown'" ); + ok( !$date->IsSet, "unix is 0 with Value => 0, Format => 'unknown'" ); $date->Set( Value => '', Format => 'unknown' ); - is( $date->Unix(), 0, "unix is 0 with Value => '', Format => 'unknown'" ); + ok( !$date->IsSet, "unix is 0 with Value => '', Format => 'unknown'" ); $date->Set( Value => ' ', Format => 'unknown' ); - is( $date->Unix(), 0, "unix is 0 with Value => ' ', Format => 'unknown'" ); + ok( !$date->IsSet, "unix is 0 with Value => ' ', Format => 'unknown'" ); } #TODO: AsString #TODO: RFC2822, W3CDTF with Timezones +done_testing; diff --git a/rt/t/api/db_indexes.t b/rt/t/api/db_indexes.t new file mode 100644 index 000000000..3c305d84d --- /dev/null +++ b/rt/t/api/db_indexes.t @@ -0,0 +1,165 @@ +use strict; +use warnings; +use Test::Warn; + +use RT::Test tests => undef; + +my $handle = $RT::Handle; +my $db_type = RT->Config->Get('DatabaseType'); + +# Pg,Oracle needs DBA +RT::Test::__reconnect_rt('as dba'); +ok( $handle->dbh->do("ALTER SESSION SET CURRENT_SCHEMA=". RT->Config->Get('DatabaseUser') ) ) + if $db_type eq 'Oracle'; + +note "test handle->Indexes method"; +{ + my %indexes = $handle->Indexes; + ok grep $_ eq 'tickets1', @{ $indexes{'tickets'} }; + ok grep $_ eq 'tickets2', @{ $indexes{'tickets'} }; + ok grep $_ eq 'users1', @{ $indexes{'users'} }; + ok grep $_ eq 'users4', @{ $indexes{'users'} }; +} + +note "test handle->DropIndex method"; +{ + my ($status, $msg) = $handle->DropIndex( Table => 'Tickets', Name => 'Tickets1' ); + ok $status, $msg; + + my %indexes = $handle->Indexes; + ok !grep $_ eq 'tickets1', @{ $indexes{'tickets'} }; + + ($status, $msg) = $handle->DropIndex( Table => 'Tickets', Name => 'Tickets1' ); + ok !$status, $msg; +} + +note "test handle->DropIndexIfExists method"; +{ + my ($status, $msg) = $handle->DropIndexIfExists( Table => 'Tickets', Name => 'Tickets2' ); + ok $status, $msg; + + my %indexes = $handle->Indexes; + ok !grep $_ eq 'tickets2', @{ $indexes{'tickets'} }; + + ($status, $msg) = $handle->DropIndexIfExists( Table => 'Tickets', Name => 'Tickets2' ); + ok $status, $msg; +} + +note "test handle->IndexInfo method"; +{ + if ($db_type ne 'Oracle' && $db_type ne 'mysql') { + my %res = $handle->IndexInfo( Table => 'Attachments', Name => 'Attachments1' ); + is_deeply( + \%res, + { + Table => 'attachments', Name => 'attachments1', + Unique => 0, Functional => 0, + Columns => ['parent'] + } + ); + } else { + my %res = $handle->IndexInfo( Table => 'Attachments', Name => 'Attachments2' ); + is_deeply( + \%res, + { + Table => 'attachments', Name => 'attachments2', + Unique => 0, Functional => 0, + Columns => ['transactionid'] + } + ); + } + + my %res = $handle->IndexInfo( Table => 'GroupMembers', Name => 'GroupMembers1' ); + is_deeply( + \%res, + { + Table => 'groupmembers', Name => 'groupmembers1', + Unique => 1, Functional => 0, + Columns => ['groupid', 'memberid'] + } + ); + + if ( $db_type eq 'Pg' || $db_type eq 'Oracle' ) { + %res = $handle->IndexInfo( Table => 'Queues', Name => 'Queues1' ); + is_deeply( + \%res, + { + Table => 'queues', Name => 'queues1', + Unique => 1, Functional => 1, + Columns => ['name'], + CaseInsensitive => { name => 1 }, + } + ); + } +} + +note "test ->CreateIndex and ->IndexesThatBeginWith methods"; +{ + { + my ($name, $msg) = $handle->CreateIndex( + Table => 'Users', Name => 'test_users1', + Columns => ['Organization'], + ); + ok $name, $msg; + } + { + my ($name, $msg) = $handle->CreateIndex( + Table => 'Users', Name => 'test_users2', + Columns => ['Organization', 'Name'], + ); + ok $name, $msg; + } + + my @list = $handle->IndexesThatBeginWith( Table => 'Users', Columns => ['Organization'] ); + is_deeply([sort map $_->{Name}, @list], [qw(test_users1 test_users2)]); + + my ($status, $msg) = $handle->DropIndex( Table => 'Users', Name => 'test_users1' ); + ok $status, $msg; + ($status, $msg) = $handle->DropIndex( Table => 'Users', Name => 'test_users2' ); + ok $status, $msg; +} + +note "Test some cases sensitivity aspects"; +{ + { + my %res = $handle->IndexInfo( Table => 'groupmembers', Name => 'groupmembers1' ); + is_deeply( + \%res, + { + Table => 'groupmembers', Name => 'groupmembers1', + Unique => 1, Functional => 0, + Columns => ['groupid', 'memberid'] + } + ); + } + + { + my ($status, $msg) = $handle->DropIndex( Table => 'groupmembers', Name => 'groupmembers1' ); + ok $status, $msg; + + my %indexes = $handle->Indexes; + ok !grep $_ eq 'groupmembers1', @{ $indexes{'groupmembers'} }; + } + + { + my ($name, $msg) = $handle->CreateIndex( + Table => 'groupmembers', Name => 'groupmembers1', + Unique => 1, + Columns => ['groupid', 'memberid'] + ); + ok $name, $msg; + + my %indexes = $handle->Indexes; + ok grep $_ eq 'groupmembers1', @{ $indexes{'groupmembers'} }; + } + + { + my ($status, $msg) = $handle->DropIndexIfExists( Table => 'groupmembers', Name => 'groupmembers1' ); + ok $status, $msg; + + my %indexes = $handle->Indexes; + ok !grep $_ eq 'groupmembers1', @{ $indexes{'groupmembers'} }; + } +} + +done_testing(); diff --git a/rt/t/api/group-rights.t b/rt/t/api/group-rights.t index 0494c286e..4f5f03d0d 100644 --- a/rt/t/api/group-rights.t +++ b/rt/t/api/group-rights.t @@ -2,7 +2,7 @@ use strict; use warnings; use RT::Test nodata => 1, tests => 114; -RT::Group->AddRights( +RT::Group->AddRight( General => 'RTxGroupRight' => 'Just a right for testing rights', ); diff --git a/rt/t/api/group.t b/rt/t/api/group.t index d55fc5c4a..f82dfc57e 100644 --- a/rt/t/api/group.t +++ b/rt/t/api/group.t @@ -96,7 +96,7 @@ is($group_3->HasMemberRecursively($principal_2), undef, "group 3 has member 2 re ok(my $u = RT::Group->new(RT->SystemUser)); ok($u->Load(4), "Loaded the first user"); -is($u->PrincipalObj->ObjectId , 4, "user 4 is the fourth principal"); +is($u->PrincipalObj->id , 4, "user 4 is the fourth principal"); is($u->PrincipalObj->PrincipalType , 'Group' , "Principal 4 is a group"); diff --git a/rt/t/api/groups.t b/rt/t/api/groups.t index d2dc126dc..c2e7fc583 100644 --- a/rt/t/api/groups.t +++ b/rt/t/api/groups.t @@ -2,7 +2,7 @@ use strict; use warnings; use RT::Test nodata => 1, tests => 27; -RT::Group->AddRights( +RT::Group->AddRight( General => 'RTxGroupRight' => 'Just a right for testing rights', ); @@ -49,8 +49,7 @@ my $testuser = RT::User->new(RT->SystemUser); ($id,$msg) = $testuser->Create(Name => 'JustAnAdminCc'); ok ($id,$msg); -my $global_admin_cc = RT::Group->new(RT->SystemUser); -$global_admin_cc->LoadSystemRoleGroup('AdminCc'); +my $global_admin_cc = RT->System->RoleGroup( 'AdminCc' ); ok($global_admin_cc->id, "Found the global admincc group"); my $groups = RT::Groups->new(RT->SystemUser); $groups->WithRight(Right => 'OwnTicket', Object => $q); diff --git a/rt/t/api/i18n_guess.t b/rt/t/api/i18n_guess.t index a64b2952c..0a99011f2 100644 --- a/rt/t/api/i18n_guess.t +++ b/rt/t/api/i18n_guess.t @@ -4,8 +4,8 @@ use warnings; use RT::Test tests => 16; -use constant HAS_ENCODE_GUESS => do { local $@; eval { require Encode::Guess; 1 } }; -use constant HAS_ENCODE_DETECT => do { local $@; eval { require Encode::Detect::Detector; 1 } }; +use constant HAS_ENCODE_GUESS => Encode::Guess->require; +use constant HAS_ENCODE_DETECT => Encode::Detect::Detector->require; my $string = "\x{442}\x{435}\x{441}\x{442} \x{43f}\x{43e}\x{434}\x{434}\x{435}\x{440}\x{436}\x{43a}\x{430}"; diff --git a/rt/t/api/i18n_mime_encoding.t b/rt/t/api/i18n_mime_encoding.t new file mode 100644 index 000000000..5ad532ed2 --- /dev/null +++ b/rt/t/api/i18n_mime_encoding.t @@ -0,0 +1,32 @@ +use warnings; +use strict; + +use RT::Test nodata => 1, tests => undef; +use RT::I18N; +use Test::Warn; + +diag "normal mime encoding conversion: utf8 => iso-8859-1"; +{ + my $mime = MIME::Entity->build( + Type => 'text/plain; charset=utf-8', + Data => ['Ã€ä¸æ–‡'], + ); + + warning_like { + RT::I18N::SetMIMEEntityToEncoding( $mime, 'iso-8859-1', ); + } + [ qr/does not map to iso-8859-1/ ], 'got one "not map" error'; + is( $mime->stringify_body, 'Ã€ä¸æ–‡', 'body is not changed' ); + is( $mime->head->mime_attr('Content-Type'), 'application/octet-stream' ); +} + +diag "mime encoding conversion: utf8 => iso-8859-1"; +{ + my $mime = MIME::Entity->build( + Type => 'text/plain; charset=utf-8', + Data => ['Ã€ä¸æ–‡'], + ); + is( $mime->stringify_body, 'Ã€ä¸æ–‡', 'body is not changed' ); +} + +done_testing; diff --git a/rt/t/api/initialdata.t b/rt/t/api/initialdata.t new file mode 100644 index 000000000..5856528a3 --- /dev/null +++ b/rt/t/api/initialdata.t @@ -0,0 +1,16 @@ +use strict; +use warnings; + +use RT::Test tests => 'no_declare'; + +# This test script processes the sample initialdata file in +# ../data/initialdata/initialdata +# To add initialdata tests, add the data to the initialdata file and it +# will be processed by this script. + +my $initialdata = RT::Test::get_relocatable_file("initialdata" => "..", "data", "initialdata"); +my ($rv, $msg) = RT->DatabaseHandle->InsertData( $initialdata, undef, disconnect_after => 0 ); +ok($rv, "Inserted test data from $initialdata") + or diag "Error: $msg"; + +done_testing();
\ No newline at end of file diff --git a/rt/t/api/link.t b/rt/t/api/link.t index a9e54a716..3066388f2 100644 --- a/rt/t/api/link.t +++ b/rt/t/api/link.t @@ -1,7 +1,7 @@ use strict; use warnings; -use RT::Test nodata => 1, tests => 84; +use RT::Test nodata => 1, tests => 83; use RT::Test::Web; use Test::Warn; @@ -35,9 +35,7 @@ ok $cid, 'created a ticket #'. $cid or diag "error: $msg"; my ($status, $msg); clean_links(); - warning_like { - ($status, $msg) = $parent->AddLink; - } qr/Base or Target must be specified/, "warned about linking a ticket to itself"; + ($status, $msg) = $parent->AddLink; ok(!$status, "didn't create a link: $msg"); warning_like { diff --git a/rt/t/api/password-types.t b/rt/t/api/password-types.t index 4cb634248..9eeded499 100644 --- a/rt/t/api/password-types.t +++ b/rt/t/api/password-types.t @@ -4,17 +4,29 @@ use warnings; use RT::Test; use Digest::MD5; -my $default = "sha512"; +my $default = "bcrypt"; my $root = RT::User->new(RT->SystemUser); $root->Load("root"); -# Salted SHA-512 (default) +# bcrypt (default) my $old = $root->__Value("Password"); like($old, qr/^\!$default\!/, "Stored as salted $default"); ok($root->IsPassword("password")); is($root->__Value("Password"), $old, "Unchanged after password check"); +# bcrypt (smaller number of rounds) +my $salt = Crypt::Eksblowfish::Bcrypt::en_base64("a"x16); +$root->_Set( Field => "Password", Value => RT::User->_GeneratePassword_bcrypt("smaller", 6, $salt) ); +like($root->__Value("Password"), qr/^\!$default\!06\!/, "Stored with a smaller number of rounds"); +ok($root->IsPassword("smaller"), "Smaller number of bcrypt rounds works"); +like($root->__Value("Password"), qr/^\!$default\!10\!/, "And is now upgraded to salted $default"); + +# Salted SHA-512, one round +$root->_Set( Field => "Password", Value => RT::User->_GeneratePassword_sha512("other", "salt") ); +ok($root->IsPassword("other"), "SHA-512 password works"); +like($root->__Value("Password"), qr/^\!$default\!/, "And is now upgraded to salted $default"); + # Crypt $root->_Set( Field => "Password", Value => crypt("something", "salt")); ok($root->IsPassword("something"), "crypt()ed password works"); diff --git a/rt/t/api/queue.t b/rt/t/api/queue.t index 07b8ed479..71efb4d39 100644 --- a/rt/t/api/queue.t +++ b/rt/t/api/queue.t @@ -2,7 +2,7 @@ use strict; use warnings; use RT; -use RT::Test nodata => 1, tests => 24; +use RT::Test nodata => 1, tests => undef; { @@ -58,8 +58,7 @@ ok(!$id, $val); my $Queue = RT::Queue->new(RT->SystemUser); my ($id, $msg) = $Queue->Create(Name => "Foo"); ok ($id, "Foo $id was created"); -ok(my $group = RT::Group->new(RT->SystemUser)); -ok($group->LoadQueueRoleGroup(Queue => $id, Type=> 'Requestor')); +ok(my $group = $Queue->RoleGroup('Requestor')); ok ($group->Id, "Found the requestors object for this Queue"); { @@ -79,13 +78,12 @@ ok ($Queue->IsWatcher(Type => 'Cc', PrincipalId => $bob->PrincipalId), "The Queu "The Queue no longer has bob at fsck.com as a requestor"); } -$group = RT::Group->new(RT->SystemUser); -ok($group->LoadQueueRoleGroup(Queue => $id, Type=> 'Cc')); +$group = $Queue->RoleGroup('Cc'); ok ($group->Id, "Found the cc object for this Queue"); -$group = RT::Group->new(RT->SystemUser); -ok($group->LoadQueueRoleGroup(Queue => $id, Type=> 'AdminCc')); +$group = $Queue->RoleGroup('AdminCc'); ok ($group->Id, "Found the AdminCc object for this Queue"); } +done_testing; diff --git a/rt/t/api/record.t b/rt/t/api/record.t index 4b6b0b89c..7abd41ca5 100644 --- a/rt/t/api/record.t +++ b/rt/t/api/record.t @@ -16,8 +16,8 @@ ok (require RT::Record); my $ticket = RT::Ticket->new(RT->SystemUser); my $group = RT::Group->new(RT->SystemUser); -is($ticket->ObjectTypeStr, 'Ticket', "Ticket returns correct typestring"); -is($group->ObjectTypeStr, 'Group', "Group returns correct typestring"); +is($ticket->RecordType, 'Ticket', "Ticket returns correct typestring"); +is($group->RecordType, 'Group', "Group returns correct typestring"); } diff --git a/rt/t/api/reminder-permissions.t b/rt/t/api/reminder-permissions.t new file mode 100644 index 000000000..8253d67af --- /dev/null +++ b/rt/t/api/reminder-permissions.t @@ -0,0 +1,49 @@ +use strict; +use warnings; +use RT::Test tests => 9; + +my $user_a = RT::Test->load_or_create_user( + Name => 'user_a', + Password => 'password', +); + +ok( $user_a && $user_a->id, 'created user_a' ); +ok( + RT::Test->add_rights( + { + Principal => $user_a, + Right => [qw/SeeQueue CreateTicket ShowTicket OwnTicket/] + }, + ), + 'add basic rights for user_a' +); + +my $ticket = RT::Test->create_ticket( + Subject => 'test reminder permission', + Queue => 'General', +); +ok( $ticket->id, 'created a ticket' ); +$ticket->CurrentUser($user_a); + +my ( $status, $msg ) = $ticket->Reminders->Add( + Subject => 'user a reminder', + Owner => $user_a->id, +); +ok( !$status, "couldn't create reminders without ModifyTicket: $msg" ); + +ok( + RT::Test->add_rights( + { + Principal => $user_a, + Right => [qw/ModifyTicket/] + }, + ), + 'add ModifyTicket right for user_a' +); + +( $status, $msg ) = $ticket->Reminders->Add( + Subject => 'user a reminder', + Owner => $user_a->id, +); +ok( $status, "created a reminder with ModifyTicket: $msg" ); + diff --git a/rt/t/api/rights.t b/rt/t/api/rights.t index 5cf3a0008..a6346a737 100644 --- a/rt/t/api/rights.t +++ b/rt/t/api/rights.t @@ -29,10 +29,8 @@ ok $user && $user->id, 'loaded or created user'; } { - my $group = RT::Group->new( RT->SystemUser ); - ok( $group->LoadQueueRoleGroup( Queue => $queue->id, Type=> 'Owner' ), - "load queue owners role group" - ); + my $group = $queue->RoleGroup( 'Owner' ); + ok( $group->Id, "load queue owners role group" ); my $ace = RT::ACE->new( RT->SystemUser ); my ($ace_id, $msg) = $group->PrincipalObj->GrantRight( Right => 'ReplyToTicket', Object => $queue @@ -84,10 +82,8 @@ my $ticket; { # Testing of EquivObjects - my $group = RT::Group->new( RT->SystemUser ); - ok( $group->LoadQueueRoleGroup( Queue => $queue->id, Type=> 'AdminCc' ), - "load queue AdminCc role group" - ); + my $group = $queue->RoleGroup( 'AdminCc' ); + ok( $group->Id, "load queue AdminCc role group" ); my $ace = RT::ACE->new( RT->SystemUser ); my ($ace_id, $msg) = $group->PrincipalObj->GrantRight( Right => 'ModifyTicket', Object => $queue diff --git a/rt/t/api/rtname.t b/rt/t/api/rtname.t index 8b7b54bd1..f2bffd559 100644 --- a/rt/t/api/rtname.t +++ b/rt/t/api/rtname.t @@ -1,7 +1,7 @@ use strict; use warnings; -use RT::Test nodata => 1, tests => 9; +use RT::Test nodata => 1, tests => 12; use RT::Interface::Email; @@ -31,3 +31,8 @@ is(RT::Interface::Email::ParseTicketId("[site #123] test"), 123); is(RT::Interface::Email::ParseTicketId("[newsite #123] test"), 123); is(RT::Interface::Email::ParseTicketId("[othersite #123] test"), undef); +# Parens work fine +RT->Config->Set( EmailSubjectTagRegex => qr/(new|)(site)/ ); +is(RT::Interface::Email::ParseTicketId("[site #123] test"), 123); +is(RT::Interface::Email::ParseTicketId("[newsite #123] test"), 123); +is(RT::Interface::Email::ParseTicketId("[othersite #123] test"), undef); diff --git a/rt/t/api/savedsearch.t b/rt/t/api/savedsearch.t index 0aa67eeda..2e924bf7b 100644 --- a/rt/t/api/savedsearch.t +++ b/rt/t/api/savedsearch.t @@ -13,9 +13,9 @@ use Test::Warn; my $searchuser = RT::User->new(RT->SystemUser); my ($ret, $msg) = $searchuser->Create(Name => 'searchuser'.$$, - Privileged => 1, - EmailAddress => "searchuser\@p$$.example.com", - RealName => 'Search user'); + Privileged => 1, + EmailAddress => "searchuser\@p$$.example.com", + RealName => 'Search user'); ok($ret, "created searchuser: $msg"); $searchuser->PrincipalObj->GrantRight(Right => 'LoadSavedSearch'); $searchuser->PrincipalObj->GrantRight(Right => 'CreateSavedSearch'); @@ -26,9 +26,9 @@ my $ingroup = RT::Group->new(RT->SystemUser); $ingroup->CreateUserDefinedGroup(Name => 'searchgroup1'.$$); $ingroup->AddMember($searchuser->Id); $searchuser->PrincipalObj->GrantRight(Right => 'EditSavedSearches', - Object => $ingroup); + Object => $ingroup); $searchuser->PrincipalObj->GrantRight(Right => 'ShowSavedSearches', - Object => $ingroup); + Object => $ingroup); # This is the group whose searches searchuser should not be able to see. my $outgroup = RT::Group->new(RT->SystemUser); @@ -44,9 +44,9 @@ $searchuser->PrincipalObj->GrantRight(Right => 'OwnTicket', Object => $queue); my $ticket = RT::Ticket->new(RT->SystemUser); $ticket->Create(Queue => $queue->Id, - Requestor => [ $searchuser->Name ], - Owner => $searchuser, - Subject => 'saved search test'); + Requestor => [ $searchuser->Name ], + Owner => $searchuser, + Subject => 'saved search test'); # Now start the search madness. @@ -67,41 +67,41 @@ my $format = '\' <b><a href="/Ticket/Display.html?id=__id__">__id__</a></b>/TI my $mysearch = RT::SavedSearch->new($curruser); ($ret, $msg) = $mysearch->Save(Privacy => 'RT::User-' . $searchuser->Id, - Type => 'Ticket', - Name => 'owned by me', - SearchParams => {'Format' => $format, - 'Query' => "Owner = '" - . $searchuser->Name - . "'"}); + Type => 'Ticket', + Name => 'owned by me', + SearchParams => {'Format' => $format, + 'Query' => "Owner = '" + . $searchuser->Name + . "'"}); ok($ret, "mysearch was created"); my $groupsearch = RT::SavedSearch->new($curruser); ($ret, $msg) = $groupsearch->Save(Privacy => 'RT::Group-' . $ingroup->Id, - Type => 'Ticket', - Name => 'search queue', - SearchParams => {'Format' => $format, - 'Query' => "Queue = '" - . $queue->Name . "'"}); + Type => 'Ticket', + Name => 'search queue', + SearchParams => {'Format' => $format, + 'Query' => "Queue = '" + . $queue->Name . "'"}); ok($ret, "groupsearch was created"); my $othersearch = RT::SavedSearch->new($curruser); ($ret, $msg) = $othersearch->Save(Privacy => 'RT::Group-' . $outgroup->Id, - Type => 'Ticket', - Name => 'searchuser requested', - SearchParams => {'Format' => $format, - 'Query' => - "Requestor.Name LIKE 'search'"}); + Type => 'Ticket', + Name => 'searchuser requested', + SearchParams => {'Format' => $format, + 'Query' => + "Requestor.Name LIKE 'search'"}); ok(!$ret, "othersearch NOT created"); like($msg, qr/Failed to load object for/, "...for the right reason"); $othersearch = RT::SavedSearch->new(RT->SystemUser); ($ret, $msg) = $othersearch->Save(Privacy => 'RT::Group-' . $outgroup->Id, - Type => 'Ticket', - Name => 'searchuser requested', - SearchParams => {'Format' => $format, - 'Query' => - "Requestor.Name LIKE 'search'"}); + Type => 'Ticket', + Name => 'searchuser requested', + SearchParams => {'Format' => $format, + 'Query' => + "Requestor.Name LIKE 'search'"}); ok($ret, "othersearch created by systemuser"); # Now try to load some searches. @@ -148,8 +148,8 @@ warning_like { isnt($loadedsearch4->Id, $othersearch->Id, "Did not load othersearch"); # Try to update an existing search. -$loadedsearch1->Update( SearchParams => {'Format' => $format, - 'Query' => "Queue = '" . $queue->Name . "'" } ); +$loadedsearch1->Update( SearchParams => {'Format' => $format, + 'Query' => "Queue = '" . $queue->Name . "'" } ); like($loadedsearch1->GetParameter('Query'), qr/Queue/, "Updated mysearch parameter"); is($loadedsearch1->Type, 'Ticket', "mysearch is still for tickets"); @@ -162,8 +162,8 @@ like($mysearch->GetParameter('Query'), qr/Queue/, "other mysearch object updated my $genericsearch = RT::SavedSearch->new($curruser); $genericsearch->Save(Name => 'generic search', - Type => 'all', - SearchParams => {'Query' => "Queue = 'General'"}); + Type => 'all', + SearchParams => {'Query' => "Queue = 'General'"}); my $ticketsearches = RT::SavedSearches->new($curruser); $ticketsearches->LimitToPrivacy('RT::User-'.$curruser->Id, 'Ticket'); diff --git a/rt/t/api/scrip.t b/rt/t/api/scrip.t index eb543476b..d6019a082 100644 --- a/rt/t/api/scrip.t +++ b/rt/t/api/scrip.t @@ -1,52 +1,44 @@ use strict; use warnings; -use RT; -use RT::Test tests => 25; +use RT::Test; +my $queue = RT::Test->load_or_create_queue( Name => 'General' ); +ok $queue && $queue->id, 'loaded or created queue'; +note 'basic scrips functionality test: create+execute'; { - -ok (require RT::Scrip); - - -my $q = RT::Queue->new(RT->SystemUser); -$q->Create(Name => 'ScripTest'); -ok($q->Id, "Created a scriptest queue"); - -my $s1 = RT::Scrip->new(RT->SystemUser); -my ($val, $msg) =$s1->Create( Queue => $q->Id, - ScripAction => 'User Defined', - ScripCondition => 'User Defined', - CustomIsApplicableCode => 'if ($self->TicketObj->Subject =~ /fire/) { return (1);} else { return(0)}', - CustomPrepareCode => 'return 1', - CustomCommitCode => '$self->TicketObj->SetPriority("87");', - Template => 'Blank' + my $s1 = RT::Scrip->new(RT->SystemUser); + my ($val, $msg) = $s1->Create( + Queue => $queue->Id, + ScripAction => 'User Defined', + ScripCondition => 'User Defined', + CustomIsApplicableCode => '$self->TicketObj->Subject =~ /fire/? 1 : 0', + CustomPrepareCode => 'return 1', + CustomCommitCode => '$self->TicketObj->SetPriority("87");', + Template => 'Blank' ); -ok($val,$msg); - -my $ticket = RT::Ticket->new(RT->SystemUser); -my ($tv,$ttv,$tm) = $ticket->Create(Queue => $q->Id, - Subject => "hair on fire", - ); -ok($tv, $tm); - -is ($ticket->Priority , '87', "Ticket priority is set right"); - - -my $ticket2 = RT::Ticket->new(RT->SystemUser); -my ($t2v,$t2tv,$t2m) = $ticket2->Create(Queue => $q->Id, - Subject => "hair in water", - ); -ok($t2v, $t2m); - -isnt ($ticket2->Priority , '87', "Ticket priority is set right"); + ok($val,$msg); + my $ticket = RT::Ticket->new(RT->SystemUser); + my ($tv,$ttv,$tm) = $ticket->Create( + Queue => $queue->Id, + Subject => "hair on fire", + ); + ok($tv, $tm); + is ($ticket->Priority , '87', "Ticket priority is set right"); + my $ticket2 = RT::Ticket->new(RT->SystemUser); + my ($t2v,$t2tv,$t2m) = $ticket2->Create( + Queue => $queue->Id, + Subject => "hair in water", + ); + ok($t2v, $t2m); + isnt ($ticket2->Priority , '87', "Ticket priority is set right"); } - +note 'modify properties of a scrip'; { my $scrip = RT::Scrip->new($RT::SystemUser); my ( $val, $msg ) = $scrip->Create( @@ -117,3 +109,158 @@ isnt ($ticket2->Priority , '87', "Ticket priority is set right"); ok( $scrip->Delete, 'delete the scrip' ); } + +my $queue_B = RT::Test->load_or_create_queue( Name => 'B' ); +ok $queue_B && $queue_B->id, 'loaded or created queue'; + +note 'check creation errors vs. templates'; +{ + my $scrip = RT::Scrip->new(RT->SystemUser); + my ($status, $msg) = $scrip->Create( + Queue => $queue->id, + ScripAction => 'User Defined', + ScripCondition => 'User Defined', + Template => 'not exist', + ); + ok(!$status, "couldn't create scrip, not existing template"); + + ($status, $msg) = $scrip->Create( + ScripAction => 'User Defined', + ScripCondition => 'User Defined', + Template => 'not exist', + ); + ok(!$status, "couldn't create scrip, not existing template"); + + ($status, $msg) = $scrip->Create( + Queue => $queue->id, + ScripAction => 'User Defined', + ScripCondition => 'User Defined', + Template => 54321, + ); + ok(!$status, "couldn't create scrip, not existing template"); + + ($status, $msg) = $scrip->Create( + ScripAction => 'User Defined', + ScripCondition => 'User Defined', + Template => 54321, + ); + ok(!$status, "couldn't create scrip, not existing template"); + + my $template = RT::Template->new( RT->SystemUser ); + ($status, $msg) = $template->Create( Queue => $queue->id, Name => 'bar' ); + ok $status, 'created a template'; + + ($status, $msg) = $scrip->Create( + ScripAction => 'User Defined', + ScripCondition => 'User Defined', + Template => $template->id, + ); + ok(!$status, "couldn't create scrip, wrong template"); + + ($status, $msg) = $scrip->Create( + Queue => $queue_B->id, + ScripAction => 'User Defined', + ScripCondition => 'User Defined', + Template => $template->id, + ); + ok(!$status, "couldn't create scrip, wrong template"); +} + +note 'check applications vs. templates'; +{ + my $template = RT::Template->new( RT->SystemUser ); + my ($status, $msg) = $template->Create( Queue => $queue->id, Name => 'foo' ); + ok $status, 'created a template'; + + my $scrip = RT::Scrip->new(RT->SystemUser); + ($status, $msg) = $scrip->Create( + Queue => $queue->Id, + ScripAction => 'User Defined', + ScripCondition => 'User Defined', + Template => 'foo', + CustomIsApplicableCode => "1;", + CustomPrepareCode => "1;", + CustomCommitCode => "1;", + ); + ok($status, 'created a scrip') or diag "error: $msg"; + RT::Test->object_scrips_are($scrip, [$queue], [0, $queue_B]); + + ($status, $msg) = $scrip->AddToObject( $queue_B->id ); + ok(!$status, $msg); + RT::Test->object_scrips_are($scrip, [$queue], [0, $queue_B]); + my $obj_scrip = RT::ObjectScrip->new( RT->SystemUser ); + ok($obj_scrip->LoadByCols( Scrip => $scrip->id, ObjectId => $queue->id )); + is($obj_scrip->Stage, 'TransactionCreate'); + is($obj_scrip->FriendlyStage, 'Normal'); + + $template = RT::Template->new( RT->SystemUser ); + ($status, $msg) = $template->Create( Queue => $queue_B->id, Name => 'foo' ); + ok $status, 'created a template'; + + ($status, $msg) = $scrip->AddToObject( $queue_B->id ); + ok($status, 'added scrip to another queue'); + RT::Test->object_scrips_are($scrip, [$queue, $queue_B], [0]); + + ($status, $msg) = $scrip->RemoveFromObject( $queue_B->id ); + ok($status, 'removed scrip from queue'); + + ($status, $msg) = $template->Delete; + ok $status, 'deleted template foo in queue B'; + + ($status, $msg) = $scrip->AddToObject( $queue_B->id ); + ok(!$status, $msg); + RT::Test->object_scrips_are($scrip, [$queue], [0, $queue_B]); + + ($status, $msg) = $template->Create( Queue => 0, Name => 'foo' ); + ok $status, 'created a global template'; + + ($status, $msg) = $scrip->AddToObject( $queue_B->id ); + ok($status, 'added scrip'); + RT::Test->object_scrips_are($scrip, [$queue, $queue_B], [0]); +} + +note 'basic check for disabling scrips'; +{ + my $scrip = RT::Scrip->new(RT->SystemUser); + my ($status, $msg) = $scrip->Create( + Queue => $queue->id, + ScripCondition => 'On Create', + ScripAction => 'User Defined', + CustomPrepareCode => 'return 1', + CustomCommitCode => '$self->TicketObj->SetPriority("87"); return 1', + Template => 'Blank' + ); + ok($status, "created scrip"); + is($scrip->Disabled, 0, "not disabled"); + + { + my $ticket = RT::Ticket->new(RT->SystemUser); + my ($tid, undef, $msg) = $ticket->Create( + Queue => $queue->id, + Subject => "test", + ); + ok($tid, "created ticket") or diag "error: $msg"; + is ($ticket->Priority , '87', "Ticket priority is set right"); + } + + ($status,$msg) = $scrip->SetDisabled(1); + is($scrip->Disabled, 1, "disabled"); + + { + my $ticket = RT::Ticket->new(RT->SystemUser); + my ($tid, undef, $msg) = $ticket->Create( + Queue => $queue->id, + Subject => "test", + ); + ok($tid, "created ticket") or diag "error: $msg"; + isnt ($ticket->Priority , '87', "Ticket priority is set right"); + } + + is($scrip->FriendlyStage('TransactionCreate'), 'Normal', + 'Correct stage wording for TransactionCreate'); + is($scrip->FriendlyStage('TransactionBatch'), 'Batch', + 'Correct stage wording for TransactionBatch'); + RT->Config->Set('UseTransactionBatch', 0); + is($scrip->FriendlyStage('TransactionBatch'), 'Batch (disabled by config)', + 'Correct stage wording for TransactionBatch with UseTransactionBatch disabled'); +} diff --git a/rt/t/api/scrip_order.t b/rt/t/api/scrip_order.t index 6fba7e579..689b55970 100644 --- a/rt/t/api/scrip_order.t +++ b/rt/t/api/scrip_order.t @@ -2,52 +2,271 @@ use strict; use warnings; -use RT; -use RT::Test tests => 7; - - - -my $scrip_queue = RT::Queue->new(RT->SystemUser); -my ($queue_id, $msg) = $scrip_queue->Create( Name => "ScripOrdering-$$", - Description => 'Test scrip ordering by description' ); -ok($queue_id, "Created scrip-ordering test queue? ".$msg); - -my $priority_ten_scrip = RT::Scrip->new(RT->SystemUser); -(my $id, $msg) = $priority_ten_scrip->Create( - Description => "10 set priority $$", - Queue => $queue_id, - ScripCondition => 'On Create', - ScripAction => 'User Defined', - CustomPrepareCode => '$RT::Logger->debug("Setting priority to 10..."); return 1;', - CustomCommitCode => '$self->TicketObj->SetPriority(10);', - Template => 'Blank', - Stage => 'TransactionCreate', -); -ok($id, "Created priority-10 scrip? ".$msg); - -my $priority_five_scrip = RT::Scrip->new(RT->SystemUser); -($id, $msg) = $priority_ten_scrip->Create( - Description => "05 set priority $$", - Queue => $queue_id, - ScripCondition => 'On Create', - ScripAction => 'User Defined', - CustomPrepareCode => '$RT::Logger->debug("Setting priority to 5..."); return 1;', - CustomCommitCode => '$self->TicketObj->SetPriority(5);', - Template => 'Blank', - Stage => 'TransactionCreate', -); -ok($id, "Created priority-5 scrip? ".$msg); - -my $ticket = RT::Ticket->new(RT->SystemUser); -($id, $msg) = $ticket->Create( - Queue => $queue_id, - Requestor => 'order@example.com', - Subject => "Scrip order test $$", -); -ok($ticket->id, "Created ticket? id=$id"); - -isnt($ticket->Priority , 0, "Ticket shouldn't be priority 0"); -isnt($ticket->Priority , 5, "Ticket shouldn't be priority 5"); -is ($ticket->Priority , 10, "Ticket should be priority 10"); +use RT::Test tests => 204; + +my $queue = RT::Test->load_or_create_queue( Name => 'General' ); +ok $queue && $queue->id, 'loaded or created queue'; + +note "check that execution order reflects sort order"; +{ + my $ten = main->create_scrip_ok( + Description => "Set priority to 10", + Queue => $queue->id, + CustomCommitCode => '$self->TicketObj->SetPriority(10);', + ); + + my $five = main->create_scrip_ok( + Description => "Set priority to 5", + Queue => $queue->id, + CustomCommitCode => '$self->TicketObj->SetPriority(5);', + ); + + my $ticket = RT::Ticket->new(RT->SystemUser); + my ($id, $msg) = $ticket->Create( + Queue => $queue->id, + Subject => "Scrip order test $$", + ); + ok($ticket->id, "Created ticket? id=$id"); + is($ticket->Priority , 5, "By default newer scrip is last"); + + main->move_scrip_ok( $five, $queue->id, 'up' ); + + $ticket = RT::Ticket->new(RT->SystemUser); + ($id, $msg) = $ticket->Create( + Queue => $queue->id, + Subject => "Scrip order test $$", + ); + ok($ticket->id, "Created ticket? id=$id"); + is($ticket->Priority , 10, "Moved scrip and result is different"); +} + +my $queue_B = RT::Test->load_or_create_queue( Name => 'Other' ); +ok $queue_B && $queue_B->id, 'loaded or created queue'; + +note "move around two local scrips"; +{ + main->delete_all_scrips(); + + my @scrips; + push @scrips, main->create_scrip_ok( Queue => $queue->id ); + push @scrips, main->create_scrip_ok( Queue => $queue->id ); + main->check_scrips_order(\@scrips, [$queue]); + + main->move_scrip_ok( $scrips[0], $queue->id, 'down' ); + @scrips = @scrips[1, 0]; + main->check_scrips_order(\@scrips, [$queue]); + + main->move_scrip_ok( $scrips[0], $queue->id, 'down' ); + @scrips = @scrips[1, 0]; + main->check_scrips_order(\@scrips, [$queue]); + + main->move_scrip_ok( $scrips[1], $queue->id, 'up' ); + @scrips = @scrips[1, 0]; + main->check_scrips_order(\@scrips, [$queue]); + + main->move_scrip_ok( $scrips[1], $queue->id, 'up' ); + @scrips = @scrips[1, 0]; + main->check_scrips_order(\@scrips, [$queue]); +} + +note "move around two global scrips"; +{ + main->delete_all_scrips(); + + my @scrips; + push @scrips, main->create_scrip_ok( Queue => 0 ); + push @scrips, main->create_scrip_ok( Queue => 0 ); + main->check_scrips_order(\@scrips, [$queue]); + + main->move_scrip_ok( $scrips[0], 0, 'down' ); + @scrips = @scrips[1, 0]; + main->check_scrips_order(\@scrips, [$queue]); + + main->move_scrip_ok( $scrips[0], 0, 'down' ); + @scrips = @scrips[1, 0]; + main->check_scrips_order(\@scrips, [$queue]); + + main->move_scrip_ok( $scrips[1], 0, 'up' ); + @scrips = @scrips[1, 0]; + main->check_scrips_order(\@scrips, [$queue]); + + main->move_scrip_ok( $scrips[1], 0, 'up' ); + @scrips = @scrips[1, 0]; + main->check_scrips_order(\@scrips, [$queue]); +} + +note "move local scrip below global"; +{ + main->delete_all_scrips(); + my @scrips; + push @scrips, main->create_scrip_ok( Queue => $queue->id ); + push @scrips, main->create_scrip_ok( Queue => $queue_B->id ); + push @scrips, main->create_scrip_ok( Queue => 0 ); + push @scrips, main->create_scrip_ok( Queue => $queue->id ); + main->check_scrips_order(\@scrips, [$queue, $queue_B]); + + main->move_scrip_ok( $scrips[0], $queue->id, 'down' ); + @scrips = @scrips[1, 2, 0, 3]; + main->check_scrips_order(\@scrips, [$queue, $queue_B]); +} + +note "move local scrip above global"; +{ + main->delete_all_scrips(); + my @scrips; + push @scrips, main->create_scrip_ok( Queue => $queue_B->id ); + push @scrips, main->create_scrip_ok( Queue => 0 ); + push @scrips, main->create_scrip_ok( Queue => $queue->id ); + push @scrips, main->create_scrip_ok( Queue => $queue_B->id ); + main->check_scrips_order(\@scrips, [$queue, $queue_B]); + + main->move_scrip_ok( $scrips[-1], $queue_B->id, 'up' ); + @scrips = @scrips[0, 3, 1, 2]; + main->check_scrips_order(\@scrips, [$queue, $queue_B]); +} + +note "move global scrip down with local in between"; +{ + main->delete_all_scrips(); + my @scrips; + push @scrips, main->create_scrip_ok( Queue => 0 ); + push @scrips, main->create_scrip_ok( Queue => $queue_B->id ); + push @scrips, main->create_scrip_ok( Queue => $queue->id ); + push @scrips, main->create_scrip_ok( Queue => 0 ); + push @scrips, main->create_scrip_ok( Queue => $queue->id ); + main->check_scrips_order(\@scrips, [$queue, $queue_B]); + + main->move_scrip_ok( $scrips[0], 0, 'down' ); + @scrips = @scrips[1, 2, 3, 0, 4]; + main->check_scrips_order(\@scrips, [$queue, $queue_B]); +} + +note "move global scrip up with local in between"; +{ + main->delete_all_scrips(); + my @scrips; + push @scrips, main->create_scrip_ok( Queue => $queue->id ); + push @scrips, main->create_scrip_ok( Queue => 0 ); + push @scrips, main->create_scrip_ok( Queue => $queue_B->id ); + push @scrips, main->create_scrip_ok( Queue => $queue->id ); + push @scrips, main->create_scrip_ok( Queue => 0 ); + main->check_scrips_order(\@scrips, [$queue, $queue_B]); + + main->move_scrip_ok( $scrips[-1], 0, 'up' ); + @scrips = @scrips[0, 4, 1, 2, 3]; + main->check_scrips_order(\@scrips, [$queue, $queue_B]); +} + +note "delete scrips one by one"; +{ + main->delete_all_scrips(); + my @scrips; + push @scrips, main->create_scrip_ok( Queue => $queue->id ); + push @scrips, main->create_scrip_ok( Queue => $queue_B->id ); + push @scrips, main->create_scrip_ok( Queue => 0 ); + push @scrips, main->create_scrip_ok( Queue => $queue_B->id ); + push @scrips, main->create_scrip_ok( Queue => $queue->id ); + push @scrips, main->create_scrip_ok( Queue => 0 ); + main->check_scrips_order(\@scrips, [$queue, $queue_B]); + + foreach my $idx (3, 2, 0 ) { + $_->Delete foreach splice @scrips, $idx, 1; + main->check_scrips_order(\@scrips, [$queue, $queue_B]); + } +} + +sub create_scrip_ok { + local $Test::Builder::Level = $Test::Builder::Level + 1; + my $self = shift; + my %args = ( + ScripCondition => 'On Create', + ScripAction => 'User Defined', + CustomPrepareCode => 'return 1', + CustomCommitCode => 'return 1', + Template => 'Blank', + Stage => 'TransactionCreate', + @_ + ); + + my $scrip = RT::Scrip->new( RT->SystemUser ); + my ($id, $msg) = $scrip->Create( %args ); + ok($id, "Created scrip") or diag "error: $msg"; + + return $scrip; +} + +sub delete_all_scrips { + local $Test::Builder::Level = $Test::Builder::Level + 1; + my $self = shift; + my $scrips = RT::Scrips->new( RT->SystemUser ); + $scrips->UnLimit; + $_->Delete foreach @{ $scrips->ItemsArrayRef }; +} + +sub move_scrip_ok { + local $Test::Builder::Level = $Test::Builder::Level + 1; + my $self = shift; + my ($scrip, $queue, $dir) = @_; + + my $rec = RT::ObjectScrip->new( RT->SystemUser ); + $rec->LoadByCols( Scrip => $scrip->id, ObjectId => $queue ); + ok $rec->id, 'found application of the scrip'; + + my $method = 'Move'. ucfirst lc $dir; + my ($status, $msg) = $rec->$method(); + ok $status, "moved scrip $dir" or diag "error: $msg"; +} + +sub check_scrips_order { + local $Test::Builder::Level = $Test::Builder::Level + 1; + my $self = shift; + my $scrips = shift; + my $queues = shift; + + foreach my $qid ( 0, map $_->id, @$queues ) { + my $list = RT::Scrips->new( RT->SystemUser ); + $list->LimitToGlobal; + $list->LimitToQueue( $qid ) if $qid; + $list->ApplySortOrder; + is_deeply( + [map $_->id, @{ $list->ItemsArrayRef } ], + [map $_->id, grep $_->IsAdded( $qid ) || $_->IsGlobal, @$scrips], + 'list of scrips match expected' + ) + } + + foreach my $qid ( map $_->id, @$queues ) { + my $list = RT::ObjectScrips->new( RT->SystemUser ); + $list->LimitToObjectId( 0 ); + $list->LimitToObjectId( $qid ); + + my %so; + $so{ $_->SortOrder }++ foreach @{ $list->ItemsArrayRef }; + ok( !grep( {$_ != 1} values %so), 'no dublicate order' ); + } + { + my $list = RT::ObjectScrips->new( RT->SystemUser ); + $list->UnLimit; + $list->OrderBy( FIELD => 'SortOrder', ORDER => 'ASC' ); + + my $prev; + foreach my $rec ( @{ $list->ItemsArrayRef } ) { + my $so = $rec->SortOrder; + do { $prev = $so; next } unless defined $prev; + + ok $so == $prev || $so == $prev+1, "sequential order"; + $prev = $so; + } + } +} + +sub dump_sort_order { + + diag " id oid so"; + diag join "\n", map { join "\t", @$_ } map @$_, $RT::Handle->dbh->selectall_arrayref( + "select Scrip, ObjectId, SortOrder from ObjectScrips ORDER BY SortOrder" + ); + +} diff --git a/rt/t/api/searchbuilder.t b/rt/t/api/searchbuilder.t index 84568718d..9237dcd37 100644 --- a/rt/t/api/searchbuilder.t +++ b/rt/t/api/searchbuilder.t @@ -20,7 +20,7 @@ ok( $queues->UnLimit(),'Unlimited the result set of the queues object'); my $items = $queues->ItemsArrayRef(); my @items = @{$items}; -ok($queues->NewItem->_Accessible('Name','read')); +ok($queues->RecordClass->_Accessible('Name','read')); my @sorted = sort {lc($a->Name) cmp lc($b->Name)} @items; ok (@sorted, "We have an array of queues, sorted". join(',',map {$_->Name} @sorted)); diff --git a/rt/t/api/system-available-rights.t b/rt/t/api/system-available-rights.t new file mode 100644 index 000000000..d7b6f5e8d --- /dev/null +++ b/rt/t/api/system-available-rights.t @@ -0,0 +1,65 @@ +use strict; +use warnings; + +use RT::Test tests => undef; +use Set::Tiny; + +my @warnings; +local $SIG{__WARN__} = sub { + push @warnings, "@_"; +}; + +my $requestor = RT::Group->new( RT->SystemUser ); +$requestor->LoadRoleGroup( + Object => RT->System, + Name => "Requestor", +); +ok $requestor->id, "Loaded global requestor role group"; + +$requestor = $requestor->PrincipalObj; +ok $requestor->id, "Loaded global requestor role group principal"; + +note "Try granting an article right to a system role group"; +{ + my ($ok, $msg) = $requestor->GrantRight( + Right => "ShowArticle", + Object => RT->System, + ); + ok !$ok, "Couldn't grant nonsensical right to global Requestor role: $msg"; + like shift @warnings, qr/Couldn't validate right name.*?ShowArticle/; + + ($ok, $msg) = $requestor->GrantRight( + Right => "ShowTicket", + Object => RT->System, + ); + ok $ok, "Granted queue right to global queue role: $msg"; + + ($ok, $msg) = RT->PrivilegedUsers->PrincipalObj->GrantRight( + Right => "ShowArticle", + Object => RT->System, + ); + ok $ok, "Granted article right to non-role global group: $msg"; + + reset_rights(); +} + +note "AvailableRights"; +{ + my @available = ( + [ keys %{RT->System->AvailableRights} ], + [ keys %{RT->System->AvailableRights( $requestor )} ], + ); + + my $all = Set::Tiny->new( @{$available[0]} ); + my $role = Set::Tiny->new( @{$available[1]} ); + + ok $role->is_proper_subset($all), "role rights are a proper subset of all"; +} + +ok !@warnings, "No uncaught warnings" + or diag explain \@warnings; + +# for clarity +sub reset_rights { RT::Test->set_rights() } + +done_testing; diff --git a/rt/t/api/system.t b/rt/t/api/system.t index f1100d332..f3d9226cf 100644 --- a/rt/t/api/system.t +++ b/rt/t/api/system.t @@ -2,8 +2,18 @@ use strict; use warnings; use RT; -use RT::Test nodata => 1, tests => 7; +use RT::Test nodata => 1, tests => 16; +BEGIN{ + use_ok('RT::System'); +} + +# Skipping most of the methods added just to make RT::System +# look like RT::Record. + +can_ok('RT::System', qw( AvailableRights RightCategories AddRight + id Id SubjectTag Name QueueCacheNeedsUpdate AddUpgradeHistory + UpgradeHistory )); { @@ -15,18 +25,50 @@ ok ($rights->{'CreateTicket'},"CreateTicket right found"); ok ($rights->{'AdminGroupMembership'},"ModifyGroupMembers right found"); ok (!$rights->{'CasdasdsreateTicket'},"bogus right not found"); +} +{ +my $sys = RT::System->new(); +is( $sys->Id, 1, 'Id is 1'); +is ($sys->id, 1, 'id is 1'); } { -use RT::System; -my $sys = RT::System->new(); -is( $sys->Id, 1); -is ($sys->id, 1); +# Test upgrade history methods. +my $sys = RT::System->new(RT->SystemUser); +isa_ok($sys, 'RT::System'); -} +my $file = 'test_file.txt'; +my $content = 'Some file contents.'; +my $upgrade_history = RT->System->UpgradeHistory(); + +is( keys %$upgrade_history, 0, 'No history in test DB'); + +RT->System->AddUpgradeHistory(RT =>{ + action => 'insert', + filename => $file, + content => $content, + stage => 'before', + }); + +$upgrade_history = RT->System->UpgradeHistory(); +ok( exists($upgrade_history->{'RT'}), 'History has an RT key.'); +is( @{$upgrade_history->{'RT'}}, 1, '1 item in history array'); +is($upgrade_history->{RT}[0]{stage}, 'before', 'stage is before for item 1'); +RT->System->AddUpgradeHistory(RT =>{ + action => 'insert', + filename => $file, + content => $content, + stage => 'after', + }); + +$upgrade_history = RT->System->UpgradeHistory(); +is( @{$upgrade_history->{'RT'}}, 2, '2 item in history array'); +is($upgrade_history->{RT}[1]{stage}, 'after', 'stage is after for item 2'); + +} diff --git a/rt/t/api/template.t b/rt/t/api/template.t index 331d9f996..1baac44b6 100644 --- a/rt/t/api/template.t +++ b/rt/t/api/template.t @@ -2,23 +2,31 @@ use warnings; use strict; -use RT; -use RT::Test tests => 10; +use RT::Test tests => 37; + +use_ok('RT::Template'); my $queue = RT::Test->load_or_create_queue( Name => 'Templates' ); ok $queue && $queue->id, "loaded or created a queue"; +my $alt_queue = RT::Test->load_or_create_queue( Name => 'Alternative' ); +ok $alt_queue && $alt_queue->id, 'loaded or created queue'; + { - my $template = RT::Template->new( RT->SystemUser ); + my $template = RT::Template->new(RT->SystemUser); isa_ok($template, 'RT::Template'); +} + +{ + my $template = RT::Template->new( RT->SystemUser ); my ($val,$msg) = $template->Create( Queue => $queue->id, - Name => 'InsertTest', + Name => 'Test', Content => 'This is template content' ); ok $val, "created a template" or diag "error: $msg"; ok my $id = $template->id, "id is defined"; - is $template->Name, 'InsertTest'; + is $template->Name, 'Test'; is $template->Content, 'This is template content', "We created the object right"; ($val, $msg) = $template->SetContent( 'This is new template content'); @@ -32,3 +40,164 @@ ok $queue && $queue->id, "loaded or created a queue"; $template->Load($id); ok !$template->id, "can not load template after deletion"; } + +note "can not create template w/o Name"; +{ + clean_templates( Queue => $queue->id ); + my $template = RT::Template->new( RT->SystemUser ); + my ($val,$msg) = $template->Create( Queue => $queue->id ); + ok(!$val,$msg); +} + +note "can not create template with duplicate name"; +{ + clean_templates( Queue => $queue->id ); + my $template = RT::Template->new( RT->SystemUser ); + my ($val,$msg) = $template->Create( Queue => $queue->id, Name => 'Test' ); + ok($val,$msg); + + ($val,$msg) = $template->Create( Queue => $queue->id, Name => 'Test' ); + ok(!$val,$msg); +} + +note "change template's name"; +{ + clean_templates( Queue => $queue->id ); + my $template = RT::Template->new( RT->SystemUser ); + my ($val,$msg) = $template->Create( Queue => $queue->id, Name => 'Test' ); + ok($val,$msg); + + ($val,$msg) = $template->SetName( 'Some' ); + ok($val,$msg); + is $template->Name, 'Some'; +} + +note "can not change name to empty"; +{ + clean_templates( Queue => $queue->id ); + my $template = RT::Template->new( RT->SystemUser ); + my ($val,$msg) = $template->Create( Queue => $queue->id, Name => 'Test' ); + ok($val,$msg); + + ($val,$msg) = $template->Create( Queue => $queue->id, Name => '' ); + ok(!$val,$msg); + ($val,$msg) = $template->Create( Queue => $queue->id, Name => undef ); + ok(!$val,$msg); +} + +note "can not change name to duplicate"; +{ + clean_templates( Queue => $queue->id ); + my $template = RT::Template->new( RT->SystemUser ); + my ($val,$msg) = $template->Create( Queue => $queue->id, Name => 'Test' ); + ok($val,$msg); + + ($val,$msg) = $template->Create( Queue => $queue->id, Name => 'Some' ); + ok($val,$msg); +} + +note "changing queue of template is not implemented"; +{ + clean_templates( Queue => $queue->id ); + my $template = RT::Template->new( RT->SystemUser ); + my ($val,$msg) = $template->Create( Queue => $queue->id, Name => 'Test' ); + ok($val,$msg); + + ($val,$msg) = $template->SetQueue( $alt_queue->id ); + ok(!$val,$msg); +} + +note "make sure template can not be deleted if it has scrips"; +{ + clean_templates( Queue => $queue->id ); + my $template = RT::Template->new( RT->SystemUser ); + my ($val,$msg) = $template->Create( Queue => $queue->id, Name => 'Test' ); + ok($val,$msg); + + my $scrip = RT::Scrip->new( RT->SystemUser ); + ($val,$msg) = $scrip->Create( + Queue => $queue->id, + ScripCondition => "On Create", + ScripAction => 'Autoreply To Requestors', + Template => $template->Name, + ); + ok($val, $msg); + + ($val, $msg) = $template->Delete; + ok(!$val,$msg); +} + +note "make sure template can be deleted if it's an override"; +{ + clean_templates( Queue => $queue->id ); + my $template = RT::Template->new( RT->SystemUser ); + my ($val,$msg) = $template->Create( Queue => $queue->id, Name => 'Overrided' ); + ok($val,$msg); + + $template = RT::Template->new( RT->SystemUser ); + ($val,$msg) = $template->Create( Queue => 0, Name => 'Overrided' ); + ok($val,$msg); + + my $scrip = RT::Scrip->new( RT->SystemUser ); + ($val,$msg) = $scrip->Create( + Queue => $queue->id, + ScripCondition => "On Create", + ScripAction => 'Autoreply To Requestors', + Template => $template->Name, + ); + ok($val, $msg); + + ($val, $msg) = $template->Delete; + ok($val,$msg); +} + +note "make sure template can be deleted if it has an override"; +{ + clean_templates( Queue => $queue->id ); + my $template = RT::Template->new( RT->SystemUser ); + my ($val,$msg) = $template->Create( Queue => 0, Name => 'Overrided' ); + ok($val,$msg); + + $template = RT::Template->new( RT->SystemUser ); + ($val,$msg) = $template->Create( Queue => $queue->id, Name => 'Overrided' ); + ok($val,$msg); + + my $scrip = RT::Scrip->new( RT->SystemUser ); + ($val,$msg) = $scrip->Create( + Queue => $queue->id, + ScripCondition => "On Create", + ScripAction => 'Autoreply To Requestors', + Template => $template->Name, + ); + ok($val, $msg); + + ($val, $msg) = $template->Delete; + ok($val,$msg); +} + + +{ + my $t = RT::Template->new(RT->SystemUser); + $t->Create(Name => "Foo", Queue => $queue->id); + my $t2 = RT::Template->new(RT->Nobody); + $t2->Load($t->Id); + ok($t2->QueueObj->id, "Got the template's queue objet"); +} + +sub clean_templates { + my %args = (@_); + + my $templates = RT::Templates->new( RT->SystemUser ); + $templates->Limit( FIELD => 'Queue', VALUE => $args{'Queue'} ) + if defined $args{'Queue'}; + $templates->Limit( FIELD => 'Name', VALUE => $_ ) + foreach ref $args{'Name'}? @{$args{'Name'}} : ($args{'Name'}||()); + while ( my $t = $templates->Next ) { + my ($status) = $t->Delete; + unless ( $status ) { + $_->Delete foreach @{ $t->UsedBy->ItemsArrayRef }; + $t->Delete; + } + } +} + diff --git a/rt/t/api/ticket.t b/rt/t/api/ticket.t index da287a607..c5f1e240f 100644 --- a/rt/t/api/ticket.t +++ b/rt/t/api/ticket.t @@ -100,7 +100,7 @@ ok( $t->Create(Queue => 'General', Due => '2002-05-21 00:00:00', ReferredToBy => ok ( my $id = $t->Id, "Got ticket id"); like ($t->RefersTo->First->Target , qr/fsck.com/, "Got refers to"); like ($t->ReferredToBy->First->Base , qr/cpan.org/, "Got referredtoby"); -is ($t->ResolvedObj->Unix, 0, "It hasn't been resolved - ". $t->ResolvedObj->Unix); +ok (!$t->ResolvedObj->IsSet, "It hasn't been resolved"); } @@ -115,8 +115,7 @@ my ($id, $msg) = $ticket->Create(Subject => "Foo", Queue => '1' ); ok ($id, "Ticket $id was created"); -ok(my $group = RT::Group->new(RT->SystemUser)); -ok($group->LoadTicketRoleGroup(Ticket => $id, Type=> 'Requestor')); +ok(my $group = $ticket->RoleGroup('Requestor')); ok ($group->Id, "Found the requestors object for this ticket"); ok(my $jesse = RT::User->new(RT->SystemUser), "Creating a jesse rt::user"); @@ -135,14 +134,11 @@ ok ( ($add_id, $add_msg) = $ticket->DeleteWatcher(Type =>'Requestor', Email => ' ok (!$ticket->IsWatcher(Type => 'Requestor', PrincipalId => $bob->PrincipalId), "The ticket no longer has bob at fsck.com as a requestor"); -$group = RT::Group->new(RT->SystemUser); -ok($group->LoadTicketRoleGroup(Ticket => $id, Type=> 'Cc')); +$group = $ticket->RoleGroup('Cc'); ok ($group->Id, "Found the cc object for this ticket"); -$group = RT::Group->new(RT->SystemUser); -ok($group->LoadTicketRoleGroup(Ticket => $id, Type=> 'AdminCc')); +$group = $ticket->RoleGroup('AdminCc'); ok ($group->Id, "Found the AdminCc object for this ticket"); -$group = RT::Group->new(RT->SystemUser); -ok($group->LoadTicketRoleGroup(Ticket => $id, Type=> 'Owner')); +$group = $ticket->RoleGroup('Owner'); ok ($group->Id, "Found the Owner object for this ticket"); ok($group->HasMember(RT->SystemUser->UserObj->PrincipalObj), "the owner group has the member 'RT_System'"); @@ -209,20 +205,32 @@ is ($t1->Requestors->MembersObj->Count, 2); } +diag "Test owner changes"; { my $root = RT::User->new(RT->SystemUser); $root->Load('root'); ok ($root->Id, "Loaded the root user"); my $t = RT::Ticket->new(RT->SystemUser); -$t->Load(1); -$t->SetOwner('root'); +my ($val, $msg) = $t->Create( Subject => 'Owner test 1', Queue => 'General'); +ok( $t->Id, "Created a new ticket with id $val: $msg"); + +($val, $msg) = $t->SetOwner('bogususer'); +ok( !$val, "Can't set owner to bogus user"); +is( $msg, "That user does not exist", "Got message: $msg"); + +($val, $msg) = $t->SetOwner('root'); is ($t->OwnerObj->Name, 'root' , "Root owns the ticket"); + +($val, $msg) = $t->SetOwner('root'); +ok( !$val, "User already owns ticket"); +is( $msg, "That user already owns that ticket", "Got message: $msg"); + $t->Steal(); is ($t->OwnerObj->id, RT->SystemUser->id , "SystemUser owns the ticket"); my $txns = RT::Transactions->new(RT->SystemUser); $txns->OrderBy(FIELD => 'id', ORDER => 'DESC'); -$txns->Limit(FIELD => 'ObjectId', VALUE => '1'); +$txns->Limit(FIELD => 'ObjectId', VALUE => $t->Id); $txns->Limit(FIELD => 'ObjectType', VALUE => 'RT::Ticket'); $txns->Limit(FIELD => 'Type', OPERATOR => '!=', VALUE => 'EmailRecord'); @@ -230,6 +238,37 @@ my $steal = $txns->First; is($steal->OldValue , $root->Id , "Stolen from root"); is($steal->NewValue , RT->SystemUser->Id , "Stolen by the systemuser"); +ok(my $user1 = RT::User->new(RT->SystemUser), "Creating a user1 rt::user"); +($val, $msg) = $user1->Create(Name => 'User1', EmailAddress => 'user1@example.com'); +ok( $val, "Created new user with id: $val"); +ok( $user1->Id, "Found the user1 rt user"); + +my $t1 = RT::Ticket->new($user1); +($val, $msg) = $t1->Load($t->Id); +ok( $t1->Id, "Loaded ticket with id $val"); + +($val, $msg) = $t1->SetOwner('root'); +ok( !$val, "user1 can't set owner to root: $msg"); +is ($t->OwnerObj->id, RT->SystemUser->id , "SystemUser still owns ticket " . $t1->Id); + +my $queue = RT::Queue->new(RT->SystemUser); +$queue->Load("General"); + +($val, $msg) = $user1->PrincipalObj->GrantRight( + Object => $queue, Right => 'ModifyTicket' + ); + +($val, $msg) = $t1->SetOwner('root'); +ok( !$val, "With ModifyTicket user1 can't set owner to root: $msg"); +is ($t->OwnerObj->id, RT->SystemUser->id , "SystemUser still owns ticket " . $t1->Id); + +($val, $msg) = $user1->PrincipalObj->GrantRight( + Object => $queue, Right => 'ReassignTicket' + ); + +($val, $msg) = $t1->SetOwner('root'); +ok( $val, "With ReassignTicket user1 reassigned ticket " . $t1->Id . " to root: $msg"); +is ($t1->OwnerObj->Name, 'root' , "Root owns ticket " . $t1->Id); } @@ -250,7 +289,16 @@ like($msg, qr/resolved/i, "Status message is correct"); ($id, $msg) = $tt->SetStatus('resolved'); ok(!$id,$msg); +my $dep = RT::Ticket->new( RT->SystemUser ); +my ( $dep_id, undef, $dep_msg ) = $dep->Create( + Queue => 'general', + Subject => 'dep ticket', + 'DependedOnBy' => $tt->id, +); +ok( $dep->id, $dep_msg ); +($id, $msg) = $tt->SetStatus('rejected'); +ok( $id, $msg ); } diff --git a/rt/t/api/tickets.t b/rt/t/api/tickets.t index 50d08f756..172965c3b 100644 --- a/rt/t/api/tickets.t +++ b/rt/t/api/tickets.t @@ -2,8 +2,7 @@ use strict; use warnings; use RT; -use RT::Test tests => 18; - +use RT::Test tests => undef; { @@ -114,3 +113,35 @@ ok( $unlimittickets->Count > 0, "UnLimited tickets object should return tickets" ok $count == 1, "found one ticket"; } +{ + my $tickets = RT::Tickets->new( RT->SystemUser ); + my ($ret, $msg) = $tickets->FromSQL("Resolved IS NULL"); + ok $ret, "Ran query with IS NULL: $msg"; + my $count = $tickets->Count(); + ok $count > 1, "Found more than one ticket"; + undef $count; +} + +{ + my $ticket = RT::Ticket->new( RT->SystemUser ); + ok $ticket->Load(1), "Loaded test ticket 1"; + ok $ticket->SetStatus('resolved'), "Set to resolved"; + + my $tickets = RT::Tickets->new( RT->SystemUser ); + my ($ret, $msg) = $tickets->FromSQL("Resolved IS NOT NULL"); + ok $ret, "Ran query with IS NOT NULL: $msg"; + my $count = $tickets->Count(); + ok $count == 1, "Found one ticket"; + undef $count; +} + +{ + my $tickets = RT::Tickets->new( RT->SystemUser ); + $tickets->LimitDate( FIELD => "Resolved", OPERATOR => "IS", VALUE => "NULL" ); + $tickets->LimitDate( FIELD => "Resolved", OPERATOR => "IS NOT", VALUE => "NULL" ); + my $count = $tickets->Count(); + ok $count > 1, "Found more than one ticket"; + undef $count; +} + +done_testing; diff --git a/rt/t/api/txn_content.t b/rt/t/api/txn_content.t index 392b6a73b..672d6c2e0 100644 --- a/rt/t/api/txn_content.t +++ b/rt/t/api/txn_content.t @@ -1,7 +1,7 @@ use warnings; use strict; -use RT::Test tests => 3; +use RT::Test tests => 4; use MIME::Entity; my $ticket = RT::Ticket->new(RT->SystemUser); my $mime = MIME::Entity->build( @@ -16,4 +16,8 @@ my $txns = $ticket->Transactions; $txns->Limit( FIELD => 'Type', VALUE => 'Create' ); my $txn = $txns->First; ok( $txn, 'got Create txn' ); -is( $txn->Content, "this is body\n", "txn's content" ); + +# ->Content converts from text/html to plain text if we don't explicitly ask +# for html. Our html -> text converter seems to add an extra trailing newline +like( $txn->Content, qr/^\s*this is body\s*$/, "txn's html content converted to plain text" ); +is( $txn->Content(Type => 'text/html'), "this is body\n", "txn's html content" ); diff --git a/rt/t/api/user-prefs.t b/rt/t/api/user-prefs.t new file mode 100644 index 000000000..a4aa49f1b --- /dev/null +++ b/rt/t/api/user-prefs.t @@ -0,0 +1,59 @@ + +use strict; +use warnings; +use RT; +use RT::Test tests => undef; + +use_ok( 'RT::User' ); + +my $create_user = RT::User->new(RT->SystemUser); +isa_ok($create_user, 'RT::User'); +my ($ret, $msg) = $create_user->Create(Name => 'CreateTest1'.$$, + EmailAddress => $$.'create-test-1@example.com'); +ok ($ret, "Creating user CreateTest1 - " . $msg ); + +# Create object to operate as the test user +my $user1 = RT::User->new($create_user); +($ret, $msg) = $user1->Load($create_user->Id); +ok ($ret, "Loaded the new user $msg"); + +diag "Set a search preference"; +my $prefs = { + 'Order' => 'DESC|ASC|ASC|ASC', + 'OrderBy' => 'Due', + 'Format' => '\'<a href="__WebPath__/Ticket/Display.html?id=__id__">__id__</a>/TITLE:#\', +\'<a href="__WebPath__/Ticket/Display.html?id=__id__">__Subject__</a>/TITLE:Subject\', +\'__Priority__\', +\'__QueueName__\', +\'__ExtendedStatus__\', +\'__Due__\'', + 'RowsPerPage' => '50' +}; + +ok (!$user1->HasRight( Right => 'ModifySelf', Object => $RT::System), "Can't ModifySelf"); +($ret, $msg) = $user1->SetPreferences("SearchDisplay", $prefs); +ok( !$ret, "No permission to set preferences"); +ok (($ret, $msg) = $create_user->PrincipalObj->GrantRight( Right => 'ModifySelf'), + "Granted ModifySelf"); +($ret, $msg) = $user1->SetPreferences("SearchDisplay", $prefs); +ok( $ret, "Search preference set"); + +diag "Fetch preference"; +ok (my $saved_prefs = $user1->Preferences("SearchDisplay"), "Fetched prefs"); +is ($prefs->{OrderBy}, 'Due', "Prefs look ok"); + +diag "Delete prefs"; +ok (($ret, $msg) = $create_user->PrincipalObj->RevokeRight( Right => 'ModifySelf'), + "Revoked ModifySelf"); +($ret, $msg) = $user1->DeletePreferences("SearchDisplay"); +ok( !$ret, "No permission to delete preferences"); +ok (($ret, $msg) = $create_user->PrincipalObj->GrantRight( Right => 'ModifySelf'), + "Granted ModifySelf"); +($ret, $msg) = $user1->DeletePreferences("SearchDisplay"); +ok( $ret, "Search preference deleted"); + +$saved_prefs = $user1->Preferences("SearchDisplay"); +ok (!$saved_prefs, "No saved preferences returned"); + +done_testing; + diff --git a/rt/t/api/user.t b/rt/t/api/user.t index e6b891f73..94494f162 100644 --- a/rt/t/api/user.t +++ b/rt/t/api/user.t @@ -2,7 +2,7 @@ use strict; use warnings; use RT; -use RT::Test tests => 111; +use RT::Test tests => 122; { @@ -106,7 +106,7 @@ ok($user->Privileged, "User 'root' is privileged again"); ok(my $u = RT::User->new(RT->SystemUser)); ok($u->Load(1), "Loaded the first user"); -is($u->PrincipalObj->ObjectId , 1, "user 1 is the first principal"); +is($u->PrincipalObj->id , 1, "user 1 is the first principal"); is($u->PrincipalObj->PrincipalType, 'User' , "Principal 1 is a user, not a group"); @@ -335,3 +335,30 @@ ok($rqv, "Revoked the right successfully - $rqm"); } +{ + my $root = RT::Test->load_or_create_user( Name => 'root' ); + ok $root && $root->id; + + my $queue = RT::Test->load_or_create_queue( Name => 'General' ); + ok $queue && $queue->id; + + my $ticket = RT::Ticket->new( RT->SystemUser ); + my ($id) = $ticket->Create( Subject => 'test', Queue => $queue ); + ok $id; + + my $b_ticket = RT::Ticket->new( RT->SystemUser ); + ($id) = $b_ticket->Create( Subject => 'test', Queue => $queue ); + ok $id; + + ok $root->ToggleBookmark($b_ticket); + ok !$root->ToggleBookmark($b_ticket); + ok $root->ToggleBookmark($b_ticket); + + ok $root->HasBookmark( $b_ticket ); + ok !$root->HasBookmark( $ticket ); + + my @marks = $root->Bookmarks; + is scalar @marks, 1; + is $marks[0], $b_ticket->id; +} + diff --git a/rt/t/api/users.t b/rt/t/api/users.t index 1f3a48770..e65f9a9b5 100644 --- a/rt/t/api/users.t +++ b/rt/t/api/users.t @@ -2,7 +2,7 @@ use strict; use warnings; use RT::Test tests => 10; -RT::System->AddRights( +RT::System->AddRight( General => 'RTxUserRight' => 'Just a right for testing rights', ); |