[Bps-public-commit] rt-extension-rest2 branch, transaction-cfs, repushed

Jim Brandt jbrandt at bestpractical.com
Fri Aug 9 13:43:12 EDT 2019


The branch transaction-cfs was deleted and repushed:
       was a0afa6790079e9bb6396cb8d9c0b2e9177c35935
       now 52ef66d789ed1ddbd925464d63a954f2ef72cc87

1:  a0afa67 ! 1:  460500d Add Transaction Custom Field updates on Correspond and Comment
    @@ -1,6 +1,6 @@
     Author: michel <michel at bestpractical.com>
     
    -    Added Transaction Custom Field updates on Correspond and Comment
    +    Add Transaction Custom Field updates on Correspond and Comment
     
     diff --git a/README b/README
     --- a/README
    @@ -45,24 +45,19 @@
              Subject   => $args{Subject},
          );
      
    -+    # we use $txn_ret and $txn_msg so we don't interfere with the main $ret and $msg
    -+    # see also comment below on the call to UpdateCustomFields
    -+    my ( $txn_ret, $txn_msg, $TxnCustomFields ) = $self->_massage_txn_custom_fields(
    -+        $args{TxnCustomFields} || $args{TransactionCustomFields} );
    -+
    -+    if ( ! $txn_ret ) {
    -+        return error_as_json( $self->response, \400, $txn_msg );
    -+    }
    -+
    -     my ( $Trans, $msg, $TransObj ) ;
    - 
    +-    my ( $Trans, $msg, $TransObj ) ;
    +-
    ++    my ( $Trans, $msg, $TransObj );
          if ($self->type eq 'correspond') {
    +         ( $Trans, $msg, $TransObj ) = $self->record->Correspond(
    +             MIMEObj   => $MIME,
     @@
                  \400, $msg || "Message failed for unknown reason");
          }
      
    -+    my ( $update_ret, $update_msg ) = $self->_update_txn_custom_fields( $TransObj, $TxnCustomFields );
    -+    $msg .= " - Error: transaction custom fields not updated" unless $update_ret;
    ++    my ( $update_ret, $update_msg ) = $self->_update_txn_custom_fields(
    ++        $TransObj, $args{TxnCustomFields} || $args{TransactionCustomFields} );
    ++    $msg .= " - CF Processing Error: transaction custom fields not updated" unless $update_ret;
     +
          $self->created_transaction($TransObj);
          $self->response->body(JSON::to_json([$msg], { pretty => 1 }));
    @@ -70,64 +65,40 @@
          return 1;
      }
      
    -+# takes a TxnCustomFields (or TransactionCustomFields) argument in
    -+# returns 
    -+#     a status code, 
    -+#    a message (in case of error)
    -+#     a hashref where the CF names are translated into the full
    -+#        form Object-RT::Transaction--CustomField-<id> that can
    -+#        be used by UpdateCustomFields
    -+#        the value is undef if no argument was passed
    -+sub _massage_txn_custom_fields {
    ++sub _update_txn_custom_fields {
     +    my $self = shift;
    -+    my $txn_cf_by_name = shift;
    -+
    -+    # if there are no transaction custom fields we're good
    -+    if( ! $txn_cf_by_name ) {
    -+        return ( 1, '', undef);
    -+    }
    -+
    -+    my $user = $self->request->env->{"rt.current_user"};
    -+
    -+    # we need the queue to get the transaction custom fields that can apply to it
    -+    my $queue_obj = $self->record->QueueObj;
    -+
    -+    # Pre-check that the user can actually update the CFs
    -+    unless ( $queue_obj->CurrentUserHasRight('ModifyCustomField') ) {
    -+        RT->Logger->error( "Permission denied: " . $user->Name . " cannot modify transaction custom fields");
    -+        return ( 0, "Permission denied", undef );
    -+    }
    ++    my $TransObj = shift;
    ++    my $TxnCustomFields = shift;
     +
     +    # generate a hash suitable for UpdateCustomFields
    -+    # ie the keys are the "full names" of the custom fields 
    ++    # ie the keys are the "full names" of the custom fields
     +    my %txn_custom_fields;
    -+    foreach my $cf_name ( %{$txn_cf_by_name} ) {
    -+        my $cf_obj = $queue_obj->LoadCustomFieldByIdentifier($cf_name);
    ++
    ++    # Create an empty Transaction object to pass to GetCustomFieldInputName
    ++    # UpdateCustomFields expects ARGS where the Txn input name doesn't have
    ++    # an Id yet. It uses $self to determine which Txn to operate on.
    ++    my $EmptyTxn = RT::Transaction->new( RT->SystemUser );
    ++
    ++    foreach my $cf_name ( keys %{$TxnCustomFields} ) {
    ++        my $cf_obj = $TransObj->LoadCustomFieldByIdentifier($cf_name);
     +
     +        unless ( $cf_obj and $cf_obj->Id ) {
     +            RT->Logger->error( "Unable to load transaction custom field: $cf_name" );
     +            return ( 0, "Unable to load transaction custom field: $cf_name", undef );
     +        }
     +
    -+        my $txn_input_name = RT::Interface::Web::GetCustomFieldInputNamePrefix(
    -+                             Object      => $queue_obj,
    ++        my $txn_input_name = RT::Interface::Web::GetCustomFieldInputName(
    ++                             Object      => $EmptyTxn,
     +                             CustomField => $cf_obj,
    ++                             Grouping    => undef
     +        );
     +
    -+        $txn_custom_fields{$txn_input_name} = $txn_cf_by_name->{$cf_name};
    ++        $txn_custom_fields{$txn_input_name} = $TxnCustomFields->{$cf_name};
     +    }
    -+
    -+    return ( 1, "Custom fields validated", \%txn_custom_fields );
    -+}
    -+
    -+sub _update_txn_custom_fields {
    -+    my $self = shift;
    -+    my $TransObj = shift;
    -+    my $TxnCustomFields = shift;
     +
     +    my ( $txn_ret, $txn_msg );
     +    if ( keys %$TxnCustomFields ) {
    -+        ( $txn_ret, $txn_msg ) = $TransObj->UpdateCustomFields( %$TxnCustomFields );
    ++        ( $txn_ret, $txn_msg ) = $TransObj->UpdateCustomFields( %txn_custom_fields );
     +
     +        if ( !$txn_ret ) {
     +            # the correspond/comment is already a success, the mails have been sent
    @@ -149,13 +120,14 @@
     --- /dev/null
     +++ b/xt/transaction-customfields.t
     @@
    -+
     +use strict;
     +use warnings;
     +use RT::Extension::REST2::Test tests => undef;
     +use Test::Deep;
     +
     +my $mech = RT::Extension::REST2::Test->mech;
    ++my ( $baseurl, $m ) = RT::Test->started_ok;
    ++diag "Started server at $baseurl";
     +
     +my $auth = RT::Extension::REST2::Test->authorization_header;
     +my $rest_base_path = '/REST/2.0';
    @@ -168,97 +140,58 @@
     +
     +my $cf = RT::CustomField->new( RT->SystemUser );
     +my $cfid;
    -+($cfid, $msg) = $cf->Create(Name => 'TxnCF', Type => 'Freeform', MaxValues => '0', LookupType => RT::Transaction->CustomFieldLookupType );
    ++($cfid, $msg) = $cf->Create(Name => 'TxnCF', Type => 'FreeformSingle', MaxValues => '0', LookupType => RT::Transaction->CustomFieldLookupType );
     +ok($cfid,$msg);
    -+
     +
     +($id,$msg) = $cf->AddToObject($queue);
     +ok($id,$msg);
     +
     +my $ticket = RT::Ticket->new(RT->SystemUser);
    -+my $transid;
    -+($id,$transid, $msg) = $ticket->Create(Queue => $queue->id, Subject => 'TxnCF test',);
    -+ok($id,$msg);
    ++my ( $ticket1_id, $transid );
    ++($ticket1_id, $transid, $msg) = $ticket->Create(Queue => $queue->id, Subject => 'TxnCF test',);
    ++ok( $ticket1_id, $msg );
     +
    -+my $res = $mech->get("$rest_base_path/ticket/$id", 'Authorization' => $auth);
    -+    is( $res->code, 200);
    ++my $res = $mech->get("$rest_base_path/ticket/$ticket1_id", 'Authorization' => $auth);
    ++is( $res->code, 200, 'Fetched ticket via REST2 API');
     +
    -+my $tnb=0;
    -+{   $tnb++;
    -+    my $payload = { Content         => "reply $tnb",
    ++{
    ++    my $payload = { Content         => "reply one",
     +                    ContentType     => "text/plain",
    -+                    TxnCustomFields => { "TxnCF" => "txncf value $tnb"},
    ++                    TxnCustomFields => { "TxnCF" => "txncf value one"},
     +                  };
    -+    my $res = $mech->post_json("$rest_base_path/ticket/$id/correspond", $payload, 'Authorization' => $auth);
    ++    my $res = $mech->post_json("$rest_base_path/ticket/$ticket1_id/correspond", $payload, 'Authorization' => $auth);
     +    is( $res->code, 201, 'correspond response code is 201');
     +    is_deeply( $mech->json_response, [ "Correspondence added" ], 'message is "Correspondence Added"');
     +
    -+    my $txn= last_txn( $id, 'Correspond');
    -+    is( $txn->{CustomFields}->{$cfid}->[0], "txncf value 1", 'CustomField by id');
    ++    my $ticket = RT::Ticket->new(RT->SystemUser);
    ++    my ( $ret, $msg ) = $ticket->Load( $ticket1_id );
    ++    ok( $ret, $msg );
    ++    my $txns = $ticket->Transactions;
    ++    $txns->Limit( FIELD => 'Type', VALUE => 'Correspond' );
    ++    my $txn = $txns->Last;
    ++    ok( $txn->Id, "Found Correspond transaction" );
    ++    is( $txn->FirstCustomFieldValue('TxnCF'), "txncf value one", 'Found transaction custom field');
     +}
     +
    ++# TODO Determine how to use RT::Test::Web tools to check and clear expected warnings
    ++
    ++=pod
    ++
     +{
    -+    my $payload = { Content         => "reply #2",
    ++    my $payload = { Content         => "reply two",
     +                    ContentType     => "text/plain",
     +                    TxnCustomFields => { "not a real CF name" => "txncf value"},
     +                  };
    -+    my $res = $mech->post_json("$rest_base_path/ticket/$id/correspond", $payload, 'Authorization' => $auth);
    -+    is( $res->code, 400, 'correspond response code is 400');
    -+    is( $mech->json_response->{message}, "unknown transaction custom field: not a real CF name", 'wrong cf name');
    ++    my $res = $mech->post_json("$rest_base_path/ticket/$ticket1_id/correspond", $payload, 'Authorization' => $auth);
    ++
    ++    # Doesn't work like RT
    ++    my @warnings = $m->get_warnings;
    ++
    ++    is( $res->code, 201, 'Correspond response code is 201 because correspond succeeded');
    ++    is( $mech->json_response, [ "Correspondence added - CF Processing Error: transaction custom fields not updated" ], 'Bogus cf name');
     +}
     +
    -+done_testing(); exit;
    ++=cut
     +
    -+# this is clumsy and brittle, and should probably be replaced by direct access to the data through RT::Test
    -+
    -+sub last_txn {
    -+    my( $ticket_id, $type ) = @_;
    -+    $type ||= 'Correspond';
    -+    my $ticket_res  = $mech->get("$rest_base_path/ticket/$id", 'Authorization' => $auth);
    -+
    -+    # build the list of txn
    -+    my $history_url = link_of_type( $mech->json_response, 'history' );
    -+    $mech->get( $history_url, 'Authorization' => $auth);
    -+    my $content= $mech->json_response;
    -+    my @items= @{$content->{items}};
    -+    if( $content->{total} >  $content->{per_page}) {
    -+        my $last_page = int( $content->{total} / $content->{per_page} ) + 1;
    -+        foreach my $page (2..$last_page) {
    -+            $mech->get( "$history_url?page=$page", 'Authorization' => $auth);
    -+            $content= $mech->json_response;
    -+            push @items, @{$content->{items}};
    -+        }
    -+    }
    -+
    -+    # get the txn record for the last action of type $type
    -+    my $last_txn;
    -+    foreach my $txn (reverse @items) {
    -+        $mech->get( $txn->{_url}, 'Authorization' => $auth );
    -+        $content= $mech->json_response;
    -+        #use DDP; warn "txn content:\n"; p $content;
    -+        if( $content->{Type} eq $type ) {
    -+            $last_txn = $content;
    -+            last;
    -+        }
    -+    }
    -+
    -+    if( $last_txn) {
    -+        return $last_txn;
    -+    }
    -+    else {
    -+        return;
    -+    }
    -+}
    -+
    -+sub link_of_type {
    -+    my( $json, $ref)= @_;
    -+    my $links = $json->{_hyperlinks};
    -+    foreach my $link (@$links) {
    -+        if( $link->{ref} eq $ref) {
    -+            return $link->{_url};
    -+        }
    -+    }
    -+    return;
    -+}
    -+
    -+
    ++done_testing();
    +
-:  ------- > 2:  3c29c50 Move custom field updater to Utils for use elsewhere
-:  ------- > 3:  52ef66d Add custom fields on comment and correspond



More information about the Bps-public-commit mailing list