[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