From cfcda98c6859672b843c15407e0c55d39da98b83 Mon Sep 17 00:00:00 2001 From: Edmund von der Burg Date: Fri, 20 May 2011 16:05:15 +0100 Subject: Added tests for bad requests --- perllib/FixMyStreet/App/Controller/JSON.pm | 81 ++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 perllib/FixMyStreet/App/Controller/JSON.pm (limited to 'perllib/FixMyStreet/App/Controller/JSON.pm') diff --git a/perllib/FixMyStreet/App/Controller/JSON.pm b/perllib/FixMyStreet/App/Controller/JSON.pm new file mode 100644 index 000000000..a0e5490cb --- /dev/null +++ b/perllib/FixMyStreet/App/Controller/JSON.pm @@ -0,0 +1,81 @@ +package FixMyStreet::App::Controller::JSON; +use Moose; +use namespace::autoclean; + +BEGIN { extends 'Catalyst::Controller'; } + +use JSON; +use DateTime; +use DateTime::Format::ISO8601; + +=head1 NAME + +FixMyStreet::App::Controller::JSON - Catalyst Controller + +=head1 DESCRIPTION + +Provide information as JSON + +=head1 METHODS + +=head2 json + +=cut + +sub json : Path : Args(0) { + my ( $self, $c ) = @_; + + # gather the parameters + my $type = $c->req->param('type') || ''; + my $start_date = $c->req->param('start_date') || ''; + my $end_date = $c->req->param('end_date') || ''; + + my $yyyy_mm_dd = qr{^\d{4}-\d\d-\d\d$}; + if ( $start_date !~ $yyyy_mm_dd + || $end_date !~ $yyyy_mm_dd ) + { + $c->stash->{error} = 'Invalid dates supplied'; + return; + } + + # convert the dates to datetimes and trap errors + my $iso8601 = DateTime::Format::ISO8601->new; + my $start_dt = eval { $iso8601->parse_datetime($start_date); }; + my $end_dt = eval { $iso8601->parse_datetime($end_date); }; + unless ( $start_dt && $end_dt ) { + $c->stash->{error} = 'Invalid dates supplied'; + return; + } + + # check that the type is supported + unless ( $type eq 'new_problems' || $type eq 'fixed_problems' ) { + $c->stash->{error} = 'Invalid type supplied'; + return; + } + + my $response = $c->stash->{response} ||= {}; + + # elsif ( $type eq 'new_problems' ) { + # $problems = Problems::created_in_interval( $start_date, $end_date ); + # } + # elsif ( $type eq 'fixed_problems' ) { + # $problems = Problems::fixed_in_interval( $start_date, $end_date ); + # } + +} + +sub end : Private { + my ( $self, $c ) = @_; + + my $response = + $c->stash->{error} + ? { error => $c->stash->{error} } + : $c->stash->{response}; + + $c->res->content_type('application/json; charset=utf-8'); + $c->res->body( encode_json($response) ); +} + +__PACKAGE__->meta->make_immutable; + +1; -- cgit v1.2.3 From 1e67ddbedf6481e3e8650a498679eafd710230ca Mon Sep 17 00:00:00 2001 From: Edmund von der Burg Date: Fri, 20 May 2011 17:33:34 +0100 Subject: port json.cgi code to Catalyst --- perllib/FixMyStreet/App/Controller/JSON.pm | 53 ++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 10 deletions(-) (limited to 'perllib/FixMyStreet/App/Controller/JSON.pm') diff --git a/perllib/FixMyStreet/App/Controller/JSON.pm b/perllib/FixMyStreet/App/Controller/JSON.pm index a0e5490cb..c437aafc0 100644 --- a/perllib/FixMyStreet/App/Controller/JSON.pm +++ b/perllib/FixMyStreet/App/Controller/JSON.pm @@ -47,23 +47,56 @@ sub json : Path : Args(0) { return; } + # check that the dates are sane + if ( $start_dt > $end_dt ) { + $c->stash->{error} = 'Start date after end date'; + return; + } + # check that the type is supported unless ( $type eq 'new_problems' || $type eq 'fixed_problems' ) { $c->stash->{error} = 'Invalid type supplied'; return; } - my $response = $c->stash->{response} ||= {}; - - # elsif ( $type eq 'new_problems' ) { - # $problems = Problems::created_in_interval( $start_date, $end_date ); - # } - # elsif ( $type eq 'fixed_problems' ) { - # $problems = Problems::fixed_in_interval( $start_date, $end_date ); - # } - + # query the database + $c->stash->{response} = + $type eq 'new_problems' + ? Problems::created_in_interval( $start_date, $end_date ) + : Problems::fixed_in_interval( $start_date, $end_date ); } +# If we convert this code to be fully DBIC based then the following snippet is a +# good start. The roadblock to doing it fully is the 'site_restriction' in the +# SQL which is currently provided as SQL, rather than something that could be +# easily added to the DBIC query. The hardest cobrand to change would be the +# cities - so perhaps do it after we know wether that needs to be kept or not. +# +# my $state = +# $type eq 'new_problems' ? 'confirmed' +# : $type eq 'fixed_problems' ? 'fixed_problems' +# : die; +# +# my $one_day = DateTime::Duration->new( days => 1 ); +# +# my $problems = $c->model('DB::Problem')->search( +# { +# created => { +# '>=' => $start_dt, +# '<=' => $end_dt + $one_day, +# }, +# state => $state, +# # ------ add is site_restriction here ------- +# }, +# { +# columns => [ +# 'id', 'title', 'council', 'category', +# 'detail', 'name', 'anonymous', 'confirmed', +# 'whensent', 'service', +# ] +# } +# ); + sub end : Private { my ( $self, $c ) = @_; @@ -73,7 +106,7 @@ sub end : Private { : $c->stash->{response}; $c->res->content_type('application/json; charset=utf-8'); - $c->res->body( encode_json($response) ); + $c->res->body( encode_json( $response || {} ) ); } __PACKAGE__->meta->make_immutable; -- cgit v1.2.3 From e8d2fd68b5a594e1f03fc4a4ca338fcd83f16bdf Mon Sep 17 00:00:00 2001 From: Edmund von der Burg Date: Fri, 3 Jun 2011 11:50:32 +0100 Subject: Match the old JSON urls --- perllib/FixMyStreet/App/Controller/JSON.pm | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'perllib/FixMyStreet/App/Controller/JSON.pm') diff --git a/perllib/FixMyStreet/App/Controller/JSON.pm b/perllib/FixMyStreet/App/Controller/JSON.pm index c437aafc0..d3688f19a 100644 --- a/perllib/FixMyStreet/App/Controller/JSON.pm +++ b/perllib/FixMyStreet/App/Controller/JSON.pm @@ -18,15 +18,24 @@ Provide information as JSON =head1 METHODS -=head2 json +=head2 problems + +Provide JSON of new/fixed problems in a specified time range =cut -sub json : Path : Args(0) { - my ( $self, $c ) = @_; +sub problems : Local { + my ( $self, $c, $path_type ) = @_; + + # get the type from the path - this is to deal with the historic url + # structure. In futur + $path_type ||= ''; + my $type = + $path_type eq 'new' ? 'new_problems' + : $path_type eq 'fixed' ? 'fixed_problems' + : ''; # gather the parameters - my $type = $c->req->param('type') || ''; my $start_date = $c->req->param('start_date') || ''; my $end_date = $c->req->param('end_date') || ''; -- cgit v1.2.3 From 2d0503ccfd4c55ea7252e19603fe4732c2f36f9e Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Wed, 8 Jun 2011 12:39:40 +0100 Subject: Start moving stuff out of Problems.pm, do JSON as per its better-way comment. --- perllib/FixMyStreet/App/Controller/JSON.pm | 82 +++++++++++++++++------------- 1 file changed, 47 insertions(+), 35 deletions(-) (limited to 'perllib/FixMyStreet/App/Controller/JSON.pm') diff --git a/perllib/FixMyStreet/App/Controller/JSON.pm b/perllib/FixMyStreet/App/Controller/JSON.pm index d3688f19a..cbd483f16 100644 --- a/perllib/FixMyStreet/App/Controller/JSON.pm +++ b/perllib/FixMyStreet/App/Controller/JSON.pm @@ -7,6 +7,7 @@ BEGIN { extends 'Catalyst::Controller'; } use JSON; use DateTime; use DateTime::Format::ISO8601; +use List::MoreUtils 'uniq'; =head1 NAME @@ -69,42 +70,53 @@ sub problems : Local { } # query the database - $c->stash->{response} = - $type eq 'new_problems' - ? Problems::created_in_interval( $start_date, $end_date ) - : Problems::fixed_in_interval( $start_date, $end_date ); -} + my ( $state, $date_col ); + if ( $type eq 'new_problems' ) { + $state = 'confirmed'; + $date_col = 'created'; + } elsif ( $type eq 'fixed_problems' ) { + $state = 'fixed'; + $date_col = 'lastupdate'; + } + + my $one_day = DateTime::Duration->new( days => 1 ); + my @problems = $c->model('DB::Problem')->site_restricted->search( { + $date_col => { + '>=' => $start_dt, + '<=' => $end_dt + $one_day, + }, + state => $state, + }, { + columns => [ + 'id', 'title', 'council', 'category', + 'detail', 'name', 'anonymous', 'confirmed', + 'whensent', 'service', + ] + } ); + + my @councils; + foreach my $problem (@problems) { + $problem->name( '' ) if $problem->anonymous == 1; + $problem->service( 'Web interface' ) if $problem->service eq ''; + if ($problem->council) { + (my $council = $problem->council) =~ s/\|.*//g; + my @council_ids = split /,/, $council; + push(@councils, @council_ids); + $problem->council( \@council_ids ); + } + } + @councils = uniq @councils; + my $areas_info = mySociety::MaPit::call('areas', \@councils); + foreach my $problem (@problems) { + if ($problem->council) { + my @council_names = map { $areas_info->{$_}->{name} } @{$problem->council} ; + $problem->council( join(' and ', @council_names) ); + } + } -# If we convert this code to be fully DBIC based then the following snippet is a -# good start. The roadblock to doing it fully is the 'site_restriction' in the -# SQL which is currently provided as SQL, rather than something that could be -# easily added to the DBIC query. The hardest cobrand to change would be the -# cities - so perhaps do it after we know wether that needs to be kept or not. -# -# my $state = -# $type eq 'new_problems' ? 'confirmed' -# : $type eq 'fixed_problems' ? 'fixed_problems' -# : die; -# -# my $one_day = DateTime::Duration->new( days => 1 ); -# -# my $problems = $c->model('DB::Problem')->search( -# { -# created => { -# '>=' => $start_dt, -# '<=' => $end_dt + $one_day, -# }, -# state => $state, -# # ------ add is site_restriction here ------- -# }, -# { -# columns => [ -# 'id', 'title', 'council', 'category', -# 'detail', 'name', 'anonymous', 'confirmed', -# 'whensent', 'service', -# ] -# } -# ); + @problems = map { { $_->get_columns } } @problems; + $c->stash->{response} = \@problems; +} sub end : Private { my ( $self, $c ) = @_; -- cgit v1.2.3 From 500190d03fcbfd8993f46b61bca9e12a7339dbc2 Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Wed, 8 Jun 2011 13:51:17 +0100 Subject: Switch to using c->cobrand->problems to return all problems for a cobrand (so on Barnet only return Barnet problems). --- perllib/FixMyStreet/App/Controller/JSON.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'perllib/FixMyStreet/App/Controller/JSON.pm') diff --git a/perllib/FixMyStreet/App/Controller/JSON.pm b/perllib/FixMyStreet/App/Controller/JSON.pm index cbd483f16..37df98735 100644 --- a/perllib/FixMyStreet/App/Controller/JSON.pm +++ b/perllib/FixMyStreet/App/Controller/JSON.pm @@ -80,7 +80,7 @@ sub problems : Local { } my $one_day = DateTime::Duration->new( days => 1 ); - my @problems = $c->model('DB::Problem')->site_restricted->search( { + my @problems = $c->cobrand->problems->search( { $date_col => { '>=' => $start_dt, '<=' => $end_dt + $one_day, -- cgit v1.2.3 From 21d576c363f9a37ef1c7b322169093084f4a5101 Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Thu, 9 Jun 2011 22:26:45 +0100 Subject: Ordering so test doesn't sometimes randomly fail. --- perllib/FixMyStreet/App/Controller/JSON.pm | 1 + 1 file changed, 1 insertion(+) (limited to 'perllib/FixMyStreet/App/Controller/JSON.pm') diff --git a/perllib/FixMyStreet/App/Controller/JSON.pm b/perllib/FixMyStreet/App/Controller/JSON.pm index 37df98735..3a3010911 100644 --- a/perllib/FixMyStreet/App/Controller/JSON.pm +++ b/perllib/FixMyStreet/App/Controller/JSON.pm @@ -87,6 +87,7 @@ sub problems : Local { }, state => $state, }, { + order_by => { -asc => 'confirmed' }, columns => [ 'id', 'title', 'council', 'category', 'detail', 'name', 'anonymous', 'confirmed', -- cgit v1.2.3