diff --git a/app/assets/stylesheets/components/navigation.scss b/app/assets/stylesheets/components/navigation.scss index e98bad1dc..1bcf79d19 100644 --- a/app/assets/stylesheets/components/navigation.scss +++ b/app/assets/stylesheets/components/navigation.scss @@ -47,6 +47,12 @@ box-shadow: 0 -3px 0 0 #F6D7D2; } + &--government { + background: #942514; + color: #F6D7D2; + box-shadow: 0 -3px 0 0 #942514; + } + } &-service-switch, diff --git a/app/main/forms.py b/app/main/forms.py index e9a11b538..065b62a6d 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -2316,6 +2316,8 @@ class ServiceBroadcastAccountTypeField(GovukRadiosField): # (service_mode, broadcast_channel, allowed_broadcast_provider) # to a value to be used in our form such as "live-severe-ee" def process_data(self, value): + if not value or isinstance(value, str): + return super().process_data(value) (live, broadcast_channel, allowed_broadcast_provider) = value account_type = None if broadcast_channel: @@ -2330,13 +2332,61 @@ class ServiceBroadcastAccountTypeField(GovukRadiosField): # broadcast_channel and provider_restriction to be used by the flask route to send to the # API def post_validate(self, form, validation_stopped): - if not validation_stopped: + if not validation_stopped and self.data: split_values = self.data.split("-") self.service_mode = split_values[0] self.broadcast_channel = split_values[1] self.provider_restriction = split_values[2] if len(split_values) == 3 else 'all' +class OptionalServiceBroadcastAccountTypeField(ServiceBroadcastAccountTypeField): + def pre_validate(self, form): + if self.data is None: + return + super().pre_validate(form) + + +class ServiceBroadcastChannelForm(StripWhitespaceForm): + channel = ServiceBroadcastAccountTypeField( + 'Emergency alerts settings', + thing='mode or channel', + choices=[ + ("training-test", "Training mode"), + ("live-test", "Test channel"), + ("live-severe", "Live channel"), + ("live-government", "Government channel"), + ], + ) + + +class ServiceBroadcastNetworkForm(StripWhitespaceForm): + + network_variant = ServiceBroadcastAccountTypeField( + 'Choose a mobile network', + thing='a mobile network', + choices=[ + ('live-test', 'All networks'), + ('', 'A single network'), + ] + ) + network = OptionalServiceBroadcastAccountTypeField( + 'Choose a mobile network', + thing='a mobile network', + choices=[ + ('live-test-ee', 'EE'), + ('live-test-o2', 'O2'), + ('live-test-vodafone', 'Vodafone'), + ('live-test-three', 'Three'), + ], + ) + + def validate_network(self, field): + if not self.network_variant.data and not field.data: + raise ValidationError('Select a mobile network') + if self.network_variant.data == 'all': + field.data = '' + + class ServiceBroadcastAccountTypeForm(StripWhitespaceForm): account_type = ServiceBroadcastAccountTypeField( 'Change cell broadcast service type', @@ -2349,6 +2399,7 @@ class ServiceBroadcastAccountTypeForm(StripWhitespaceForm): ("live-test-vodafone", "Test channel (Vodafone)"), ("live-test", "Test channel (all networks)"), ("live-severe", "Live (all networks)"), + ("live-government", "Government channel (all networks)"), ], validators=[DataRequired()] ) diff --git a/app/main/views/service_settings.py b/app/main/views/service_settings.py index 29387c35e..5153351a3 100644 --- a/app/main/views/service_settings.py +++ b/app/main/views/service_settings.py @@ -46,6 +46,8 @@ from app.main.forms import ( RenameServiceForm, SearchByNameForm, ServiceBroadcastAccountTypeForm, + ServiceBroadcastChannelForm, + ServiceBroadcastNetworkForm, ServiceContactDetailsForm, ServiceDataRetentionEditForm, ServiceDataRetentionForm, @@ -318,15 +320,79 @@ def service_set_permission(service_id, permission): @main.route("/services//service-settings/broadcasts", methods=["GET", "POST"]) @user_is_platform_admin -def service_set_broadcast_account_type(service_id): - form = ServiceBroadcastAccountTypeForm( - account_type=( +def service_set_broadcast_channel(service_id): + form = ServiceBroadcastChannelForm( + channel=( current_service.live, current_service.broadcast_channel, - current_service.allowed_broadcast_provider + 'all', ) ) + if form.validate_on_submit(): + if form.channel.data == 'live-test': + return redirect(url_for( + '.service_set_broadcast_network', + service_id=current_service.id, + )) + return redirect(url_for( + '.service_confirm_broadcast_account_type', + service_id=current_service.id, + account_type=form.channel.data, + )) + + return render_template( + 'views/service-settings/service-set-broadcast-channel.html', + form=form, + ) + + +@main.route("/services//service-settings/broadcasts/network", methods=["GET", "POST"]) +@user_is_platform_admin +def service_set_broadcast_network(service_id): + if current_service.allowed_broadcast_provider == 'all': + form = ServiceBroadcastNetworkForm( + network_variant=( + current_service.live, + current_service.broadcast_channel, + current_service.allowed_broadcast_provider, + ), + ) + else: + form = ServiceBroadcastNetworkForm( + network_variant='', + network=( + current_service.live, + current_service.broadcast_channel, + current_service.allowed_broadcast_provider + ) + ) + + if form.validate_on_submit(): + return redirect(url_for( + '.service_confirm_broadcast_account_type', + service_id=current_service.id, + account_type=form.network_variant.data or form.network.data, + )) + + return render_template( + 'views/service-settings/service-set-broadcast-network.html', + form=form, + ) + + +@main.route( + "/services//service-settings/broadcasts/", + methods=["GET", "POST"] +) +@user_is_platform_admin +def service_confirm_broadcast_account_type(service_id, account_type): + form = ServiceBroadcastAccountTypeForm(account_type=account_type) + form.validate() + + if form.account_type.errors: + abort(404) + if form.validate_on_submit(): service_api_client.set_service_broadcast_settings( current_service.id, @@ -341,11 +407,10 @@ def service_set_broadcast_account_type(service_id): broadcast_channel=form.account_type.broadcast_channel, provider_restriction=form.account_type.provider_restriction, ) - return redirect(url_for(".service_settings", service_id=service_id)) return render_template( - 'views/service-settings/service-set-broadcast-account-type.html', + 'views/service-settings/service-confirm-broadcast-account-type.html', form=form, ) diff --git a/app/navigation.py b/app/navigation.py index 81fdf53cd..77e1f59e3 100644 --- a/app/navigation.py +++ b/app/navigation.py @@ -243,7 +243,9 @@ class MainNavigation(Navigation): 'service_set_auth_type', 'service_set_channel', 'send_files_by_email_contact_details', - 'service_set_broadcast_account_type', + 'service_confirm_broadcast_account_type', + 'service_set_broadcast_channel', + 'service_set_broadcast_network', 'service_set_email_branding', 'service_set_inbound_number', 'service_set_inbound_sms', diff --git a/app/templates/views/service-settings.html b/app/templates/views/service-settings.html index e28f0a168..567003446 100644 --- a/app/templates/views/service-settings.html +++ b/app/templates/views/service-settings.html @@ -429,20 +429,21 @@ {% endfor %} {% call row() %} - {{ text_field('Send cell broadcasts')}} + {{ text_field('Emergency alerts')}} {% call field(wrap=True) %} {% if not current_service.broadcast_channel %} Off {% else %} + {% if current_service.live and current_service.broadcast_channel == "government" %}Government{% endif %} {% if current_service.live and current_service.broadcast_channel == "severe" %}Live{% endif %} - {% if current_service.live and current_service.broadcast_channel == "test" %}Test {% if current_service.allowed_broadcast_provider != "all" %}({{ current_service.allowed_broadcast_provider|format_mobile_network }}){% else %}(All networks){% endif %}{%endif%} + {% if current_service.live and current_service.broadcast_channel == "test" %}Test {% if current_service.allowed_broadcast_provider != "all" %}({{ current_service.allowed_broadcast_provider|format_mobile_network }}){% else %}(all networks){% endif %}{%endif%} {% if not current_service.live%}Training {% endif%} {% endif %} {% endcall %} {{ edit_field( 'Change', - url_for('.service_set_broadcast_account_type', service_id=current_service.id), - suffix='your settings for Send cell broadcasts' + url_for('.service_set_broadcast_channel', service_id=current_service.id), + suffix='your settings for emergency alerts' ) }} {% endcall %} diff --git a/app/templates/views/service-settings/service-confirm-broadcast-account-type.html b/app/templates/views/service-settings/service-confirm-broadcast-account-type.html new file mode 100644 index 000000000..229f55856 --- /dev/null +++ b/app/templates/views/service-settings/service-confirm-broadcast-account-type.html @@ -0,0 +1,60 @@ +{% extends "withnav_template.html" %} +{% from "components/page-header.html" import page_header %} +{% from "components/page-footer.html" import page_footer %} +{% from "components/form.html" import form_wrapper %} + +{% block service_page_title %} + Confirm emergency alert settings +{% endblock %} + +{% block maincolumn_content %} + +
+
+ {{ page_header( + 'Confirm emergency alert settings', + back_link=url_for('.service_set_broadcast_channel', service_id=current_service.id) + ) }} + {% if form.account_type.service_mode == 'training' %} +

