[Bps-public-commit] rt-extension-rest2 branch, rest2_api_custom_field_admin, created. 1.07-3-g5abdab8

Aaron Trevena ast at bestpractical.com
Mon Apr 6 10:06:12 EDT 2020


The branch, rest2_api_custom_field_admin has been created
        at  5abdab89323930fd1a7924722bd7f532b09beaea (commit)

- Log -----------------------------------------------------------------
commit e272ed46b4cce264378952966c73a0e52915b949
Author: gibus <gibus at easter-eggs.com>
Date:   Thu May 24 16:21:11 2018 +0200

    Add available values for Select RT::CustomField
    
    Also filter values of Select CF with category parameter
    
    Based on public github PR #11

diff --git a/Changes b/Changes
index c756d8c..afcfdfb 100644
--- a/Changes
+++ b/Changes
@@ -1,5 +1,9 @@
 Revision history for RT-Extension-REST2
 
+ - Add a new JSON property, "Values:" as an array of all possible values for
+   RT::Customfield of type Select.
+ - Allow filtering values for BasedOn custom fields, by specifying a category argument
+
 1.07 2019-05-24
  - Accept 'Content' as a parameter on create. The documentation previously showed
    this in examples, but it wasn't yet supported. Now it works as documented.
diff --git a/lib/RT/Extension/REST2.pm b/lib/RT/Extension/REST2.pm
index c4b61c6..827f469 100644
--- a/lib/RT/Extension/REST2.pm
+++ b/lib/RT/Extension/REST2.pm
@@ -529,7 +529,10 @@ Below are some examples using the endpoints above.
         search for custom fields using L</JSON searches> syntax
 
     GET /customfield/:id
-        retrieve a custom field
+        retrieve a custom field, with values if type is Select
+
+    GET /customfield/:id?category=<category name>
+        retrieve a custom field, with values filtered by category if type is Select
 
 =head3 Custom Roles
 
diff --git a/lib/RT/Extension/REST2/Resource/CustomField.pm b/lib/RT/Extension/REST2/Resource/CustomField.pm
index 904424b..ddc9aa7 100644
--- a/lib/RT/Extension/REST2/Resource/CustomField.pm
+++ b/lib/RT/Extension/REST2/Resource/CustomField.pm
@@ -7,6 +7,7 @@ use namespace::autoclean;
 
 extends 'RT::Extension::REST2::Resource::Record';
 with 'RT::Extension::REST2::Resource::Record::Readable',
+        => { -alias => { serialize => '_default_serialize' } },
      'RT::Extension::REST2::Resource::Record::Hypermedia';
 
 sub dispatch_rules {
@@ -20,6 +21,21 @@ sub dispatch_rules {
     )
 }
 
+sub serialize {
+    my $self = shift;
+    my $data = $self->_default_serialize(@_);
+
+    if ($data->{Values}) {
+        if ($self->record->BasedOn && defined $self->request->param('category')) {
+            my $category = $self->request->param('category') || '';
+            @{$data->{Values}} = grep {$_->{category} eq $category} @{$data->{Values}};
+        }
+        @{$data->{Values}} = map {$_->{name}} @{$data->{Values}};
+    }
+
+    return $data;
+}
+
 __PACKAGE__->meta->make_immutable;
 
 1;
diff --git a/lib/RT/Extension/REST2/Util.pm b/lib/RT/Extension/REST2/Util.pm
index e814c1c..9ae1680 100644
--- a/lib/RT/Extension/REST2/Util.pm
+++ b/lib/RT/Extension/REST2/Util.pm
@@ -91,6 +91,19 @@ sub serialize_record {
         }
     }
 
