[Rt-commit] rt branch, 5.0/rest2-support-attachments-when-creating-ticket, repushed
Dianne Skoll
dianne at bestpractical.com
Thu Oct 22 14:40:02 EDT 2020
The branch 5.0/rest2-support-attachments-when-creating-ticket was deleted and repushed:
was e4efdd1e67288f6152e9076530fdf3af6104c5c7
now 52a2fc0bb0e9062ca66362096b8c7ec7657ac3d3
1: e4efdd1e67 ! 1: 52a2fc0bb0 Allow attachments to be added when a ticket is created.
@@ -5,6 +5,34 @@
The attachments are supplied in an Attachments array, each element
of which is a three-element hash containing FileName, FileType and
FileContent members. FileContent is the base64-encoded content.
+
+ The ticket can also be created with a request content type of
+ multipart/form-data. In this case, attachments can be transmitted
+ as raw data rather than requiring base64-encoding.
+
+diff --git a/lib/RT/REST2.pm b/lib/RT/REST2.pm
+--- a/lib/RT/REST2.pm
++++ b/lib/RT/REST2.pm
+@@
+ (L<https://en.wikipedia.org/wiki/HTTP_ETag>). We'll first try updating this
+ ticket with an I<invalid> C<ETag> to see what happens.
+
++You can add attachments when you create a ticket. Simply add an "Attachments"
++entry in the JSON request content; the format of this entry is described
++in L<Add Attachments>
++
+ =head3 Updating Tickets
+
+ For updating tickets we use the C<PUT> verb, but otherwise it looks much
+@@
+ =head3 Add Attachments
+
+ You can attach any binary or text file to your response or comment by
+-specifying C<Attachements> property in the JSON object, which should be a
++specifying C<Attachments> property in the JSON object, which should be a
+ JSON array where each item represents a file you want to attach. Each item
+ is a JSON object with the following properties:
+
diff --git a/lib/RT/REST2/Resource/Ticket.pm b/lib/RT/REST2/Resource/Ticket.pm
--- a/lib/RT/REST2/Resource/Ticket.pm
@@ -33,6 +61,47 @@
my ($ok, $txn, $msg) = $self->_create_record($data);
return ($ok, $msg);
}
+@@
+ return $links;
+ }
+
++# Allow attachments to be added as parts to the multipart/form_data
++# upload
++sub from_multipart {
++ my $self = shift;
++ my $json_str = $self->request->parameters->{JSON};
++ return error_as_json(
++ $self->response,
++ \400, "JSON is a required field for multipart/form-data")
++ unless $json_str;
++
++ my $data = JSON::decode_json($json_str);
++
++ my @attachments = $self->request->upload('Attachments');
++
++ foreach my $attachment (@attachments) {
++ open my $filehandle, '<', $attachment->tempname;
++ if (defined $filehandle && length $filehandle) {
++ my ( @content, $buffer );
++ while ( read( $filehandle, $buffer, 72*57 ) ) {
++ push @content, MIME::Base64::encode_base64($buffer);
++ }
++ close $filehandle;
++
++ push @{$data->{Attachments}},
++ {
++ FileName => $attachment->filename,
++ FileType => $attachment->headers->{'content-type'},
++ FileContent => join("\n", @content),
++ };
++ }
++ }
++ return $self->from_json($data);
++};
++
+ __PACKAGE__->meta->make_immutable;
+
+ 1;
diff --git a/lib/RT/REST2/Util.pm b/lib/RT/REST2/Util.pm
--- a/lib/RT/REST2/Util.pm
@@ -46,18 +115,32 @@
my $value = $data->{$field};
next unless ref $value;
+diff --git a/t/rest2/data/html.htm b/t/rest2/data/html.htm
+new file mode 100644
+--- /dev/null
++++ b/t/rest2/data/html.htm
+@@
++<p><i>Easy</i> as π</p>
+
+diff --git a/t/rest2/data/plain.txt b/t/rest2/data/plain.txt
+new file mode 100644
+--- /dev/null
++++ b/t/rest2/data/plain.txt
+@@
++Hello, World!
+
diff --git a/t/rest2/tickets.t b/t/rest2/tickets.t
--- a/t/rest2/tickets.t
+++ b/t/rest2/tickets.t
@@
- use warnings;
- use RT::Test::REST2 tests => undef;
use Test::Deep;
-+use MIME::Base64;
+ use MIME::Base64;
+
+use Encode qw(decode encode);
-
++
# Test using integer priorities
RT->Config->Set(EnablePriorityAsString => 0);
+ my $mech = RT::Test::REST2->mech;
@@
like($third_ticket->{_url}, qr{$rest_base_path/ticket/$ticket3_id$});
}
@@ -126,4 +209,69 @@
+ like( $attachments->[4]->Content, qr/IHDR/, "Looks like a PNG image" );
+}
+
++# Ticket Creation - with attachments, using multipart/form-data
++my $json = JSON->new->utf8;
++{
++ my $plain_name = 'plain.txt';
++ my $plain_path = RT::Test::get_relocatable_file($plain_name, 'data');
++ my $html_name = 'html.htm';
++ my $html_path = RT::Test::get_relocatable_file($html_name, 'data');
++ my $img_name = 'image.png';
++ my $img_path = RT::Test::get_relocatable_file($img_name, 'data');
++
++ my $payload = {
++ Subject => 'Ticket creation using REST, multipart/form-data, with attachments.',
++ Queue => 'General',
++ Content => 'Testing ticket creation, multipart/form-data, with attachments using REST API.',
++ };
++
++ my $res = $mech->post( "$rest_base_path/ticket", $payload,
++ 'Authorization' => $auth,
++ 'Content_Type' => 'form-data',
++ 'Content' => [
++ 'JSON' => $json->encode($payload),
++ 'Attachments' => [$plain_path, $plain_name, 'text/plain'],
++ 'Attachments' => [$html_path, $html_name, 'text/html' ],
++ 'Attachments' => [$img_path, $img_name, 'image/png' ]
++ ]);
++ is( $res->code, 201 );
++ ok( $ticket_url = $res->header('location') );
++ ok( ($ticket_id) = $ticket_url =~ qr[/ticket/(\d+)] );
++}
++
++# Validate that the ticket was created correctly
++
++{
++ my $ticket = RT::Ticket->new($user);
++ $ticket->Load($ticket_id);
++ my $transaction_id = $ticket->Transactions->Last->id;
++ my $attachments = $ticket->Attachments->ItemsArrayRef;
++
++ # The 5 attachments are:
++ # 1) Top-level multipart
++ # 2) Top-level ticket content
++ # 3-5) The three attachments added in the Attachments array
++ is( scalar(@$attachments), 5 );
++
++ is( $attachments->[0]->ContentType, 'multipart/mixed' );
++
++ is( $attachments->[1]->ContentType, 'text/plain' );
++ is( $attachments->[1]->Content,
++ 'Testing ticket creation, multipart/form-data, with attachments using REST API.' );
++
++ is( $attachments->[2]->ContentType, 'text/plain' );
++ is( $attachments->[2]->Filename, 'plain.txt' );
++ is( $attachments->[2]->Content, "Hello, World!\n" );
++
++ is( $attachments->[3]->ContentType, 'text/html' );
++ is( $attachments->[3]->Filename, 'html.htm' );
++ is( $attachments->[3]->Content, "<p><i>Easy</i> as \x{03c0}</p>\n" );
++
++ is( $attachments->[4]->ContentType, 'image/png' );
++ is( $attachments->[4]->Filename, 'image.png' );
++ like( $attachments->[4]->Content, qr/IHDR/, "Looks like a PNG image" );
++}
++
++
++
done_testing;
More information about the rt-commit
mailing list