diff --git a/app/main/forms.py b/app/main/forms.py index 5b5273b99..b6a5aaf38 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -246,6 +246,15 @@ class OrganisationTypeForm(Form): organisation_type = organisation_type() +class FreeSMSAllowance(Form): + free_sms_allowance = IntegerField( + 'Numbers of text message fragments per year', + validators=[ + DataRequired(message='Can’t be empty') + ] + ) + + class ConfirmPasswordForm(Form): def __init__(self, validate_password_func, *args, **kwargs): self.validate_password_func = validate_password_func diff --git a/app/main/views/service_settings.py b/app/main/views/service_settings.py index c4c788920..1dbe5ba0f 100644 --- a/app/main/views/service_settings.py +++ b/app/main/views/service_settings.py @@ -35,6 +35,7 @@ from app.main.forms import ( ServiceInboundApiForm, InternationalSMSForm, OrganisationTypeForm, + FreeSMSAllowance, ) from app import user_api_client, current_service, organisations_client, inbound_number_client from notifications_utils.formatters import formatted_list @@ -589,14 +590,32 @@ def set_organisation_type(service_id): ) return redirect(url_for('.service_settings', service_id=service_id)) - form.organisation_type.data = current_service.get('organisation_type') - return render_template( 'views/service-settings/set-organisation-type.html', form=form, ) +@main.route("/services//service-settings/set-free-sms-allowance", methods=['GET', 'POST']) +@login_required +@user_has_permissions(admin_override=True) +def set_free_sms_allowance(service_id): + + form = FreeSMSAllowance(free_sms_allowance=current_service['free_sms_fragment_limit']) + + if form.validate_on_submit(): + service_api_client.update_service( + service_id, + free_sms_fragment_limit=form.free_sms_allowance.data, + ) + return redirect(url_for('.service_settings', service_id=service_id)) + + return render_template( + 'views/service-settings/set-free-sms-allowance.html', + form=form, + ) + + @main.route("/services//service-settings/set-branding-and-org", methods=['GET', 'POST']) @login_required @user_has_permissions(admin_override=True) diff --git a/app/notify_client/service_api_client.py b/app/notify_client/service_api_client.py index a35044e6c..49bccdfdd 100644 --- a/app/notify_client/service_api_client.py +++ b/app/notify_client/service_api_client.py @@ -104,7 +104,9 @@ class ServiceAPIClient(NotifyAdminAPIClient): 'organisation', 'letter_contact_block', 'dvla_organisation', - 'permissions' + 'permissions', + 'organisation_type', + 'free_sms_fragment_limit', } 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 77033ba94..c85a3920b 100644 --- a/app/templates/views/service-settings.html +++ b/app/templates/views/service-settings.html @@ -198,7 +198,7 @@ {% call row() %} {{ text_field('Free text message allowance')}} {{ text_field('{:,}'.format(current_service.free_sms_fragment_limit)) }} - {{ text_field() }} + {{ edit_field('Change', url_for('.set_free_sms_allowance', service_id=current_service.id)) }} {% endcall %} {% call row() %} {{ text_field('Email branding' )}} diff --git a/app/templates/views/service-settings/set-free-sms-allowance.html b/app/templates/views/service-settings/set-free-sms-allowance.html new file mode 100644 index 000000000..58ff3b36d --- /dev/null +++ b/app/templates/views/service-settings/set-free-sms-allowance.html @@ -0,0 +1,21 @@ +{% extends "withnav_template.html" %} +{% from "components/textbox.html" import textbox %} +{% from "components/page-footer.html" import page_footer %} + +{% block service_page_title %} + Emails +{% endblock %} + +{% block maincolumn_content %} + +
+

Free text message allowance

+ {{ textbox(form.free_sms_allowance) }} + {{ page_footer( + 'Save', + back_link=url_for('.service_settings', service_id=current_service.id), + back_link_text='Back to settings' + ) }} +
+ +{% endblock %} diff --git a/tests/app/main/views/test_service_settings.py b/tests/app/main/views/test_service_settings.py index d0fa1d07d..e07b27215 100644 --- a/tests/app/main/views/test_service_settings.py +++ b/tests/app/main/views/test_service_settings.py @@ -66,7 +66,7 @@ from tests.conftest import ( 'Label Value Action', 'Organisation type Central Change', - 'Free text message allowance 250,000', + 'Free text message allowance 250,000 Change', 'Email branding GOV.UK Change', 'Letter branding HM Government Change', @@ -1363,12 +1363,17 @@ def test_should_set_branding_and_organisations( @pytest.mark.parametrize('method', ['get', 'post']) +@pytest.mark.parametrize('endpoint', [ + 'main.set_organisation_type', + 'main.set_free_sms_allowance', +]) def test_organisation_type_pages_are_platform_admin_only( client_request, method, + endpoint, ): getattr(client_request, method)( - 'main.set_organisation_type', + endpoint, service_id=SERVICE_ONE_ID, _expected_status=403, _test_page_title=False, @@ -1406,7 +1411,7 @@ def test_should_show_page_to_set_organisation_type( 'nhs', pytest.mark.xfail('private sector'), ]) -def test_should_set_organisaton_type( +def test_should_set_organisation_type( logged_in_platform_admin_client, mock_update_service, organisation_type, @@ -1430,6 +1435,48 @@ def test_should_set_organisaton_type( ) +def test_should_show_page_to_set_sms_allowance( + logged_in_platform_admin_client, +): + response = logged_in_platform_admin_client.get(url_for( + 'main.set_free_sms_allowance', + service_id=SERVICE_ONE_ID + )) + assert response.status_code == 200 + page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') + + assert normalize_spaces(page.select_one('label').text) == 'Numbers of text message fragments per year' + + +@pytest.mark.parametrize('given_allowance, expected_api_argument', [ + ('1', 1), + ('250000', 250000), + pytest.mark.xfail(('foo', 'foo')), +]) +def test_should_set_sms_allowance( + logged_in_platform_admin_client, + mock_update_service, + given_allowance, + expected_api_argument, +): + response = logged_in_platform_admin_client.post( + url_for( + 'main.set_free_sms_allowance', + service_id=SERVICE_ONE_ID, + ), + data={ + 'free_sms_allowance': given_allowance, + }, + ) + assert response.status_code == 302 + assert response.location == url_for('main.service_settings', service_id=SERVICE_ONE_ID, _external=True) + + mock_update_service.assert_called_once_with( + SERVICE_ONE_ID, + free_sms_fragment_limit=expected_api_argument, + ) + + def test_switch_service_enable_letters( logged_in_platform_admin_client, service_one,