[Rt-commit] rt branch, 5.0/rest2-record-links, created. rt-5.0.0-55-g605115b27b

? sunnavy sunnavy at bestpractical.com
Wed Oct 21 14:09:14 EDT 2020


The branch, 5.0/rest2-record-links has been created
        at  605115b27be80ae184fe35b21af9b39e555982e3 (commit)

- Log -----------------------------------------------------------------
commit 41ce8a287c5eea7dfa4a4b469d444d8697d448f7
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 ccfca41d22..5c53750163 100644
--- a/lib/RT/REST2/Util.pm
+++ b/lib/RT/REST2/Util.pm
@@ -216,7 +216,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 25e9bf97cb08da176da77c1b59013b5ed6850829
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 1079f95cd6..c4b4fab285 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 605115b27be80ae184fe35b21af9b39e555982e3
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;
 

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


More information about the rt-commit mailing list