[Rt-commit] rt branch, 5.0-trunk, updated. rt-5.0.0-192-g07c897f379

? sunnavy sunnavy at bestpractical.com
Wed Jan 6 15:46:19 EST 2021


The branch, 5.0-trunk has been updated
       via  07c897f379d1a727d5d3df10db868faed0341d55 (commit)
       via  226f3a673d05d384affaeae408c989d3ef610664 (commit)
       via  2f8101e1a60be99a442a024d8e7599281a40e7ae (commit)
       via  15cb486e3bcfce62f2cdb4bbd9644b408b1bcf95 (commit)
       via  56c04325085a2e8ac13a14b63ca6dc484b1a5155 (commit)
      from  993d034c86cb8f2f8975339c178374c4632c291d (commit)

Summary of changes:
 lib/RT/REST2.pm                          | 31 ++++++++++++++
 lib/RT/REST2/Resource/Record/Writable.pm | 71 ++++++++++++++++++++++++++++++++
 lib/RT/REST2/Util.pm                     |  4 +-
 t/rest2/ticket-links.t                   | 40 ++++++++++++++++++
 4 files changed, 145 insertions(+), 1 deletion(-)

- Log -----------------------------------------------------------------
commit 56c04325085a2e8ac13a14b63ca6dc484b1a5155
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Wed Oct 21 15:42:56 2020 +0800

    Allow to pass array to link params on record create
    
    This is to support multiple links like { "RefersTo": [1,2,3] }. Without
    this, deserialize_record would error out something like:
    
        Received unknown value via JSON for field RefersTo: ARRAY

diff --git a/lib/RT/REST2/Util.pm b/lib/RT/REST2/Util.pm
index 92a6736123..eba3d8302e 100644
--- a/lib/RT/REST2/Util.pm
+++ b/lib/RT/REST2/Util.pm
@@ -221,7 +221,9 @@ sub deserialize_record {
 
     # Sanitize input for the Perl API
     for my $field (sort keys %$data) {
-        next if $field eq 'CustomFields';
+        my $skip_regex = join '|', 'CustomFields',
+            $record->DOES("RT::Record::Role::Links") ? ( sort keys %RT::Link::TYPEMAP ) : ();
+        next if $field =~ /$skip_regex/;
 
         my $value = $data->{$field};
         next unless ref $value;

commit 15cb486e3bcfce62f2cdb4bbd9644b408b1bcf95
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Wed Oct 21 16:15:51 2020 +0800

    Support to update record links

diff --git a/lib/RT/REST2.pm b/lib/RT/REST2.pm
index 5f7fc1b7f4..0864f172cb 100644
--- a/lib/RT/REST2.pm
+++ b/lib/RT/REST2.pm
@@ -499,6 +499,15 @@ Below are some examples using the endpoints above.
         -d '{ "Subject": "Update test", "CustomFields": {"Severity": "High"}}'
         'https://myrt.com/REST/2.0/ticket/6'
 
+    # Update a ticket, with links update
+    curl -X PUT -H "Content-Type: application/json" -u 'root:password'
+        -d '{ "DependsOn": [2, 3], "ReferredToBy": 1 }'
+        'https://myrt.com/REST/2.0/ticket/6'
+
+    curl -X PUT -H "Content-Type: application/json" -u 'root:password'
+        -d '{ "AddDependsOn": [4, 5], "DeleteReferredToBy": 1 }'
+        'https://myrt.com/REST/2.0/ticket/6'
+
     # Correspond a ticket
     curl -X POST -H "Content-Type: application/json" -u 'root:password'
         -d '{ "Content": "Testing a correspondence", "ContentType": "text/plain" }'
diff --git a/lib/RT/REST2/Resource/Record/Writable.pm b/lib/RT/REST2/Resource/Record/Writable.pm
index 8fdcb4bd57..1010c20f74 100644
--- a/lib/RT/REST2/Resource/Record/Writable.pm
+++ b/lib/RT/REST2/Resource/Record/Writable.pm
@@ -174,6 +174,7 @@ sub update_record {
 
     push @results, update_custom_fields($self->record, $data->{CustomFields});
     push @results, $self->_update_role_members($data);
+    push @results, $self->_update_links($data);
     push @results, $self->_update_disabled($data->{Disabled})
       unless grep { $_ eq 'Disabled' } $self->record->WritableAttributes;
     push @results, $self->_update_privileged($data->{Privileged})
@@ -302,6 +303,76 @@ sub _update_role_members {
     return @results;
 }
 
+sub _update_links {
+    my $self = shift;
+    my $data = shift;
+
+    my $record = $self->record;
+
+    return unless $record->DOES('RT::Record::Role::Links');
+
+    my @results;
+    for my $name ( grep { $_ ne 'MergedInto' } sort keys %RT::Link::TYPEMAP ) {
+        my $mode = $RT::Link::TYPEMAP{$name}{Mode};
+        my $type = $RT::Link::TYPEMAP{$name}{Type};
+        if ( $data->{$name} ) {
+            my $links = $record->Links( $mode eq 'Base' ? 'Target' : 'Base', $type );
+            my %current;
+            while ( my $link = $links->Next ) {
+                my $uri_method = $mode . 'URI';
+                my $uri        = $link->$uri_method;
+
+                if ( $uri->IsLocal ) {
+                    my $local_method = "Local$mode";
+                    $current{ $link->$local_method } = 1;
+                }
+                else {
+                    $current{ $link->$mode } = 1;
+                }
+            }
+
+            for my $value ( ref $data->{$name} eq 'ARRAY' ? @{ $data->{$name} } : $data->{$name} ) {
+                if ( $current{$value} ) {
+                    delete $current{$value};
+                }
+                else {
+                    my ( $ok, $msg ) = $record->AddLink(
+                        $mode => $value,
+                        Type  => $type,
+                    );
+                    push @results, $msg;
+                }
+            }
+
+            for my $value ( sort keys %current ) {
+                my ( $ok, $msg ) = $record->DeleteLink(
+                    $mode => $value,
+                    Type  => $type,
+                );
+                push @results, $msg;
+            }
+        }
+        else {
+            for my $action (qw/Add Delete/) {
+                my $arg = "$action$name";
+                next unless $data->{$arg};
+
+                for my $value ( ref $data->{$arg} eq 'ARRAY' ? @{ $data->{$arg} } : $data->{$arg} ) {
+                    my $method = $action . 'Link';
+                    my ( $ok, $msg ) = $record->$method(
+                        $mode => $value,
+                        Type  => $type,
+                    );
+                    push @results, $msg;
+                }
+            }
+        }
+    }
+
+    return @results;
+}
+
+
 sub _update_disabled {
     my $self = shift;
     my $data = shift;

commit 2f8101e1a60be99a442a024d8e7599281a40e7ae
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Thu Oct 22 01:51:20 2020 +0800

    Add REST2 tests for ticket link updates

diff --git a/t/rest2/ticket-links.t b/t/rest2/ticket-links.t
index 14de8af1c3..ab67c2946f 100644
--- a/t/rest2/ticket-links.t
+++ b/t/rest2/ticket-links.t
@@ -90,6 +90,46 @@ $user->PrincipalObj->GrantRight( Right => 'ShowTicket' );
     }], 'one external refers-to link');
 }
 
