[Rt-commit] rt branch, 4.0/rest-search-refactor, created. rt-4.0.6-179-g8ade2ed

? sunnavy sunnavy at bestpractical.com
Wed Jun 13 10:15:19 EDT 2012


The branch, 4.0/rest-search-refactor has been created
        at  8ade2ed3bfdabc395d01a0ea18e0012093cfa84d (commit)

- Log -----------------------------------------------------------------
commit af8eda3bb306a4e52b2a87bce8c2259a68bfaa2f
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Thu Jun 23 12:56:28 2011 +0800

    prepare to support restful searches for queues, users and groups

diff --git a/bin/rt.in b/bin/rt.in
index 2a9f643..8681106 100755
--- a/bin/rt.in
+++ b/bin/rt.in
@@ -327,32 +327,53 @@ sub list {
         $data{orderby} =~ s/^\+?(.*)/-$1/;
     }
 
-    if (!defined $q) {
-        $q = $config{query}; 
+    $type ||= "ticket";
+
+    if (!defined $q ) {
+        if ( $type eq 'ticket' ) {
+            $q = $config{query};
+        }
+        else {
+            $q = '';
+        }
     }
-    
-    $q =~ s/^#//; # get rid of leading hash
-    if ($q =~ /^\d+$/) {
-        # only digits, must be an id, formulate a correct query
-        $q = "id=$q" if $q =~ /^\d+$/;
-    } else {
-        # a string only, take it as an owner or requestor (quoting done later)
-        $q = "(Owner=$q or Requestor like $q) and $config{query}"
-             if $q =~ /^[\w\-]+$/;
-        # always add a query for a specific queue or (comma separated) queues
-        $queue =~ s/,/ or Queue=/g if $queue;
-        $q .= " and (Queue=$queue)" if $queue and $q and $q !~ /Queue\s*=/i
-            and $q !~ /id\s*=/i;
+
+    if ( $type ne 'ticket' ) {
+        $rawprint = 1;
     }
-    # correctly quote strings in a query
-    $q =~ s/(=|like\s)\s*([^'\d\s]\S*)\b/$1\'$2\'/g;
 
-    $type ||= "ticket";
-    unless ($type && defined $q) {
+    unless (defined $q) {
         my $item = $type ? "query string" : "object type";
         whine "No $item specified.";
         $bad = 1;
     }
+
+    $q =~ s/^#//; # get rid of leading hash
+    if ( $type eq 'ticket' ) {
+        if ( $q =~ /^\d+$/ ) {
+
+            # only digits, must be an id, formulate a correct query
+            $q = "id=$q" if $q =~ /^\d+$/;
+        }
+        else {
+
+          # a string only, take it as an owner or requestor (quoting done later)
+            $q = "(Owner=$q or Requestor like $q) and $config{query}"
+              if $q =~ /^[\w\-]+$/;
+
+           # always add a query for a specific queue or (comma separated) queues
+            $queue =~ s/,/ or Queue=/g if $queue;
+            $q .= " and (Queue=$queue)"
+              if $queue
+                  and $q
+                  and $q !~ /Queue\s*=/i
+                  and $q !~ /id\s*=/i;
+        }
+
+        # correctly quote strings in a query
+        $q =~ s/(=|like\s)\s*([^'\d\s]\S*)\b/$1\'$2\'/g;
+    }
+
     #return help("list", $type) if $bad;
     return suggest_help("list", $type, $bad) if $bad;
 
@@ -2159,13 +2180,14 @@ Text:
     Displays a list of objects matching the specified conditions.
     ("ls", "list", and "search" are synonyms.)
 
-    Conditions are expressed in the SQL-like syntax used internally by
-    RT. (For more information, see "rt help query".) The query string
-    must be supplied as one argument.
+    The query string must be supplied as one argument.
+
+    if on tickets, query is in the SQL-like syntax used internally by
+    RT. (For more information, see "rt help query".), otherwise, query
+    is plain string with format "FIELD OP VALUE", e.g. "Name = General".
 
-    (Right now, the server doesn't support listing anything but tickets.
-    Other types will be supported in future; this client will be able to
-    take advantage of that support without any changes.)
+    if query string is absent, we limit to privileged ones on users and
+    user defined ones on groups automatically.
 
     Options:
 
@@ -2196,6 +2218,9 @@ Text:
         rt ls -t ticket "Subject like '[PATCH]%'"
         rt ls -q systems
         rt ls -f owner,subject
+        rt ls -t queue 'Name = General'
+        rt ls -t user 'EmailAddress like foo at bar.com'
+        rt ls -t group 'Name like foo'
 
 --
 

commit 410ce6fbebfd97a5e5809e82c5ea3e144a3f7246
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Thu Jun 23 13:19:30 2011 +0800

    restful search support for queues/users/groups

diff --git a/share/html/REST/1.0/Forms/group/default b/share/html/REST/1.0/Forms/group/default
index 7686f21..ca08b3d 100644
--- a/share/html/REST/1.0/Forms/group/default
+++ b/share/html/REST/1.0/Forms/group/default
@@ -58,7 +58,17 @@ my @comments;
 my ($c, $o, $k, $e) = ("", [], {}, 0);
 my %data = %$changes;
 my $group = RT::Group->new($session{CurrentUser});
-my @fields = qw(Name Description);
+
+my @fields;
+if ( $fields && %$fields ) {
+    @fields =
+      grep { exists $fields->{ lc $_ } }
+      qw(Name Description);
+}
+else {
+    @fields = qw(Name Description);
+}
+
 my %fields = map { lc $_ => $_ } @fields;
 
 if ($id ne 'new') {
@@ -109,31 +119,33 @@ if (%data == 0) {
     my @data;
 
     push @data, [ id => "group/".$group->Id ];
-    push @data, [ Name => $group->Name ];
-    push @data, [ Description => $group->Description ];
-
+    foreach my $key (@fields) {
+        push @data, [ $key => $group->$key ];
+    }
 
     # Members
-    my $gms = [];
-    my $GroupMembers = $group->MembersObj();
-    while ( my $mo = $GroupMembers->Next() ) {
-        if ( $mo->MemberObj->IsGroup ) {
-            my $us = $mo->MemberObj->Object->UserMembersObj();
-            my @users;
-            while ( my $u = $us->Next() ) {
-                push @users, $u->RealName . ' <' . $u->EmailAddress . '>';
+    unless ( $fields && !exists $fields->{members} ) {
+        my $gms = [];
+        my $GroupMembers = $group->MembersObj();
+        while ( my $mo = $GroupMembers->Next() ) {
+            if ( $mo->MemberObj->IsGroup ) {
+                my $us = $mo->MemberObj->Object->UserMembersObj();
+                my @users;
+                while ( my $u = $us->Next() ) {
+                    push @users, $u->RealName . ' <' . $u->EmailAddress . '>';
+                }
+                push @$gms,
+                    'GROUP ['
+                    . $mo->MemberObj->Object->Name . ']' . ' ('
+                    . join( ';', @users ) . ')';
+            } elsif ( $mo->MemberObj->IsUser ) {
+                push @$gms,
+                    $mo->MemberObj->Object->RealName . ' <'
+                    . $mo->MemberObj->Object->EmailAddress . '>';
             }
-            push @$gms,
-                'GROUP ['
-                . $mo->MemberObj->Object->Name . ']' . ' ('
-                . join( ';', @users ) . ')';
-        } elsif ( $mo->MemberObj->IsUser ) {
-            push @$gms,
-                $mo->MemberObj->Object->RealName . ' <'
-                . $mo->MemberObj->Object->EmailAddress . '>';
         }
+        push @data, [ Members => $gms ];
     }
-    push @data, [ Members => $gms ];
 
     # Custom fields
     my $CustomFields = $group->CustomFields;
diff --git a/share/html/REST/1.0/Forms/queue/default b/share/html/REST/1.0/Forms/queue/default
index e6d50f3..9f02db2 100755
--- a/share/html/REST/1.0/Forms/queue/default
+++ b/share/html/REST/1.0/Forms/queue/default
@@ -58,8 +58,17 @@ my @comments;
 my ($c, $o, $k, $e) = ("", [], {}, 0);
 my %data = %$changes;
 my $queue = RT::Queue->new($session{CurrentUser});
-my @fields = qw(Name Description CorrespondAddress CommentAddress
+
+my @fields;
+if ( $fields && %$fields ) {
+    @fields =
+      grep { exists $fields->{ lc $_ } }
+      qw(Name Description CorrespondAddress CommentAddress InitialPriority FinalPriority DefaultDueIn);
+}
+else {
+    @fields = qw(Name Description CorrespondAddress CommentAddress
                 InitialPriority FinalPriority DefaultDueIn);
+}
 my %fields = map { lc $_ => $_ } @fields;
 
 if ($id ne 'new') {
diff --git a/share/html/REST/1.0/Forms/user/default b/share/html/REST/1.0/Forms/user/default
index a5786ba..87c2bce 100755
--- a/share/html/REST/1.0/Forms/user/default
+++ b/share/html/REST/1.0/Forms/user/default
@@ -51,17 +51,33 @@
 $id
 $format => 's'
 $changes => {}
+$fields => undef
 </%ARGS>
 <%perl>
 my @comments;
 my ($c, $o, $k, $e) = ("", [], {}, 0);
 my %data = %$changes;
 my $user = RT::User->new($session{CurrentUser});
-my @fields = qw(RealName NickName Gecos Organization Address1 Address2 City
-                State Zip Country HomePhone WorkPhone MobilePhone PagerPhone
-                FreeformContactInfo Comments Signature Lang EmailEncoding
-                WebEncoding ExternalContactInfoId ContactInfoSystem
-                ExternalAuthId AuthSystem Privileged Disabled);
+
+my @fields;
+if ( $fields && %$fields ) {
+    @fields =
+      grep { exists $fields->{ lc $_ } }
+      qw(Name EmailAddress RealName NickName Gecos Organization Address1
+      Address2 City State Zip Country HomePhone WorkPhone MobilePhone PagerPhone
+      FreeformContactInfo Comments Signature Lang EmailEncoding
+      WebEncoding ExternalContactInfoId ContactInfoSystem
+      ExternalAuthId AuthSystem Privileged Disabled);
+}
+else {
+    @fields =
+      qw(Name EmailAddress RealName NickName Gecos Organization Address1
+      Address2 City State Zip Country HomePhone WorkPhone MobilePhone PagerPhone
+      FreeformContactInfo Comments Signature Lang EmailEncoding
+      WebEncoding ExternalContactInfoId ContactInfoSystem
+      ExternalAuthId AuthSystem Privileged Disabled);
+}
+
 my %fields = map { lc $_ => $_ } @fields;
 
 if ($id ne 'new') {
@@ -117,14 +133,17 @@ if (keys %data == 0) {
     my @data;
 
     push @data, [ id => "user/".$user->Id ];
-    push @data, [ Name => $user->Name ];
-    push @data, [ Password => '********' ];
-    push @data, [ EmailAddress => $user->EmailAddress ];
 
-    foreach my $key (@fields) {
-        my $val = $user->$key;
+    unless ( $fields && %$fields && !exists $fields->{'password'} ) {
+        push @data, [ Password => '********' ];
+    }
 
-        if ( (defined ($format) && $format eq 'l') || (defined $val && $val ne '')) {
+    for my $key (@fields) {
+        my $val = $user->$key;
+        if (   ( $fields && exists $fields->{ lc $key } )
+            || ( defined $format && $format eq 'l' )
+            || ( defined $val && $val ne '' ) )
+        {
             $key = "ContactInfo" if $key eq 'FreeformContactInfo';
             push @data, [ $key => $val ];
         }
diff --git a/share/html/REST/1.0/search/dhandler b/share/html/REST/1.0/search/dhandler
index e1ddb9b..417de01 100755
--- a/share/html/REST/1.0/search/dhandler
+++ b/share/html/REST/1.0/search/dhandler
@@ -47,10 +47,153 @@
 %# END BPS TAGGED BLOCK }}}
 %# REST/1.0/search/dhandler
 %#
+<%ARGS>
+$query
+$format => undef
+$orderby => undef
+$fields => undef
+</%ARGS>
 <%INIT>
-my $status = "500 Server Error";
-my $output = "Unsupported object type.";
-</%INIT>
-RT/<% $RT::VERSION %> <% $status %>
+my $type = $m->dhandler_arg;
+my ( $status, $output );
+
+if ( $type =~ /^(queue|user|group)$/i ) {
+    $status = "200 Ok";
+    $output = '';
+    my $type = lc $1;
+    my $class = 'RT::' . ucfirst $type . 's';
+    my $objects = $class->new( $session{CurrentUser} );
+
+    # Parse and validate any field specifications.
+    require RT::Interface::REST;
+    my $field = RT::Interface::REST->field_spec;
+    my ( %fields, @fields );
+    if ($fields) {
+        $format ||= "l";
+        unless ( $fields =~ /^(?:$field,)*$field$/ ) {
+            $status = "400 Bad Request";
+            $output = "Invalid field specification: $fields";
+            goto OUTPUT;
+        }
+        @fields = map lc, split /\s*,\s*/, $fields;
+        @fields{@fields} = ();
+        unless ( exists $fields{id} ) {
+            unshift @fields, "id";
+            $fields{id} = ();
+        }
+    }
+
+    $format ||= "s";
+    if ( $format !~ /^[isl]$/ ) {
+        $status = "400 Bad request";
+        $output = "Unknown listing format: $format. (Use i, s, or l.)\n";
+        goto OUTPUT;
+    }
+
+    if ($orderby) {
+        my ( $order, $field ) = $orderby =~ /^([\+\-])?(.+)/;
+        $order = $order && $order eq '-' ? 'DESC' : 'ASC';
+        $objects->OrderBy( FIELD => $field, ORDER => $order );
+    }
+
+    my ( $n, $s );
+    $n = 0;
+    my @output;
+
+    if ( defined $query && length $query ) {
+        require Text::ParseWords;
+        my ( $field, $op, $value ) = Text::ParseWords::shellwords($query);
+        if ( $op !~ /^(?:[!<>]?=|(NOT )?LIKE|STARTSWITH|ENDSWITH|MATCHES)$/i ) {
+            $status = "400 Bad Request";
+            $output = "Invalid operator specification: $op";
+            goto OUTPUT;
+        }
 
-<% $output |n %>
+        if ( $field && $op && defined $value ) {
+            $objects->Limit(
+                FIELD    => $field,
+                OPERATOR => uc $op,
+                VALUE    => $value
+            );
+        }
+        else {
+            $output = "Invalid query specification: $query";
+            goto OUTPUT;
+        }
+    }
+    else {
+        if ( $type eq 'queue' ) {
+            $objects->UnLimit;
+        }
+        elsif ( $type eq 'group' ) {
+            $objects->LimitToUserDefinedGroups;
+        }
+        elsif ( $type eq 'user' ) {
+            $objects->LimitToPrivileged;
+        }
+    }
+
+    while ( my $object = $objects->Next ) {
+        $n++;
+
+        my $id = $object->Id;
+        if ( $format eq "i" ) {
+            $output .= "$type/" . $id . "\n";
+        }
+        elsif ( $format eq "s" ) {
+            if ($fields) {
+                my $result = $m->comp(
+                    "/REST/1.0/Forms/$type/default",
+                    id     => $id,
+                    format => $format,
+                    fields => \%fields
+                );
+                my ( $notes, $order, $key_values, $errors ) = @$result;
+
+                # If it's the first time through, add our header
+                if ( $n == 1 ) {
+                    $output .= join( "\t", @$order ) . "\n";
+                }
+
+                # Cut off the annoying $type/ before the id;
+                $key_values->{'id'} = $id;
+                $output .= join(
+                    "\t",
+                    map {
+                        ref $key_values->{$_} eq 'ARRAY'
+                          ? join( ', ', @{ $key_values->{$_} } )
+                          : $key_values->{$_}
+                      } @$order
+                ) . "\n";
+            }
+            else {
+                $output .= $object->Id . ": " . $object->Name . "\n";
+            }
+        }
+        else {
+            my $d = $m->comp(
+                "/REST/1.0/Forms/$type/default",
+                id     => $id,
+                format => $format,
+                fields => \%fields
+            );
+            my ( $c, $o, $k, $e ) = @$d;
+            push @output, [ $c, $o, $k ];
+        }
+    }
+    if ( $n == 0 && $format ne "i" ) {
+        $output = "No matching results.\n";
+    }
+
+    $output = form_compose( \@output ) if @output;
+}
+else {
+    $status = "500 Server Error";
+    $output = "Unsupported object type.";
+    goto OUTPUT;
+}
+
+OUTPUT:
+$m->out("RT/". $RT::VERSION . " " . $status ."\n\n");
+$m->out($output );
+</%INIT>

commit b6782d08e8857b14c167c986c821158ed800fbc4
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Thu Jun 23 15:11:53 2011 +0800

    merge restful ticket search to dhandler to avoid replicated code

diff --git a/share/html/REST/1.0/search/dhandler b/share/html/REST/1.0/search/dhandler
index 417de01..0c524ee 100755
--- a/share/html/REST/1.0/search/dhandler
+++ b/share/html/REST/1.0/search/dhandler
@@ -57,7 +57,7 @@ $fields => undef
 my $type = $m->dhandler_arg;
 my ( $status, $output );
 
-if ( $type =~ /^(queue|user|group)$/i ) {
+if ( $type =~ /^(ticket|queue|user|group)$/i ) {
     $status = "200 Ok";
     $output = '';
     my $type = lc $1;
@@ -90,35 +90,43 @@ if ( $type =~ /^(queue|user|group)$/i ) {
         goto OUTPUT;
     }
 
-    if ($orderby) {
-        my ( $order, $field ) = $orderby =~ /^([\+\-])?(.+)/;
-        $order = $order && $order eq '-' ? 'DESC' : 'ASC';
-        $objects->OrderBy( FIELD => $field, ORDER => $order );
-    }
-
     my ( $n, $s );
     $n = 0;
     my @output;
 
     if ( defined $query && length $query ) {
-        require Text::ParseWords;
-        my ( $field, $op, $value ) = Text::ParseWords::shellwords($query);
-        if ( $op !~ /^(?:[!<>]?=|(NOT )?LIKE|STARTSWITH|ENDSWITH|MATCHES)$/i ) {
-            $status = "400 Bad Request";
-            $output = "Invalid operator specification: $op";
-            goto OUTPUT;
-        }
-
-        if ( $field && $op && defined $value ) {
-            $objects->Limit(
-                FIELD    => $field,
-                OPERATOR => uc $op,
-                VALUE    => $value
-            );
+        if ( $type eq 'ticket' ) {
+            my ( $n, $s );
+            eval { ( $n, $s ) = $objects->FromSQL($query); };
+            if ( $@ || $n == 0 ) {
+                $s ||= $@;
+                $status = "400 Bad request";
+                $output = "Invalid query: '$s'.\n";
+                goto OUTPUT;
+            }
         }
         else {
-            $output = "Invalid query specification: $query";
-            goto OUTPUT;
+            require Text::ParseWords;
+            my ( $field, $op, $value ) = Text::ParseWords::shellwords($query);
+            if ( $op !~
+                /^(?:[!<>]?=|(NOT )?LIKE|STARTSWITH|ENDSWITH|MATCHES)$/i )
+            {
+                $status = "400 Bad Request";
+                $output = "Invalid operator specification: $op";
+                goto OUTPUT;
+            }
+
+            if ( $field && $op && defined $value ) {
+                $objects->Limit(
+                    FIELD    => $field,
+                    OPERATOR => uc $op,
+                    VALUE    => $value
+                );
+            }
+            else {
+                $output = "Invalid query specification: $query";
+                goto OUTPUT;
+            }
         }
     }
     else {
@@ -133,6 +141,12 @@ if ( $type =~ /^(queue|user|group)$/i ) {
         }
     }
 
+    if ($orderby) {
+        my ( $order, $field ) = $orderby =~ /^([\+\-])?(.+)/;
+        $order = $order && $order eq '-' ? 'DESC' : 'ASC';
+        $objects->OrderBy( FIELD => $field, ORDER => $order );
+    }
+
     while ( my $object = $objects->Next ) {
         $n++;
 
@@ -167,7 +181,12 @@ if ( $type =~ /^(queue|user|group)$/i ) {
                 ) . "\n";
             }
             else {
-                $output .= $object->Id . ": " . $object->Name . "\n";
+                if ( $type eq 'ticket' ) {
+                    $output .= $object->Id . ": " . $object->Subject . "\n";
+                }
+                else {
+                    $output .= $object->Id . ": " . $object->Name . "\n";
+                }
             }
         }
         else {
diff --git a/share/html/REST/1.0/search/ticket b/share/html/REST/1.0/search/ticket
deleted file mode 100755
index 16c6c6a..0000000
--- a/share/html/REST/1.0/search/ticket
+++ /dev/null
@@ -1,165 +0,0 @@
-%# 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 }}}
-%# REST/1.0/search/ticket
-%#
-<%ARGS>
-$query
-$format => undef
-$orderby => undef
-$fields => undef
-</%ARGS>
-<%INIT>
-use RT::Interface::REST;
-my $output = "";
-my $status = "200 Ok";
-my $tickets = RT::Tickets->new($session{CurrentUser});
-
-# Parse and validate any field specifications.
-my $field  = RT::Interface::REST->field_spec;
-my (%fields, @fields);
-if ($fields) {
-    $format ||= "l";
-    unless ($fields =~ /^(?:$field,)*$field$/) {
-        $status = "400 Bad Request";
-        $output = "Invalid field specification: $fields";
-        goto OUTPUT;
-    }
-    @fields = map lc, split /\s*,\s*/, $fields;
-    @fields{@fields} = ();
-    unless (exists $fields{id}) {
-        unshift @fields, "id";
-        $fields{id} = ();
-    }
-}
-
-$format ||= "s";
-if ($format !~ /^[isl]$/) {
-    $status = "400 Bad request";
-    $output = "Unknown listing format: $format. (Use i, s, or l.)\n";
-    goto OUTPUT;
-}
-
-my ($n, $s);
-eval {
-    ($n, $s) = $tickets->FromSQL($query);
-};
-
-if ($orderby) {
-    my %args;
-
-    my $order = substr($orderby, 0, 1);
-    if ($order eq '+' || $order eq '-') {
-        # remove the +/- sorting sigil
-        substr($orderby, 0, 1, '');
-
-        if ($order eq '+') {
-            $args{ORDER} = 'ASC';
-        }
-        elsif ($order eq '-') {
-            $args{ORDER} = 'DESC';
-        }
-    }
-
-    $tickets->OrderBy(
-        FIELD => $orderby,
-        %args,
-    );
-}
-
-if ($@ || $n == 0) {
-    $s ||= $@;
-    $status = "400 Bad request";
-    $output = "Invalid query: '$s'.\n";
-    goto OUTPUT;
-}
-
-$n = 0;
-my @output;
-while (my $ticket = $tickets->Next) {
-    $n++;
-
-	my $id = $ticket->Id;
-    if ($format eq "i") {
-        $output .= "ticket/" . $id . "\n";
-    }
-    elsif ($format eq "s") {
-	if ($fields) {
-        	my $result = $m->comp("/REST/1.0/Forms/ticket/default", id => $id, format => $format, fields => \%fields);
-		my ($notes, $order, $key_values, $errors) = @$result;
-		# If it's the first time through, add our header
-		if ($n == 1) {
-			$output .= join("\t",@$order)."\n";
-		}
-		# Cut off the annoying ticket/ before the id;
-		$key_values->{'id'} = $id;
-		$output .= join("\t", map { ref $key_values->{$_} eq 'ARRAY' ?
-join( ', ', @{$key_values->{$_}} ) : $key_values->{$_} } @$order)."\n";
-
-
-	} else {
-        	$output .= $ticket->Id . ": ". $ticket->Subject . "\n";
-	}
-    }
-    else {
-        my $d = $m->comp("/REST/1.0/Forms/ticket/default", id => $id, format => $format, fields => \%fields);
-        my ($c, $o, $k, $e) = @$d;
-	push @output, [ $c, $o, $k ];
-    }
-}
-if ($n == 0 && $format ne "i") {
-    $output = "No matching results.\n";
-}
-
-$output = form_compose(\@output) if @output;
-
-OUTPUT:
-$m->out("RT/". $RT::VERSION . " " . $status ."\n\n");
-
-$m->out($output );
-return();
-</%INIT>

commit 6e9456802e02d8d6c9f1481326d3187c14d1bd40
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Fri Jun 24 12:13:36 2011 +0800

    clean some replicated code

diff --git a/share/html/REST/1.0/Forms/group/default b/share/html/REST/1.0/Forms/group/default
index ca08b3d..a71ed8f 100644
--- a/share/html/REST/1.0/Forms/group/default
+++ b/share/html/REST/1.0/Forms/group/default
@@ -59,14 +59,9 @@ my ($c, $o, $k, $e) = ("", [], {}, 0);
 my %data = %$changes;
 my $group = RT::Group->new($session{CurrentUser});
 
-my @fields;
+my @fields = qw(Name Description);
 if ( $fields && %$fields ) {
-    @fields =
-      grep { exists $fields->{ lc $_ } }
-      qw(Name Description);
-}
-else {
-    @fields = qw(Name Description);
+    @fields = grep { exists $fields->{ lc $_ } } @fields;
 }
 
 my %fields = map { lc $_ => $_ } @fields;
diff --git a/share/html/REST/1.0/Forms/queue/default b/share/html/REST/1.0/Forms/queue/default
index 9f02db2..393962d 100755
--- a/share/html/REST/1.0/Forms/queue/default
+++ b/share/html/REST/1.0/Forms/queue/default
@@ -59,16 +59,12 @@ my ($c, $o, $k, $e) = ("", [], {}, 0);
 my %data = %$changes;
 my $queue = RT::Queue->new($session{CurrentUser});
 
-my @fields;
+my @fields =
+  qw(Name Description CorrespondAddress CommentAddress InitialPriority FinalPriority DefaultDueIn);
 if ( $fields && %$fields ) {
-    @fields =
-      grep { exists $fields->{ lc $_ } }
-      qw(Name Description CorrespondAddress CommentAddress InitialPriority FinalPriority DefaultDueIn);
-}
-else {
-    @fields = qw(Name Description CorrespondAddress CommentAddress
-                InitialPriority FinalPriority DefaultDueIn);
+    @fields = grep { exists $fields->{ lc $_ } } @fields;
 }
+
 my %fields = map { lc $_ => $_ } @fields;
 
 if ($id ne 'new') {
diff --git a/share/html/REST/1.0/Forms/user/default b/share/html/REST/1.0/Forms/user/default
index 87c2bce..01ef531 100755
--- a/share/html/REST/1.0/Forms/user/default
+++ b/share/html/REST/1.0/Forms/user/default
@@ -59,23 +59,15 @@ my ($c, $o, $k, $e) = ("", [], {}, 0);
 my %data = %$changes;
 my $user = RT::User->new($session{CurrentUser});
 
-my @fields;
+my @fields =
+  qw(Name EmailAddress RealName NickName Gecos Organization Address1
+  Address2 City State Zip Country HomePhone WorkPhone MobilePhone PagerPhone
+  FreeformContactInfo Comments Signature Lang EmailEncoding
+  WebEncoding ExternalContactInfoId ContactInfoSystem
+  ExternalAuthId AuthSystem Privileged Disabled);
+
 if ( $fields && %$fields ) {
-    @fields =
-      grep { exists $fields->{ lc $_ } }
-      qw(Name EmailAddress RealName NickName Gecos Organization Address1
-      Address2 City State Zip Country HomePhone WorkPhone MobilePhone PagerPhone
-      FreeformContactInfo Comments Signature Lang EmailEncoding
-      WebEncoding ExternalContactInfoId ContactInfoSystem
-      ExternalAuthId AuthSystem Privileged Disabled);
-}
-else {
-    @fields =
-      qw(Name EmailAddress RealName NickName Gecos Organization Address1
-      Address2 City State Zip Country HomePhone WorkPhone MobilePhone PagerPhone
-      FreeformContactInfo Comments Signature Lang EmailEncoding
-      WebEncoding ExternalContactInfoId ContactInfoSystem
-      ExternalAuthId AuthSystem Privileged Disabled);
+  @fields = grep { exists $fields->{ lc $_ } } @fields;
 }
 
 my %fields = map { lc $_ => $_ } @fields;

commit 2ef89d22587def82aa6ff1b2862c9ba5845647cc
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Fri Jun 24 12:30:02 2011 +0800

    shouldn't allow user to search password field

diff --git a/share/html/REST/1.0/search/dhandler b/share/html/REST/1.0/search/dhandler
index 0c524ee..9cdbac7 100755
--- a/share/html/REST/1.0/search/dhandler
+++ b/share/html/REST/1.0/search/dhandler
@@ -117,6 +117,12 @@ if ( $type =~ /^(ticket|queue|user|group)$/i ) {
             }
 
             if ( $field && $op && defined $value ) {
+                if ( $type eq 'user' && $field =~ /password/i ) {
+                    $status = "400 Bad Request";
+                    $output = "Invalid field specification: $field";
+                    goto OUTPUT;
+                }
+
                 $objects->Limit(
                     FIELD    => $field,
                     OPERATOR => uc $op,

commit b858f5b05ea3094b4c9fa62a2b1b5ecb2639b20a
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Fri Jun 24 12:44:04 2011 +0800

    allow restful user search only if current user has AdminUsers right
    
    user data is sensible and shouldn't be seen easily.
    besides, we don't have SeeUser right either.

diff --git a/share/html/REST/1.0/search/dhandler b/share/html/REST/1.0/search/dhandler
index 9cdbac7..b454471 100755
--- a/share/html/REST/1.0/search/dhandler
+++ b/share/html/REST/1.0/search/dhandler
@@ -61,6 +61,21 @@ if ( $type =~ /^(ticket|queue|user|group)$/i ) {
     $status = "200 Ok";
     $output = '';
     my $type = lc $1;
+
+    if (
+        $type eq 'user'
+        && !$session{CurrentUser}->HasRight(
+            Object => $RT::System,
+            Right  => 'AdminUsers',
+        )
+      )
+    {
+
+        $status = "403 Forbidden";
+        $output = "Permission denied";
+        goto OUTPUT;
+    }
+
     my $class = 'RT::' . ucfirst $type . 's';
     my $objects = $class->new( $session{CurrentUser} );
 

commit a19ec9dc08667f8669431c04e5173ad60957dec3
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Sat Jun 25 15:28:54 2011 +0800

    search user defined groups only

diff --git a/share/html/REST/1.0/search/dhandler b/share/html/REST/1.0/search/dhandler
index b454471..c99aeea 100755
--- a/share/html/REST/1.0/search/dhandler
+++ b/share/html/REST/1.0/search/dhandler
@@ -109,6 +109,11 @@ if ( $type =~ /^(ticket|queue|user|group)$/i ) {
     $n = 0;
     my @output;
 
+
+    if ( $type eq 'group' ) {
+        $objects->LimitToUserDefinedGroups;
+    }
+
     if ( defined $query && length $query ) {
         if ( $type eq 'ticket' ) {
             my ( $n, $s );
@@ -154,9 +159,6 @@ if ( $type =~ /^(ticket|queue|user|group)$/i ) {
         if ( $type eq 'queue' ) {
             $objects->UnLimit;
         }
-        elsif ( $type eq 'group' ) {
-            $objects->LimitToUserDefinedGroups;
-        }
         elsif ( $type eq 'user' ) {
             $objects->LimitToPrivileged;
         }

commit fd12f69a80081d546a41f1ca4963d3d43f2c2acc
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Tue Jun 28 22:29:15 2011 +0800

    whitelist of restful search fields
    
    this is better than only blacklisting hardcoded "password"

diff --git a/share/html/REST/1.0/search/dhandler b/share/html/REST/1.0/search/dhandler
index c99aeea..9178b8f 100755
--- a/share/html/REST/1.0/search/dhandler
+++ b/share/html/REST/1.0/search/dhandler
@@ -136,12 +136,14 @@ if ( $type =~ /^(ticket|queue|user|group)$/i ) {
                 goto OUTPUT;
             }
 
+            if ( ! $search_whitelist{$type}{lc $field} ) {
+                $status = "400 Bad Request";
+                $output = "Invalid field specification: $field";
+                goto OUTPUT;
+            }
+
+
             if ( $field && $op && defined $value ) {
-                if ( $type eq 'user' && $field =~ /password/i ) {
-                    $status = "400 Bad Request";
-                    $output = "Invalid field specification: $field";
-                    goto OUTPUT;
-                }
 
                 $objects->Limit(
                     FIELD    => $field,
@@ -239,3 +241,25 @@ OUTPUT:
 $m->out("RT/". $RT::VERSION . " " . $status ."\n\n");
 $m->out($output );
 </%INIT>
+
+<%ONCE>
+my %search_whitelist = (
+    queue => {
+        map { lc $_ => 1 }
+          grep { $RT::Record::_TABLE_ATTR->{'RT::Queue'}{$_}{read} }
+          keys %{ $RT::Record::_TABLE_ATTR->{'RT::Queue'} }
+    },
+    user => {
+        map { lc $_ => 1 }
+          grep { $RT::Record::_TABLE_ATTR->{'RT::User'}{$_}{read} }
+          keys %{ $RT::Record::_TABLE_ATTR->{'RT::User'} }
+    },
+    group => {
+        map { lc $_ => 1 }
+          grep { $RT::Record::_TABLE_ATTR->{'RT::Group'}{$_}{read} }
+          keys %{ $RT::Record::_TABLE_ATTR->{'RT::Group'} }
+    }
+);
+
+</%ONCE>
+

commit 99572eb685274a138dbbb1ecb29f8c3d0a295694
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Mon Jul 4 18:52:27 2011 +0800

    allow < and > ops too

diff --git a/share/html/REST/1.0/search/dhandler b/share/html/REST/1.0/search/dhandler
index 9178b8f..8ce8497 100755
--- a/share/html/REST/1.0/search/dhandler
+++ b/share/html/REST/1.0/search/dhandler
@@ -129,7 +129,7 @@ if ( $type =~ /^(ticket|queue|user|group)$/i ) {
             require Text::ParseWords;
             my ( $field, $op, $value ) = Text::ParseWords::shellwords($query);
             if ( $op !~
-                /^(?:[!<>]?=|(NOT )?LIKE|STARTSWITH|ENDSWITH|MATCHES)$/i )
+                /^(?:[!<>]?=|[<>]|(NOT )?LIKE|STARTSWITH|ENDSWITH|MATCHES)$/i )
             {
                 $status = "400 Bad Request";
                 $output = "Invalid operator specification: $op";

commit a6fd969fdb1967d03709e317e15d83c782f467af
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Mon Jul 4 20:19:26 2011 +0800

    tests for restful search of queue/group/user

diff --git a/t/web/rest-search-group.t b/t/web/rest-search-group.t
new file mode 100644
index 0000000..a5bc4e6
--- /dev/null
+++ b/t/web/rest-search-group.t
@@ -0,0 +1,85 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use RT::Test tests => 18;
+
+my $group_foo = RT::Group->new($RT::SystemUser);
+$group_foo->CreateUserDefinedGroup( Name => 'foo' );
+
+my $group_bar = RT::Group->new($RT::SystemUser);
+$group_bar->CreateUserDefinedGroup( Name => 'bar' );
+
+my ( $baseurl, $m ) = RT::Test->started_ok;
+
+ok( $m->login, 'logged in' );
+
+search_groups_ok(
+    { query => 'id = ' . $group_foo->id },
+    [ $group_foo->id . ': foo' ],
+    'search by id'
+);
+
+search_groups_ok(
+    {
+        query  => 'Name = ' . $group_foo->Name,
+        format => 's',
+        fields => 'id,name',
+    },
+    [ "id\tName", $group_foo->id . "\tfoo" ],
+    'search by name with customized fields'
+);
+
+search_groups_ok(
+    { query => 'foo = 3' },
+    ['Invalid field specification: foo'],
+    'invalid field'
+);
+
+search_groups_ok(
+    { query => 'id foo 3' },
+    ['Invalid operator specification: foo'],
+    'invalid op'
+);
+
+search_groups_ok(
+    { query => '', orderby => 'id' },
+    [ $group_foo->id . ': foo', $group_bar->id . ': bar', ],
+    'order by id'
+);
+
+search_groups_ok(
+    { query => '', orderby => 'name' },
+    [ $group_bar->id . ': bar', $group_foo->id . ': foo' ],
+    'order by name'
+);
+
+search_groups_ok(
+    { query => '', orderby => '+name' },
+    [ $group_bar->id . ': bar', $group_foo->id . ': foo' ],
+    'order by +name'
+);
+
+search_groups_ok(
+    { query => '', orderby => '-name' },
+    [ $group_foo->id . ': foo', $group_bar->id . ': bar' ],
+    'order by -name'
+);
+
+sub search_groups_ok {
+    local $Test::Builder::Level = $Test::Builder::Level + 1;
+    my $query    = shift;
+    my $expected = shift;
+    my $name     = shift || 'search groups';
+
+    my $uri = URI->new("$baseurl/REST/1.0/search/group");
+    $uri->query_form(%$query);
+    $m->get_ok($uri);
+
+    my @lines = split /\n/, $m->content;
+    shift @lines;    # header
+    shift @lines;    # empty line
+
+    is_deeply( \@lines, $expected, $name );
+
+}
+
diff --git a/t/web/rest-search-queue.t b/t/web/rest-search-queue.t
new file mode 100644
index 0000000..e9701ad
--- /dev/null
+++ b/t/web/rest-search-queue.t
@@ -0,0 +1,83 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use RT::Test tests => 20;
+
+my $queue_foo = RT::Test->load_or_create_queue( Name => 'foo' );
+my $queue_bar = RT::Test->load_or_create_queue( Name => 'bar' );
+
+my ( $baseurl, $m ) = RT::Test->started_ok;
+
+ok( $m->login, 'logged in' );
+
+search_queues_ok( { query => 'id = 1' }, ['1: General'], 'search id = 1' );
+search_queues_ok(
+    {
+        query  => 'Name = General',
+        format => 's',
+        fields => 'id,name,description'
+    },
+    [ "id\tName\tDescription", "1\tGeneral\tThe default queue" ],
+    'search by name with customized fields'
+);
+
+search_queues_ok(
+    { query => 'id > 10' },
+    ['No matching results.'],
+    'no matching results'
+);
+
+search_queues_ok(
+    { query => 'foo = 3' },
+    ['Invalid field specification: foo'],
+    'invalid field'
+);
+
+search_queues_ok(
+    { query => 'id foo 3' },
+    ['Invalid operator specification: foo'],
+    'invalid op'
+);
+
+search_queues_ok(
+    { query => '', orderby => 'id' },
+    [ '1: General', $queue_foo->id . ': foo', $queue_bar->id . ': bar', ],
+    'order by id'
+);
+
+search_queues_ok(
+    { query => '', orderby => 'name' },
+    [ '1: General', $queue_bar->id . ': bar', $queue_foo->id . ': foo' ],
+    'order by name'
+);
+
+search_queues_ok(
+    { query => '', orderby => '+name' },
+    [ '1: General', $queue_bar->id . ': bar', $queue_foo->id . ': foo' ],
+    'order by +name'
+);
+
+search_queues_ok(
+    { query => '', orderby => '-name' },
+    [ $queue_foo->id . ': foo', $queue_bar->id . ': bar', '1: General', ],
+    'order by -name'
+);
+
+sub search_queues_ok {
+    local $Test::Builder::Level = $Test::Builder::Level + 1;
+    my $query    = shift;
+    my $expected = shift;
+    my $name     = shift || 'search queues';
+
+    my $uri = URI->new("$baseurl/REST/1.0/search/queue");
+    $uri->query_form(%$query);
+    $m->get_ok($uri);
+
+    my @lines = split /\n/, $m->content;
+    shift @lines;    # header
+    shift @lines;    # empty line
+
+    is_deeply( \@lines, $expected, $name );
+
+}
+
diff --git a/t/web/rest-search-user.t b/t/web/rest-search-user.t
new file mode 100644
index 0000000..e633aa3
--- /dev/null
+++ b/t/web/rest-search-user.t
@@ -0,0 +1,100 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use RT::Test tests => 23;
+
+my $root = RT::Test->load_or_create_user( Name => 'root', );
+my $user_foo = RT::Test->load_or_create_user(
+    Name     => 'foo',
+    Password => 'password',
+);
+my $user_bar = RT::Test->load_or_create_user( Name => 'bar' );
+
+my ( $baseurl, $m ) = RT::Test->started_ok;
+
+ok( $m->login, 'logged in' );
+
+search_users_ok(
+    { query => 'id = ' . $user_foo->id },
+    [ $user_foo->id . ': foo' ],
+    'search by id'
+);
+
+search_users_ok(
+    {
+        query  => 'Name = ' . $user_foo->Name,
+        format => 's',
+        fields => 'id,name'
+    },
+    [ "id\tName", $user_foo->id . "\tfoo" ],
+    'search by name with customized fields'
+);
+
+
+search_users_ok(
+    { query => 'foo = 3' },
+    ['Invalid field specification: foo'],
+    'invalid field'
+);
+
+search_users_ok(
+    { query => 'id foo 3' },
+    ['Invalid operator specification: foo'],
+    'invalid op'
+);
+
+search_users_ok(
+    { query => 'password = foo' },
+    ['Invalid field specification: password'],
+    "can't search password"
+);
+
+search_users_ok(
+    { query => '', orderby => 'id' },
+    [ $root->id . ': root', $user_foo->id . ': foo', $user_bar->id . ': bar', ],
+    'order by id'
+);
+
+search_users_ok(
+    { query => '', orderby => 'name' },
+    [ $user_bar->id . ': bar', $user_foo->id . ': foo', $root->id . ': root' ],
+    'order by name'
+);
+
+search_users_ok(
+    { query => '', orderby => '+name' },
+    [ $user_bar->id . ': bar', $user_foo->id . ': foo', $root->id . ': root' ],
+    'order by +name'
+);
+
+search_users_ok(
+    { query => '', orderby => '-name' },
+    [ $root->id . ': root', $user_foo->id . ': foo', $user_bar->id . ': bar' ],
+    'order by -name'
+);
+
+ok( $m->login( 'foo', 'password', logout => 1 ), 'logged in as foo' );
+search_users_ok(
+    { query => 'id = ' . $user_foo->id },
+    [ 'Permission denied' ],
+    "can't search without permission"
+);
+
+sub search_users_ok {
+    local $Test::Builder::Level = $Test::Builder::Level + 1;
+    my $query    = shift;
+    my $expected = shift;
+    my $name     = shift || 'search users';
+
+    my $uri = URI->new("$baseurl/REST/1.0/search/user");
+    $uri->query_form(%$query);
+    $m->get_ok($uri);
+
+    my @lines = split /\n/, $m->content;
+    shift @lines;    # header
+    shift @lines;    # empty line
+
+    is_deeply( \@lines, $expected, $name );
+
+}
+

commit 02fad4466852497d6008e3471fe54dab88a9a56a
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Wed Jun 13 08:41:32 2012 +0800

    REST: show Disabled column for queues/groups

diff --git a/share/html/REST/1.0/Forms/group/default b/share/html/REST/1.0/Forms/group/default
index a71ed8f..3b966e9 100644
--- a/share/html/REST/1.0/Forms/group/default
+++ b/share/html/REST/1.0/Forms/group/default
@@ -59,7 +59,7 @@ my ($c, $o, $k, $e) = ("", [], {}, 0);
 my %data = %$changes;
 my $group = RT::Group->new($session{CurrentUser});
 
-my @fields = qw(Name Description);
+my @fields = qw(Name Description Disabled);
 if ( $fields && %$fields ) {
     @fields = grep { exists $fields->{ lc $_ } } @fields;
 }
diff --git a/share/html/REST/1.0/Forms/queue/default b/share/html/REST/1.0/Forms/queue/default
index 393962d..5691af5 100755
--- a/share/html/REST/1.0/Forms/queue/default
+++ b/share/html/REST/1.0/Forms/queue/default
@@ -60,7 +60,7 @@ my %data = %$changes;
 my $queue = RT::Queue->new($session{CurrentUser});
 
 my @fields =
-  qw(Name Description CorrespondAddress CommentAddress InitialPriority FinalPriority DefaultDueIn);
+  qw(Name Description CorrespondAddress CommentAddress InitialPriority FinalPriority DefaultDueIn Disabled);
 if ( $fields && %$fields ) {
     @fields = grep { exists $fields->{ lc $_ } } @fields;
 }

commit 9da2fcd775a050da7b4a17a6b33ba341cc630357
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Wed Jun 13 09:41:37 2012 +0800

    REST: handle Disabled column search for queues/groups/users

diff --git a/share/html/REST/1.0/search/dhandler b/share/html/REST/1.0/search/dhandler
index 8ce8497..9db6666 100755
--- a/share/html/REST/1.0/search/dhandler
+++ b/share/html/REST/1.0/search/dhandler
@@ -144,12 +144,28 @@ if ( $type =~ /^(ticket|queue|user|group)$/i ) {
 
 
             if ( $field && $op && defined $value ) {
+                if ( $field eq 'Disabled' ) {
+                    if ($value) {
+                        $objects->FindAllRows;
+                        if ( $type eq 'queue' ) {
 
-                $objects->Limit(
-                    FIELD    => $field,
-                    OPERATOR => uc $op,
-                    VALUE    => $value
-                );
+                            # special case for queue that
+                            # Disabled could be 2(___Approvals)
+                            $objects->Limit(
+                                FIELD    => $field,
+                                OPERATOR => uc $op,
+                                VALUE    => $value
+                            );
+                        }
+                    }
+                }
+                else {
+                    $objects->Limit(
+                        FIELD    => $field,
+                        OPERATOR => uc $op,
+                        VALUE    => $value
+                    );
+                }
             }
             else {
                 $output = "Invalid query specification: $query";
@@ -250,11 +266,13 @@ my %search_whitelist = (
           keys %{ $RT::Record::_TABLE_ATTR->{'RT::Queue'} }
     },
     user => {
+        disabled => 1,
         map { lc $_ => 1 }
           grep { $RT::Record::_TABLE_ATTR->{'RT::User'}{$_}{read} }
           keys %{ $RT::Record::_TABLE_ATTR->{'RT::User'} }
     },
     group => {
+        disabled => 1,
         map { lc $_ => 1 }
           grep { $RT::Record::_TABLE_ATTR->{'RT::Group'}{$_}{read} }
           keys %{ $RT::Record::_TABLE_ATTR->{'RT::Group'} }

commit 8ade2ed3bfdabc395d01a0ea18e0012093cfa84d
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Wed Jun 13 22:07:29 2012 +0800

    test number fix

diff --git a/t/web/rest-search-group.t b/t/web/rest-search-group.t
index a5bc4e6..c5f9d4a 100644
--- a/t/web/rest-search-group.t
+++ b/t/web/rest-search-group.t
@@ -1,7 +1,7 @@
 #!/usr/bin/env perl
 use strict;
 use warnings;
-use RT::Test tests => 18;
+use RT::Test tests => 20;
 
 my $group_foo = RT::Group->new($RT::SystemUser);
 $group_foo->CreateUserDefinedGroup( Name => 'foo' );
diff --git a/t/web/rest-search-queue.t b/t/web/rest-search-queue.t
index e9701ad..649912f 100644
--- a/t/web/rest-search-queue.t
+++ b/t/web/rest-search-queue.t
@@ -1,7 +1,7 @@
 #!/usr/bin/env perl
 use strict;
 use warnings;
-use RT::Test tests => 20;
+use RT::Test tests => 22;
 
 my $queue_foo = RT::Test->load_or_create_queue( Name => 'foo' );
 my $queue_bar = RT::Test->load_or_create_queue( Name => 'bar' );
diff --git a/t/web/rest-search-user.t b/t/web/rest-search-user.t
index e633aa3..b6b11ca 100644
--- a/t/web/rest-search-user.t
+++ b/t/web/rest-search-user.t
@@ -1,7 +1,7 @@
 #!/usr/bin/env perl
 use strict;
 use warnings;
-use RT::Test tests => 23;
+use RT::Test tests => 25;
 
 my $root = RT::Test->load_or_create_user( Name => 'root', );
 my $user_foo = RT::Test->load_or_create_user(

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


More information about the Rt-commit mailing list