Merge pull request #696 from dod-ccpo/form-page-complete-indicator

Fix TO Form progress bar
This commit is contained in:
leigh-mil 2019-03-13 09:58:05 -04:00 committed by GitHub
commit 4c282354bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 103 additions and 15 deletions

View File

@ -18,11 +18,16 @@ class BaseForm(FlaskForm):
def data(self): def data(self):
# remove 'csrf_token' key/value pair # remove 'csrf_token' key/value pair
# remove empty strings and None from list fields # remove empty strings and None from list fields
# prevent values that are not an option in a RadioField from being saved to the DB
_data = super().data _data = super().data
_data.pop("csrf_token", None) _data.pop("csrf_token", None)
for field in _data: for field in _data:
if _data[field].__class__.__name__ == "list": if _data[field].__class__.__name__ == "list":
_data[field] = [el for el in _data[field] if el not in EMPTY_LIST_FIELD] _data[field] = [el for el in _data[field] if el not in EMPTY_LIST_FIELD]
if self[field].__class__.__name__ == "RadioField":
choices = [el[0] for el in self[field].choices]
if _data[field] not in choices:
_data[field] = None
return _data return _data
def validate(self, *args, **kwargs): def validate(self, *args, **kwargs):

View File

@ -27,6 +27,10 @@ from .data import (
from atst.utils.localization import translate from atst.utils.localization import translate
def remove_empty_string(value):
return value or None
class AppInfoWithExistingPortfolioForm(BaseForm): class AppInfoWithExistingPortfolioForm(BaseForm):
scope = TextAreaField( scope = TextAreaField(
translate("forms.task_order.scope_label"), translate("forms.task_order.scope_label"),
@ -50,20 +54,30 @@ class AppInfoWithExistingPortfolioForm(BaseForm):
translate("forms.task_order.complexity.label"), translate("forms.task_order.complexity.label"),
description=translate("forms.task_order.complexity.description"), description=translate("forms.task_order.complexity.description"),
choices=APPLICATION_COMPLEXITY, choices=APPLICATION_COMPLEXITY,
default="", default=None,
filters=[remove_empty_string],
widget=ListWidget(prefix_label=False), widget=ListWidget(prefix_label=False),
option_widget=CheckboxInput(), option_widget=CheckboxInput(),
) )
complexity_other = StringField(translate("forms.task_order.complexity_other_label")) complexity_other = StringField(
translate("forms.task_order.complexity_other_label"),
default=None,
filters=[remove_empty_string],
)
dev_team = SelectMultipleField( dev_team = SelectMultipleField(
translate("forms.task_order.dev_team.label"), translate("forms.task_order.dev_team.label"),
description=translate("forms.task_order.dev_team.description"), description=translate("forms.task_order.dev_team.description"),
choices=DEV_TEAM, choices=DEV_TEAM,
default="", default=None,
filters=[remove_empty_string],
widget=ListWidget(prefix_label=False), widget=ListWidget(prefix_label=False),
option_widget=CheckboxInput(), option_widget=CheckboxInput(),
) )
dev_team_other = StringField(translate("forms.task_order.dev_team_other_label")) dev_team_other = StringField(
translate("forms.task_order.dev_team_other_label"),
default=None,
filters=[remove_empty_string],
)
team_experience = RadioField( team_experience = RadioField(
translate("forms.task_order.team_experience.label"), translate("forms.task_order.team_experience.label"),
description=translate("forms.task_order.team_experience.description"), description=translate("forms.task_order.team_experience.description"),
@ -77,6 +91,7 @@ class AppInfoForm(AppInfoWithExistingPortfolioForm):
portfolio_name = StringField( portfolio_name = StringField(
translate("forms.task_order.portfolio_name_label"), translate("forms.task_order.portfolio_name_label"),
description=translate("forms.task_order.portfolio_name_description"), description=translate("forms.task_order.portfolio_name_description"),
filters=[remove_empty_string],
validators=[ validators=[
Required(), Required(),
Length( Length(
@ -87,7 +102,10 @@ class AppInfoForm(AppInfoWithExistingPortfolioForm):
], ],
) )
defense_component = SelectField( defense_component = SelectField(
translate("forms.task_order.defense_component_label"), choices=SERVICE_BRANCHES translate("forms.task_order.defense_component_label"),
choices=SERVICE_BRANCHES,
default="",
filters=[remove_empty_string],
) )
@ -129,29 +147,36 @@ class FundingForm(BaseForm):
class UnclassifiedFundingForm(FundingForm): class UnclassifiedFundingForm(FundingForm):
clin_02 = StringField( clin_02 = StringField(
translate("forms.task_order.unclassified_clin_02_label"), translate("forms.task_order.unclassified_clin_02_label"),
filters=[lambda x: x or None], filters=[remove_empty_string],
) )
clin_04 = StringField( clin_04 = StringField(
translate("forms.task_order.unclassified_clin_04_label"), translate("forms.task_order.unclassified_clin_04_label"),
filters=[lambda x: x or None], filters=[remove_empty_string],
) )
class OversightForm(BaseForm): class OversightForm(BaseForm):
ko_first_name = StringField( ko_first_name = StringField(
translate("forms.task_order.oversight_first_name_label") translate("forms.task_order.oversight_first_name_label"),
filters=[remove_empty_string],
)
ko_last_name = StringField(
translate("forms.task_order.oversight_last_name_label"),
filters=[remove_empty_string],
) )
ko_last_name = StringField(translate("forms.task_order.oversight_last_name_label"))
ko_email = StringField( ko_email = StringField(
translate("forms.task_order.oversight_email_label"), translate("forms.task_order.oversight_email_label"),
validators=[Optional(), Email()], validators=[Optional(), Email()],
filters=[remove_empty_string],
) )
ko_phone_number = TelField( ko_phone_number = TelField(
translate("forms.task_order.oversight_phone_label"), translate("forms.task_order.oversight_phone_label"),
validators=[Optional(), PhoneNumber()], validators=[Optional(), PhoneNumber()],
filters=[remove_empty_string],
) )
ko_dod_id = StringField( ko_dod_id = StringField(
translate("forms.task_order.oversight_dod_id_label"), translate("forms.task_order.oversight_dod_id_label"),
filters=[remove_empty_string],
validators=[ validators=[
RequiredIf(lambda form: form._fields.get("ko_invite").data), RequiredIf(lambda form: form._fields.get("ko_invite").data),
Length(min=10), Length(min=10),
@ -161,15 +186,21 @@ class OversightForm(BaseForm):
am_cor = BooleanField(translate("forms.task_order.oversight_am_cor_label")) am_cor = BooleanField(translate("forms.task_order.oversight_am_cor_label"))
cor_first_name = StringField( cor_first_name = StringField(
translate("forms.task_order.oversight_first_name_label") translate("forms.task_order.oversight_first_name_label"),
filters=[remove_empty_string],
)
cor_last_name = StringField(
translate("forms.task_order.oversight_last_name_label"),
filters=[remove_empty_string],
) )
cor_last_name = StringField(translate("forms.task_order.oversight_last_name_label"))
cor_email = StringField( cor_email = StringField(
translate("forms.task_order.oversight_email_label"), translate("forms.task_order.oversight_email_label"),
filters=[remove_empty_string],
validators=[Optional(), Email()], validators=[Optional(), Email()],
) )
cor_phone_number = TelField( cor_phone_number = TelField(
translate("forms.task_order.oversight_phone_label"), translate("forms.task_order.oversight_phone_label"),
filters=[remove_empty_string],
validators=[ validators=[
RequiredIf(lambda form: not form._fields.get("am_cor").data), RequiredIf(lambda form: not form._fields.get("am_cor").data),
Optional(), Optional(),
@ -178,6 +209,7 @@ class OversightForm(BaseForm):
) )
cor_dod_id = StringField( cor_dod_id = StringField(
translate("forms.task_order.oversight_dod_id_label"), translate("forms.task_order.oversight_dod_id_label"),
filters=[remove_empty_string],
validators=[ validators=[
RequiredIf( RequiredIf(
lambda form: not form._fields.get("am_cor").data lambda form: not form._fields.get("am_cor").data
@ -189,19 +221,26 @@ class OversightForm(BaseForm):
) )
so_first_name = StringField( so_first_name = StringField(
translate("forms.task_order.oversight_first_name_label") translate("forms.task_order.oversight_first_name_label"),
filters=[remove_empty_string],
)
so_last_name = StringField(
translate("forms.task_order.oversight_last_name_label"),
filters=[remove_empty_string],
) )
so_last_name = StringField(translate("forms.task_order.oversight_last_name_label"))
so_email = StringField( so_email = StringField(
translate("forms.task_order.oversight_email_label"), translate("forms.task_order.oversight_email_label"),
filters=[remove_empty_string],
validators=[Optional(), Email()], validators=[Optional(), Email()],
) )
so_phone_number = TelField( so_phone_number = TelField(
translate("forms.task_order.oversight_phone_label"), translate("forms.task_order.oversight_phone_label"),
filters=[remove_empty_string],
validators=[Optional(), PhoneNumber()], validators=[Optional(), PhoneNumber()],
) )
so_dod_id = StringField( so_dod_id = StringField(
translate("forms.task_order.oversight_dod_id_label"), translate("forms.task_order.oversight_dod_id_label"),
filters=[remove_empty_string],
validators=[ validators=[
RequiredIf(lambda form: form._fields.get("so_invite").data), RequiredIf(lambda form: form._fields.get("so_invite").data),
Length(min=10), Length(min=10),

View File

@ -190,9 +190,17 @@ class UpdateTaskOrderWorkflow(ShowTaskOrderWorkflow):
to_data.pop("defense_component") to_data.pop("defense_component")
# don't save other text in DB unless "other" is checked # don't save other text in DB unless "other" is checked
if "complexity" in to_data and "other" not in to_data["complexity"]: if (
"complexity" in to_data
and bool(to_data["complexity"])
and "other" not in to_data["complexity"]
):
to_data["complexity_other"] = None to_data["complexity_other"] = None
if "dev_team" in to_data and "other" not in to_data["dev_team"]: if (
"dev_team" in to_data
and bool(to_data["dev_team"])
and "other" not in to_data["dev_team"]
):
to_data["dev_team_other"] = None to_data["dev_team_other"] = None
if self.form_data.get("am_cor"): if self.form_data.get("am_cor"):

View File

@ -0,0 +1,36 @@
import pytest
from wtforms.fields import RadioField
from werkzeug.datastructures import ImmutableMultiDict
from atst.forms.forms import BaseForm
class FormWithChoices(BaseForm):
force_side = RadioField(
"Choose your side",
choices=[
("light", "Light Side"),
("dark", "Dark Side"),
("neutral", "Chaotic Neutral"),
],
)
class TestBaseForm:
class Foo:
person = {"force_side": None}
obj = Foo()
def test_radio_field_saves_only_as_choice(self):
form_data_1 = ImmutableMultiDict({"force_side": "None"})
form_1 = FormWithChoices(form_data_1, obj=self.obj)
assert form_1.data["force_side"] is None
form_data_2 = ImmutableMultiDict({"force_side": "a fake choice"})
form_2 = FormWithChoices(form_data_2, obj=self.obj)
assert form_2.data["force_side"] is None
form_data_3 = ImmutableMultiDict({"force_side": "dark"})
form_3 = FormWithChoices(form_data_3, obj=self.obj)
assert form_3.data["force_side"] is "dark"