From 32cf6ba69d06d621048f59d9438e557d810e0cb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Fri, 14 Sep 2018 12:16:33 +0200 Subject: [PATCH] maps: require all words to match when querying layer features (#26268) --- combo/apps/maps/models.py | 21 +++++++++++++-------- tests/test_maps_cells.py | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/combo/apps/maps/models.py b/combo/apps/maps/models.py index e860ac4d..3a8ae69d 100644 --- a/combo/apps/maps/models.py +++ b/combo/apps/maps/models.py @@ -203,21 +203,26 @@ class MapLayer(models.Model): features = [x for x in features if match(x)] if request and request.GET.get('q'): - query = slugify(request.GET['q']) + # all words must match + query_words = [slugify(x) for x in request.GET['q'].split()] + + additional_strings = [] + if multiple_layers: # also match on layer name + additional_strings = [self.label] def match(feature): - for geo_property in feature['properties'].values(): + matching_query_words = set() + for geo_property in feature['properties'].values() + additional_strings: if not isinstance(geo_property, six.string_types): continue - if query in slugify(geo_property): + for word in query_words: + if word in slugify(geo_property): + matching_query_words.add(word) + if len(matching_query_words) == len(query_words): return True return False - if multiple_layers and query in slugify(self.label): - # also match on layer name, get them all - pass - else: - features = [x for x in features if match(x)] + features = [x for x in features if match(x)] for feature in features: feature['properties']['layer'] = { diff --git a/tests/test_maps_cells.py b/tests/test_maps_cells.py index f1db9651..5e385570 100644 --- a/tests/test_maps_cells.py +++ b/tests/test_maps_cells.py @@ -280,6 +280,18 @@ def test_get_geojson(app, layer, user): resp = app.get(reverse('mapcell-geojson', kwargs={'cell_id': cell.id}) + '?lng=2.54&lat=48.84&distance=100') assert len(json.loads(resp.content)['features']) == 0 + # check on multiple words + with mock.patch('combo.utils.requests_wrapper.RequestsSession.request') as requests_get: + requests_get.return_value = mock.Mock( + content=SAMPLE_GEOJSON_CONTENT, + json=lambda: json.loads(SAMPLE_GEOJSON_CONTENT), + status_code=200) + resp = app.get(reverse('mapcell-geojson', kwargs={'cell_id': cell.id}) + '?q=bar baz') + assert len(json.loads(resp.content)['features']) == 1 + + resp = app.get(reverse('mapcell-geojson', kwargs={'cell_id': cell.id}) + '?q=quux baz') + assert len(json.loads(resp.content)['features']) == 0 + # add a second layer layer2 = MapLayer() layer2.label = 'xxx' @@ -305,6 +317,12 @@ def test_get_geojson(app, layer, user): resp = app.get(reverse('mapcell-geojson', kwargs={'cell_id': cell.id}) + '?q=bicycle') assert len(json.loads(resp.content)['features']) == 2 + resp = app.get(reverse('mapcell-geojson', kwargs={'cell_id': cell.id}) + '?q=bar bicycle') + assert len(json.loads(resp.content)['features']) == 1 + + resp = app.get(reverse('mapcell-geojson', kwargs={'cell_id': cell.id}) + '?q=quux bicycle') + assert len(json.loads(resp.content)['features']) == 0 + def test_get_geojson_properties(app, layer, user): page = Page(title='xxx', slug='new', template_name='standard') -- 2.19.0