+    # Add available values for Select RT::CustomField
+    if (ref($record) eq 'RT::CustomField' && $record->Type eq 'Select') {
+        my $values = $record->Values;
+        while (my $val = $values->Next) {
+            my $category = $record->BasedOn ? $val->Category : '';
+            if (exists $data{Values}) {
+                push @{$data{Values}}, {name => $val->Name, category => $category};
+            } else {
+                $data{Values} = [{name => $val->Name, category => $category}];
+            }
+        }
+    }
+
     # Replace UIDs with object placeholders
     for my $uid (grep ref eq 'SCALAR', values %data) {
         $uid = expand_uid($uid);

commit 5abdab89323930fd1a7924722bd7f532b09beaea
Author: gibus <gibus at easter-eggs.com>
Date:   Tue Sep 25 22:49:45 2018 +0200

    Add tests for CustomField
    
    Based on public github PR #11

diff --git a/MANIFEST b/MANIFEST
index 7ef88eb..8ba75b7 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -70,6 +70,7 @@ xt/asset-customfields.t
 xt/assets.t
 xt/catalogs.t
 xt/conflict.t
+xt/customfields.t
 xt/group-members.t
 xt/not_found.t
 xt/organization.t
diff --git a/xt/customfields.t b/xt/customfields.t
new file mode 100644
index 0000000..766e153
--- /dev/null
+++ b/xt/customfields.t
@@ -0,0 +1,221 @@
+use strict;
+use warnings;
+use lib 't/lib';
+use RT::Extension::REST2::Test tests => undef;
+
+my $mech = RT::Extension::REST2::Test->mech;
+my $auth = RT::Extension::REST2::Test->authorization_header;
+my $rest_base_path = '/REST/2.0';
+my $user = RT::Extension::REST2::Test->user;
+
+my $freeform_cf = RT::CustomField->new(RT->SystemUser);
+$freeform_cf->Create(Name => 'Freeform CF', Type => 'Freeform', MaxValues => 1, Queue => 'General');
+my $freeform_cf_id = $freeform_cf->id;
+
+my $select_cf = RT::CustomField->new(RT->SystemUser);
+$select_cf->Create(Name => 'Select CF', Type => 'Select', MaxValues => 1, Queue => 'General');
+$select_cf->AddValue(Name => 'First Value', SortOder => 0);
+$select_cf->AddValue(Name => 'Second Value', SortOrder => 1);
+$select_cf->AddValue(Name => 'Third Value', SortOrder => 2);
+my $select_cf_id = $select_cf->id;
+my $select_cf_values = $select_cf->Values->ItemsArrayRef;
+
+my $basedon_cf = RT::CustomField->new(RT->SystemUser);
+$basedon_cf->Create(Name => 'SubSelect CF', Type => 'Select', MaxValues => 1, Queue => 'General', BasedOn => $select_cf->id);
+$basedon_cf->AddValue(Name => 'With First Value', Category => $select_cf_values->[0]->Name, SortOder => 0);
+$basedon_cf->AddValue(Name => 'With No Value', SortOder => 0);
+my $basedon_cf_id = $basedon_cf->id;
+my $basedon_cf_values = $basedon_cf->Values->ItemsArrayRef;
+
+# Right test - search all tickets customfields without SeeCustomField
+{
+    my $res = $mech->post_json("$rest_base_path/customfields",
+        [{field => 'LookupType', value => 'RT::Queue-RT::Ticket'}],
+        'Authorization' => $auth,
+    );
+    is($res->code, 200);
+
+    my $content = $mech->json_response;
+    is($content->{total}, 3);
+    is($content->{count}, 0);
+    is_deeply($content->{items}, []);
+}
+
+# search all tickets customfields
+{
+    $user->PrincipalObj->GrantRight( Right => 'SeeCustomField' );
+
+    my $res = $mech->post_json("$rest_base_path/customfields",
+        [{field => 'LookupType', value => 'RT::Queue-RT::Ticket'}],
+        'Authorization' => $auth,
+    );
+    is($res->code, 200);
+
+    my $content = $mech->json_response;
+    is($content->{total}, 3);
+    is($content->{count}, 3);
+    my $items = $content->{items};
+    is(scalar(@$items), 3);
+    
+    is($items->[0]->{type}, 'customfield');
+    is($items->[0]->{id}, $freeform_cf->id);
+    like($items->[0]->{_url}, qr{$rest_base_path/customfield/$freeform_cf_id$});
+
+    is($items->[1]->{type}, 'customfield');
+    is($items->[1]->{id}, $select_cf->id);
+    like($items->[1]->{_url}, qr{$rest_base_path/customfield/$select_cf_id$});
+
+    is($items->[2]->{type}, 'customfield');
+    is($items->[2]->{id}, $basedon_cf->id);
+    like($items->[2]->{_url}, qr{$rest_base_path/customfield/$basedon_cf_id$});
+}
+
+# Freeform CustomField display
+{
+    my $res = $mech->get("$rest_base_path/customfield/$freeform_cf_id",
+        'Authorization' => $auth,
+    );
+    is($res->code, 200);
+    my $content = $mech->json_response;
+    is($content->{id}, $freeform_cf_id);
+    is($content->{Name}, $freeform_cf->Name);
+    is($content->{Description}, '');
+    is($content->{LookupType}, 'RT::Queue-RT::Ticket');
+    is($content->{Type}, 'Freeform');
+    is($content->{MaxValues}, 1);
+    is($content->{Disabled}, 0);
+
+    my @fields = qw(SortOrder Pattern Created Creator LastUpdated LastUpdatedBy);
+    push @fields, qw(UniqueValues EntryHint) if RT::Handle::cmp_version($RT::VERSION, '4.4.0') >= 0;
+    ok(exists $content->{$_}, "got $_") for @fields;
+
+    my $links = $content->{_hyperlinks};
+    is(scalar @$links, 1);
+    is($links->[0]{ref}, 'self');
+    is($links->[0]{id}, $freeform_cf_id);
+    is($links->[0]{type}, 'customfield');
+    like($links->[0]{_url}, qr{$rest_base_path/customfield/$freeform_cf_id$});
+}
+
+# Select CustomField display
+{
+    my $res = $mech->get("$rest_base_path/customfield/$select_cf_id",
+        'Authorization' => $auth,
+    );
+    is($res->code, 200);
+    my $content = $mech->json_response;
+    is($content->{id}, $select_cf_id);
+    is($content->{Name}, $select_cf->Name);
+    is($content->{Description}, '');
+    is($content->{LookupType}, 'RT::Queue-RT::Ticket');
+    is($content->{Type}, 'Select');
+    is($content->{MaxValues}, 1);
+    is($content->{Disabled}, 0);
+
+    my @fields = qw(SortOrder Pattern Created Creator LastUpdated LastUpdatedBy);
+    push @fields, qw(UniqueValues EntryHint) if RT::Handle::cmp_version($RT::VERSION, '4.4.0') >= 0;
+    ok(exists $content->{$_}, "got $_") for @fields;
+
+    my $links = $content->{_hyperlinks};
+    is(scalar @$links, 1);
+    is($links->[0]{ref}, 'self');
+    is($links->[0]{id}, $select_cf_id);
+    is($links->[0]{type}, 'customfield');
+    like($links->[0]{_url}, qr{$rest_base_path/customfield/$select_cf_id$});
+
+    my $values = $content->{Values};
+    is_deeply($values, ['First Value', 'Second Value', 'Third Value']);
+}
+
+# BasedOn CustomField display
+{
+    my $res = $mech->get("$rest_base_path/customfield/$basedon_cf_id",
+        'Authorization' => $auth,
+    );
+    is($res->code, 200);
+    my $content = $mech->json_response;
+    is($content->{id}, $basedon_cf_id);
+    is($content->{Name}, $basedon_cf->Name);
+    is($content->{Description}, '');
+    is($content->{LookupType}, 'RT::Queue-RT::Ticket');
+    is($content->{Type}, 'Select');
+    is($content->{MaxValues}, 1);
+    is($content->{Disabled}, 0);
+
+    my @fields = qw(SortOrder Pattern Created Creator LastUpdated LastUpdatedBy);
+    push @fields, qw(UniqueValues EntryHint) if RT::Handle::cmp_version($RT::VERSION, '4.4.0') >= 0;
+    ok(exists $content->{$_}, "got $_") for @fields;
+
+    my $links = $content->{_hyperlinks};
+    is(scalar @$links, 1);
+    is($links->[0]{ref}, 'self');
+    is($links->[0]{id}, $basedon_cf_id);
+    is($links->[0]{type}, 'customfield');
+    like($links->[0]{_url}, qr{$rest_base_path/customfield/$basedon_cf_id$});
+
+    my $values = $content->{Values};
+    is_deeply($values, ['With First Value', 'With No Value']);
+}
+
+# BasedOn CustomField display with category filter
+{
+    my $res = $mech->get("$rest_base_path/customfield/$basedon_cf_id?category=First%20Value",
+        'Authorization' => $auth,
+    );
+    is($res->code, 200);
+    my $content = $mech->json_response;
+    is($content->{id}, $basedon_cf_id);
+    is($content->{Name}, $basedon_cf->Name);
+    is($content->{Description}, '');
+    is($content->{LookupType}, 'RT::Queue-RT::Ticket');
+    is($content->{Type}, 'Select');
+    is($content->{MaxValues}, 1);
+    is($content->{Disabled}, 0);
+
+    my @fields = qw(SortOrder Pattern Created Creator LastUpdated LastUpdatedBy);
+    push @fields, qw(UniqueValues EntryHint) if RT::Handle::cmp_version($RT::VERSION, '4.4.0') >= 0;
+    ok(exists $content->{$_}, "got $_") for @fields;
+
+    my $links = $content->{_hyperlinks};
+    is(scalar @$links, 1);
+    is($links->[0]{ref}, 'self');
+    is($links->[0]{id}, $basedon_cf_id);
+    is($links->[0]{type}, 'customfield');
+    like($links->[0]{_url}, qr{$rest_base_path/customfield/$basedon_cf_id$});
+
+    my $values = $content->{Values};
+    is_deeply($values, ['With First Value']);
+}
+
+# BasedOn CustomField display with null category filter
+{
+    my $res = $mech->get("$rest_base_path/customfield/$basedon_cf_id?category=",
+        'Authorization' => $auth,
+    );
+    is($res->code, 200);
+    my $content = $mech->json_response;
+    is($content->{id}, $basedon_cf_id);
+    is($content->{Name}, $basedon_cf->Name);
+    is($content->{Description}, '');
+    is($content->{LookupType}, 'RT::Queue-RT::Ticket');
+    is($content->{Type}, 'Select');
+    is($content->{MaxValues}, 1);
+    is($content->{Disabled}, 0);
+
+    my @fields = qw(SortOrder Pattern Created Creator LastUpdated LastUpdatedBy);
+    push @fields, qw(UniqueValues EntryHint) if RT::Handle::cmp_version($RT::VERSION, '4.4.0') >= 0;
+    ok(exists $content->{$_}, "got $_") for @fields;
+
+    my $links = $content->{_hyperlinks};
+    is(scalar @$links, 1);
+    is($links->[0]{ref}, 'self');
+    is($links->[0]{id}, $basedon_cf_id);
+    is($links->[0]{type}, 'customfield');
+    like($links->[0]{_url}, qr{$rest_base_path/customfield/$basedon_cf_id$});
+
+    my $values = $content->{Values};
+    is_deeply($values, ['With No Value']);
+}
+
+done_testing;
+

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


More information about the Bps-public-commit mailing list