1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
package t::open311::endpoint::Endpoint1;
use Web::Simple;
extends 'Open311::Endpoint';
use Types::Standard ':all';
use MooX::HandlesVia;
use Open311::Endpoint::Service;
use t::open311::endpoint::ServiceType1;
use Open311::Endpoint::Service::Attribute;
use Open311::Endpoint::Service::Request;
use constant request_class => 'Open311::Endpoint::Service::Request';
sub services {
return (
t::open311::endpoint::ServiceType1->new(
service_code => 'POT',
service_name => 'Pothole Repairs',
description => '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 => {
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',
description => 'Bin Enforcement Service',
attributes => [],
type => 'realtime',
keywords => [qw/ bin /],
group => 'sanitation',
)
);
}
# FOR TESTING, we'll just maintain requests in a *global* array...
# obviously a real Service driver will use a DB or API call!
{
our @SERVICE_REQUESTS;
has _requests => (
is => 'ro',
isa => ArrayRef[ InstanceOf[ 'Open311::Endpoint::Service::Request' ] ],
default => sub { \@SERVICE_REQUESTS },
handles_via => 'Array',
handles => {
next_request_id => 'count',
_add_request => 'push',
get_request => 'get',
get_requests => 'elements',
filter_requests => 'grep',
}
);
}
sub post_service_request {
my ($self, $service, $args) = @_;
my $request = $self->request_class->new(
# NB: possible race condition between next_request_id and _add_request
# (this is fine for synchronous test-cases)
service => $service,
service_request_id => $self->next_request_id,
status => 'open',
description => $args->{description},
agency_responsible => '',
requested_datetime => DateTime->now(),
updated_datetime => DateTime->now(),
address => $args->{address_string} // '',
address_id => $args->{address_id} // '',
media_url => $args->{media_url} // '',
zipcode => $args->{zipcode} // '',
# NB: other info is passed in that would be stored by an Open311
# endpoint, see Open311::Endpoint::Service::Request for full list,
# but we don't need to handle all of those in this test
);
$self->_add_request( $request );
return ( $request );
}
sub get_service_requests {
my ($self, $args) = @_;
my $service_code = $args->{service_code} or return $self->get_requests;
# we use ~~ as the service_code arg will be an arrayref like ['POT']
return $self->filter_requests( sub { shift->service->service_code ~~ $service_code });
}
sub get_service_request {
my ($self, $service_request_id, $args) = @_;
return $self->get_request( $service_request_id );
}
1;
|