-#!/usr/bin/perl -w
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"
+ );
+
+}