+# Create/Modify ticket with links
+$user->PrincipalObj->GrantRight( Right => $_ ) for qw/CreateTicket ModifyTicket/;
+
+{
+    my $res = $mech->post_json(
+        "$rest_base_path/ticket",
+        { Queue => 'General', DependsOn => [ $parent_id, $child_id ], RefersTo => $child_id },
+        'Authorization' => $auth,
+    );
+    is( $res->code, 201, 'post response code' );
+    my $content = $mech->json_response;
+    my $id      = $content->{id};
+    ok( $id, "create another ticket with links" );
+
+    $res = $mech->put_json( "$rest_base_path/ticket/$id", { RefersTo => $parent_id }, 'Authorization' => $auth, );
+    is( $res->code, 200, 'put response code' );
+
+    $content = $mech->json_response;
+    is_deeply(
+        $content,
+        [ "Ticket $id refers to Ticket $parent_id.", "Ticket $id no longer refers to Ticket $child_id." ],
+        'update RefersTo'
+    );
+
+    $res = $mech->put_json(
+        "$rest_base_path/ticket/$id",
+        { DeleteDependsOn => $parent_id, AddMembers => [ $parent_id, $child_id ] },
+        'Authorization' => $auth
+    );
+    is( $res->code, 200, 'put response code' );
+    $content = $mech->json_response;
+    is_deeply(
+        $content,
+        [   "Ticket $id no longer depends on Ticket $parent_id.",
+            "Ticket $parent_id member of Ticket $id.",
+            "Ticket $child_id member of Ticket $id."
+        ],
+        'add Members and delete DependsOn'
+    );
+}
 
 done_testing;
 

commit 226f3a673d05d384affaeae408c989d3ef610664
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Mon Jan 4 16:54:04 2021 -0500

    Explain the options for modifying links via REST2

diff --git a/lib/RT/REST2.pm b/lib/RT/REST2.pm
index 0864f172cb..e36ef2a549 100644
--- a/lib/RT/REST2.pm
+++ b/lib/RT/REST2.pm
@@ -529,6 +529,28 @@ Below are some examples using the endpoints above.
         -d '{ "Content": "Testing a comment", "ContentType": "text/plain", "CustomFields": {"Severity": "High"} }'
         'https://myrt.com/REST/2.0/ticket/6/comment'
 
+=head3 Ticket Fields
+
+The following describes some of the values you can send when creating and updating
+tickets as shown in the examples above.
+
+=over 4
+
+=item Ticket Links
+
+As shown above, you can update links on a ticket with a C<PUT> and passing the link
+relationship you want to create. The available keys are Parent, Child, RefersTo,
+ReferredToBy, DependsOn, and DependedOnBy. These correspond with the standard link
+types on a ticket. The value can be a single ticket id or an array of ticket ids.
+The indicated link relationship will be set to the value passed, adding or removing
+as needed.
+
+You can specifically add or remove a link by prepending C<Add> or C<Delete> to
+the link type, like C<AddParent> or C<DeleteParent>. These versions also accept
+a single ticket id or an array.
+
+=back
+
 =head3 Transactions
 
     GET /transactions?query=<JSON>

commit 07c897f379d1a727d5d3df10db868faed0341d55
Merge: 993d034c86 226f3a673d
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Thu Jan 7 04:28:12 2021 +0800

    Merge branch '5.0/rest2-record-links' into 5.0-trunk


-----------------------------------------------------------------------


More information about the rt-commit mailing list