Skip to content

Commit

Permalink
allow sort order to be specified for attribute values
Browse files Browse the repository at this point in the history
Add a values_sorted property to Attribute that is an array ref with the
order the keys of values should be returned in. If that's present then
use that to sort the values, otherwise remain alphabetical.
  • Loading branch information
struan committed Apr 29, 2020
1 parent 2d22da7 commit 4c11ded
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 1 deletion.
12 changes: 11 additions & 1 deletion perllib/Open311/Endpoint.pm
Expand Up @@ -407,7 +407,7 @@ sub GET_Service_Definition {
key => $key,
name => $name,
}
} sort { $a->[0] cmp $b->[0] } $attribute->values_kv
} $self->service_attribute_values( $attribute )
]) : (),
map { $_ => $attribute->$_ }
qw/ code datatype datatype_description description /,
Expand All @@ -419,6 +419,16 @@ sub GET_Service_Definition {
return $service_definition;
}

sub service_attribute_values {
my ( $self, $attribute ) = @_;

if ( $attribute->has_sorted_values ) {
return map { [ $_ => $attribute->values->{$_} ] } $attribute->get_sorted_values;
} else {
return sort { $a->[0] cmp $b->[0] } $attribute->values_kv;
}
}

sub POST_Service_Request_input_schema {
my ($self, $args) = @_;

Expand Down
11 changes: 11 additions & 0 deletions perllib/Open311/Endpoint/Service/Attribute.pm
Expand Up @@ -70,6 +70,17 @@ has values => (
}
);

has values_sorted => (
is => 'ro',
isa => ArrayRef,
default => sub { [] },
handles_via => 'Array',
handles => {
get_sorted_values => 'elements',
has_sorted_values => 'count',
}
);

sub schema_definition {
my $self = shift;

Expand Down
104 changes: 104 additions & 0 deletions t/open311/endpoint.t
Expand Up @@ -29,6 +29,15 @@ subtest "GET Service List" => sub {
<service_name>Pothole Repairs</service_name>
<type>realtime</type>
</service>
<service>
<description>Sorted Pothole Repairs Service</description>
<group>highways</group>
<keywords>deep,hole,wow</keywords>
<metadata>true</metadata>
<service_code>SPOT</service_code>
<service_name>Sorted Pothole Repairs</service_name>
<type>realtime</type>
</service>
<service>
<description>Bin Enforcement Service</description>
<group>sanitation</group>
Expand All @@ -52,6 +61,14 @@ CONTENT
"metadata" => "true",
"description" => "Pothole Repairs Service",
"service_code" => "POT"
}, {
"keywords" => "deep,hole,wow",
"group" => "highways",
"service_name" => "Sorted Pothole Repairs",
"type" => "realtime",
"metadata" => "true",
"description" => "Sorted Pothole Repairs Service",
"service_code" => "SPOT"
}, {
"keywords" => "bin",
"group" => "sanitation",
Expand Down Expand Up @@ -151,6 +168,93 @@ CONTENT
}, 'json structure ok';
};


subtest "GET Service Definition with non standard values order" => sub {
my $res = $endpoint->run_test_request( GET => '/services/SPOT.xml' );
ok $res->is_success, 'xml success',
or diag $res->content;
is_string $res->content, <<CONTENT, 'xml string ok';
<?xml version="1.0" encoding="utf-8"?>
<service_definition>
<attributes>
<attribute>
<code>depth</code>
<datatype>number</datatype>
<datatype_description>an integer</datatype_description>
<description>depth of pothole, in centimetres</description>
<order>1</order>
<required>true</required>
<variable>true</variable>
</attribute>
<attribute>
<code>shape</code>
<datatype>singlevaluelist</datatype>
<datatype_description>square | circle | triangle</datatype_description>
<description>shape of the pothole</description>
<order>2</order>
<required>false</required>
<values>
<value>
<name>Circle</name>
<key>circle</key>
</value>
<value>
<name>Triangle</name>
<key>triangle</key>
</value>
<value>
<name>Square</name>
<key>square</key>
</value>
</values>
<variable>true</variable>
</attribute>
</attributes>
<service_code>SPOT</service_code>
</service_definition>
CONTENT

$res = $endpoint->run_test_request( GET => '/services/SPOT.json' );
ok $res->is_success, 'json success';
is_deeply decode_json($res->content),
{
"service_code" => "SPOT",
"attributes" => [
{
"order" => 1,
"code" => "depth",
"required" => "true",
"variable" => "true",
"datatype_description" => "an integer",
"description" => "depth of pothole, in centimetres",
"datatype" => "number",
},
{
"order" => 2,
"code" => "shape",
"variable" => "true",
"datatype_description" => "square | circle | triangle",
"description" => "shape of the pothole",
"required" => "false",
"datatype" => "singlevaluelist",
"values" => [
{
"name" => "Circle",
"key" => "circle"
},
{
"name" => "Triangle",
"key" => "triangle"
},
{
"name" => "Square",
"key" => "square"
},
],
}
],
}, 'json structure ok';
};
subtest "POST Service Request validation" => sub {
my $res = $endpoint->run_test_request(
POST => '/requests.json',
Expand Down
30 changes: 30 additions & 0 deletions t/open311/endpoint/Endpoint1.pm
Expand Up @@ -40,6 +40,36 @@ sub services {
keywords => [qw/ deep hole wow/],
group => 'highways',
),
t::open311::endpoint::ServiceType1->new(
service_code => 'SPOT',
service_name => 'Sorted Pothole Repairs',
description => 'Sorted Pothole Repairs Service',
attributes => [
Open311::Endpoint::Service::Attribute->new(
code => 'depth',
required => 1,
datatype => 'number',
datatype_description => 'an integer',
description => 'depth of pothole, in centimetres',
),
Open311::Endpoint::Service::Attribute->new(
code => 'shape',
required => 0,
datatype => 'singlevaluelist',
datatype_description => 'square | circle | triangle',
description => 'shape of the pothole',
values_sorted => [ 'circle', 'triangle', 'square' ],
values => {
square => 'Square',
circle => 'Circle',
triangle => 'Triangle',
},
),
],
type => 'realtime',
keywords => [qw/ deep hole wow/],
group => 'highways',
),
t::open311::endpoint::ServiceType1->new(
service_code => 'BIN',
service_name => 'Bin Enforcement',
Expand Down

0 comments on commit 4c11ded

Please sign in to comment.