diff --git a/.cypress/cypress/integration/category_tests.js b/.cypress/cypress/integration/category_tests.js index 8cd72b50db..bcb543a3cd 100644 --- a/.cypress/cypress/integration/category_tests.js +++ b/.cypress/cypress/integration/category_tests.js @@ -13,7 +13,7 @@ describe('Basic categories', function() { 'Footpath/bridleway away from road', 'Graffiti', 'Offensive graffiti', - 'Licensing', + 'G|Licensing', 'Parks/landscapes', 'Pavements', 'Potholes', @@ -75,7 +75,7 @@ describe('Basic categories', function() { cy.get('[value="Abandoned vehicles"]').should('not.be.visible'); cy.get('[value="Bus stops"]').should('not.be.visible'); cy.get('[value="Flyposting"]').should('not.be.visible'); - cy.get('[value="Licensing"]').should('be.visible'); + cy.get('[value="G|Licensing"]').should('be.visible'); cy.get('[value="Dropped Kerbs"]').should('be.visible'); cy.get('[value="Skips"]').should('be.visible'); cy.get('[value="Street lighting"]').should('be.visible'); @@ -84,7 +84,7 @@ describe('Basic categories', function() { cy.get('[value="Abandoned vehicles"]').should('not.be.visible'); cy.get('[value="Bus stops"]').should('be.visible'); cy.get('[value="Flyposting"]').should('not.be.visible'); - cy.get('[value="Licensing"]').should('be.visible'); + cy.get('[value="G|Licensing"]').should('be.visible'); cy.get('[value="Dropped Kerbs"]').should('not.be.visible'); cy.get('[value="Skips"]').should('be.visible'); cy.get('[value="Road traffic signs"]').should('be.visible'); diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm index 1971087777..785c4708d1 100644 --- a/perllib/FixMyStreet/App/Controller/Report.pm +++ b/perllib/FixMyStreet/App/Controller/Report.pm @@ -843,6 +843,7 @@ sub stash_category_groups : Private { (my $id = $_) =~ s/[^a-zA-Z]+//g; if (@{$category_groups{$_}} == 1) { my $contact = $category_groups{$_}[0]; + $contact->set_extra_metadata(hoisted => $_); push @list, [ $contact->category_display, $contact ]; } else { my $cats = $category_groups{$_}; diff --git a/perllib/FixMyStreet/App/Controller/Report/New.pm b/perllib/FixMyStreet/App/Controller/Report/New.pm index 400548923f..ad1b1731ae 100644 --- a/perllib/FixMyStreet/App/Controller/Report/New.pm +++ b/perllib/FixMyStreet/App/Controller/Report/New.pm @@ -1823,19 +1823,22 @@ sub generate_map : Private { sub check_for_category : Private { my ( $self, $c, $opts ) = @_; - my $category; - if (!$opts->{with_group}) { - $category = $c->get_param('category') || ''; - } else { - # Group is either an actual group, or a category that wasn't in a group - my $group = $c->get_param('category') || $c->get_param('filter_group') || ''; - if (any { $_->{name} && $group eq $_->{name} } @{$c->stash->{category_groups}}) { + my $category = $c->get_param('category') || ''; + if ($opts->{with_group}) { + if (my ($group) = $category =~ /^G\|(.*)/) { + # A top-level group $c->stash->{group} = $c->stash->{filter_group} = $group; (my $group_id = $group) =~ s/[^a-zA-Z]+//g; my $cat_param = "category.$group_id"; $category = $c->get_param($cat_param); - } else { - $category = $group; + } elsif ($category =~ /^H\|(.*?)\|(.*)/) { + # A hoisted to top-level category + ($group, $category) = ($1, $2); + $c->stash->{group} = $c->stash->{filter_group} = $group; + } elsif (!$category && ($group = $c->get_param('filter_group'))) { + if (any { $_->{name} && $group eq $_->{name} } @{$c->stash->{category_groups}}) { + $c->stash->{group} = $c->stash->{filter_group} = $group; + } } } $category ||= $c->stash->{report}->category || ''; diff --git a/t/app/controller/auth_social.t b/t/app/controller/auth_social.t index 4211e56054..6a4fc89972 100644 --- a/t/app/controller/auth_social.t +++ b/t/app/controller/auth_social.t @@ -129,7 +129,7 @@ for my $state ( 'refused', 'no email', 'existing UID', 'okay' ) { $mech->submit_form_ok( { with_fields => { pc => $test->{pc} || 'SW1A1AA' } }, "submit location" ); $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" ); $mech->submit_form(with_fields => { - category => 'Bins', + category => 'G|Bins', 'category.Bins' => 'Damaged bin', title => 'Test title', detail => 'Test detail', @@ -173,7 +173,7 @@ for my $state ( 'refused', 'no email', 'existing UID', 'okay' ) { if ($page eq 'report') { $mech->content_contains('/report/new'); $mech->content_contains('Salt bin'); - $mech->content_contains('name="category" value="Bins" data-subcategory="Bins" checked'); + $mech->content_like(qr{value="G|Bins"\s+data-subcategory="Bins" checked}); $mech->content_contains('name="category.Bins" data-category_display="Damaged bin" value=\'Damaged bin\' checked'); } elsif ($page eq 'update') { $mech->content_contains('/report/update'); @@ -319,7 +319,7 @@ for my $tw_state ( 'refused', 'existing UID', 'no email' ) { $mech->submit_form_ok( { with_fields => { pc => 'SW1A1AA' } }, "submit location" ); $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" ); $mech->submit_form(with_fields => { - category => 'Bins', + category => 'G|Bins', 'category.Bins' =>'Damaged bin', title => 'Test title', detail => 'Test detail', diff --git a/t/app/controller/report_new.t b/t/app/controller/report_new.t index 08c0496bb0..624b0abb63 100644 --- a/t/app/controller/report_new.t +++ b/t/app/controller/report_new.t @@ -680,9 +680,9 @@ subtest "category groups" => sub { my $div = ']*>\s*'; my $div_end = '\s*'; my $pavements_label = ']* for="category_Pavements">Pavements\s*' . $div_end; - my $pavements_input = ']* value="Pavements" data-subcategory="Pavements">\s*'; - my $pavements_input_checked = ']* value="Pavements" data-subcategory="Pavements" checked>\s*'; - my $roads = $div . ']* value="Roads" data-subcategory="Roads">\s*]* for="category_Roads">Roads\s*' . $div_end; + my $pavements_input = ']* value="G|Pavements"\s+data-subcategory="Pavements">\s*'; + my $pavements_input_checked = ']* value="G|Pavements"\s+data-subcategory="Pavements" checked>\s*'; + my $roads = $div . ']* value="G|Roads"\s+data-subcategory="Roads">\s*]* for="category_Roads">Roads\s*' . $div_end; my $trees_label = '\s*' . $div_end; my $trees_input = $div . ']* value=\'Trees\'>\s*'; my $trees_input_checked = $div . ']* value=\'Trees\' checked>\s*'; @@ -708,18 +708,28 @@ subtest "category groups" => sub { $mech->content_like(qr{$fieldset_pavements$options}); $mech->content_like(qr{$fieldset_roads$options}); # Server submission of pavement subcategory - $mech->get_ok("/report/new?lat=$saved_lat&lon=$saved_lon&category=Pavements&category.Pavements=Potholes"); + $mech->get_ok("/report/new?lat=$saved_lat&lon=$saved_lon&category=G|Pavements&category.Pavements=Potholes"); $mech->content_like(qr{$pavements_input_checked$pavements_label$roads$trees_input$trees_label}); $mech->content_like(qr{$fieldset_pavements$optionsS}); $mech->content_like(qr{$fieldset_roads$options}); $contact9->update( { extra => { group => 'Lights' } } ); $mech->get_ok("/report/new?lat=$saved_lat&lon=$saved_lon"); - $streetlighting = $div . ']*value=\'Street lighting\'>\s*]* for="category_\d+">Street lighting\s*' . $div_end; + $streetlighting = $div . ']*value=\'H|Lights\|Street lighting\'>\s*]* for="category_\d+">Street lighting\s*' . $div_end; + $potholes_input = $div . ']* value=\'H|Pavements\|Potholes\'>\s*'; $potholes_label = ']* for="category_\d+">Potholes\s*' . $div_end; $mech->content_like(qr{$potholes_input$potholes_label$roads$streetlighting$trees_input$trees_label}); $mech->content_unlike(qr{$fieldset_pavements}); $mech->content_like(qr{$fieldset_roads$options}); + + $mech->submit_form_ok({ with_fields => { + category => 'H|Lights|Street lighting', + title => 'Test Report', + detail => 'Test report details', + username_register => 'jo@example.org', + name => 'Jo Bloggs', + } }); + $mech->content_contains('Now check your email'); }; }; diff --git a/t/cobrand/brent.t b/t/cobrand/brent.t index f3b93eb03d..799a829424 100644 --- a/t/cobrand/brent.t +++ b/t/cobrand/brent.t @@ -927,7 +927,7 @@ FixMyStreet::override_config { with_fields => { title => "Test Report", detail => 'Test report details.', - category => 'Parks and open spaces', + category => 'G|Parks and open spaces', 'category.Parksandopenspaces' => 'Overgrown grass', } }, "submit details"); @@ -951,7 +951,7 @@ FixMyStreet::override_config { with_fields => { title => "Test Report", detail => 'Test report details.', - category => 'Parks and open spaces', + category => 'G|Parks and open spaces', 'category.Parksandopenspaces' => 'Overgrown grass', } }, "submit details"); @@ -970,7 +970,7 @@ FixMyStreet::override_config { with_fields => { title => "Test Report", detail => 'Test report details.', - category => 'Parks and open spaces', + category => 'G|Parks and open spaces', 'category.Parksandopenspaces' => 'Overgrown grass', } }, "submit details"); @@ -994,7 +994,7 @@ FixMyStreet::override_config { with_fields => { title => "Test Report", detail => 'Test report details.', - category => 'Parks and open spaces', + category => 'G|Parks and open spaces', 'category.Parksandopenspaces' => 'Ponds', } }, "submit details"); diff --git a/t/cobrand/northumberland.t b/t/cobrand/northumberland.t index 0e5d51c38f..7764597bcd 100644 --- a/t/cobrand/northumberland.t +++ b/t/cobrand/northumberland.t @@ -87,7 +87,7 @@ FixMyStreet::override_config { $mech->content_contains('Main Carriageway'); $mech->content_contains('Potholes'); $mech->content_contains("Trees'>"); - $mech->content_contains('value=\'Flytipping\' data-nh="1"'); + $mech->content_contains('value=\'H|Staff Only - Out Of Hours|Flytipping\' data-nh="1"'); # A-road where NH responsible for litter, council categories will also be present mock_road("A5103", 1); @@ -97,7 +97,7 @@ FixMyStreet::override_config { $mech->content_contains('Main Carriageway'); $mech->content_contains('Potholes'); $mech->content_contains('Trees\'>'); - $mech->content_contains('value=\'Flytipping\' data-nh="1"'); + $mech->content_contains('value=\'H|Staff Only - Out Of Hours|Flytipping\' data-nh="1"'); # A-road where NH not responsible for litter, no NH litter categories mock_road("A34", 0); @@ -107,7 +107,7 @@ FixMyStreet::override_config { $mech->content_lacks('Main Carriageway'); $mech->content_contains('Potholes'); $mech->content_contains('Trees\'>'); - $mech->content_contains('value=\'Flytipping\' data-nh="1"'); + $mech->content_contains('value=\'H|Staff Only - Out Of Hours|Flytipping\' data-nh="1"'); }; }; diff --git a/templates/web/base/report/new/category.html b/templates/web/base/report/new/category.html index e83a73a3b8..7efcd900eb 100644 --- a/templates/web/base/report/new/category.html +++ b/templates/web/base/report/new/category.html @@ -24,7 +24,12 @@ [%~ FOREACH group_or_cat IN category_groups ~%]
[% IF group_or_cat.name %] - + [% group_hint = group_or_cat.categories.first.get_extra_metadata('group_hint') %] [%~ IF group_hint %] @@ -32,9 +37,15 @@ [% group_hint | safe %]
[% END ~%] - [% ELSE # A category not in a group %] - [% cat_lc = group_or_cat.category | lower =%] - diff --git a/web/cobrands/fixmystreet/fixmystreet.js b/web/cobrands/fixmystreet/fixmystreet.js index de09f6df3d..0e7716e2f4 100644 --- a/web/cobrands/fixmystreet/fixmystreet.js +++ b/web/cobrands/fixmystreet/fixmystreet.js @@ -1848,11 +1848,11 @@ function re_select(group, category) { var group_id = group.replace(/[^a-z]+/gi, ''); var cat_in_group = $("#subcategory_" + group_id + " input[value=\"" + category + "\"]"); if (cat_in_group.length) { - $('#form_category_fieldset input[value="' + group + '"]')[0].checked = true; + $('#form_category_fieldset input[data-valuealone="' + group + '"]')[0].checked = true; cat_in_group[0].checked = true; } else { var top_level = group || category; - var top_level_match = $("#form_category_fieldset input[value=\"" + top_level + "\"]"); + var top_level_match = $("#form_category_fieldset input[data-valuealone=\"" + top_level + "\"]"); if (top_level && top_level_match.length) { top_level_match[0].checked = true; } @@ -1976,7 +1976,7 @@ fixmystreet.fetch_reporting_data = function() { fixmystreet.reporting = {}; fixmystreet.reporting.selectedCategory = function() { var $group_or_cat_input = $('#form_category_fieldset input:checked'), - group_or_cat = $group_or_cat_input.val() || '', + group_or_cat = $group_or_cat_input.data('valuealone') || '', group_id = group_or_cat.replace(/[^a-z]+/gi, ''), $subcategory = $("#subcategory_" + group_id), $subcategory_input = $subcategory.find('input:checked'),