+ Training +

+

+ No phones will receive alerts sent from this service. +

+ {% else %} +

+ {% if form.account_type.broadcast_channel == 'severe' %} + Live + {% elif form.account_type.broadcast_channel == 'government' %} + Government + {% else %} + {{ form.account_type.broadcast_channel|title }} + {% endif %} + {% if form.account_type.provider_restriction != 'all' %} + ({{ form.account_type.provider_restriction|format_mobile_network }}) + {% endif %} + {% if form.account_type.broadcast_channel == 'test' and form.account_type.provider_restriction == 'all'%} + (all networks) + {% endif %} + +

+

+ Members of the public + {% if form.account_type.broadcast_channel == 'test' %} + who have switched on the test channel on their phones + {% endif %} + will receive alerts sent from this service + {%- if form.account_type.broadcast_channel == 'government' -%} + , even if they’ve opted out + {%- endif %}. +

+ {% endif %} + + {% call form_wrapper() %} + {{ page_footer('Confirm') }} + {% endcall %} +
+
+ +{% endblock %} diff --git a/app/templates/views/service-settings/service-set-broadcast-account-type.html b/app/templates/views/service-settings/service-set-broadcast-account-type.html index 83b739d16..78d64c049 100644 --- a/app/templates/views/service-settings/service-set-broadcast-account-type.html +++ b/app/templates/views/service-settings/service-set-broadcast-account-type.html @@ -6,7 +6,7 @@ {% block service_page_title %} Send cell broadcasts {% endblock %} - + {% block maincolumn_content %}
@@ -24,7 +24,7 @@ } } }) }} - {{ page_footer('Save') }} + {{ page_footer('Continue') }} {% endcall %}
diff --git a/app/templates/views/service-settings/service-set-broadcast-channel.html b/app/templates/views/service-settings/service-set-broadcast-channel.html new file mode 100644 index 000000000..b8a07b1d1 --- /dev/null +++ b/app/templates/views/service-settings/service-set-broadcast-channel.html @@ -0,0 +1,32 @@ +{% extends "withnav_template.html" %} +{% from "components/page-footer.html" import page_footer %} +{% from "components/form.html" import form_wrapper %} +{% from "components/back-link/macro.njk" import govukBackLink %} + +{% block service_page_title %} + Emergency alerts settings +{% endblock %} + +{% block maincolumn_content %} + +
+
+ {{ govukBackLink({ + "text": "Back", + "href": url_for('.service_settings', service_id=current_service.id) + }) }} + {% call form_wrapper() %} + {{ form.channel(param_extensions={ + 'fieldset': { + 'legend': { + 'isPageHeading': True, + 'classes': 'govuk-fieldset__legend--l' + } + } + }) }} + {{ page_footer('Continue') }} + {% endcall %} +
+
+ +{% endblock %} diff --git a/app/templates/views/service-settings/service-set-broadcast-network.html b/app/templates/views/service-settings/service-set-broadcast-network.html new file mode 100644 index 000000000..a32f24819 --- /dev/null +++ b/app/templates/views/service-settings/service-set-broadcast-network.html @@ -0,0 +1,37 @@ +{% extends "withnav_template.html" %} +{% from "components/page-header.html" import page_header %} +{% from "components/page-footer.html" import page_footer %} +{% from "components/form.html" import form_wrapper %} +{% from "components/radios.html" import radio, conditional_radio_panel %} +{% from "components/select-input.html" import select_wrapper %} +{% from "components/back-link/macro.njk" import govukBackLink %} + +{% block service_page_title %} + Choose a mobile network +{% endblock %} + +{% block maincolumn_content %} + +
+
+ {{ page_header( + 'Choose a mobile network', + back_link=url_for('.service_set_broadcast_channel', service_id=current_service.id) + ) }} + {% call form_wrapper() %} + {% call select_wrapper(form.network_variant, hide_legend=True) %} + {% for option in form.network_variant %} + {{ radio(option, data_target='single-network' if option.data == "" else None) }} + {% endfor %} + {% endcall %} + {% call conditional_radio_panel('single-network') %} + {{ form.network( + param_extensions={'fieldset': {'legend': {'classes': 'govuk-visually-hidden'}}} + ) }} + {% endcall %} + {{ page_footer('Continue') }} + {% endcall %} +
+
+ +{% endblock %} diff --git a/app/templates/withnav_template.html b/app/templates/withnav_template.html index 296f2a029..f13c62b43 100644 --- a/app/templates/withnav_template.html +++ b/app/templates/withnav_template.html @@ -22,11 +22,17 @@ {% elif current_service.has_permission('broadcast') %} {% if current_service.trial_mode %} Training - {% else %} + {% elif current_service.broadcast_channel == 'severe' %} Live - {% endif %} - {% if current_service.allowed_broadcast_provider != "all" %} - ({{ current_service.allowed_broadcast_provider }}) + {% elif current_service.broadcast_channel == 'test' %} + {{ current_service.broadcast_channel|title }} + {% if current_service.allowed_broadcast_provider == "all" %} + (all networks) + {% else %} + ({{ current_service.allowed_broadcast_provider }}) + {% endif %} + {% elif current_service.broadcast_channel == 'government' %} + Government {% endif %} {% endif %} diff --git a/tests/app/main/views/test_broadcast.py b/tests/app/main/views/test_broadcast.py index 83709ce98..804505afb 100644 --- a/tests/app/main/views/test_broadcast.py +++ b/tests/app/main/views/test_broadcast.py @@ -286,37 +286,59 @@ def test_broadcast_tour_page_4_shows_service_name( ) -@pytest.mark.parametrize('trial_mode, allowed_broadcast_provider, selector, expected_text, expected_tagged_text', ( +@pytest.mark.parametrize( + 'trial_mode, channel, allowed_broadcast_provider, selector, expected_text, expected_tagged_text', ( - True, - "all", - '.navigation-service-type.navigation-service-type--training', - 'service one Training Switch service', - 'Training', - ), - ( - False, - "all", - '.navigation-service-type.navigation-service-type--live', - 'service one Live Switch service', - 'Live', - ), - - ( - True, - 'vodafone', - '.navigation-service-type.navigation-service-type--training', - 'service one Training (vodafone) Switch service', - 'Training (vodafone)', - ), - ( - False, - 'vodafone', - '.navigation-service-type.navigation-service-type--live', - 'service one Live (vodafone) Switch service', - 'Live (vodafone)', - ), -)) + ( + True, + None, + 'all', + '.navigation-service-type.navigation-service-type--training', + 'service one Training Switch service', + 'Training', + ), + ( + True, + 'test', + 'all', + '.navigation-service-type.navigation-service-type--training', + 'service one Training Switch service', + 'Training', + ), + ( + False, + 'severe', + 'all', + '.navigation-service-type.navigation-service-type--live', + 'service one Live Switch service', + 'Live', + ), + ( + False, + 'test', + 'all', + '.navigation-service-type.navigation-service-type--live', + 'service one Test (all networks) Switch service', + 'Test (all networks)', + ), + ( + False, + 'test', + 'vodafone', + '.navigation-service-type.navigation-service-type--live', + 'service one Test (vodafone) Switch service', + 'Test (vodafone)', + ), + ( + False, + 'government', + 'all', + '.navigation-service-type.navigation-service-type--government', + 'service one Government Switch service', + 'Government', + ), + ) +) def test_broadcast_service_shows_live_or_training( client_request, service_one, @@ -324,6 +346,7 @@ def test_broadcast_service_shows_live_or_training( mock_get_service_templates_when_no_templates_exist, trial_mode, allowed_broadcast_provider, + channel, selector, expected_text, expected_tagged_text, @@ -331,6 +354,7 @@ def test_broadcast_service_shows_live_or_training( service_one['allowed_broadcast_provider'] = allowed_broadcast_provider service_one['permissions'] += ['broadcast'] service_one['restricted'] = trial_mode + service_one['broadcast_channel'] = channel page = client_request.get( '.broadcast_dashboard', service_id=SERVICE_ONE_ID, diff --git a/tests/app/main/views/test_service_settings.py b/tests/app/main/views/test_service_settings.py index 596fa0987..6d2f3f2de 100644 --- a/tests/app/main/views/test_service_settings.py +++ b/tests/app/main/views/test_service_settings.py @@ -113,7 +113,7 @@ def mock_get_service_settings_page_common( 'Custom data retention Email – 7 days Change data retention', 'Receive inbound SMS Off Change your settings for Receive inbound SMS', 'Email authentication Off Change your settings for Email authentication', - 'Send cell broadcasts Off Change your settings for Send cell broadcasts', + 'Emergency alerts Off Change your settings for emergency alerts', ]), ]) def test_should_show_overview( @@ -186,7 +186,7 @@ def test_platform_admin_sees_only_relevant_settings_for_broadcast_service( 'Label Value Action', 'Notes None Change the notes for the service', 'Email authentication Off Change your settings for Email authentication', - 'Send cell broadcasts Training Change your settings for Send cell broadcasts', + 'Emergency alerts Training Change your settings for emergency alerts', ] assert len(rows) == len(expected_rows) @@ -203,7 +203,7 @@ def test_platform_admin_sees_only_relevant_settings_for_broadcast_service( (True, "training", "test", "all", "Training"), (True, "live", "test", "ee", "Test (EE)"), (True, "live", "test", "three", "Test (Three)"), - (True, "live", "test", "all", "Test (All networks)"), + (True, "live", "test", "all", "Test (all networks)"), (True, "live", "severe", "all", "Live"), ] ) @@ -238,7 +238,7 @@ def test_platform_admin_sees_correct_description_of_broadcast_service_setting( )) assert response.status_code == 200 page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') - broadcast_setting_row = page.find(string=re.compile("Send cell broadcasts")).find_parent('tr') + broadcast_setting_row = page.find(string=re.compile("Emergency alerts")).find_parent('tr') broadcast_setting_description = broadcast_setting_row.select('td')[1].text.strip() assert broadcast_setting_description == expected_text @@ -5418,23 +5418,20 @@ def test_get_service_set_broadcast_account_type( ): response = platform_admin_client.get( url_for( - 'main.service_set_broadcast_account_type', + 'main.service_set_broadcast_channel', service_id=SERVICE_ONE_ID, ) ) assert response.status_code == 200 page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') - assert page.select_one('h1').text.strip() == "Change cell broadcast service type" + assert page.select_one('h1').text.strip() == 'Emergency alerts settings' expected_labels = [ "Training mode", - "Test channel (EE)", - "Test channel (O2)", - "Test channel (Three)", - "Test channel (Vodafone)", - "Test channel (all networks)", - "Live (all networks)", + "Test channel", + "Live channel", + "Government channel", ] labels = page.find_all('label', class_="govuk-radios__label") assert len(labels) == len(expected_labels) @@ -5451,7 +5448,7 @@ def test_get_service_set_broadcast_account_type_has_no_radio_selected_for_non_br ): response = platform_admin_client.get( url_for( - 'main.service_set_broadcast_account_type', + 'main.service_set_broadcast_channel', service_id=SERVICE_ONE_ID, ) ) @@ -5474,16 +5471,23 @@ def test_get_service_set_broadcast_account_type_has_no_radio_selected_for_non_br "live", "test", "vodafone", - "Test channel (Vodafone)", - "live-test-vodafone", + "Test channel", + "live-test", ), ( "live", "severe", "all", - "Live (all networks)", + "Live channel", "live-severe", ), + ( + "live", + "government", + "all", + "Government channel", + "live-government", + ), ] ) def test_get_service_set_broadcast_account_type_has_radio_selected_for_broadcast_service( @@ -5506,7 +5510,7 @@ def test_get_service_set_broadcast_account_type_has_radio_selected_for_broadcast response = platform_admin_client.get( url_for( - 'main.service_set_broadcast_account_type', + 'main.service_set_broadcast_channel', service_id=SERVICE_ONE_ID, ) ) @@ -5521,12 +5525,299 @@ def test_get_service_set_broadcast_account_type_has_radio_selected_for_broadcast assert selected_label.text.strip() == expected_text +@pytest.mark.parametrize( + 'account_type,expected_redirect_endpoint,extra_args', + [ + ( + 'training-test', + '.service_confirm_broadcast_account_type', + {'account_type': 'training-test'}, + ), + ( + 'live-test', + '.service_set_broadcast_network', + {}, + ), + ( + 'live-severe', + '.service_confirm_broadcast_account_type', + {'account_type': 'live-severe'}, + ), + ( + 'live-government', + '.service_confirm_broadcast_account_type', + {'account_type': 'live-government'}, + ), + ] +) +def test_get_service_set_broadcast_channel_redirects( + client_request, + platform_admin_user, + mocker, + account_type, + expected_redirect_endpoint, + extra_args, +): + client_request.login(platform_admin_user) + client_request.post( + 'main.service_set_broadcast_channel', + service_id=SERVICE_ONE_ID, + _data={ + 'channel': account_type, + }, + _expected_redirect=url_for( + expected_redirect_endpoint, + service_id=SERVICE_ONE_ID, + _external=True, + **extra_args, + ) + ) + + +@pytest.mark.parametrize( + 'service_mode,broadcast_channel,allowed_broadcast_provider,expected_selected', + [ + ( + "training", + "test", + "all", + [], + ), + ( + "live", + "severe", + "all", + [], + ), + ( + "live", + "government", + "all", + [], + ), + ( + "live", + "test", + "all", + [ + ("All networks", "live-test"), + ], + ), + ( + "live", + "test", + "ee", + [ + ("A single network", ""), + ("EE", "live-test-ee"), + ], + ), + ( + "live", + "test", + "o2", + [ + ("A single network", ""), + ("O2", "live-test-o2"), + ], + ), + ( + "live", + "test", + "three", + [ + ("A single network", ""), + ("Three", "live-test-three"), + ], + ), + ( + "live", + "test", + "vodafone", + [ + ("A single network", ""), + ("Vodafone", "live-test-vodafone"), + ], + ), + ] +) +def test_get_service_set_broadcast_network_has_radio_selected( + client_request, + platform_admin_user, + mocker, + service_mode, + broadcast_channel, + allowed_broadcast_provider, + expected_selected, +): + client_request.login(platform_admin_user) + service_one = service_json( + SERVICE_ONE_ID, + permissions=['broadcast'], + restricted=False if service_mode == 'live' else True, + broadcast_channel=broadcast_channel, + allowed_broadcast_provider=allowed_broadcast_provider, + ) + mocker.patch('app.service_api_client.get_service', return_value={'data': service_one}) + + page = client_request.get( + 'main.service_set_broadcast_network', + service_id=SERVICE_ONE_ID, + ) + + assert [ + ( + normalize_spaces(radio.find_next_sibling('label').text), + radio['value'], + ) + for radio in page.select('input[checked]') + ] == expected_selected + + +@pytest.mark.parametrize( + 'data, expected_result', + ( + ( + {'network_variant': 'live-test'}, + 'live-test' + ), + ( + {'network_variant': '', 'network': 'live-test-ee'}, + 'live-test-ee' + ), + ( + {'network_variant': '', 'network': 'live-test-o2'}, + 'live-test-o2' + ), + ( + {'network_variant': '', 'network': 'live-test-three'}, + 'live-test-three' + ), + ( + {'network_variant': '', 'network': 'live-test-vodafone'}, + 'live-test-vodafone' + ), + ), +) +def test_post_service_set_broadcast_network( + client_request, + platform_admin_user, + data, + expected_result, +): + client_request.login(platform_admin_user) + client_request.post( + 'main.service_set_broadcast_network', + service_id=SERVICE_ONE_ID, + _data=data, + _expected_status=302, + _expected_redirect=url_for( + 'main.service_confirm_broadcast_account_type', + service_id=SERVICE_ONE_ID, + account_type=expected_result, + _external=True, + ) + ) + + +@pytest.mark.parametrize( + 'data', + ( + {}, + {'network_variant': ''}, # Missing choice of MNO + ), +) +def test_post_service_set_broadcast_network_makes_you_choose( + client_request, + platform_admin_user, + mocker, + data, +): + client_request.login(platform_admin_user) + page = client_request.post( + 'main.service_set_broadcast_network', + service_id=SERVICE_ONE_ID, + _data=data, + _expected_status=200, + ) + assert normalize_spaces( + page.select_one('.govuk-error-message').text + ) == 'Error: Select a mobile network' + + +@pytest.mark.parametrize( + 'value, expected_paragraphs', + [ + ('training-test', [ + 'Training', + 'No phones will receive alerts sent from this service.', + ]), + ('live-test-ee', [ + 'Test (EE)', + 'Members of the public who have switched on the test ' + 'channel on their phones will receive alerts sent from ' + 'this service.', + ]), + ('live-test-o2', [ + 'Test (O2)', + 'Members of the public who have switched on the test ' + 'channel on their phones will receive alerts sent from ' + 'this service.', + ]), + ('live-test-three', [ + 'Test (Three)', + 'Members of the public who have switched on the test ' + 'channel on their phones will receive alerts sent from ' + 'this service.', + ]), + ('live-test-vodafone', [ + 'Test (Vodafone)', + 'Members of the public who have switched on the test ' + 'channel on their phones will receive alerts sent from ' + 'this service.', + ]), + ('live-test', [ + 'Test (all networks)', + 'Members of the public who have switched on the test ' + 'channel on their phones will receive alerts sent from ' + 'this service.', + ]), + ('live-severe', [ + 'Live', + 'Members of the public will receive alerts sent from this ' + 'service.', + ]), + ('live-government', [ + 'Government', + 'Members of the public will receive alerts sent from this ' + 'service, even if they’ve opted out.' + ]), + ] +) +def test_post_service_set_broadcast_account_type_confirmation_page( + client_request, + platform_admin_user, + value, + expected_paragraphs, +): + client_request.login(platform_admin_user) + page = client_request.get( + 'main.service_confirm_broadcast_account_type', + service_id=SERVICE_ONE_ID, + account_type=value, + ) + assert [ + normalize_spaces(p.text) for p in page.select('main p') + ] == expected_paragraphs + + @pytest.mark.parametrize( 'value,service_mode,broadcast_channel,allowed_broadcast_provider', [ ("training-test", "training", "test", "all"), ("live-test-vodafone", "live", "test", "vodafone"), ("live-severe", "live", "severe", "all"), + ("live-government", "live", "government", "all"), ] ) def test_post_service_set_broadcast_account_type_posts_data_to_api_and_redirects( @@ -5543,12 +5834,10 @@ def test_post_service_set_broadcast_account_type_posts_data_to_api_and_redirects response = platform_admin_client.post( url_for( - 'main.service_set_broadcast_account_type', + 'main.service_confirm_broadcast_account_type', service_id=SERVICE_ONE_ID, - ), - data={ - 'account_type': value - } + account_type=value, + ) ) assert response.status_code == 302 assert response.location == url_for('main.service_settings', service_id=SERVICE_ONE_ID, _external=True) @@ -5567,21 +5856,27 @@ def test_post_service_set_broadcast_account_type_posts_data_to_api_and_redirects ) +@pytest.mark.parametrize('endpoint, expected_error', ( + ('main.service_set_broadcast_channel', 'Error: Select mode or channel'), + ('main.service_set_broadcast_network', 'Error: Select a mobile network'), +)) def test_post_service_set_broadcast_account_type_shows_errors_if_no_radio_selected( platform_admin_client, mocker, + endpoint, + expected_error, ): set_service_broadcast_settings_mock = mocker.patch('app.service_api_client.set_service_broadcast_settings') mock_event_handler = mocker.patch('app.main.views.service_settings.create_broadcast_account_type_change_event') response = platform_admin_client.post( url_for( - 'main.service_set_broadcast_account_type', + endpoint, service_id=SERVICE_ONE_ID, ) ) assert response.status_code == 200 page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') - assert "This field is required" in page.find("span", {"class": "govuk-error-message"}).text + assert expected_error in page.find("span", {"class": "govuk-error-message"}).text assert not set_service_broadcast_settings_mock.called assert not mock_event_handler.called diff --git a/tests/app/test_navigation.py b/tests/app/test_navigation.py index 8582733ff..68f612e84 100644 --- a/tests/app/test_navigation.py +++ b/tests/app/test_navigation.py @@ -245,7 +245,9 @@ EXCLUDED_ENDPOINTS = tuple(map(Navigation.get_endpoint_with_blueprint, { 'service_preview_email_branding', 'service_preview_letter_branding', 'service_set_auth_type', - 'service_set_broadcast_account_type', + 'service_confirm_broadcast_account_type', + 'service_set_broadcast_channel', + 'service_set_broadcast_network', 'service_set_channel', 'service_set_email_branding', 'service_set_inbound_number',