From 55e89b3f12d7964f118b800138e783c2f6cb6e59 Mon Sep 17 00:00:00 2001 From: Ben Thorner Date: Wed, 6 Apr 2022 16:54:09 +0100 Subject: [PATCH] Add validation for provider SMS percentages We could alternatively put the "add up to 100%" error on the page using form-level errors [^1] and a custom flash message. Putting the error on each field is slightly simpler and does make it clear the issue is with all of the fields together. [^1]: https://github.com/wtforms/wtforms/commit/22636b55eda9300b549c8bbaae6f9ae31595d445 --- app/main/forms.py | 21 +++++++++++++ tests/app/main/views/test_providers.py | 43 ++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/app/main/forms.py b/app/main/forms.py index 403e3317c..243534d9b 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -1742,6 +1742,8 @@ class EstimateUsageForm(StripWhitespaceForm): class AdminProviderRatioForm(Form): def __init__(self, providers): + self._providers = providers + # hack: https://github.com/wtforms/wtforms/issues/736 self._unbound_fields = [ ( @@ -1760,6 +1762,25 @@ class AdminProviderRatioForm(Form): for provider in providers }) + def validate(self): + if not super().validate(): + return False + + total = sum( + getattr(self, provider['identifier']).data + for provider in self._providers + ) + + if total == 100: + return True + + for provider in self._providers: + getattr(self, provider['identifier']).errors += [ + 'Must add up to 100%' + ] + + return False + class ServiceContactDetailsForm(StripWhitespaceForm): contact_details_type = RadioField( diff --git a/tests/app/main/views/test_providers.py b/tests/app/main/views/test_providers.py index 1770493ff..aefacdffc 100644 --- a/tests/app/main/views/test_providers.py +++ b/tests/app/main/views/test_providers.py @@ -337,3 +337,46 @@ def test_edit_sms_provider_ratio_submit( ) assert mock_update_provider.call_args_list == expected_calls + + +@pytest.mark.parametrize('post_data, expected_error', [ + ( + { + sms_provider_1['identifier']: 90, + sms_provider_2['identifier']: 20 + }, + "Must add up to 100%" + ), + ( + { + sms_provider_1['identifier']: 101, + sms_provider_2['identifier']: 20 + }, + "Must be between 0 and 100" + ), +]) +def test_edit_sms_provider_submit_invalid_percentages( + client_request, + platform_admin_user, + mocker, + post_data, + expected_error, + stub_providers, +): + mocker.patch( + 'app.provider_client.get_all_providers', + return_value=stub_providers + ) + mock_update_provider = mocker.patch( + 'app.provider_client.update_provider' + ) + + client_request.login(platform_admin_user) + page = client_request.post( + '.edit_sms_provider_ratio', + _data=post_data, + _follow_redirects=True + ) + + assert expected_error in page.select_one('.govuk-error-message').text + mock_update_provider.assert_not_called()