[Bps-public-commit] rt-extension-rest2 branch, tickets-bulk, created. 1.01-3-ga5e832f

? sunnavy sunnavy at bestpractical.com
Tue Feb 27 16:23:29 EST 2018


The branch, tickets-bulk has been created
        at  a5e832fca39271040533db348ac71cf12a1a481e (commit)

- Log -----------------------------------------------------------------
commit d550f87d3237ddaf168a79f80a454fab4bb159f3
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Wed Feb 28 03:46:39 2018 +0800

    don't touch http response in update_record
    
    It's more consistent to handle http response in update_resource just
    like create_resource. And it's also easier to reuse update_record.

diff --git a/lib/RT/Extension/REST2/Resource/Record/Writable.pm b/lib/RT/Extension/REST2/Resource/Record/Writable.pm
index e0d1128..490e2be 100644
--- a/lib/RT/Extension/REST2/Resource/Record/Writable.pm
+++ b/lib/RT/Extension/REST2/Resource/Record/Writable.pm
@@ -57,8 +57,7 @@ sub update_record {
 
     # XXX TODO: Figure out how to return success/failure?  Core RT::Record's
     # ->Update will need to be replaced or improved.
-    $self->response->body( JSON::encode_json(\@results) );
-    return;
+    return @results;
 }
 
 sub _update_custom_fields {
@@ -259,7 +258,9 @@ sub update_resource {
             \404, "Resource does not exist; use POST to create");
     }
 
