diff --git a/app/broadcast_areas/__init__.py b/app/broadcast_areas/__init__.py
index a9e86c1c1..f7488d0dc 100644
--- a/app/broadcast_areas/__init__.py
+++ b/app/broadcast_areas/__init__.py
@@ -44,7 +44,7 @@ class BroadcastArea(SortableMixin):
BroadcastAreasRepository().get_simple_polygons_for_area(self.id)
)
- @property
+ @cached_property
def sub_areas(self):
return [
BroadcastArea(row)
diff --git a/app/broadcast_areas/repo.py b/app/broadcast_areas/repo.py
index 3527d0abd..e1aec1333 100644
--- a/app/broadcast_areas/repo.py
+++ b/app/broadcast_areas/repo.py
@@ -166,11 +166,16 @@ class BroadcastAreasRepository(object):
return areas
def get_all_areas_for_library(self, library_id):
+ # only interested in areas with children - local authorities, counties, unitary authorities. not wards.
q = """
SELECT id, name
FROM broadcast_areas
+ JOIN (
+ SELECT DISTINCT broadcast_area_library_group_id
+ FROM broadcast_areas
+ WHERE broadcast_area_library_group_id IS NOT NULL
+ ) AS parent_broadcast_areas ON parent_broadcast_areas.broadcast_area_library_group_id = broadcast_areas.id
WHERE broadcast_area_library_id = ?
- AND broadcast_area_library_group_id IS NULL
"""
results = self.query(q, library_id)
diff --git a/app/main/views/broadcast.py b/app/main/views/broadcast.py
index 0ec91c4f1..16b820f65 100644
--- a/app/main/views/broadcast.py
+++ b/app/main/views/broadcast.py
@@ -160,8 +160,10 @@ def choose_broadcast_sub_area(service_id, broadcast_message_id, library_slug, ar
)
area = BroadcastMessage.libraries.get_areas(area_slug)[0]
+ is_county = any(sub_area.sub_areas for sub_area in area.sub_areas)
+
form = BroadcastAreaFormWithSelectAll.from_library(
- area.sub_areas,
+ [] if is_county else area.sub_areas,
select_all_choice=(area.id, f'All of {area.name}'),
)
if form.validate_on_submit():
@@ -171,6 +173,20 @@ def choose_broadcast_sub_area(service_id, broadcast_message_id, library_slug, ar
service_id=current_service.id,
broadcast_message_id=broadcast_message.id,
))
+
+ if is_county:
+ # area = county. sub_areas = districts. they have wards, so link to individual district pages
+ return render_template(
+ 'views/broadcast/counties.html',
+ form=form,
+ search_form=SearchByNameForm(),
+ show_search_form=(len(area.sub_areas) > 7),
+ library_slug=library_slug,
+ page_title=f'Choose an area of {area.name}',
+ broadcast_message=broadcast_message,
+ county=area,
+ )
+
return render_template(
'views/broadcast/sub-areas.html',
form=form,
diff --git a/app/templates/views/broadcast/counties.html b/app/templates/views/broadcast/counties.html
new file mode 100644
index 000000000..25a317c21
--- /dev/null
+++ b/app/templates/views/broadcast/counties.html
@@ -0,0 +1,42 @@
+{% from "components/page-header.html" import page_header %}
+{% from "components/live-search.html" import live_search %}
+{% from "components/page-footer.html" import sticky_page_footer %}
+{% from "components/form.html" import form_wrapper %}
+
+
+
+{% extends "withnav_template.html" %}
+
+{% block service_page_title %}
+ {{ page_title }}
+{% endblock %}
+
+{% block maincolumn_content %}
+
+ {{ page_header(
+ page_title,
+ back_link=url_for('.choose_broadcast_library', service_id=current_service.id, broadcast_message_id=broadcast_message.id),
+ )}}
+
+ {% call form_wrapper() %}
+
+
+ {{ form.select_all }}
+
+ {{ live_search(target_selector='.file-list-item', show=show_search_form, form=search_form, label='Or by district') }}
+
+ {% for area in county.sub_areas|sort %}
+
+ {% endfor %}
+
+ {{ sticky_page_footer('Add to broadcast') }}
+
+ {% endcall %}
+
+{% endblock %}
diff --git a/tests/app/broadcast_areas/test_broadcast_area.py b/tests/app/broadcast_areas/test_broadcast_area.py
index d14f1b1e8..5a10fe338 100644
--- a/tests/app/broadcast_areas/test_broadcast_area.py
+++ b/tests/app/broadcast_areas/test_broadcast_area.py
@@ -16,7 +16,7 @@ def test_loads_libraries():
False,
),
(
- 'wd20-lad20',
+ 'wd20-lad20-ctyua19',
'Local authorities',
True,
),
@@ -40,7 +40,7 @@ def test_examples():
countries = broadcast_area_libraries.get('ctry19').get_examples()
assert countries == 'England, Northern Ireland, Scotland, and Wales'
- wards = broadcast_area_libraries.get('wd20-lad20').get_examples()
+ wards = broadcast_area_libraries.get('wd20-lad20-ctyua19').get_examples()
assert wards == 'Aberdeen City, Aberdeenshire, Adur, and 375 moreā¦'
diff --git a/tests/app/main/views/test_broadcast.py b/tests/app/main/views/test_broadcast.py
index 37b8d7ce6..088ff76b7 100644
--- a/tests/app/main/views/test_broadcast.py
+++ b/tests/app/main/views/test_broadcast.py
@@ -412,7 +412,7 @@ def test_choose_broadcast_area_page_for_area_with_sub_areas(
'.choose_broadcast_area',
service_id=SERVICE_ONE_ID,
broadcast_message_id=fake_uuid,
- library_slug='wd20-lad20',
+ library_slug='wd20-lad20-ctyua19',
)
assert normalize_spaces(page.select_one('h1').text) == (
'Choose a local authority'
@@ -425,7 +425,7 @@ def test_choose_broadcast_area_page_for_area_with_sub_areas(
'main.choose_broadcast_sub_area',
service_id=SERVICE_ONE_ID,
broadcast_message_id=fake_uuid,
- library_slug='wd20-lad20',
+ library_slug='wd20-lad20-ctyua19',
)
choices = [
(
@@ -453,7 +453,7 @@ def test_choose_broadcast_area_page_for_area_with_sub_areas(
]
-def test_choose_broadcast_sub_area_page(
+def test_choose_broadcast_sub_area_page_for_district_shows_checkboxes_for_wards(
client_request,
service_one,
mock_get_draft_broadcast_message,
@@ -464,7 +464,7 @@ def test_choose_broadcast_sub_area_page(
'main.choose_broadcast_sub_area',
service_id=SERVICE_ONE_ID,
broadcast_message_id=fake_uuid,
- library_slug='wd20-lad20',
+ library_slug='wd20-lad20-ctyua19',
area_slug='lad20-S12000033',
)
assert normalize_spaces(page.select_one('h1').text) == (
@@ -502,6 +502,62 @@ def test_choose_broadcast_sub_area_page(
]
+def test_choose_broadcast_sub_area_page_for_county_shows_links_for_districts(
+ client_request,
+ service_one,
+ mock_get_draft_broadcast_message,
+ fake_uuid,
+):
+ service_one['permissions'] += ['broadcast']
+ page = client_request.get(
+ 'main.choose_broadcast_sub_area',
+ service_id=SERVICE_ONE_ID,
+ broadcast_message_id=fake_uuid,
+ library_slug='wd20-lad20-ctyua19',
+ area_slug='ctyua19-E10000016', # Kent
+ )
+ assert normalize_spaces(page.select_one('h1').text) == (
+ 'Choose an area of Kent'
+ )
+ live_search = page.select_one("[data-module=live-search]")
+ assert live_search['data-targets'] == '.file-list-item'
+ assert live_search.select_one('input')['type'] == 'search'
+ all_choices_checkbox = [
+ (
+ choice.select_one('input')['value'],
+ normalize_spaces(choice.select_one('label').text),
+ )
+ for choice in page.select('form[method=post] .govuk-checkboxes__item')
+ ]
+ districts = [
+ (
+ district['href'],
+ district.text,
+ )
+ for district in page.select('form[method=post] a')
+ ]
+ assert all_choices_checkbox == [
+ ('y', 'All of Kent'),
+ ]
+ assert len(districts) == 12
+ assert districts[0][0] == url_for(
+ 'main.choose_broadcast_sub_area',
+ service_id=SERVICE_ONE_ID,
+ broadcast_message_id=fake_uuid,
+ library_slug='wd20-lad20-ctyua19',
+ area_slug='lad20-E07000105'
+ )
+ assert districts[0][1] == 'Ashford'
+ assert districts[-1][0] == url_for(
+ 'main.choose_broadcast_sub_area',
+ service_id=SERVICE_ONE_ID,
+ broadcast_message_id=fake_uuid,
+ library_slug='wd20-lad20-ctyua19',
+ area_slug='lad20-E07000116'
+ )
+ assert districts[-1][1] == 'Tunbridge Wells'
+
+
def test_add_broadcast_area(
client_request,
service_one,
@@ -554,7 +610,7 @@ def test_add_broadcast_area(
'wd20-S13002836',
]),
))
-def test_add_broadcast_sub_area(
+def test_add_broadcast_sub_area_district_view(
client_request,
service_one,
mock_get_draft_broadcast_message,
@@ -574,7 +630,7 @@ def test_add_broadcast_sub_area(
'.choose_broadcast_sub_area',
service_id=SERVICE_ONE_ID,
broadcast_message_id=fake_uuid,
- library_slug='wd20-lad20',
+ library_slug='wd20-lad20-ctyua19',
area_slug='lad20-S12000033',
_data=post_data,
)
@@ -592,6 +648,44 @@ def test_add_broadcast_sub_area(
)
+def test_add_broadcast_sub_area_county_view(
+ client_request,
+ service_one,
+ mock_get_draft_broadcast_message,
+ mock_update_broadcast_message,
+ fake_uuid,
+ mocker,
+):
+ service_one['permissions'] += ['broadcast']
+ polygon_class = namedtuple("polygon_class", ["as_coordinate_pairs_lat_long"])
+ coordinates = [[50.1, 0.1], [50.2, 0.2], [50.3, 0.2]]
+ polygons = polygon_class(as_coordinate_pairs_lat_long=coordinates)
+ mocker.patch('app.models.broadcast_message.BroadcastMessage.get_simple_polygons', return_value=polygons)
+
+ client_request.post(
+ '.choose_broadcast_sub_area',
+ service_id=SERVICE_ONE_ID,
+ broadcast_message_id=fake_uuid,
+ library_slug='wd20-lad20-ctyua19',
+ area_slug='ctyua19-E10000016', # Kent
+ _data={'select_all': 'y'},
+ )
+ mock_update_broadcast_message.assert_called_once_with(
+ service_id=SERVICE_ONE_ID,
+ broadcast_message_id=fake_uuid,
+ data={
+ 'simple_polygons': coordinates,
+ 'areas': [
+ # These two areas are on the broadcast already
+ 'ctry19-E92000001',
+ 'ctry19-S92000003',
+ ] + [
+ 'ctyua19-E10000016'
+ ]
+ },
+ )
+
+
def test_remove_broadcast_area_page(
client_request,
service_one,