Skip to content

Commit

Permalink
Merge pull request #1529 from cisagov/nl/589-applicant-cant-advance-fix
Browse files Browse the repository at this point in the history
Issue #589: applicant cant advance fix
  • Loading branch information
CocoByte authored Dec 30, 2023
2 parents 162d482 + 5df9c0f commit 0cada58
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 3 deletions.
34 changes: 33 additions & 1 deletion src/registrar/forms/application_wizard.py
Original file line number Diff line number Diff line change
Expand Up @@ -577,12 +577,44 @@ class OtherContactsForm(RegistrarForm):
error_messages={"required": "Enter a phone number for this contact."},
)

def clean(self):
"""
This method overrides the default behavior for forms.
This cleans the form after field validation has already taken place.
In this override, allow for a form which is empty to be considered
valid even though certain required fields have not passed field
validation
"""

# Set form_is_empty to True initially
form_is_empty = True
for name, field in self.fields.items():
# get the value of the field from the widget
value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
# if any field in the submitted form is not empty, set form_is_empty to False
if value is not None and value != "":
form_is_empty = False

if form_is_empty:
# clear any errors raised by the form fields
# (before this clean() method is run, each field
# performs its own clean, which could result in
# errors that we wish to ignore at this point)
#
# NOTE: we cannot just clear() the errors list.
# That causes problems.
for field in self.fields:
if field in self.errors:
del self.errors[field]

return self.cleaned_data


class BaseOtherContactsFormSet(RegistrarFormSet):
JOIN = "other_contacts"

def should_delete(self, cleaned):
empty = (isinstance(v, str) and not v.strip() for v in cleaned.values())
empty = (isinstance(v, str) and (v.strip() == "" or v is None) for v in cleaned.values())
return all(empty)

def to_database(self, obj: DomainApplication):
Expand Down
4 changes: 2 additions & 2 deletions src/registrar/tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,15 +211,15 @@ def test_your_contact_phone_invalid(self):

def test_other_contact_email_invalid(self):
"""must be a valid email address."""
form = OtherContactsForm(data={"email": "boss@boss"})
form = OtherContactsForm(data={"email": "splendid@boss"})
self.assertEqual(
form.errors["email"],
["Enter an email address in the required format, like [email protected]."],
)

def test_other_contact_phone_invalid(self):
"""Must be a valid phone number."""
form = OtherContactsForm(data={"phone": "boss@boss"})
form = OtherContactsForm(data={"phone": "super@boss"})
self.assertTrue(form.errors["phone"][0].startswith("Enter a valid phone number "))

def test_requirements_form_blank(self):
Expand Down
86 changes: 86 additions & 0 deletions src/registrar/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,92 @@ def test_application_no_other_contacts(self):
actual_url_slug = no_contacts_page.request.path.split("/")[-2]
self.assertEqual(expected_url_slug, actual_url_slug)

def test_application_delete_other_contact(self):
"""Other contacts can be deleted after being saved to database."""
# Populate the databse with a domain application that
# has 1 "other contact" assigned to it
ao, _ = Contact.objects.get_or_create(
first_name="Testy",
last_name="Tester",
title="Chief Tester",
email="[email protected]",
phone="(555) 555 5555",
)
you, _ = Contact.objects.get_or_create(
first_name="Testy you",
last_name="Tester you",
title="Admin Tester",
email="[email protected]",
phone="(555) 555 5556",
)
other, _ = Contact.objects.get_or_create(
first_name="Testy2",
last_name="Tester2",
title="Another Tester",
email="[email protected]",
phone="(555) 555 5557",
)
application, _ = DomainApplication.objects.get_or_create(
organization_type="federal",
federal_type="executive",
purpose="Purpose of the site",
anything_else="No",
is_policy_acknowledged=True,
organization_name="Testorg",
address_line1="address 1",
state_territory="NY",
zipcode="10002",
authorizing_official=ao,
submitter=you,
creator=self.user,
status="started",
)
application.other_contacts.add(other)

# prime the form by visiting /edit
self.app.get(reverse("edit-application", kwargs={"id": application.pk}))
# django-webtest does not handle cookie-based sessions well because it keeps
# resetting the session key on each new request, thus destroying the concept
# of a "session". We are going to do it manually, saving the session ID here
# and then setting the cookie on each request.
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)

other_contacts_page = self.app.get(reverse("application:other_contacts"))
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)

other_contacts_form = other_contacts_page.forms[0]

# Minimal check to ensure the form is loaded with data (if this part of
# the application doesn't work, we should be equipped with other unit
# tests to flag it)
self.assertEqual(other_contacts_form["other_contacts-0-first_name"].value, "Testy2")

# clear the form
other_contacts_form["other_contacts-0-first_name"] = ""
other_contacts_form["other_contacts-0-middle_name"] = ""
other_contacts_form["other_contacts-0-last_name"] = ""
other_contacts_form["other_contacts-0-title"] = ""
other_contacts_form["other_contacts-0-email"] = ""
other_contacts_form["other_contacts-0-phone"] = ""

# Submit the now empty form
result = other_contacts_form.submit()
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)

# Verify that the contact we saved earlier has been removed from the database
application = DomainApplication.objects.get() # There are no contacts anymore
self.assertEqual(
application.other_contacts.count(),
0,
)

# Verify that on submit, user is advanced to "no contacts" page
no_contacts_page = result.follow()
expected_url_slug = str(Step.NO_OTHER_CONTACTS)
actual_url_slug = no_contacts_page.request.path.split("/")[-2]
self.assertEqual(expected_url_slug, actual_url_slug)

def test_application_about_your_organiztion_interstate(self):
"""Special districts have to answer an additional question."""
type_page = self.app.get(reverse("application:")).follow()
Expand Down

0 comments on commit 0cada58

Please sign in to comment.