[Rt-commit] rt branch, 4.4/ticket-search-order-by-watcher-cfs, created. rt-4.4.4-103-g7bf68a0f34

? sunnavy sunnavy at bestpractical.com
Wed Apr 22 18:04:18 EDT 2020


The branch, 4.4/ticket-search-order-by-watcher-cfs has been created
        at  7bf68a0f3457543e38949ab853ff9de93b437b16 (commit)

- Log -----------------------------------------------------------------
commit bbac78c6986f9b43c80864efd48173e172488a93
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Wed Nov 27 00:55:00 2019 +0800

    Support order by watcher's custom fields for ticket search

diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index e094c63ef6..15a2851fef 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -1065,7 +1065,9 @@ Try and turn a custom role descriptor (e.g. C<CustomRole.{Engineer}>) into
 sub _CustomRoleDecipher {
     my ($self, $string) = @_;
 
-    my ($field, $column) = ($string =~ /^\{(.+)\}(?:\.(\w+))?$/);
+    # $column could be core fields like "EmailAddress" or CFs like
+    # "CustomField.{Department}", the CF format is used in OrderByCols.
+    my ($field, $column) = ($string =~ /^\{(.+?)\}(?:\.(.+))?$/);
 
     my $role;
 
@@ -1434,7 +1436,54 @@ sub OrderByCols {
                 $self->{_sql_u_watchers_alias_for_sort}{ $cache_key }
                     = $users = ( $self->_WatcherJoin( Name => $type, Class => "RT::" . $class ) )[2];
             }
-            push @res, { %$row, ALIAS => $users, FIELD => $column };
+
+            if ( $column =~ /^CustomField\.\{(.+)\}$/ ) {
+                my $cf_name = $1;
+                my $cf      = RT::CustomField->new( $self->CurrentUser );
+                $cf->LoadByCols( LookupType => RT::User->CustomFieldLookupType, Name => $cf_name );
+                if ( $cf->id ) {
+                    my $ocfvs = $self->NewAlias('ObjectCustomFieldValues');
+                    $self->Join(
+                        TYPE   => 'LEFT',
+                        ALIAS1 => $users,
+                        FIELD1 => 'id',
+                        ALIAS2 => $ocfvs,
+                        FIELD2 => 'ObjectId',
+                    );
+
+                    $self->Limit(
+                        LEFTJOIN        => $ocfvs,
+                        FIELD           => 'CustomField',
+                        VALUE           => $cf->id,
+                        ENTRYAGGREGATOR => 'AND',
+                    );
+
+                    # The following is copied from RT::SearchBuilder::_OrderByCF
+                    my $CFvs = $self->Join(
+                        TYPE   => 'LEFT',
+                        ALIAS1 => $ocfvs,
+                        FIELD1 => 'CustomField',
+                        TABLE2 => 'CustomFieldValues',
+                        FIELD2 => 'CustomField',
+                    );
+                    $self->Limit(
+                        LEFTJOIN        => $CFvs,
+                        FIELD           => 'Name',
+                        QUOTEVALUE      => 0,
+                        VALUE           => "$ocfvs.Content",
+                        ENTRYAGGREGATOR => 'AND'
+                    );
+                    push @res, { %$row, ALIAS => $CFvs, FIELD => 'SortOrder' },
+                        { %$row, ALIAS => $ocfvs, FIELD => 'Content' };
+                }
+                else {
+                    RT->Logger->warning("Couldn't load user custom field $cf_name");
+                    next;
+                }
+            }
+            else {
+                push @res, { %$row, ALIAS => $users, FIELD => $column };
+            }
        } elsif ( defined $meta->[0] && $meta->[0] eq 'CUSTOMFIELD' ) {
            my ($object, $field, $cf, $column) = $self->_CustomFieldDecipher( $subkey );
            my $cfkey = $cf ? $cf->id : "$object.$field";

commit 9a1556ab44573ccb07f3371ae2818bf63930857f
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Wed Nov 27 00:55:45 2019 +0800

    Test order by watcher's custom fields for ticket search

diff --git a/t/ticket/sort-by-user.t b/t/ticket/sort-by-user.t
index 42f95fc258..bde06d2ef3 100644
--- a/t/ticket/sort-by-user.t
+++ b/t/ticket/sort-by-user.t
@@ -1,5 +1,5 @@
 
-use RT::Test nodata => 1, tests => 52;
+use RT::Test nodata => 1, tests => undef;
 
 use strict;
 use warnings;
@@ -33,6 +33,7 @@ foreach my $u (qw(Z A)) {
     my $user = RT::User->new( RT->SystemUser );
     my ($uid) = $user->Create(
         Name => $name,
+        EmailAddress => $name . '@localhost',
         Privileged => 1,
     );
     ok $uid, "created user #$uid";
@@ -117,7 +118,7 @@ run_tests();
 run_tests();
 
 @data = (
-    { Subject => 'RT' },
+    { Subject => 'Nobody' },
     { Subject => 'Z', LastUpdatedBy => $uids[0] },
     { Subject => 'A', LastUpdatedBy => $uids[1] },
 );
@@ -127,4 +128,50 @@ run_tests();
 );
 run_tests();
 
+my $cf = RT::Test->load_or_create_custom_field(
+    Name  => 'Department',
+    Type  => 'FreeformSingle',
+    LookupType => RT::User->CustomFieldLookupType,
+);
+my ( $ret, $msg ) = $cf->AddToObject( RT::User->new( RT->SystemUser ) );
+ok( $ret, "Added CF globally: $msg" );
+
+( $ret, $msg ) = $users[0]->AddCustomFieldValue( Field => $cf, Value => 'Bar' );
+ok( $ret, "Added CF value 'Foo' to users[0]: $msg" );
+
+( $ret, $msg ) = $users[1]->AddCustomFieldValue( Field => $cf, Value => 'Foo' );
+ok( $ret, "Added CF value 'Bar' to users[1]: $msg" );
+
+ at data = (
+    { Subject => '-' },
+    { Subject => 'Z', Owner => $uids[1] },
+    { Subject => 'A', Owner => $uids[0] },
+);
+ at tickets = RT::Test->create_tickets( { Queue => $queue->id }, @data );
+ at test = (
+    { Order => "Owner.CustomField.{Department}" },
+);
+run_tests();
+
+my $cr = RT::CustomRole->new( RT->SystemUser );
+( $ret, $msg ) = $cr->Create(
+    Name      => 'Engineer',
+    MaxValues => 0,
+);
+ok( $ret, "Created custom role: $msg" );
+
+( $ret, $msg ) = $cr->AddToObject( ObjectId => $queue->id );
+ok( $ret, "Added CR to queue: $msg" );
+
+ at data = (
+    { Subject => '-' },
+    { Subject => 'Z', $cr->GroupType => $uids[1] },
+    { Subject => 'A', $cr->GroupType => $uids[0] },
+);
+ at tickets = RT::Test->create_tickets( { Queue => $queue->id }, @data );
+ at test = ( { Order => "CustomRole.{Engineer}.CustomField.{Department}" }, );
+run_tests();
+
 @tickets = ();
+
+done_testing;

commit de21a4892282cb7cb27afd46bc21df2dc854ebe1
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Wed Apr 22 05:38:19 2020 +0800

    Support more watcher fields including user cfs in search result format

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index b6ccf6ff7e..6848955f66 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -3909,7 +3909,7 @@ sub GetColumnMapEntry {
 
     # complex things
     elsif ( my ( $mainkey, $subkey ) = $args{'Name'} =~ /^(.*?)\.(.+)$/ ) {
-        $subkey =~ s/^\{(.*)\}$/$1/;
+        $subkey =~ s/^\{(.*)\}/$1/ unless $mainkey eq 'CustomRole';
         return undef unless $args{'Map'}->{$mainkey};
         return $args{'Map'}{$mainkey}{ $args{'Attribute'} }
             unless ref $args{'Map'}{$mainkey}{ $args{'Attribute'} } eq 'CODE';
diff --git a/share/html/Elements/ColumnMap b/share/html/Elements/ColumnMap
index 836d658d8c..50082ef37d 100644
--- a/share/html/Elements/ColumnMap
+++ b/share/html/Elements/ColumnMap
@@ -54,6 +54,104 @@ $Attr  => undef
 
 use Scalar::Util;
 
+my $role_value = sub {
+    my $role   = shift;
+    my $object = shift;
+
+    # $[0] is the index number of current row
+    my $field  = $_[1] || '';
+
+    my ( $role_type, $attr, $cf_name );
+
+
+    if ( $role eq 'CustomRole' ) {
+        my $role_name;
+        if ( $field =~ /^\{(.+)\}\.CustomField\.\{(.+)\}/ ) {
+
+            # {test}.CustomField.{foo}
+            $role_name = $1;
+            $cf_name   = $2;
+        }
+        elsif ( $field =~ /^\{(.+)\}(?:\.(\w+))?$/ ) {
+
+            # {test}.Name or {test}
+            $role_name = $1;
+            $attr      = $2;
+        }
+
+        # Cache the role object on a per-request basis, to avoid
+        # having to load it for every row
+        my $key = "RT::CustomRole-" . $role_name;
+
+        $role_type = $m->notes($key);
+        if ( !$role_type ) {
+            my $role_obj = RT::CustomRole->new( $object->CurrentUser );
+            $role_obj->Load($role_name);
+
+            RT->Logger->notice("Unable to load custom role $role_name")
+                unless $role_obj->Id;
+
+            $role_type = $role_obj->GroupType;
+            $m->notes( $key, $role_type );
+        }
+    }
+    else {
+        if ( $field =~ /^CustomField\.\{(.+)\}/ ) {
+            $cf_name = $1;
+        }
+        elsif ( $field =~ /^(\w+)$/ ) {
+            $attr = $1;
+        }
+        $role_type = $role;
+    }
+
+    return if !$role_type;
+
+    my $role_group = $object->RoleGroup($role_type);
+    if ( $cf_name || $attr ) {
+        # TODO Show direct members only?
+        my $users = $role_group->UserMembersObj;
+        my @values;
+
+        while ( my $user = $users->Next ) {
+            if ($cf_name) {
+                my $key = join( "-", "CF", $user->CustomFieldLookupType, $cf_name );
+                my $cf = $m->notes($key);
+                if ( !$cf ) {
+                    $cf = $user->LoadCustomFieldByIdentifier($cf_name);
+                    RT->Logger->debug( "Unable to load $cf_name for " . $user->CustomFieldLookupType )
+                        unless $cf->Id;
+                    $m->notes( $key, $cf );
+                }
+
+                my $ocfvs = $cf->ValuesForObject($user)->ItemsArrayRef;
+                my $comp
+                    = $m->comp_exists( "/Elements/ShowCustomField" . $cf->Type )
+                    ? "/Elements/ShowCustomField" . $cf->Type
+                    : undef;
+
+                push @values, map { $comp ? \( $m->scomp( $comp, Object => $_ ) ) : $_->Content } @$ocfvs;
+
+            }
+            elsif ( $user->_Accessible( $attr, 'read' ) ) {
+                push @values, $user->$attr || ();
+            }
+        }
+        return @values if @values <= 1;
+
+        if ($cf_name) {
+            @values = map { \"<li>", $_, \"</li>" } @values;
+            @values = ( \"<ul class='cf-values'>", @values, \"</ul>" );
+        }
+        else {
+            return join ', ', @values;
+        }
+    }
+    else {
+        return \( $m->scomp( "/Elements/ShowPrincipal", Object => $role_group ) );
+    }
+};
+
 my ($COLUMN_MAP, $WCOLUMN_MAP);
 $WCOLUMN_MAP = $COLUMN_MAP = {
     id => {
@@ -143,34 +241,21 @@ $WCOLUMN_MAP = $COLUMN_MAP = {
     },
     CustomRole => {
         attribute => sub { return shift @_ },
-        title     => sub { return pop @_ },
-        value     => sub {
-            my $object = shift;
-            my $role_name = pop;
-
-            my $role_type = do {
-                # Cache the role object on a per-request basis, to avoid
-                # having to load it for every row
-                my $key = "RT::CustomRole-" . $role_name;
-
-                my $role_type = $m->notes($key);
-                if (!$role_type) {
-                    my $role_obj = RT::CustomRole->new($object->CurrentUser);
-                    $role_obj->Load($role_name);
-
-                    RT->Logger->notice("Unable to load custom role $role_name")
-                        unless $role_obj->Id;
-
-                    $role_type = $role_obj->GroupType;
-                    $m->notes($key, $role_type);
-                }
-
-                $role_type;
-            };
-
-            return if !$role_type;
-            return \($m->scomp("/Elements/ShowPrincipal", Object => $object->RoleGroup($role_type) ) );
+        title     => sub {
+            my $field = pop @_;
+            if (   $field =~ /^\{(.+)\}\.CustomField\.\{(.+)\}/
+                || $field =~ /^\{(.+)\}\.(.+)/ )
+            {
+                return "$1.$2";
+            }
+            elsif ( $field =~ /^\{(.+)\}$/ ) {
+                return $1;
+            }
+            else {
+                return $field;
+            }
         },
+        value => sub { return $role_value->('CustomRole', @_) },
     },
 
     CheckBox => {
@@ -254,9 +339,19 @@ if ($RecordClass->DOES("RT::Record::Role::Roles")) {
         for my $role ($RecordClass->Roles(UserDefined => 0)) {
             my $attrs = $RecordClass->Role($role);
             $ROLE_MAP->{$RecordClass}{$role} = {
-                title => $role,
-                attribute => $attrs->{Column} || "$role.EmailAddress",
-                value => sub { return \($m->scomp("/Elements/ShowPrincipal", Object => $_[0]->RoleGroup($role) ) ) },
+                attribute => sub { return shift @_ },
+                title => sub {
+                    my $field = pop @_;
+                    if (   $field =~ /^CustomField\.\{(.+)\}/
+                        || $field =~ /^(?!$role)(.+)/ )
+                    {
+                        return "$role.$1";
+                    }
+                    else {
+                        return $role;
+                    }
+                },
+                value => sub { return $role_value->($role, @_, @_ == 2 ? '' : () ) },
             };
             $ROLE_MAP->{$RecordClass}{$role . "s"} = $ROLE_MAP->{$RecordClass}{$role}
                 unless $attrs->{Single};

commit 51d5c34441b8b513a361cb5d7ee1592658a166bc
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Wed Nov 27 02:17:51 2019 +0800

    Add more watcher fields including user cfs to OrderBy/Columns in search builder
    
    Besides user cfs, the following core fields are added: id, Name,
    EmailAddress, RealName, Organization, City and Country.
    
    The previous ambiguous "Owner" in OrderBy select is renamed to "Owner.Name".

diff --git a/share/html/Search/Elements/BuildFormatString b/share/html/Search/Elements/BuildFormatString
index ce541f889e..d5e8718960 100644
--- a/share/html/Search/Elements/BuildFormatString
+++ b/share/html/Search/Elements/BuildFormatString
@@ -128,8 +128,29 @@ foreach my $id (keys %queues) {
     next unless $queue->Id;
     $CustomRoles->LimitToObjectId($queue->Id);
 }
-while ( my $Role = $CustomRoles->Next ) {
-    push @fields, "CustomRole.{" . $Role->Name . "}";
+
+my @user_fields = qw/id Name EmailAddress Organization RealName City Country/;
+my $user_cfs    = RT::CustomFields->new( $session{CurrentUser} );
+$user_cfs->Limit( FIELD => 'LookupType', VALUE => RT::User->CustomFieldLookupType );
+while ( my $user_cf = $user_cfs->Next ) {
+    push @user_fields, join '.', 'CustomField', '{' . $user_cf->Name . '}';
+}
+
+for my $watcher (qw/AdminCc Cc Owner Requestor/) {
+    for my $user_field (@user_fields) {
+        my $field = join '.', $watcher, $user_field;
+        push @fields, $field;
+    }
+}
+
+# Add all available CustomRoles to the list of sortable columns.
+while ( my $role = $CustomRoles->Next ) {
+    push @fields, 'CustomRole.{' . $role->Name . '}';
+
+    # Add all available CustomRoles to the list of sortable columns.
+    for my $user_field (@user_fields) {
+        push @fields, join '.', 'CustomRole.{' . $role->Name . '}', $user_field;
+    }
 }
 
 $m->callback( Fields => \@fields, ARGSRef => \%ARGS );
diff --git a/share/html/Search/Elements/EditSort b/share/html/Search/Elements/EditSort
index 7b70b923e3..9d9a15aaaf 100644
--- a/share/html/Search/Elements/EditSort
+++ b/share/html/Search/Elements/EditSort
@@ -108,20 +108,26 @@ for my $field (keys %FieldDescriptions) {
     $fields{$field} = $field;
 }
 
-$fields{'Owner'} = 'Owner';
-$fields{ $_ . '.EmailAddress' } = $_ . '.EmailAddress'
-    for qw(Requestor Cc AdminCc);
-
 # Add all available CustomFields to the list of sortable columns.
 my @cfs = grep /^CustomField/, @{$ARGS{AvailableColumns}};
 $fields{$_} = $_ for @cfs;
 
+# Add all available core roles to the list of sortable columns.
+my @roles = grep /^(?:Owner|Requestor|Cc|AdminCc)\./, @{$ARGS{AvailableColumns}};
+$fields{$_} = $_ for @roles;
+
 # Add all available CustomRoles to the list of sortable columns.
-my @roles = grep /^CustomRole/, @{$ARGS{AvailableColumns}};
-for my $role (@roles) {
-    my ($label) = $role =~ /^CustomRole.\{(.*)\}$/;
-    my $value = $role;
-    $fields{$label . '.EmailAddress' } = $value . '.EmailAddress';
+my @custom_roles = grep /^CustomRole\./, @{$ARGS{AvailableColumns}};
+for my $role ( @custom_roles ) {
+    my $label = $role;
+    # In case custom role contains "{}" in name.
+    if ( $label =~ /\.CustomField/ ) {
+        $label =~ s!^CustomRole\.\{(.*)\}(?=\.CustomField\.)!$1!;
+    }
+    else {
+        $label =~ s!^CustomRole\.\{(.*)\}!$1!;
+    }
+    $fields{$label} = $role;
 }
 
 # Add PAW sort

commit 5671d94aae838894def6769fbc5eed601ca858ff
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Wed Nov 27 02:22:14 2019 +0800

    Upgrade OrderBy "Owner" to new version "Owner.Name" in saved searchs
    
    As we added more watcher fields to OrderBy, previous ambiguous "Owner"
    has been removed.

diff --git a/etc/upgrade/4.4.5/content b/etc/upgrade/4.4.5/content
new file mode 100644
index 0000000000..3123332c46
--- /dev/null
+++ b/etc/upgrade/4.4.5/content
@@ -0,0 +1,36 @@
+use strict;
+use warnings;
+
+our @Initial = (
+    sub {
+        my $searches = RT::Attributes->new( RT->SystemUser );
+        $searches->Limit( FIELD => 'Name', VALUE => 'SavedSearch' );
+        $searches->OrderBy( FIELD => 'id' );
+
+        while ( my $search = $searches->Next ) {
+            my $content = $search->Content;
+            next unless ref $content eq 'HASH';
+
+            if ( $content->{OrderBy} ) {
+                my @order_by = split /\|/, $content->{OrderBy};
+                my @new_order_by;
+                my $changed;
+                for my $order_by (@order_by) {
+                    if ( $order_by eq 'Owner' ) {
+                        push @new_order_by, 'Owner.Name';
+                        $changed = 1;
+                    }
+                    else {
+                        push @new_order_by, $order_by;
+                    }
+                }
+                if ($changed) {
+                    $content->{OrderBy} = join '|', @new_order_by;
+                    my ( $ok, $msg ) = $search->SetContent($content);
+                    RT->Logger->error("Unable to upgrade saved chart #@{[$search->id]}: $msg")
+                        unless $ok;
+                }
+            }
+        }
+    }
+);

commit 7bf68a0f3457543e38949ab853ff9de93b437b16
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Wed Nov 27 02:31:26 2019 +0800

    Update query builder tests as now we support more watcher fields

diff --git a/t/web/cf_access.t b/t/web/cf_access.t
index aa707f5dc6..505269b599 100644
--- a/t/web/cf_access.t
+++ b/t/web/cf_access.t
@@ -231,7 +231,7 @@ $m->submit_form(
 
 $m->form_name('BuildQuery');
 
-my $col = ($m->current_form->find_input('SelectDisplayColumns'))[-1];
+my ($col) = grep { ($_->possible_values)[-1] =~ /CustomField/ } $m->find_all_inputs( name => 'SelectDisplayColumns' );
 $col->value( ($col->possible_values)[-1] );
 
 $m->click('AddCol');
diff --git a/t/web/query_builder.t b/t/web/query_builder.t
index 89e89f5707..94a167041a 100644
--- a/t/web/query_builder.t
+++ b/t/web/query_builder.t
@@ -326,13 +326,25 @@ diag "make sure skipped order by field doesn't break search";
     ), "link to the ticket" );
 }
 
-diag "make sure the list of columns available in the 'Order by' dropdowns are complete";
+diag "make sure the list of columns available in the 'Order by'/'Add Columns' dropdowns are complete";
 {
     $agent->get_ok($url . 'Search/Build.html');
 
     my @orderby = qw(
+        AdminCc.City
+        AdminCc.Country
         AdminCc.EmailAddress
+        AdminCc.Name
+        AdminCc.Organization
+        AdminCc.RealName
+        AdminCc.id
+        Cc.City
+        Cc.Country
         Cc.EmailAddress
+        Cc.Name
+        Cc.Organization
+        Cc.RealName
+        Cc.id
         Created
         Creator
         Custom.Ownership
@@ -341,10 +353,22 @@ diag "make sure the list of columns available in the 'Order by' dropdowns are co
         InitialPriority
         LastUpdated
         LastUpdatedBy
-        Owner
+        Owner.City
+        Owner.Country
+        Owner.EmailAddress
+        Owner.Name
+        Owner.Organization
+        Owner.RealName
+        Owner.id
         Priority
         Queue
+        Requestor.City
+        Requestor.Country
         Requestor.EmailAddress
+        Requestor.Name
+        Requestor.Organization
+        Requestor.RealName
+        Requestor.id
         Resolved
         SLA
         Started
@@ -370,17 +394,115 @@ diag "make sure the list of columns available in the 'Order by' dropdowns are co
             is ($scraped_orderby, '[none] '.$orderby);
     }
 
+    my @formats = qw(
+        id
+        QueueName
+        Subject
+        Status
+        ExtendedStatus
+        UpdateStatus
+        Type
+        OwnerName
+        Requestors
+        Cc
+        AdminCc
+        CreatedBy
+        LastUpdatedBy
+        Priority
+        InitialPriority
+        FinalPriority
+        TimeWorked
+        TimeLeft
+        TimeEstimated
+        Starts
+        StartsRelative
+        Started
+        StartedRelative
+        Created
+        CreatedRelative
+        LastUpdated
+        LastUpdatedRelative
+        Told
+        ToldRelative
+        Due
+        DueRelative
+        Resolved
+        ResolvedRelative
+        SLA
+        RefersTo
+        ReferredToBy
+        DependsOn
+        DependedOnBy
+        MemberOf
+        Members
+        Parents
+        Children
+        Bookmark
+        Timer
+        NEWLINE
+        NBSP
+        AdminCc.id
+        AdminCc.Name
+        AdminCc.EmailAddress
+        AdminCc.Organization
+        AdminCc.RealName
+        AdminCc.City
+        AdminCc.Country
+        Cc.id
+        Cc.Name
+        Cc.EmailAddress
+        Cc.Organization
+        Cc.RealName
+        Cc.City
+        Cc.Country
+        Owner.id
+        Owner.Name
+        Owner.EmailAddress
+        Owner.Organization
+        Owner.RealName
+        Owner.City
+        Owner.Country
+        Requestor.id
+        Requestor.Name
+        Requestor.EmailAddress
+        Requestor.Organization
+        Requestor.RealName
+        Requestor.City
+        Requestor.Country
+        );
+    my $formats = join(' ', @formats);
+    my $scraped_formats = $agent->scrape_text_by_attr('name', 'SelectDisplayColumns');
+    is( $scraped_formats, $formats, 'Default format' );
+
     my $cf = RT::Test->load_or_create_custom_field(
         Name  => 'Location',
         Queue => 'General',
         Type  => 'FreeformSingle', );
     isa_ok( $cf, 'RT::CustomField' );
 
+    my $user_cf = RT::Test->load_or_create_custom_field(
+        Name       => 'Employee ID',
+        LookupType => RT::User->CustomFieldLookupType,
+        Type       => 'FreeformSingle',
+    );
+
+    my $cr = RT::CustomRole->new( RT->SystemUser );
+    my ( $ret, $msg ) = $cr->Create(
+        Name      => 'Engineer',
+        MaxValues => 0,
+    );
+    ok( $ret, "Created custom role: $msg" );
+
+    ( $ret, $msg ) = $cr->AddToObject( ObjectId => 'General' );
+    ok( $ret, "Added CR to queue: $msg" );
+
     ok($agent->form_name('BuildQuery'), "found the form");
     $agent->field("ValueOfQueue", "General");
     $agent->submit;
 
     push @orderby, 'CustomField.{Location}';
+    push @orderby, 'Engineer', map { "Engineer.$_" } qw/City Country EmailAddress Name Organization RealName id/;
+    push @orderby, map {"$_.CustomField.{Employee ID}"} qw/AdminCc Cc Requestor Owner Engineer/;
 
     $orderby = join(' ', sort @orderby);
 
@@ -393,6 +515,23 @@ diag "make sure the list of columns available in the 'Order by' dropdowns are co
         is ($scraped_orderby, '[none] '.$orderby);
     }
 
+    # Formats are not sorted, we need to insert new items accordingly
+    my @new_formats;
+    for my $format ( @formats ) {
+        push @new_formats, $format;
+        if ( $format eq 'NBSP' ) {
+            push @new_formats, 'CustomField.{Location}';
+        }
+        elsif ( $format =~ /(\w+)\.Country/ ) {
+            push @new_formats, "$1.CustomField.{Employee ID}";
+        }
+    }
+    push @new_formats, 'CustomRole.{Engineer}',
+        map {"CustomRole.{Engineer}.$_"} qw/id Name EmailAddress Organization RealName City Country/, 'CustomField.{Employee ID}';
+    $formats = join(' ', @new_formats);
+    $scraped_formats = $agent->scrape_text_by_attr('name', 'SelectDisplayColumns');
+    is( $scraped_formats, $formats, 'Format with custom fields and custom roles' );
+
     $cf->SetDisabled(1);
 }
 

-----------------------------------------------------------------------


More information about the rt-commit mailing list