Skip to content

Commit

Permalink
[FMS] Add suggest_duplicates feature to FixMyStreet
Browse files Browse the repository at this point in the history
Showing reports that might be duplicates of the report the user
is making is a cobrand feature, and only works on branded sites.

This makes it work on cobrand areas on FixMyStreet where the
duplication_suggestion is turned on for the cobrand on the
selected category.

mysociety/societyworks#3646
  • Loading branch information
MorayMySoc committed Jul 11, 2023
1 parent 0e0758c commit 8b7edf8
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 47 deletions.
20 changes: 19 additions & 1 deletion .cypress/cypress/integration/duplicates.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,25 @@ describe('Duplicate tests', function() {
cy.visit('http://borsetshire.localhost:3001/_test/teardown/regression-duplicate-hide');
});

it.only('does not show duplicate suggestions when signing in during reporting', function() {
it('has a separate duplicate suggestions step when on cobrands on FMS', function() {
cy.server();
cy.route('/report/new/ajax*').as('report-ajax');
cy.route('/around/nearby*').as('nearby-ajax');
cy.visit('http://fixmystreet.localhost:3001/_test/setup/regression-duplicate-hide'); // Server-side setup
cy.visit('http://fixmystreet.localhost:3001/report/1');
cy.contains('Report another problem here').click();
cy.wait('@report-ajax');
cy.pickCategory('Licensing');
cy.nextPageReporting();
cy.get('input[value=Skips]').click();
cy.wait('@nearby-ajax');
cy.nextPageReporting();
cy.contains('Already been reported?');
cy.get('.extra-category-questions').should('not.be.visible');
cy.visit('http://fixmystreet.localhost:3001/_test/teardown/regression-duplicate-hide');
});

it('does not show duplicate suggestions when signing in during reporting', function() {
cy.server();
cy.route('/report/new/ajax*').as('report-ajax');
cy.route('/around/nearby*').as('nearby-ajax');
Expand Down
1 change: 1 addition & 0 deletions perllib/FixMyStreet/App/Controller/Around.pm
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ sub nearby : Path {
longitude => $c->get_param('longitude'),
categories => [ $c->get_param('filter_category') || () ],
states => $states,
bodies => $c->get_param('bodies'),
};
$c->cobrand->call_hook('around_nearby_filter', $params);
$c->forward('/report/_nearby_json', [ $params ]);
Expand Down
86 changes: 45 additions & 41 deletions perllib/FixMyStreet/App/Controller/Report.pm
Original file line number Diff line number Diff line change
Expand Up @@ -675,49 +675,53 @@ sub nearby_json :PathPart('nearby.json') :Chained('id') :Args(0) {
sub _nearby_json :Private {
my ($self, $c, $params) = @_;

# This is for the list template, this is a list on that page.
$c->stash->{page} = 'report';
if ($params->{fms_no_duplicate}) {
$c->res->content_type('application/json; charset=utf-8');
$c->res->body(encode_json({ 'pins' => ''}));
} else {
# This is for the list template, this is a list on that page.
$c->stash->{page} = 'report';

# distance in metres
my $dist;
if (my $mode = $c->get_param('mode')) {
$dist = $c->cobrand->nearby_distances->{$mode};
# distance in metres
my $dist;
if (my $mode = $c->get_param('mode')) {
$dist = $c->cobrand->nearby_distances->{$mode};
}
$dist ||= $c->get_param('distance') || '';
$dist = 1000 unless $dist =~ /^\d+$/;
$dist = 1000 if $dist > 1000;
$params->{distance} = $dist / 1000 unless $params->{distance}; # DB measures in km

my $pin_size = $c->get_param('pin_size') || '';
$pin_size = 'small' unless $pin_size =~ /^(mini|small|normal|big)$/;

$params->{extra} = $c->cobrand->call_hook('display_location_extra_params');
$params->{limit} = 5;

my $nearby = $c->model('DB::Nearby')->nearby($c, %$params);

# Want to treat these as if they were on map
$nearby = [ map { $_->problem } @$nearby ];
my @pins = map {
my $p = $_->pin_data('around');
[ $p->{latitude}, $p->{longitude}, $p->{colour},
$p->{id}, $p->{title}, $pin_size, JSON->false
]
} @$nearby;

my @extra_pins = $c->cobrand->call_hook('extra_nearby_pins', $params->{latitude}, $params->{longitude}, $dist);
@pins = (@pins, @extra_pins) if @extra_pins;

my $list_html = $c->render_fragment(
'report/nearby.html',
{ reports => $nearby, inline_maps => $c->get_param("inline_maps") ? 1 : 0, extra_pins => \@extra_pins }
);
my $json = { pins => \@pins };
$json->{reports_list} = $list_html if $list_html;
my $body = encode_json($json);
$c->res->content_type('application/json; charset=utf-8');
$c->res->body($body);
}
$dist ||= $c->get_param('distance') || '';
$dist = 1000 unless $dist =~ /^\d+$/;
$dist = 1000 if $dist > 1000;
$params->{distance} = $dist / 1000 unless $params->{distance}; # DB measures in km

my $pin_size = $c->get_param('pin_size') || '';
$pin_size = 'small' unless $pin_size =~ /^(mini|small|normal|big)$/;

$params->{extra} = $c->cobrand->call_hook('display_location_extra_params');
$params->{limit} = 5;

my $nearby = $c->model('DB::Nearby')->nearby($c, %$params);

# Want to treat these as if they were on map
$nearby = [ map { $_->problem } @$nearby ];
my @pins = map {
my $p = $_->pin_data('around');
[ $p->{latitude}, $p->{longitude}, $p->{colour},
$p->{id}, $p->{title}, $pin_size, JSON->false
]
} @$nearby;

my @extra_pins = $c->cobrand->call_hook('extra_nearby_pins', $params->{latitude}, $params->{longitude}, $dist);
@pins = (@pins, @extra_pins) if @extra_pins;

my $list_html = $c->render_fragment(
'report/nearby.html',
{ reports => $nearby, inline_maps => $c->get_param("inline_maps") ? 1 : 0, extra_pins => \@extra_pins }
);

my $json = { pins => \@pins };
$json->{reports_list} = $list_html if $list_html;
my $body = encode_json($json);
$c->res->content_type('application/json; charset=utf-8');
$c->res->body($body);
}


Expand Down
24 changes: 24 additions & 0 deletions perllib/FixMyStreet/Cobrand/FixMyStreet.pm
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,30 @@ sub map_type {
return $self->next::method();
}

sub suggest_duplicates { 1 };

sub around_nearby_filter {
my ($self, $params) = @_;

if (!$params->{bodies}) {
$params->{fms_no_duplicate} = 1;
return;
}
my $bodies = decode_json($params->{bodies});
my $bodies_with_duplicate_feature = FixMyStreet->config('COBRAND_FEATURES')->{suggest_duplicates} || {};
my @cobrands;
for my $cobrand (keys %$bodies_with_duplicate_feature) {
push @cobrands, FixMyStreet::Cobrand->get_class_for_moniker($cobrand)->new;
}
for my $council (@cobrands) {
if ($council->body && grep( { $_ eq $council->body->name || $_ eq $council->body->cobrand_name } @$bodies)) {
return;
}
};

$params->{fms_no_duplicate} = 1;
}

sub example_places {
my $self = shift;
return [ 'SY23 4AD', 'Abertawe' ] if $self->on_welsh_site;
Expand Down
10 changes: 5 additions & 5 deletions t/app/controller/report_new_open311.t
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ my $contact1 = $mech->create_contact_ok(
category => 'Street lighting',
email => '100',
extra => [ { description => 'Lamppost number', code => 'number', required => 'True' },
{ description => 'Lamppost type', code => 'type', required => 'False', values =>
{ description => 'Lamppost type', code => 'lamptype', required => 'False', values =>
{ value => [ { name => ['Gas'], key => ['old'] }, { name => [ 'Yellow' ], key => [ 'modern' ] } ] }
}
],
Expand Down Expand Up @@ -125,7 +125,7 @@ foreach my $test (
},
changes => {
number => '',
type => '',
lamptype => '',
},
errors => [
'This information is required',
Expand All @@ -141,7 +141,7 @@ foreach my $test (
username_register => '[email protected]',
category => 'Street lighting',
number => 27,
type => 'old',
lamptype => 'old',
},
extra => [
{
Expand All @@ -150,7 +150,7 @@ foreach my $test (
description => 'Lamppost number',
},
{
name => 'type',
name => 'lamptype',
value => 'old',
description => 'Lamppost type',
}
Expand Down Expand Up @@ -251,7 +251,7 @@ foreach my $test (

if ( $test->{fields}->{category} eq 'Street lighting' ) {
my $result = scraper {
process 'select#form_type option', 'option[]' => '@value';
process 'select#form_lamptype option', 'option[]' => '@value';
}
->scrape( $mech->response );

Expand Down
1 change: 1 addition & 0 deletions web/js/duplicates.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
nearby_url = '/around/nearby';
url_params.mode = 'suggestions'; // Only want to bother public with very nearby reports (default 250 metres)
url_params.pin_size = 'normal';
url_params.bodies = JSON.stringify(fixmystreet.bodies);
}

if ($('html').hasClass('mobile')) {
Expand Down

0 comments on commit 8b7edf8

Please sign in to comment.