[Rt-commit] rt branch, 4.2/generalize-lifecycles, created. rt-4.1.5-14-g71e6b11
Alex Vandiver
alexmv at bestpractical.com
Mon Dec 10 16:10:55 EST 2012
The branch, 4.2/generalize-lifecycles has been created
at 71e6b11eabc04cfeca749997de0244bb637e61fe (commit)
- Log -----------------------------------------------------------------
commit e995af9a83e058d42354047ba773148fad2b8ca9
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Fri Dec 7 15:08:28 2012 -0500
Factor out common code for setting Started and Resolved
diff --git a/lib/RT/Ticket.pm b/lib/RT/Ticket.pm
index 7faa223..c643a2d 100644
--- a/lib/RT/Ticket.pm
+++ b/lib/RT/Ticket.pm
@@ -1389,36 +1389,10 @@ sub SetQueue {
return ( 0, $self->loc("Couldn't load copy of ticket #[_1].", $self->Id) );
}
- my $now = RT::Date->new( $self->CurrentUser );
- $now->SetToNow;
-
- my $old_status = $clone->Status;
-
- #If we're changing the status from initial in old to not intial in new,
- # record that we've started
- if ( $old_lifecycle->IsInitial($old_status) && !$new_lifecycle->IsInitial($new_status) && $clone->StartedObj->Unix == 0 ) {
- #Set the Started time to "now"
- $clone->_Set(
- Field => 'Started',
- Value => $now->ISO,
- RecordTransaction => 0
- );
- }
-
- #When we close a ticket, set the 'Resolved' attribute to now.
- # It's misnamed, but that's just historical.
- if ( $new_lifecycle->IsInactive($new_status) ) {
- $clone->_Set(
- Field => 'Resolved',
- Value => $now->ISO,
- RecordTransaction => 0,
- );
- }
-
- #Actually update the status
- my ($val, $msg)= $clone->_Set(
- Field => 'Status',
- Value => $new_status,
+ my ($val, $msg) = $clone->_SetStatus(
+ Lifecycle => $old_lifecycle,
+ NewLifecycle => $new_lifecycle,
+ Status => $new_status,
RecordTransaction => 0,
);
$RT::Logger->error( 'Status change failed on queue change: '. $msg )
@@ -2701,15 +2675,37 @@ sub SetStatus {
return ( 0, $self->loc('That ticket has unresolved dependencies') );
}
+ return $self->_SetStatus(
+ Status => $args{Status},
+ SetStarted => $args{SetStarted},
+ );
+}
+
+sub _SetStatus {
+ my $self = shift;
+ my %args = (
+ Status => undef,
+ SetStarted => 1,
+ RecordTransaction => 1,
+ Lifecycle => $self->QueueObj->Lifecycle,
+ @_,
+ );
+ $args{NewLifecycle} ||= $args{Lifecycle};
+
my $now = RT::Date->new( $self->CurrentUser );
$now->SetToNow();
my $raw_started = RT::Date->new(RT->SystemUser);
$raw_started->Set(Format => 'ISO', Value => $self->__Value('Started'));
- #If we're changing the status from new, record that we've started
- if ( $args{SetStarted} && $lifecycle->IsInitial($old) && !$lifecycle->IsInitial($new) && !$raw_started->Unix) {
- #Set the Started time to "now"
+ my $old = $self->__Value('Status');
+
+ # If we're changing the status from new, record that we've started
+ if ( $args{SetStarted}
+ && $args{Lifecycle}->IsInitial($old)
+ && !$args{NewLifecycle}->IsInitial($args{Status})
+ && !$raw_started->Unix) {
+ # Set the Started time to "now"
$self->_Set(
Field => 'Started',
Value => $now->ISO,
@@ -2717,9 +2713,9 @@ sub SetStatus {
);
}
- #When we close a ticket, set the 'Resolved' attribute to now.
+ # When we close a ticket, set the 'Resolved' attribute to now.
# It's misnamed, but that's just historical.
- if ( $lifecycle->IsInactive($new) ) {
+ if ( $args{NewLifecycle}->IsInactive($args{Status}) ) {
$self->_Set(
Field => 'Resolved',
Value => $now->ISO,
@@ -2727,13 +2723,14 @@ sub SetStatus {
);
}
- #Actually update the status
+ # Actually update the status
my ($val, $msg)= $self->_Set(
Field => 'Status',
Value => $args{Status},
TimeTaken => 0,
CheckACL => 0,
TransactionType => 'Status',
+ RecordTransaction => $args{RecordTransaction},
);
return ($val, $msg);
}
commit 3b69dfcf2070b3ff322ecab57a8c3d235352107d
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Fri Dec 7 12:53:00 2012 -0500
Allow lifecycles to be applied to different objects types
Refactor ticket-specific methods of tickets to RT::Lifecycle::Ticket,
and re-bless RT::Lifecycle objects on creation to the appropriate
sublclass based on 'type'. This opens the possibility of objects that
are not tickets using lifecycles for their 'Status' columns.
diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index 056599e..b66276b 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -141,6 +141,10 @@ sub Load {
$self->{'name'} = $name;
$self->{'data'} = $LIFECYCLES_CACHE{ $name };
+ my $type = $self->{'data'}{'type'} || 'ticket';
+ $type = "RT::Lifecycle::".ucfirst($type);
+ bless $self, $type if $type->require;
+
return $self;
}
@@ -152,34 +156,22 @@ Returns sorted list of the lifecycles' names.
sub List {
my $self = shift;
+ my $for = shift || 'ticket';
$self->FillCache unless keys %LIFECYCLES_CACHE;
- return sort grep length && $_ ne '__maps__', keys %LIFECYCLES_CACHE;
+ return sort grep {$LIFECYCLES_CACHE{$_}{type} eq $for}
+ grep length && $_ ne '__maps__', keys %LIFECYCLES_CACHE;
}
=head2 Name
-Returns name of the laoded lifecycle.
+Returns name of the loaded lifecycle.
=cut
sub Name { return $_[0]->{'name'} }
-=head2 Queues
-
-Returns L<RT::Queues> collection with queues that use this lifecycle.
-
-=cut
-
-sub Queues {
- my $self = shift;
- require RT::Queues;
- my $queues = RT::Queues->new( RT->SystemUser );
- $queues->Limit( FIELD => 'Lifecycle', VALUE => $self->Name );
- return $queues;
-}
-
=head2 Getting statuses and validating.
Methods to get statuses in different sets or validating them.
@@ -342,52 +334,6 @@ sub DefaultStatus {
return $self->{data}{defaults}{ $situation };
}
-=head3 DefaultOnCreate
-
-Returns the status that should be used by default
-when ticket is created.
-
-=cut
-
-sub DefaultOnCreate {
- my $self = shift;
- return $self->DefaultStatus('on_create');
-}
-
-
-=head3 DefaultOnMerge
-
-Returns the status that should be used when tickets
-are merged.
-
-=cut
-
-sub DefaultOnMerge {
- my $self = shift;
- return $self->DefaultStatus('on_merge');
-}
-
-=head3 ReminderStatusOnOpen
-
-Returns the status that should be used when reminders are opened.
-
-=cut
-
-sub ReminderStatusOnOpen {
- my $self = shift;
- return $self->DefaultStatus('reminder_on_open') || 'open';
-}
-
-=head3 ReminderStatusOnResolve
-
-Returns the status that should be used when reminders are resolved.
-
-=cut
-
-sub ReminderStatusOnResolve {
- my $self = shift;
- return $self->DefaultStatus('reminder_on_resolve') || 'resolved';
-}
=head2 Transitions, rights, labels and actions.
@@ -641,6 +587,10 @@ sub FillCache {
%LIFECYCLES_CACHE = %LIFECYCLES = %$map;
$_ = { %$_ } foreach values %LIFECYCLES_CACHE;
+ for my $lifecycles (values %LIFECYCLES_CACHE) {
+ $lifecycles->{type} ||= 'ticket';
+ }
+
my %all = (
'' => [],
initial => [],
diff --git a/lib/RT/Lifecycle/Ticket.pm b/lib/RT/Lifecycle/Ticket.pm
new file mode 100644
index 0000000..56e0148
--- /dev/null
+++ b/lib/RT/Lifecycle/Ticket.pm
@@ -0,0 +1,116 @@
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# <sales at bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
+# This work is made available to you under the terms of Version 2 of
+# the GNU General Public License. A copy of that license should have
+# been provided with this software, but in any event can be snarfed
+# from www.gnu.org.
+#
+# This work is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
+use strict;
+use warnings;
+
+package RT::Lifecycle::Ticket;
+
+use base qw(RT::Lifecycle);
+
+=head2 Queues
+
+Returns L<RT::Queues> collection with queues that use this lifecycle.
+
+=cut
+
+sub Queues {
+ my $self = shift;
+ require RT::Queues;
+ my $queues = RT::Queues->new( RT->SystemUser );
+ $queues->Limit( FIELD => 'Lifecycle', VALUE => $self->Name );
+ return $queues;
+}
+
+=head3 DefaultOnCreate
+
+Returns the status that should be used by default
+when ticket is created.
+
+=cut
+
+sub DefaultOnCreate {
+ my $self = shift;
+ return $self->DefaultStatus('on_create');
+}
+
+=head3 DefaultOnMerge
+
+Returns the status that should be used when tickets
+are merged.
+
+=cut
+
+sub DefaultOnMerge {
+ my $self = shift;
+ return $self->DefaultStatus('on_merge');
+}
+
+=head3 ReminderStatusOnOpen
+
+Returns the status that should be used when reminders are opened.
+
+=cut
+
+sub ReminderStatusOnOpen {
+ my $self = shift;
+ return $self->DefaultStatus('reminder_on_open') || 'open';
+}
+
+=head3 ReminderStatusOnResolve
+
+Returns the status that should be used when reminders are resolved.
+
+=cut
+
+sub ReminderStatusOnResolve {
+ my $self = shift;
+ return $self->DefaultStatus('reminder_on_resolve') || 'resolved';
+}
+
+1;
commit 53898e86892b261f74e6df92455cd29d696a6399
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Fri Dec 7 21:44:07 2012 -0500
Minor cleanup of lifecycle tests
diff --git a/t/lifecycles/basics.t b/t/lifecycles/basics.t
index 554c95a..b4828f7 100644
--- a/t/lifecycles/basics.t
+++ b/t/lifecycles/basics.t
@@ -1,7 +1,5 @@
-
use strict;
use warnings;
-use Data::Dumper;
BEGIN {require 't/lifecycles/utils.pl'};
@@ -244,3 +242,5 @@ diag "'!inactive -> inactive' actions are shown even if ticket has unresolved de
);
}
+undef $m;
+done_testing;
diff --git a/t/lifecycles/dates.t b/t/lifecycles/dates.t
index 4f613f8..80c24fc 100644
--- a/t/lifecycles/dates.t
+++ b/t/lifecycles/dates.t
@@ -1,7 +1,5 @@
-
use strict;
use warnings;
-use Data::Dumper;
BEGIN {require 't/lifecycles/utils.pl'};
@@ -23,9 +21,6 @@ my $tstatus = sub {
return $ticket->Status;
};
-my ($baseurl, $m) = RT::Test->started_ok;
-ok $m->login, 'logged in';
-
diag "check basic API";
{
my $schema = $general->Lifecycle;
@@ -314,3 +309,5 @@ diag "check date changes on moving a ticket";
ok $ticket->StartedObj->Unix > 0, 'started is set';
ok $ticket->ResolvedObj->Unix > 0, 'resolved is set';
}
+
+done_testing;
diff --git a/t/lifecycles/moving.t b/t/lifecycles/moving.t
index 5f184e2..8a03e3e 100644
--- a/t/lifecycles/moving.t
+++ b/t/lifecycles/moving.t
@@ -1,7 +1,5 @@
-
use strict;
use warnings;
-use Data::Dumper;
BEGIN {require 't/lifecycles/utils.pl'};
@@ -94,3 +92,5 @@ diag "one way map doesn't work backwards";
is $ticket->Queue, $delivery->id, 'queue is steal the same';
is $ticket->Status, 'ordered', 'status is steal the same';
}
+
+done_testing;
diff --git a/t/lifecycles/unresolved-deps.t b/t/lifecycles/unresolved-deps.t
index d195d3b..5da4b8f 100644
--- a/t/lifecycles/unresolved-deps.t
+++ b/t/lifecycles/unresolved-deps.t
@@ -1,8 +1,6 @@
use strict;
use warnings;
-use Data::Dumper;
-use Test::More tests => 15;
BEGIN {require 't/lifecycles/utils.pl'};
my $general = RT::Test->load_or_create_queue(
@@ -41,3 +39,5 @@ ok $m->login, 'logged in';
);
}
+undef $m;
+done_testing;
diff --git a/t/lifecycles/utils.pl b/t/lifecycles/utils.pl
index 3813df3..ec3289f 100644
--- a/t/lifecycles/utils.pl
+++ b/t/lifecycles/utils.pl
@@ -67,6 +67,6 @@ Set(\%Lifecycles,
END
}
-use RT::Test config => $config;
+use RT::Test config => $config, tests => undef;
1;
commit 71e6b11eabc04cfeca749997de0244bb637e61fe
Author: Alex Vandiver <alexmv at bestpractical.com>
Date: Fri Dec 7 21:56:48 2012 -0500
Split lifecycle status aggregation by type
This ensures that as lifecycles are applied to more than just tickets,
their aggregated statuses (as determined from ->Load( '' )->Valid) only
show statuses from lifecycles that could apply to that type of object.
diff --git a/lib/RT/Condition/StatusChange.pm b/lib/RT/Condition/StatusChange.pm
index 667ccee..1de7a8c 100644
--- a/lib/RT/Condition/StatusChange.pm
+++ b/lib/RT/Condition/StatusChange.pm
@@ -114,7 +114,7 @@ sub IsApplicable {
}
else {
$RT::Logger->error("Argument '$argument' is incorrect.")
- unless RT::Lifecycle->Load('')->IsValid( $argument );
+ unless RT::Lifecycle->Load(Type => 'ticket')->IsValid( $argument );
return 0;
}
diff --git a/lib/RT/Lifecycle.pm b/lib/RT/Lifecycle.pm
index b66276b..ac522f3 100644
--- a/lib/RT/Lifecycle.pm
+++ b/lib/RT/Lifecycle.pm
@@ -54,16 +54,11 @@ package RT::Lifecycle;
our %LIFECYCLES;
our %LIFECYCLES_CACHE;
+our %LIFECYCLES_TYPES;
__PACKAGE__->RegisterRights;
# cache structure:
# {
-# '' => { # all valid statuses
-# '' => [...],
-# initial => [...],
-# active => [...],
-# inactive => [...],
-# },
# lifecycle_x => {
# '' => [...], # all valid in lifecycle
# initial => [...],
@@ -119,31 +114,50 @@ sub new {
return $self;
}
-=head2 Load
+=head2 Load Name => I<NAME>, Type => I<TYPE>
-Takes a name of the lifecycle and loads it. If name is empty or undefined then
-loads the global lifecycle with statuses from all named lifecycles.
+Takes a name of the lifecycle and loads it. If only a Type is provided,
+loads the global lifecycle with statuses from all named lifecycles of
+that type.
Can be called as class method, returns a new object, for example:
- my $lifecycle = RT::Lifecycle->Load('default');
+ my $lifecycle = RT::Lifecycle->Load( Name => 'default');
+
+Returns an object which may be a subclass of L<RT::Lifecycle>
+(L<RT::Lifecycle::Ticket>, for example) depending on the type of the
+lifecycle in question.
=cut
sub Load {
my $self = shift;
- my $name = shift || '';
- return $self->new->Load( $name, @_ )
+ return $self->new->Load( @_ )
unless ref $self;
- return unless exists $LIFECYCLES_CACHE{ $name };
+ unshift @_, Type => "ticket", "Name"
+ if @_ % 2;
- $self->{'name'} = $name;
- $self->{'data'} = $LIFECYCLES_CACHE{ $name };
+ my %args = (
+ Type => "ticket",
+ Name => '',
+ @_,
+ );
+
+ if (exists $LIFECYCLES_CACHE{ $args{Name} }) {
+ $self->{'name'} = $args{Name};
+ $self->{'data'} = $LIFECYCLES_CACHE{ $args{Name} };
- my $type = $self->{'data'}{'type'} || 'ticket';
- $type = "RT::Lifecycle::".ucfirst($type);
- bless $self, $type if $type->require;
+ my $found_type = $self->{'data'}{'type'};
+ warn "Found type of $found_type ne $args{Type}" if $found_type ne $args{Type};
+ } elsif (not $args{Name} and exists $LIFECYCLES_TYPES{ $args{Type} }) {
+ $self->{'data'} = $LIFECYCLES_TYPES{ $args{Type} };
+ } else {
+ return undef;
+ }
+
+ my $class = "RT::Lifecycle::".ucfirst($args{Type});
+ bless $self, $class if $class->require;
return $self;
}
@@ -161,7 +175,7 @@ sub List {
$self->FillCache unless keys %LIFECYCLES_CACHE;
return sort grep {$LIFECYCLES_CACHE{$_}{type} eq $for}
- grep length && $_ ne '__maps__', keys %LIFECYCLES_CACHE;
+ grep $_ ne '__maps__', keys %LIFECYCLES_CACHE;
}
=head2 Name
@@ -507,7 +521,8 @@ move map from this cycle to provided.
sub MoveMap {
my $from = shift; # self
my $to = shift;
- $to = RT::Lifecycle->Load( $to ) unless ref $to;
+ my $type = $from->{'data'}{'type'};
+ $to = RT::Lifecycle->Load( Name => $to, Type => $type ) unless ref $to;
return $LIFECYCLES{'__maps__'}{ $from->Name .' -> '. $to->Name } || {};
}
@@ -535,13 +550,14 @@ move maps.
sub NoMoveMaps {
my $self = shift;
- my @list = $self->List;
+ my $type = $self->{'data'}{'type'};
+ my @list = $self->List( $type );
my @res;
foreach my $from ( @list ) {
foreach my $to ( @list ) {
next if $from eq $to;
push @res, $from, $to
- unless RT::Lifecycle->Load( $from )->HasMoveMap( $to );
+ unless RT::Lifecycle->Load( Name => $from, Type => $type )->HasMoveMap( $to );
}
}
return @res;
@@ -562,7 +578,7 @@ sub ForLocalization {
my @res = ();
- push @res, @{ $LIFECYCLES_CACHE{''}{''} || [] };
+ push @res, @{$_->{''}} for values %LIFECYCLES_TYPES;
foreach my $lifecycle ( values %LIFECYCLES ) {
push @res,
grep defined && length,
@@ -587,21 +603,21 @@ sub FillCache {
%LIFECYCLES_CACHE = %LIFECYCLES = %$map;
$_ = { %$_ } foreach values %LIFECYCLES_CACHE;
- for my $lifecycles (values %LIFECYCLES_CACHE) {
- $lifecycles->{type} ||= 'ticket';
- }
+ for my $lifecycle ( values %LIFECYCLES_CACHE ) {
+ my $type = $lifecycle->{type} ||= 'ticket';
+ $LIFECYCLES_TYPES{$type} ||= {
+ '' => [],
+ initial => [],
+ active => [],
+ inactive => [],
+ actions => [],
+ };
- my %all = (
- '' => [],
- initial => [],
- active => [],
- inactive => [],
- );
- foreach my $lifecycle ( values %LIFECYCLES_CACHE ) {
my @res;
- foreach my $type ( qw(initial active inactive) ) {
- push @{ $all{ $type } }, @{ $lifecycle->{ $type } || [] };
- push @res, @{ $lifecycle->{ $type } || [] };
+ foreach my $category ( qw(initial active inactive) ) {
+ my @vals = @{ $lifecycle->{ $category } ||= [] };
+ push @{ $LIFECYCLES_TYPES{$type}{$category} }, @vals;
+ push @res, @vals;
}
my %seen;
@@ -612,12 +628,15 @@ sub FillCache {
$lifecycle->{'transitions'}{''} = [ grep $_ ne 'deleted', @res ];
}
}
- foreach my $type ( qw(initial active inactive), '' ) {
- my %seen;
- @{ $all{ $type } } = grep !$seen{ lc $_ }++, @{ $all{ $type } };
- push @{ $all{''} }, @{ $all{ $type } } if $type;
+ for my $type (keys %LIFECYCLES_TYPES) {
+ for my $category ( qw(initial active inactive), '' ) {
+ my %seen;
+ @{ $LIFECYCLES_TYPES{$type}{$category} } =
+ grep !$seen{ lc $_ }++, @{ $LIFECYCLES_TYPES{$type}{$category} };
+ push @{ $LIFECYCLES_TYPES{$type}{''} },
+ @{ $LIFECYCLES_TYPES{$type}{$category} } if $category;
+ }
}
- $LIFECYCLES_CACHE{''} = \%all;
foreach my $lifecycle ( values %LIFECYCLES_CACHE ) {
my @res;
diff --git a/lib/RT/Queue.pm b/lib/RT/Queue.pm
index 2bc8f20..b161411 100644
--- a/lib/RT/Queue.pm
+++ b/lib/RT/Queue.pm
@@ -243,17 +243,17 @@ sub RightCategories {
sub Lifecycle {
my $self = shift;
- unless (ref $self && $self->id) {
- return RT::Lifecycle->Load('')
+ unless (ref $self && $self->id) {
+ return RT::Lifecycle->Load( Type => 'ticket')
}
my $name = $self->_Value( Lifecycle => @_ );
$name ||= 'default';
- my $res = RT::Lifecycle->Load( $name );
+ my $res = RT::Lifecycle->Load( Name => $name );
unless ( $res ) {
$RT::Logger->error("Lifecycle '$name' for queue '".$self->Name."' doesn't exist");
- return RT::Lifecycle->Load('default');
+ return RT::Lifecycle->Load( Name => 'default');
}
return $res;
}
@@ -278,7 +278,7 @@ lifecycle is configured. Returns undef otherwise.
sub ValidateLifecycle {
my $self = shift;
my $value = shift;
- return undef unless RT::Lifecycle->Load( $value );
+ return undef unless RT::Lifecycle->Load( Name => $value );
return 1;
}
diff --git a/share/html/Elements/QueueSummaryByLifecycle b/share/html/Elements/QueueSummaryByLifecycle
index 1410e82..79e3a59 100644
--- a/share/html/Elements/QueueSummaryByLifecycle
+++ b/share/html/Elements/QueueSummaryByLifecycle
@@ -106,7 +106,7 @@ $m->callback( CallbackName => 'Filter', Queues => \@queues );
my %lifecycle;
for my $queue (@queues) {
- my $cycle = RT::Lifecycle->Load( $queue->{'Lifecycle'} );
+ my $cycle = RT::Lifecycle->Load( Name => $queue->{'Lifecycle'} );
$lifecycle{ lc $cycle->Name } = $cycle;
}
diff --git a/share/html/Elements/QueueSummaryByStatus b/share/html/Elements/QueueSummaryByStatus
index f649d28..cd8b277 100644
--- a/share/html/Elements/QueueSummaryByStatus
+++ b/share/html/Elements/QueueSummaryByStatus
@@ -104,7 +104,7 @@ $m->callback( CallbackName => 'Filter', Queues => \@queues );
my %lifecycle;
for my $queue (@queues) {
- my $cycle = RT::Lifecycle->Load( $queue->{'Lifecycle'} );
+ my $cycle = RT::Lifecycle->Load( Name => $queue->{'Lifecycle'} );
$lifecycle{ lc $cycle->Name } = $cycle;
}
diff --git a/t/lifecycles/types.t b/t/lifecycles/types.t
new file mode 100644
index 0000000..83fe06e
--- /dev/null
+++ b/t/lifecycles/types.t
@@ -0,0 +1,29 @@
+use strict;
+use warnings;
+
+BEGIN {require 't/lifecycles/utils.pl'};
+
+is_deeply( [ RT::Lifecycle->List], [qw/ approvals default delivery /],
+ "Get the list of lifecycles (implicitly for for tickets)");
+is_deeply( [ RT::Lifecycle->List('ticket') ], [qw/ approvals default delivery /],
+ "Get the list of lifecycles for tickets");
+is_deeply( [ RT::Lifecycle->List('racecar') ], [qw/ racing /],
+ "Get the list of lifecycles for other types");
+
+my $tickets = RT::Lifecycle->Load( Name => '', Type => 'ticket' );
+ok($tickets, "Got a generalized lifecycle for tickets");
+isa_ok( $tickets, "RT::Lifecycle::Ticket", "Is the right subclass" );
+is_deeply( [ sort $tickets->Valid ],
+ [ sort (qw(new open stalled resolved rejected deleted ordered),
+ 'on way', 'delayed', 'delivered') ],
+ "Only gets ticket statuses" );
+
+
+my $racecars = RT::Lifecycle->Load( Name => '', Type => 'racecar' );
+ok($racecars, "Got a generalized lifecycle for racecars");
+isa_ok( $racecars, "RT::Lifecycle", "Is the generalized subclass" );
+is_deeply( [ sort $racecars->Valid ],
+ [ sort ('on-your-mark', 'get-set', 'go', 'first', 'second', 'third', 'no-place') ],
+ "Only gets racecar statuses" );
+
+done_testing;
diff --git a/t/lifecycles/utils.pl b/t/lifecycles/utils.pl
index ec3289f..4dbba23 100644
--- a/t/lifecycles/utils.pl
+++ b/t/lifecycles/utils.pl
@@ -63,6 +63,11 @@ Set(\%Lifecycles,
'delayed -> on way' => {label => 'Put On Way', update => 'Respond'},
},
},
+ racing => {
+ type => 'racecar',
+ active => ['on-your-mark', 'get-set', 'go'],
+ inactive => ['first', 'second', 'third', 'no-place'],
+ },
);
END
}
-----------------------------------------------------------------------
More information about the Rt-commit
mailing list