[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