From 60aa2d2b4262e2a343f4f44aef9de4954c5552ac Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Tue, 26 Jan 2021 10:14:04 +0000 Subject: [PATCH] =?UTF-8?q?Display=20areas=20that=20aren=E2=80=99t=20in=20?= =?UTF-8?q?the=20library?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/broadcast_areas/__init__.py | 35 +++++++++++++++++++ app/models/broadcast_message.py | 9 +++-- tests/__init__.py | 2 ++ tests/app/main/views/test_broadcast.py | 47 ++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 2 deletions(-) diff --git a/app/broadcast_areas/__init__.py b/app/broadcast_areas/__init__.py index 5c10f6228..0631f37cd 100644 --- a/app/broadcast_areas/__init__.py +++ b/app/broadcast_areas/__init__.py @@ -89,6 +89,41 @@ class BroadcastArea(SortableMixin): id = parent_broadcast_area.id +class CustomBroadcastArea: + + # We don’t yet have a way to estimate the number of phones in a + # user-defined polygon + count_of_phones = 0 + + def __init__(self, *, name, polygons=None): + self.name = name + self._polygons = polygons or [] + + @property + def polygons(self): + return Polygons( + # Polygons in the DB are stored with the coordinate pair + # order flipped – this flips them back again + Polygons(self._polygons).as_coordinate_pairs_lat_long + ) + + simple_polygons = polygons + + +class CustomBroadcastAreas(SerialisedModelCollection): + model = CustomBroadcastArea + + def __init__(self, *, areas, polygons): + self.items = areas + self._polygons = polygons + + def __getitem__(self, index): + return self.model( + name=self.items[index], + polygons=self._polygons if index == 0 else None, + ) + + class BroadcastAreaLibrary(SerialisedModelCollection, SortableMixin, GetItemByIdMixin): model = BroadcastArea diff --git a/app/models/broadcast_message.py b/app/models/broadcast_message.py index 569bb36bb..8dbbc492f 100644 --- a/app/models/broadcast_message.py +++ b/app/models/broadcast_message.py @@ -5,7 +5,7 @@ from notifications_utils.template import BroadcastPreviewTemplate from orderedset import OrderedSet from werkzeug.utils import cached_property -from app.broadcast_areas import broadcast_area_libraries +from app.broadcast_areas import CustomBroadcastAreas, broadcast_area_libraries from app.broadcast_areas.polygons import Polygons from app.formatters import round_to_significant_figures from app.models import JSONModel, ModelList @@ -74,7 +74,12 @@ class BroadcastMessage(JSONModel): @property def areas(self): - return self.get_areas(areas=self._dict['areas']) + return self.get_areas( + areas=self._dict['areas'] + ) or CustomBroadcastAreas( + areas=self._dict['areas'], + polygons=self._dict['simple_polygons'], + ) @property def parent_areas(self): diff --git a/tests/__init__.py b/tests/__init__.py index 0164f9e3d..f30c4c251 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -657,6 +657,7 @@ def broadcast_message_json( approved_by_id=None, cancelled_by_id=None, areas=None, + simple_polygons=None, content=None, reference=None, template_name='Example template', @@ -676,6 +677,7 @@ def broadcast_message_json( 'areas': areas or [ 'ctry19-E92000001', 'ctry19-S92000003', ], + 'simple_polygons': simple_polygons or [], 'status': status, diff --git a/tests/app/main/views/test_broadcast.py b/tests/app/main/views/test_broadcast.py index 4a5f8512c..6d731be0a 100644 --- a/tests/app/main/views/test_broadcast.py +++ b/tests/app/main/views/test_broadcast.py @@ -684,6 +684,53 @@ def test_preview_broadcast_areas_page( ] == estimates +def test_preview_broadcast_areas_page_with_custom_polygons( + mocker, + client_request, + service_one, + fake_uuid, +): + service_one['permissions'] += ['broadcast'] + mocker.patch( + 'app.broadcast_message_api_client.get_broadcast_message', + return_value=broadcast_message_json( + id_=fake_uuid, + template_id=fake_uuid, + created_by_id=fake_uuid, + service_id=SERVICE_ONE_ID, + status='draft', + areas=['Area one', 'Area two', 'Area three'], + simple_polygons=[ + [[1, 2], [3, 4], [5, 6]], + [[7, 8], [9, 10], [11, 12]], + ], + ), + ) + page = client_request.get( + '.preview_broadcast_areas', + service_id=SERVICE_ONE_ID, + broadcast_message_id=fake_uuid, + ) + + assert [ + normalize_spaces(item.text) + for item in page.select('ul.area-list li.area-list-item') + ] == [ + 'Area one remove', 'Area two remove', 'Area three remove', + ] + + assert len(page.select('#area-list-map')) == 1 + + assert [ + normalize_spaces(item.text) + for item in page.select('ul li.area-list-key') + ] == [ + 'An area of 722.3 square miles Will get the alert', + 'An extra area of 1,402.5 square miles is Likely to get the alert', + '0 phones estimated', + ] + + @pytest.mark.parametrize('areas, expected_list', ( ([], [ 'Countries',