diff options
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Report.pm | 23 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/ResultSet/ResponsePriority.pm | 24 | ||||
-rw-r--r-- | t/app/model/responsepriority.t | 103 | ||||
-rw-r--r-- | templates/web/base/report/_inspect.html | 4 | ||||
-rw-r--r-- | web/cobrands/fixmystreet/staff.js | 24 |
5 files changed, 129 insertions, 49 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm index eefb4fc99..223cea9b4 100644 --- a/perllib/FixMyStreet/App/Controller/Report.pm +++ b/perllib/FixMyStreet/App/Controller/Report.pm @@ -312,27 +312,10 @@ sub inspect : Private { $c->forward('/admin/categories_for_point'); $c->stash->{report_meta} = { map { $_->{name} => $_ } @{ $c->stash->{problem}->get_extra_fields() } }; - my %category_body = map { $_->category => $_->body_id } map { $_->contacts->all } values %{$problem->bodies}; - - my @priorities = $c->model('DB::ResponsePriority')->for_bodies($problem->bodies_str_ids)->all; - my $priorities_by_category = {}; - foreach my $pri (@priorities) { - my $any = 0; - foreach ($pri->contacts->all) { - $any = 1; - push @{$priorities_by_category->{$_->category}}, $pri->id . '=' . URI::Escape::uri_escape_utf8($pri->name); - } - if (!$any) { - foreach (grep { $category_body{$_} == $pri->body_id } @{$c->stash->{categories}}) { - push @{$priorities_by_category->{$_}}, $pri->id . '=' . URI::Escape::uri_escape_utf8($pri->name); - } - } + if ($c->cobrand->can('council_area_id')) { + my $priorities_by_category = FixMyStreet::App->model('DB::ResponsePriority')->by_categories($c->cobrand->council_area_id, @{$c->stash->{contacts}}); + $c->stash->{priorities_by_category} = $priorities_by_category; } - foreach (keys %{$priorities_by_category}) { - $priorities_by_category->{$_} = join('&', @{$priorities_by_category->{$_}}); - } - - $c->stash->{priorities_by_category} = $priorities_by_category; if ( $c->get_param('save') ) { $c->forward('/auth/check_csrf_token'); diff --git a/perllib/FixMyStreet/DB/ResultSet/ResponsePriority.pm b/perllib/FixMyStreet/DB/ResultSet/ResponsePriority.pm index aa9c426f4..89bb4dfd7 100644 --- a/perllib/FixMyStreet/DB/ResultSet/ResponsePriority.pm +++ b/perllib/FixMyStreet/DB/ResultSet/ResponsePriority.pm @@ -3,20 +3,18 @@ use base 'DBIx::Class::ResultSet'; use strict; use warnings; +use Moo; +use HTML::Entities; -sub for_bodies { - my ($rs, $bodies, $category) = @_; - my $attrs = { - 'me.body_id' => $bodies, - }; - if ($category) { - $attrs->{'contact.category'} = [ $category, undef ]; - } - $rs->search($attrs, { - order_by => 'name', - join => { 'contact_response_priorities' => 'contact' }, - distinct => 1, - }); +with('FixMyStreet::Roles::ContactExtra'); + +sub join_table { + return 'contact_response_priorities'; +} + +sub map_extras { + my ($rs, @ts) = @_; + return map { { id => $_->id, name => encode_entities($_->name) } } @ts; } 1; diff --git a/t/app/model/responsepriority.t b/t/app/model/responsepriority.t new file mode 100644 index 000000000..03c5bccae --- /dev/null +++ b/t/app/model/responsepriority.t @@ -0,0 +1,103 @@ +use strict; +use warnings; +use Test::More; + +use FixMyStreet::App; +use FixMyStreet::TestMech; +use JSON::MaybeXS; + +my $mech = FixMyStreet::TestMech->new; +my $area_id = 2237; + +my $oxfordshire = $mech->create_body_ok($area_id, 'Oxfordshire County Council'); +my $other_body = $mech->create_body_ok($area_id, 'Some Other Council'); +my $potholes_contact = $mech->create_contact_ok( body_id => $oxfordshire->id, category => 'Potholes', email => 'potholes@example.com' ); +my $traffic_lights_contact =$mech->create_contact_ok( body_id => $oxfordshire->id, category => 'Traffic lights', email => 'lights@example.com' ); + +my $potholes_response_priority = FixMyStreet::App->model('DB::ResponsePriority')->find_or_create( + { + body_id => $oxfordshire->id, + name => 'Potholes', + description => 'This priority is to do with potholes' + } +); +$potholes_response_priority->contact_response_priorities->find_or_create({ + contact_id => $potholes_contact->id, +}); + +my $general_response_priority = FixMyStreet::App->model('DB::ResponsePriority')->find_or_create( + { + body_id => $oxfordshire->id, + name => 'All categories', + description => 'This priority is for all categories' + } +); + +subtest 'for_bodies returns correct results' => sub { + my $priorities = FixMyStreet::App->model('DB::ResponsePriority')->for_bodies( + [ $oxfordshire->id ], + 'Potholes' + ); + + is $priorities->count, 2, 'Both priorities are included for Potholes category'; + + $priorities = FixMyStreet::App->model('DB::ResponsePriority')->for_bodies( + [ $oxfordshire->id ], + 'Traffic lights' + ); + + is $priorities->count, 1, 'Only 1 priority is included for Traffic lights category'; + is $priorities->first->name, $general_response_priority->name, 'Correct priority is returned for Traffic lights category'; +}; + +subtest 'by_categories returns allresponse priorities grouped by category' => sub { + my @contacts = FixMyStreet::DB->resultset('Contact')->not_deleted->search( { body_id => [ $oxfordshire->id ] } )->all; + my $priorities = FixMyStreet::App->model('DB::ResponsePriority')->by_categories($area_id, @contacts); + my $potholes = decode_json($priorities->{Potholes}); + my $traffic_lights = decode_json($priorities->{'Traffic lights'}); + + is scalar @$potholes, 2, 'Potholes have 2 defect types'; + is scalar @$traffic_lights, 1, 'Traffic lights have 1 defect type'; +}; + +subtest 'by_categories returns all response priorities for an area with multiple bodies' => sub { + my $other_response_priority = FixMyStreet::App->model('DB::ResponsePriority')->find_or_create( + { + body_id => $other_body->id, + name => 'All categories', + description => 'This priority is for all categories' + } + ); + + my @contacts = FixMyStreet::DB->resultset('Contact')->not_deleted->search( { body_id => [ $oxfordshire->id ] } )->all; + my $priorities = FixMyStreet::App->model('DB::ResponsePriority')->by_categories($area_id, @contacts); + my $potholes = decode_json($priorities->{Potholes}); + my $traffic_lights = decode_json($priorities->{'Traffic lights'}); + + is scalar @$potholes, 3, 'Potholes have 3 defect types'; + is scalar @$traffic_lights, 2, 'Traffic lights have 2 defect types'; +}; + +subtest 'by_categories encodes HTML entities' => sub { + FixMyStreet::App->model('DB::ResponsePriority')->find_or_create( + { + body_id => $other_body->id, + name => 'This priority\'s name has an apostrophe', + description => 'This priority is for all categories' + } + ); + + my @contacts = FixMyStreet::DB->resultset('Contact')->not_deleted->search( { body_id => [ $oxfordshire->id ] } )->all; + my $priorities = FixMyStreet::App->model('DB::ResponsePriority')->by_categories($area_id, @contacts); + + my $traffic_lights = decode_json($priorities->{'Traffic lights'}); + use Data::Dumper; + my $priority = @$traffic_lights[2]; + is $priority->{name}, 'This priority's name has an apostrophe'; +}; + +END { + $mech->delete_body( $other_body ); + $mech->delete_body( $oxfordshire ); + done_testing(); +} diff --git a/templates/web/base/report/_inspect.html b/templates/web/base/report/_inspect.html index 79f48743a..67e28ca1d 100644 --- a/templates/web/base/report/_inspect.html +++ b/templates/web/base/report/_inspect.html @@ -46,11 +46,11 @@ [% cat_prefix = category | lower | replace('[^a-z]', '') %] [% cat_prefix = "category_" _ cat_prefix _ "_" %] [% IF category == problem.category %] - <p data-category="[% category | html %]" data-priorities="[% priorities_by_category.$category %]" data-defect-types='[% category_defect_types.$category %]'> + <p data-category="[% category | html %]" data-priorities='[% priorities_by_category.$category %]' data-defect-types='[% category_defect_types.$category %]'> [% INCLUDE 'report/new/category_extras_fields.html' %] </p> [% ELSE %] - <p data-category="[% category | html %]" class="hidden" data-priorities="[% priorities_by_category.$category %]" data-defect-types='[% category_defect_types.$category %]'> + <p data-category="[% category | html %]" class="hidden" data-priorities='[% priorities_by_category.$category %]' data-defect-types='[% category_defect_types.$category %]'> [% INCLUDE 'report/new/category_extras_fields.html' report_meta='' %] </p> [% END %] diff --git a/web/cobrands/fixmystreet/staff.js b/web/cobrands/fixmystreet/staff.js index ac665b591..370a16618 100644 --- a/web/cobrands/fixmystreet/staff.js +++ b/web/cobrands/fixmystreet/staff.js @@ -196,8 +196,11 @@ $.extend(fixmystreet.set_up, { $('form#report_inspect_form [name=category]').change(function() { var category = $(this).val(), selector = "[data-category='" + category + "']", + $priorities = $('#problem_priority'), $defect_types = $('#defect_type'), - defect_types_data = $("form#report_inspect_form " + selector).data('defect-types') || []; + defect_types_data = $("form#report_inspect_form " + selector).data('defect-types') || [], + priorities_data = $("form#report_inspect_form " + selector).data('priorities') || [], + curr_pri = $priorities.val(); function populateSelect($select, data, label_formatter) { $select.find('option:gt(0)').remove(); @@ -210,20 +213,10 @@ $.extend(fixmystreet.set_up, { $("form#report_inspect_form [data-category]:not(" + selector + ")").addClass("hidden"); $("form#report_inspect_form " + selector).removeClass("hidden"); - // And update the associated priority list - var priorities = $("form#report_inspect_form " + selector).data('priorities'); - var $select = $('#problem_priority'), - curr_pri = $select.val(); - $select.find('option:gt(0)').remove(); - $.each(priorities.split('&'), function(i, kv) { - if (!kv) { - return; - } - kv = kv.split('=', 2); - $select.append($('<option>', { value: kv[0], text: decodeURIComponent(kv[1]) })); - }); - $select.val(curr_pri); + + populateSelect($priorities, priorities_data, 'priorities_type_format'); populateSelect($defect_types, defect_types_data, 'defect_type_format'); + $priorities.val(curr_pri); }); // The inspect form submit button can change depending on the selected state @@ -466,5 +459,8 @@ fixmystreet.utils = fixmystreet.utils || {}; $.extend(fixmystreet.utils, { defect_type_format: function(data) { return data.name; + }, + priorities_type_format: function(data) { + return data.name; } }); |