[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