diff --git a/app/main/forms.py b/app/main/forms.py index 0c607ce1b..7766a28aa 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -933,9 +933,13 @@ class OnOffField(RadioField): class ServiceOnOffSettingForm(StripWhitespaceForm): - def __init__(self, name, *args, **kwargs): + def __init__(self, name, *args, truthy='On', falsey='Off', **kwargs): super().__init__(*args, **kwargs) self.enabled.label.text = name + self.enabled.choices = [ + (True, truthy), + (False, falsey), + ] enabled = OnOffField('Choices') diff --git a/app/main/views/service_settings.py b/app/main/views/service_settings.py index ab8f17337..ba20ccbb1 100644 --- a/app/main/views/service_settings.py +++ b/app/main/views/service_settings.py @@ -277,6 +277,29 @@ def service_switch_live(service_id): ) +@main.route("/services//service-settings/switch-count-as-live", methods=["GET", "POST"]) +@login_required +@user_is_platform_admin +def service_switch_count_as_live(service_id): + + form = ServiceOnOffSettingForm( + name="Count in list of live services", + enabled=current_service.count_as_live, + truthy='Yes', + falsey='No', + ) + + if form.validate_on_submit(): + current_service.update(count_as_live=form.enabled.data) + return redirect(url_for('.service_settings', service_id=service_id)) + + return render_template( + 'views/service-settings/set-service-setting.html', + title="Count in list of live services", + form=form, + ) + + @main.route("/services//service-settings/permissions/", methods=["GET", "POST"]) @login_required @user_is_platform_admin diff --git a/app/models/service.py b/app/models/service.py index 6408ebdba..613cc07aa 100644 --- a/app/models/service.py +++ b/app/models/service.py @@ -40,6 +40,7 @@ class Service(): 'volume_sms', 'volume_letter', 'consent_to_research', + 'count_as_live', } TEMPLATE_TYPES = ( diff --git a/app/navigation.py b/app/navigation.py index 2d6ce3a8c..11baad508 100644 --- a/app/navigation.py +++ b/app/navigation.py @@ -261,6 +261,7 @@ class HeaderNavigation(Navigation): 'service_settings', 'service_sms_senders', 'service_switch_can_upload_document', + 'service_switch_count_as_live', 'service_switch_live', 'service_set_permission', 'services_or_dashboard', @@ -506,6 +507,7 @@ class MainNavigation(Navigation): 'service_delete_sms_sender', 'service_letter_validation_preview', 'service_switch_can_upload_document', + 'service_switch_count_as_live', 'service_switch_live', 'service_set_permission', 'services_or_dashboard', @@ -749,6 +751,7 @@ class CaseworkNavigation(Navigation): 'service_settings', 'service_sms_senders', 'service_switch_can_upload_document', + 'service_switch_count_as_live', 'service_switch_live', 'service_set_permission', 'services_or_dashboard', @@ -999,6 +1002,7 @@ class OrgNavigation(Navigation): 'service_settings', 'service_sms_senders', 'service_switch_can_upload_document', + 'service_switch_count_as_live', 'service_switch_live', 'service_set_permission', 'services_or_dashboard', diff --git a/app/notify_client/service_api_client.py b/app/notify_client/service_api_client.py index 8a2c2b632..2ae1fc674 100644 --- a/app/notify_client/service_api_client.py +++ b/app/notify_client/service_api_client.py @@ -88,6 +88,7 @@ class ServiceAPIClient(NotifyAdminAPIClient): 'volume_sms', 'volume_letter', 'consent_to_research', + 'count_as_live', } if disallowed_attributes: raise TypeError('Not allowed to update service attributes: {}'.format( diff --git a/app/templates/views/service-settings.html b/app/templates/views/service-settings.html index 8e95a1d25..171f15bb3 100644 --- a/app/templates/views/service-settings.html +++ b/app/templates/views/service-settings.html @@ -292,6 +292,12 @@ {{ edit_field('Change', url_for('.service_switch_live', service_id=current_service.id)) }} {% endcall %} + {% call row() %} + {{ text_field('Count in list of live services')}} + {{ text_field('Yes' if current_service.count_as_live else 'No') }} + {{ edit_field('Change', url_for('.service_switch_count_as_live', service_id=current_service.id)) }} + {% endcall %} + {% call row() %} {{ text_field('Organisation')}} {{ optional_text_field(current_service.organisation_name) }} diff --git a/app/templates/views/service-settings/set-service-setting.html b/app/templates/views/service-settings/set-service-setting.html index 763f0f9fb..a80cadb84 100644 --- a/app/templates/views/service-settings/set-service-setting.html +++ b/app/templates/views/service-settings/set-service-setting.html @@ -4,7 +4,7 @@ {% from "components/form.html" import form_wrapper %} {% block service_page_title %} - Send letters + {{ title }} {% endblock %} {% block maincolumn_content %} diff --git a/tests/__init__.py b/tests/__init__.py index b6ede9d99..bf3a0811e 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -178,6 +178,7 @@ def service_json( 'volume_sms': 222222, 'volume_letter': 333333, 'consent_to_research': True, + 'count_as_live': True, } diff --git a/tests/app/main/views/test_service_settings.py b/tests/app/main/views/test_service_settings.py index 551fa0a51..73e022302 100644 --- a/tests/app/main/views/test_service_settings.py +++ b/tests/app/main/views/test_service_settings.py @@ -99,6 +99,7 @@ def mock_get_service_settings_page_common( 'Label Value Action', 'Live Off Change', + 'Count in list of live services Yes Change', 'Organisation Org 1 Change', 'Organisation type Central Change', 'Free text message allowance 250,000 Change', @@ -447,6 +448,65 @@ def test_switch_service_to_restricted( ) +@pytest.mark.parametrize('count_as_live, selected, labelled', ( + (True, 'True', 'Yes'), + (False, 'False', 'No'), +)) +def test_show_switch_service_to_count_as_live_page( + mocker, + client_request, + platform_admin_user, + mock_update_service, + count_as_live, + selected, + labelled, +): + mocker.patch( + 'app.models.service.Service.count_as_live', + create=True, + new_callable=PropertyMock, + return_value=count_as_live, + ) + client_request.login(platform_admin_user) + page = client_request.get( + 'main.service_switch_count_as_live', + service_id=SERVICE_ONE_ID, + ) + assert page.select_one('[checked]')['value'] == selected + assert page.select_one('label[for={}]'.format( + page.select_one('[checked]')['id'] + )).text.strip() == labelled + + +@pytest.mark.parametrize('post_data, expected_persisted_value', ( + ('True', True), + ('False', False), +)) +def test_switch_service_to_count_as_live( + client_request, + platform_admin_user, + mock_update_service, + post_data, + expected_persisted_value, +): + client_request.login(platform_admin_user) + client_request.post( + 'main.service_switch_count_as_live', + service_id=SERVICE_ONE_ID, + _data={'enabled': post_data}, + _expected_status=302, + _expected_redirect=url_for( + 'main.service_settings', + service_id=SERVICE_ONE_ID, + _external=True, + ) + ) + mock_update_service.assert_called_with( + SERVICE_ONE_ID, + count_as_live=expected_persisted_value, + ) + + def test_should_not_allow_duplicate_names( logged_in_client, mock_service_name_is_not_unique,