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]: 22636b55ed
This commit is contained in:
Ben Thorner
2022-04-06 16:54:09 +01:00
parent 7f333ba5fe
commit 55e89b3f12
2 changed files with 64 additions and 0 deletions

View File

@@ -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(

View File

@@ -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()