diff --git a/combo/apps/maps/models.py b/combo/apps/maps/models.py index 38dae685..4a03bf91 100644 --- a/combo/apps/maps/models.py +++ b/combo/apps/maps/models.py @@ -255,6 +255,26 @@ class MapLayer(models.Model): else: features = data + if not isinstance(features, list): + return { + 'type': 'FeatureCollection', + 'features': [], + '_combo_err_desc': "Wrong GeoJSON response", + } + if features: + if not isinstance(features[0], dict): + return { + 'type': 'FeatureCollection', + 'features': [], + '_combo_err_desc': "Wrong GeoJSON response", + } + if not ({'geometry', 'properties'} <= set(features[0].keys())): + return { + 'type': 'FeatureCollection', + 'features': [], + '_combo_err_desc': "Wrong GeoJSON response", + } + if properties: properties = [x.strip() for x in properties.split(',') if x.strip()] for feature in features: diff --git a/tests/test_maps_cells.py b/tests/test_maps_cells.py index 928e55af..de796c16 100644 --- a/tests/test_maps_cells.py +++ b/tests/test_maps_cells.py @@ -325,6 +325,57 @@ def test_get_geojson(app, layer, user): == 'Bad response from requested URL (500 Server Error: None for url: None)' ) + wrong_data = { + 'data': [ + {'id': 1, 'text': 'foo 1'}, + {'id': 2, 'text': 'foo 2'}, + ] + } + requests_get.return_value = mock.Mock( + content=json.dumps(wrong_data), json=lambda: wrong_data, status_code=200 + ) + resp = app.get(reverse('mapcell-geojson', kwargs={'cell_id': cell.id, 'layer_slug': layer.slug})) + assert len(resp.json['features']) == 0 + assert resp.json['_combo_err_desc'] == 'Wrong GeoJSON response' + + wrong_data = ['foo', 'bar'] + requests_get.return_value = mock.Mock( + content=json.dumps(wrong_data), json=lambda: wrong_data, status_code=200 + ) + resp = app.get(reverse('mapcell-geojson', kwargs={'cell_id': cell.id, 'layer_slug': layer.slug})) + assert len(resp.json['features']) == 0 + assert resp.json['_combo_err_desc'] == 'Wrong GeoJSON response' + + wrong_data = [ + {'id': 1, 'text': 'foo 1'}, + ] + requests_get.return_value = mock.Mock( + content=json.dumps(wrong_data), json=lambda: wrong_data, status_code=200 + ) + resp = app.get(reverse('mapcell-geojson', kwargs={'cell_id': cell.id, 'layer_slug': layer.slug})) + assert len(resp.json['features']) == 0 + assert resp.json['_combo_err_desc'] == 'Wrong GeoJSON response' + + wrong_data = [ + {'id': 1, 'text': 'foo 1', 'geometry': None}, + ] + requests_get.return_value = mock.Mock( + content=json.dumps(wrong_data), json=lambda: wrong_data, status_code=200 + ) + resp = app.get(reverse('mapcell-geojson', kwargs={'cell_id': cell.id, 'layer_slug': layer.slug})) + assert len(resp.json['features']) == 0 + assert resp.json['_combo_err_desc'] == 'Wrong GeoJSON response' + + wrong_data = [ + {'id': 1, 'text': 'foo 1', 'properties': None}, + ] + requests_get.return_value = mock.Mock( + content=json.dumps(wrong_data), json=lambda: wrong_data, status_code=200 + ) + resp = app.get(reverse('mapcell-geojson', kwargs={'cell_id': cell.id, 'layer_slug': layer.slug})) + assert len(resp.json['features']) == 0 + assert resp.json['_combo_err_desc'] == 'Wrong GeoJSON response' + # check cache duration with mock.patch('combo.utils.requests_wrapper.RequestsSession.request') as requests_get: requests_get.return_value = mock.Mock( @@ -588,6 +639,7 @@ def test_get_geojson_properties(app, layer, user): cell = Map(page=page, placeholder='content', order=0, public=True) cell.title = 'Map' cell.save() + layer.cache_duration = 0 layer.save() options = MapLayerOptions.objects.create(map_cell=cell, map_layer=layer) @@ -615,6 +667,18 @@ def test_get_geojson_properties(app, layer, user): assert 'name' in features[0]['properties'] assert 'extra' not in features[0]['properties'] + wrong_data = { + 'data': [ + {'id': 1, 'text': 'foo 1'}, + {'id': 2, 'text': 'foo 2'}, + ] + } + requests_get.return_value = mock.Mock( + content=json.dumps(wrong_data), json=lambda: wrong_data, status_code=200 + ) + resp = app.get(reverse('mapcell-geojson', kwargs={'cell_id': cell.id, 'layer_slug': layer.slug})) + assert len(resp.json['features']) == 0 + with mock.patch('combo.utils.requests_wrapper.RequestsSession.request') as requests_get: layer.geojson_url = 'http://example.org/geojson?t2' layer.properties = 'name, hop'