diff --git a/app/broadcast_areas/models.py b/app/broadcast_areas/models.py index ba61fb915..271da834f 100644 --- a/app/broadcast_areas/models.py +++ b/app/broadcast_areas/models.py @@ -127,6 +127,10 @@ class BroadcastArea(BaseBroadcastArea, SortableMixin): def ancestors(self): return list(self._ancestors_iterator) + @cached_property + def parent(self): + return next(iter(self.ancestors), None) + @property def _ancestors_iterator(self): id = self.id diff --git a/app/broadcast_areas/utils.py b/app/broadcast_areas/utils.py new file mode 100644 index 000000000..fc50d95c6 --- /dev/null +++ b/app/broadcast_areas/utils.py @@ -0,0 +1,10 @@ +def aggregate_areas(areas): + areas = _aggregate_wards_by_local_authority(areas) + return areas + + +def _aggregate_wards_by_local_authority(areas): + return { + area.parent if area.id.startswith('wd20-') + else area for area in areas + } diff --git a/tests/app/broadcast_areas/custom_polygons.py b/tests/app/broadcast_areas/custom_polygons.py index 7e8ceda16..03a0dcc47 100644 --- a/tests/app/broadcast_areas/custom_polygons.py +++ b/tests/app/broadcast_areas/custom_polygons.py @@ -21,3 +21,19 @@ SANTA_A = [ [25.8910, 66.5500], [25.889, 66.55000], ] + +BURFORD = [ + [51.8925, -1.7495], + [51.7372, -1.7825], + [51.7159, -1.5257], + [51.8866, -1.5037], + [51.8925, -1.7495], +] + +CHELTENHAM = [ + [51.9324, -2.1265], + [51.8633, -2.1306], + [51.8637, -2.0242], + [51.9328, -2.0221], + [51.9324, -2.1265], +] diff --git a/tests/app/broadcast_areas/test_utils.py b/tests/app/broadcast_areas/test_utils.py new file mode 100644 index 000000000..d9db48c0e --- /dev/null +++ b/tests/app/broadcast_areas/test_utils.py @@ -0,0 +1,71 @@ +import pytest + +from app.broadcast_areas.utils import aggregate_areas +from app.models.broadcast_message import BroadcastMessage +from tests import broadcast_message_json +from tests.app.broadcast_areas.custom_polygons import ( + BRISTOL, + BURFORD, + CHELTENHAM, + SANTA_A, + SKYE, +) + + +@pytest.mark.parametrize(('area_ids', 'expected_area_names'), [ + ( + [ + 'wd20-E05004294', # Hester’s Way, Cheltenham (electoral ward) + 'wd20-E05010981', # Painswick & Upton, Stroud (electoral ward) + ], [ + 'Cheltenham', # in Gloucestershire (upper tier authority) + 'Stroud', # in Gloucestershire + ], + ), + ( + [ + 'wd20-E05004294', # Hester’s Way, Cheltenham (electoral ward) + 'wd20-E05009372', # Hackney Central (electoral ward) + ], [ + 'Cheltenham', # in Gloucestershire (upper tier authority) + 'Hackney', # in Greater London* (DB doesn't know this) + ], + ), + ( + [ + 'lad20-E07000037', # High Peak (lower tier authority) + ], + [ + 'High Peak', # in Derbyshire (upper tier authority) + ] + ), + ( + [ + 'lad20-E07000037', # High Peak (lower tier authority) + 'lad20-E07000035', # Derbyshire Dales (lower tier authority) + ], + [ + 'Derbyshire Dales', # in Derbyshire (upper tier authority) + 'High Peak', # in Derbyshire + ] + ), + ( + [ + 'ctry19-E92000001', # England + ], + [ + 'England', + ] + ) +]) +def test_aggregate_areas( + area_ids, + expected_area_names, +): + broadcast_message = BroadcastMessage( + broadcast_message_json(area_ids=area_ids) + ) + + assert sorted( + area.name for area in aggregate_areas(broadcast_message.areas) + ) == expected_area_names