New custom validator RequiredIf

This commit is contained in:
Montana 2019-01-18 09:39:52 -05:00
parent d0857a4a74
commit 67108484be
3 changed files with 57 additions and 21 deletions

View File

@ -12,7 +12,7 @@ from wtforms.fields.html5 import DateField, TelField
from wtforms.widgets import ListWidget, CheckboxInput from wtforms.widgets import ListWidget, CheckboxInput
from wtforms.validators import Required, Length from wtforms.validators import Required, Length
from atst.forms.validators import IsNumber, PhoneNumber, RequiredIfNot from atst.forms.validators import IsNumber, PhoneNumber, RequiredIf
from .forms import CacheableForm from .forms import CacheableForm
from .data import ( from .data import (
@ -117,7 +117,7 @@ class OversightForm(CacheableForm):
) )
ko_dod_id = StringField( ko_dod_id = StringField(
translate("forms.task_order.oversight_dod_id_label"), translate("forms.task_order.oversight_dod_id_label"),
validators=[Required(), Length(min=10), IsNumber()], validators=[RequiredIf("ko_invite"), Length(min=10), IsNumber()],
) )
am_cor = BooleanField(translate("forms.task_order.oversight_am_cor_label")) am_cor = BooleanField(translate("forms.task_order.oversight_am_cor_label"))
@ -128,11 +128,11 @@ class OversightForm(CacheableForm):
cor_email = StringField(translate("forms.task_order.oversight_email_label")) cor_email = StringField(translate("forms.task_order.oversight_email_label"))
cor_phone_number = TelField( cor_phone_number = TelField(
translate("forms.task_order.oversight_phone_label"), translate("forms.task_order.oversight_phone_label"),
validators=[RequiredIfNot("am_cor"), PhoneNumber()], validators=[RequiredIf("am_cor", False), PhoneNumber()],
) )
cor_dod_id = StringField( cor_dod_id = StringField(
translate("forms.task_order.oversight_dod_id_label"), translate("forms.task_order.oversight_dod_id_label"),
validators=[RequiredIfNot("am_cor"), Length(min=10), IsNumber()], validators=[RequiredIf("am_cor", False), Length(min=10), IsNumber()],
) )
so_first_name = StringField( so_first_name = StringField(

View File

@ -80,26 +80,35 @@ def ListItemsUnique(message=translate("forms.validators.list_items_unique_messag
return _list_items_unique return _list_items_unique
def RequiredIfNot(other_field_name, message=translate("forms.validators.is_required")): def RequiredIf(
other_field_name, checked=True, message=translate("forms.validators.is_required")
):
""" A validator which makes a field required only if another field """ A validator which makes a field required only if another field
has a falsy value has a truthy value
Args: Args:
other_field_name (str): the name of the field we check before other_field_name (str): the name of the field we check before
determining if this field is required; if this other field is falsy, determining if this field is required
the field will be required checked (bool): the value of other_field_name that we want to check against;
if checked is True, we require the field if other_field_name's field value
is truthy; if checked is False, we require the field if other_field_name's
field value is falsy
message (str): an optional message to display if the field is message (str): an optional message to display if the field is
required but hasNone value required but hasNone value
""" """
def _required_if_not(form, field): def _required_if(form, field):
other_field = form._fields.get(other_field_name) other_field = form._fields.get(other_field_name)
if other_field is None: if other_field is None:
raise Exception('no field named "%s" in form' % self.other_field_name) raise Exception('no field named "%s" in form' % self.other_field_name)
if not bool(other_field.data): field_required = (
bool(other_field.data) if checked else not bool(other_field.data)
)
if field_required:
if field.data is None: if field.data is None:
raise ValidationError(message) raise ValidationError(message)
else: else:
raise StopValidation() raise StopValidation()
return _required_if_not return _required_if

View File

@ -6,7 +6,7 @@ from atst.forms.validators import (
IsNumber, IsNumber,
PhoneNumber, PhoneNumber,
ListItemsUnique, ListItemsUnique,
RequiredIfNot, RequiredIf,
) )
@ -81,29 +81,56 @@ class TestListItemsUnique:
validator(dummy_form, dummy_field) validator(dummy_form, dummy_field)
class TestRequiredIfNot: class TestRequiredIf:
def test_RequiredIfNot_requires_field_if_arg_is_falsy( def test_RequiredIf_requires_field_if_arg_is_truthy(
self, dummy_form_with_field, dummy_field self, dummy_form_with_field, dummy_field
): ):
form = dummy_form_with_field("arg", False) form = dummy_form_with_field("arg", True)
validator = RequiredIfNot("arg") validator = RequiredIf("arg")
dummy_field.data = None dummy_field.data = None
with pytest.raises(ValidationError): with pytest.raises(ValidationError):
validator(form, dummy_field) validator(form, dummy_field)
def test_RequiredIfNot_does_not_require_field_if_arg_is_truthy( def test_RequiredIf_does_not_require_field_if_arg_is_falsy(
self, dummy_form_with_field, dummy_field self, dummy_form_with_field, dummy_field
): ):
form = dummy_form_with_field("arg", True) form = dummy_form_with_field("arg", False)
validator = RequiredIfNot("arg") validator = RequiredIf("arg")
dummy_field.data = None dummy_field.data = None
with pytest.raises(StopValidation): with pytest.raises(StopValidation):
validator(form, dummy_field) validator(form, dummy_field)
def test_RequiredIfNot_arg_is_None_raises_error(self, dummy_form, dummy_field): def test_RequiredIf_arg_is_None_raises_error(self, dummy_form, dummy_field):
validator = RequiredIfNot("arg") validator = RequiredIf("arg")
dummy_field.data = "some data"
with pytest.raises(Exception):
validator(dummy_form, dummy_field)
def test_not_RequiredIf_requires_field_if_arg_is_falsy(
self, dummy_form_with_field, dummy_field
):
form = dummy_form_with_field("arg", False)
validator = RequiredIf("arg", False)
dummy_field.data = None
with pytest.raises(ValidationError):
validator(form, dummy_field)
def test_not_RequiredIf_does_not_require_field_if_arg_is_truthy(
self, dummy_form_with_field, dummy_field
):
form = dummy_form_with_field("arg", True)
validator = RequiredIf("arg", False)
dummy_field.data = None
with pytest.raises(StopValidation):
validator(form, dummy_field)
def test_not_RequiredIf_arg_is_None_raises_error(self, dummy_form, dummy_field):
validator = RequiredIf("arg", False)
dummy_field.data = "some data" dummy_field.data = "some data"
with pytest.raises(Exception): with pytest.raises(Exception):