-    return $self->update_record($data);
+    my @results = $self->update_record($data);
+    $self->response->body( JSON::encode_json(\@results) );
+    return;
 }
 
 sub create_record {

commit 8859c4ea2ed83f49ff3f52a369ffb0669c8e29be
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Wed Feb 28 03:55:03 2018 +0800

    implement /tickets/bulk for bulk create/update

diff --git a/lib/RT/Extension/REST2/Resource/TicketsBulk.pm b/lib/RT/Extension/REST2/Resource/TicketsBulk.pm
new file mode 100644
index 0000000..c9f1f2a
--- /dev/null
+++ b/lib/RT/Extension/REST2/Resource/TicketsBulk.pm
@@ -0,0 +1,76 @@
+package RT::Extension::REST2::Resource::TicketsBulk;
+use strict;
+use warnings;
+
+use Moose;
+use namespace::autoclean;
+
+extends 'RT::Extension::REST2::Resource';
+with 'RT::Extension::REST2::Resource::Role::RequestBodyIsJSON' =>
+  { type => 'ARRAY' };
+
+use RT::Extension::REST2::Util qw(expand_uid);
+use RT::Extension::REST2::Resource::Ticket;
+use JSON ();
+
+sub dispatch_rules {
+    Path::Dispatcher::Rule::Regex->new( regex => qr{^/tickets/bulk/?$} );
+}
+
+sub post_is_create    { 1 }
+sub create_path       { '/tickets/bulk' }
+sub charsets_provided { [ 'utf-8' ] }
+sub default_charset   { 'utf-8' }
+sub allowed_methods   { [ 'PUT', 'POST' ] }
+
+sub content_types_provided { [ { 'application/json' => sub {} } ] }
+sub content_types_accepted { [ { 'application/json' => 'from_json' } ] }
+
+sub from_json {
+    my $self   = shift;
+    my $params = JSON::decode_json( $self->request->content );
+
+    my $method = $self->request->method;
+    my @results;
+    if ( $method eq 'PUT' ) {
+        for my $param ( @$params ) {
+            my $id = delete $param->{id};
+            if ( $id && $id =~ /^\d+$/ ) {
+                my $resource = RT::Extension::REST2::Resource::Ticket->new(
+                    request      => $self->request,
+                    response     => $self->response,
+                    record_class => 'RT::Ticket',
+                    record_id    => $id,
+                );
+                if ( $resource->resource_exists ) {
+                    push @results, [ $id, $resource->update_record( $param ) ];
+                    next;
+                }
+            }
+            push @results, [ $id, 'Resource does not exist' ];
+        }
+    }
+    else {
+        for my $param ( @$params ) {
+            my $resource = RT::Extension::REST2::Resource::Ticket->new(
+                request      => $self->request,
+                response     => $self->response,
+                record_class => 'RT::Ticket',
+            );
+            my ( $ok, $msg ) = $resource->create_record( $param );
+            if ( ref( $ok ) || !$ok ) {
+                push @results, { message => $msg || "Create failed for unknown reason" };
+            }
+            else {
+                push @results, expand_uid( $resource->record->UID );
+            }
+        }
+    }
+
+    $self->response->body( JSON::encode_json( \@results ) );
+    return;
+}
+
+__PACKAGE__->meta->make_immutable;
+
+1;

commit a5e832fca39271040533db348ac71cf12a1a481e
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Wed Feb 28 05:17:47 2018 +0800

    tests for /tickets/bulk

diff --git a/t/tickets-bulk.t b/t/tickets-bulk.t
new file mode 100644
index 0000000..a3ecbed
--- /dev/null
+++ b/t/tickets-bulk.t
@@ -0,0 +1,190 @@
+use strict;
+use warnings;
+use lib 't/lib';
+use RT::Extension::REST2::Test tests => undef;
+use Test::Deep;
+
+my $mech = RT::Extension::REST2::Test->mech;
+
+my $auth           = RT::Extension::REST2::Test->authorization_header;
+my $rest_base_path = '/REST/2.0';
+my $user           = RT::Extension::REST2::Test->user;
+my $base_url       = RT::Extension::REST2->base_uri;
+
+my $queue = RT::Test->load_or_create_queue( Name => "General" );
+
+my @ticket_ids;
+
+{
+    my $res = $mech->post_json(
+        "$rest_base_path/tickets/bulk",
+        { Queue => "General", Subject => "test" },
+        'Authorization' => $auth,
+    );
+    is( $res->code, 400 );
+    is( $mech->json_response->{message}, "JSON object must be a ARRAY", 'hash is not allowed' );
+
+    diag "no CreateTicket right";
+
+    $res = $mech->post_json(
+        "$rest_base_path/tickets/bulk",
+        [ { Queue => "General", Subject => "test" } ],
+        'Authorization' => $auth,
+    );
+    is( $res->code, 201, "bulk returns 201 for POST even no tickets created" );
+    is_deeply(
+        $mech->json_response,
+        [
+            {
+                message => "No permission to create tickets in the queue 'General'"
+            }
+        ],
+        'permission denied'
+    );
+
+    diag "grant CreateTicket right";
+    $user->PrincipalObj->GrantRight( Right => 'CreateTicket' );
+
+    $res = $mech->post_json(
+        "$rest_base_path/tickets/bulk",
+        [ { Queue => "General", Subject => "test" } ],
+        'Authorization' => $auth,
+    );
+    is( $res->code, 201, 'status code' );
+    my $content = $mech->json_response;
+    is( scalar @$content, 1, 'array with 1 item' );
+    ok( $content->[ 0 ]{id}, 'found id' );
+    push @ticket_ids, $content->[ 0 ]{id};
+    is_deeply(
+        $content,
+        [
+            {
+                type   => 'ticket',
+                id     => $ticket_ids[ -1 ],
+                "_url" => "$base_url/ticket/$ticket_ids[-1]",
+            }
+        ],
+        'json response content',
+    );
+
+    $res = $mech->post_json(
+        "$rest_base_path/tickets/bulk",
+        [ { Queue => 'General', Subject => 'foo' }, { Queue => 'General', Subject => 'bar' } ],
+        'Authorization' => $auth,
+    );
+    is( $res->code, 201, 'status code' );
+    $content = $mech->json_response;
+    is( scalar @$content, 2, 'array with 2 items' );
+    push @ticket_ids, $_->{id} for @$content;
+    is_deeply(
+        $content,
+        [
+            {
+                type   => 'ticket',
+                id     => $ticket_ids[ -2 ],
+                "_url" => "$base_url/ticket/$ticket_ids[-2]",
+            },
+            {
+                type   => 'ticket',
+                id     => $ticket_ids[ -1 ],
+                "_url" => "$base_url/ticket/$ticket_ids[-1]",
+            },
+        ],
+        'json response content',
+    );
+
+    $res = $mech->post_json(
+        "$rest_base_path/tickets/bulk",
+        [ { Subject => 'foo' }, { Queue => 'General', Subject => 'baz' } ],
+        'Authorization' => $auth,
+    );
+    is( $res->code, 201, 'status code' );
+    $content = $mech->json_response;
+    is( scalar @$content, 2, 'array with 2 items' );
+
+    push @ticket_ids, $content->[ 1 ]{id};
+    is_deeply(
+        $content,
+        [
+            {
+                message => "Could not create ticket. Queue not set"
+            },
+            {
+                type   => 'ticket',
+                id     => $ticket_ids[ -1 ],
+                "_url" => "$base_url/ticket/$ticket_ids[-1]",
+            },
+        ],
+        'json response content',
+    );
+}
+
+{
+    diag "no ModifyTicket right";
+    my $res = $mech->put_json(
+        "$rest_base_path/tickets/bulk",
+        [ { id => $ticket_ids[ 0 ], Subject => 'foo' } ],
+        'Authorization' => $auth,
+    );
+    is( $res->code, 200, "bulk returns 200 for PUT" );
+    is_deeply( $mech->json_response, [ [ $ticket_ids[ 0 ], "Ticket 1: Permission Denied", ] ], 'permission denied' );
+
+    diag "grant ModifyTicket right";
+    $user->PrincipalObj->GrantRight( Right => 'ModifyTicket' );
+
+    $res = $mech->put_json(
+        "$rest_base_path/tickets/bulk",
+        [ { id => $ticket_ids[ 0 ], Subject => 'foo' } ],
+        'Authorization' => $auth,
+    );
+    is( $res->code, 200, 'status code' );
+    is_deeply(
+        $mech->json_response,
+        [ [ $ticket_ids[ 0 ], qq{Ticket 1: Subject changed from 'test' to 'foo'} ] ],
+        'json response content'
+    );
+
+    $res = $mech->put_json(
+        "$rest_base_path/tickets/bulk",
+        [ { id => $ticket_ids[ 0 ] }, { id => $ticket_ids[ 1 ], Subject => 'bar' }, ],
+        'Authorization' => $auth,
+    );
+    is( $res->code, 200, 'status code' );
+    is_deeply(
+        $mech->json_response,
+        [
+            [ $ticket_ids[ 0 ] ], [ $ticket_ids[ 1 ], qq{Ticket $ticket_ids[ 1 ]: Subject changed from 'foo' to 'bar'} ]
+        ],
+        'json response content'
+    );
+
+    $res = $mech->put_json(
+        "$rest_base_path/tickets/bulk",
+        [
+            { id => $ticket_ids[ 0 ], Subject => 'baz' },
+            { id => 'foo',            Subject => 'baz' },
+            { id => 999,              Subject => 'baz' },
+        ],
+        'Authorization' => $auth,
+    );
+    is( $res->code, 200, 'status code' );
+    is_deeply(
+        $mech->json_response,
+        [
+            [ $ticket_ids[ 0 ], qq{Ticket $ticket_ids[ 0 ]: Subject changed from 'foo' to 'baz'} ],
+            [ 'foo',            "Resource does not exist" ],
+            [ 999,              "Resource does not exist" ],
+        ],
+        'json response content'
+    );
+}
+
+{
+    for my $method ( qw/get head delete/ ) {
+        my $res = $mech->get( "$rest_base_path/tickets/bulk", 'Authorization' => $auth );
+        is( $res->code, 405, "tickets/bulk doesn't support " . uc $method );
+    }
+}
+
+done_testing;
+

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


More information about the Bps-public-commit mailing list