From 9e7f8785490fb0a5c5d0c82e1cdd06fb6127998d Mon Sep 17 00:00:00 2001 From: Rachid Mrad Date: Fri, 12 Apr 2024 15:24:50 -0400 Subject: [PATCH 1/8] allow clanking of first and or second nameserver if enough entries --- src/registrar/forms/domain.py | 36 +++++++++++--- src/registrar/tests/test_views_domain.py | 62 ++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 7 deletions(-) diff --git a/src/registrar/forms/domain.py b/src/registrar/forms/domain.py index 7b0ac2956..5b70d3e9b 100644 --- a/src/registrar/forms/domain.py +++ b/src/registrar/forms/domain.py @@ -83,25 +83,34 @@ class DomainNameserverForm(forms.Form): # after clean_fields. it is used to determine form level errors. # is_valid is typically called from view during a post cleaned_data = super().clean() + self.clean_empty_strings(cleaned_data) + server = cleaned_data.get("server", "") - # remove ANY spaces in the server field - server = server.replace(" ", "") - # lowercase the server - server = server.lower() + server = server.replace(" ", "").lower() cleaned_data["server"] = server - ip = cleaned_data.get("ip", None) - # remove ANY spaces in the ip field + + ip = cleaned_data.get("ip", "") ip = ip.replace(" ", "") cleaned_data["ip"] = ip + domain = cleaned_data.get("domain", "") ip_list = self.extract_ip_list(ip) - # validate if the form has a server or an ip + # Capture the server_value + server_value = self.cleaned_data["server"] + + # Validate if the form has a server or an ip if (ip and ip_list) or server: self.validate_nameserver_ip_combo(domain, server, ip_list) + # Re-set the server value: + # add_error which is called on validate_nameserver_ip_combo will clean-up (delete) any invalid data. + # We need that data because we need to know the total server entries (even if invalid) in the formset + # clean method where we determine whether a blank first and/or second entry should throw a required error. + self.cleaned_data["server"] = server_value + return cleaned_data def clean_empty_strings(self, cleaned_data): @@ -149,6 +158,19 @@ class BaseNameserverFormset(forms.BaseFormSet): """ Check for duplicate entries in the formset. """ + + # Check if there are at least two valid servers + valid_servers_count = sum( + 1 for form in self.forms if form.cleaned_data.get("server") and form.cleaned_data.get("server").strip() + ) + if valid_servers_count >= 2: + # If there are, remove the "At least two name servers are required" error from each form + # This will allow for successful submissions when the first or second entries are blanked + # but there are enough entries total + for form in self.forms: + if form.errors.get("server") == ["At least two name servers are required."]: + form.errors.pop("server") + if any(self.errors): # Don't bother validating the formset unless each form is valid on its own return diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py index 064c5efdb..ba229fc10 100644 --- a/src/registrar/tests/test_views_domain.py +++ b/src/registrar/tests/test_views_domain.py @@ -974,6 +974,68 @@ class TestDomainNameservers(TestDomainOverview): page = result.follow() self.assertContains(page, "The name servers for this domain have been updated") + def test_domain_nameservers_can_blank_out_first_or_second_one_if_enough_entries(self): + """Nameserver form submits successfully with 2 valid inputs, even if the first or + second entries are blanked out. + + Uses self.app WebTest because we need to interact with forms. + """ + + nameserver1 = "" + nameserver2 = "ns2.igorville.gov" + nameserver3 = "ns3.igorville.gov" + valid_ip = "" + valid_ip_2 = "128.0.0.2" + valid_ip_3 = "128.0.0.3" + nameservers_page = self.app.get(reverse("domain-dns-nameservers", kwargs={"pk": self.domain.id})) + session_id = self.app.cookies[settings.SESSION_COOKIE_NAME] + self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) + nameservers_page.form["form-0-server"] = nameserver1 + nameservers_page.form["form-0-ip"] = valid_ip + nameservers_page.form["form-1-server"] = nameserver2 + nameservers_page.form["form-1-ip"] = valid_ip_2 + nameservers_page.form["form-2-server"] = nameserver3 + nameservers_page.form["form-2-ip"] = valid_ip_3 + with less_console_noise(): # swallow log warning message + result = nameservers_page.form.submit() + + # form submission was a successful post, response should be a 302 + self.assertEqual(result.status_code, 302) + self.assertEqual( + result["Location"], + reverse("domain-dns-nameservers", kwargs={"pk": self.domain.id}), + ) + self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) + nameservers_page = result.follow() + self.assertContains(nameservers_page, "The name servers for this domain have been updated") + + nameserver1 = "ns1.igorville.gov" + nameserver2 = "" + nameserver3 = "ns3.igorville.gov" + valid_ip = "128.0.0.1" + valid_ip_2 = "" + valid_ip_3 = "128.0.0.3" + session_id = self.app.cookies[settings.SESSION_COOKIE_NAME] + self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) + nameservers_page.form["form-0-server"] = nameserver1 + nameservers_page.form["form-0-ip"] = valid_ip + nameservers_page.form["form-1-server"] = nameserver2 + nameservers_page.form["form-1-ip"] = valid_ip_2 + nameservers_page.form["form-2-server"] = nameserver3 + nameservers_page.form["form-2-ip"] = valid_ip_3 + with less_console_noise(): # swallow log warning message + result = nameservers_page.form.submit() + + # form submission was a successful post, response should be a 302 + self.assertEqual(result.status_code, 302) + self.assertEqual( + result["Location"], + reverse("domain-dns-nameservers", kwargs={"pk": self.domain.id}), + ) + self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) + nameservers_page = result.follow() + self.assertContains(nameservers_page, "The name servers for this domain have been updated") + def test_domain_nameservers_form_invalid(self): """Nameserver form does not submit with invalid data. From 0a17f396cb534011518b12f57504bc0c5ea040a5 Mon Sep 17 00:00:00 2001 From: Rachid Mrad Date: Fri, 12 Apr 2024 15:44:40 -0400 Subject: [PATCH 2/8] UX bug fixes --- src/registrar/assets/js/get-gov.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/registrar/assets/js/get-gov.js b/src/registrar/assets/js/get-gov.js index 587b95305..b2ed71bea 100644 --- a/src/registrar/assets/js/get-gov.js +++ b/src/registrar/assets/js/get-gov.js @@ -530,7 +530,7 @@ function hideDeletedForms() { let isDotgovDomain = document.querySelector(".dotgov-domain-form"); // The Nameservers formset features 2 required and 11 optionals if (isNameserversForm) { - cloneIndex = 2; + // cloneIndex = 2; formLabel = "Name server"; // DNSSEC: DS Data } else if (isDsDataForm) { @@ -766,3 +766,21 @@ function toggleTwoDomElements(ele1, ele2, index) { } })(); +/** + * An IIFE that listens to the other contacts radio form on DAs and toggles the contacts/no other contacts forms + * + */ +(function otherContactsFormListener() { + let isNameserversForm = document.querySelector(".nameservers-form"); + if (isNameserversForm) { + let forms = document.querySelectorAll(".repeatable-form"); + if (forms.length < 3) { + // Hide the delete buttons on the 2 nameservers + forms.forEach((form, index) => { + Array.from(form.querySelectorAll('.delete-record')).forEach((deleteButton) => { + deleteButton.setAttribute("disabled", "true"); + }); + }); + } + } +})(); From 28177030210adbfd40d2ec25e9691c3e4b83fa95 Mon Sep 17 00:00:00 2001 From: Rachid Mrad Date: Fri, 12 Apr 2024 15:46:11 -0400 Subject: [PATCH 3/8] update IIFE definition --- src/registrar/assets/js/get-gov.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/registrar/assets/js/get-gov.js b/src/registrar/assets/js/get-gov.js index b2ed71bea..f2771e51c 100644 --- a/src/registrar/assets/js/get-gov.js +++ b/src/registrar/assets/js/get-gov.js @@ -767,10 +767,10 @@ function toggleTwoDomElements(ele1, ele2, index) { })(); /** - * An IIFE that listens to the other contacts radio form on DAs and toggles the contacts/no other contacts forms + * An IIFE that disables the delete buttons on nameserver forms on page load if < 3 forms * */ -(function otherContactsFormListener() { +(function nameserversFormListener() { let isNameserversForm = document.querySelector(".nameservers-form"); if (isNameserversForm) { let forms = document.querySelectorAll(".repeatable-form"); From 85bc9c272ede537a52ff283a039dc1b349959223 Mon Sep 17 00:00:00 2001 From: Rachid Mrad Date: Fri, 12 Apr 2024 15:47:47 -0400 Subject: [PATCH 4/8] cleanup --- src/registrar/assets/js/get-gov.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/assets/js/get-gov.js b/src/registrar/assets/js/get-gov.js index f2771e51c..b4c41ecf1 100644 --- a/src/registrar/assets/js/get-gov.js +++ b/src/registrar/assets/js/get-gov.js @@ -776,7 +776,7 @@ function toggleTwoDomElements(ele1, ele2, index) { let forms = document.querySelectorAll(".repeatable-form"); if (forms.length < 3) { // Hide the delete buttons on the 2 nameservers - forms.forEach((form, index) => { + forms.forEach((form) => { Array.from(form.querySelectorAll('.delete-record')).forEach((deleteButton) => { deleteButton.setAttribute("disabled", "true"); }); From 27ef823b93d7cd7d3c60e21ea859fca11e21b0fc Mon Sep 17 00:00:00 2001 From: Rachid Mrad Date: Fri, 12 Apr 2024 17:56:57 -0400 Subject: [PATCH 5/8] handle edge case of 0 and 1 empty and duplicate error --- src/registrar/forms/domain.py | 4 +- src/registrar/tests/common.py | 13 ++++++ src/registrar/tests/test_views_domain.py | 55 +++++++++++++++++++++++- 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/src/registrar/forms/domain.py b/src/registrar/forms/domain.py index 5b70d3e9b..165d32fd8 100644 --- a/src/registrar/forms/domain.py +++ b/src/registrar/forms/domain.py @@ -178,10 +178,10 @@ class BaseNameserverFormset(forms.BaseFormSet): data = [] duplicates = [] - for form in self.forms: + for index, form in enumerate(self.forms): if form.cleaned_data: value = form.cleaned_data["server"] - if value in data: + if value in data and not (form.cleaned_data.get("server", "").strip() == '' and index == 1): form.add_error( "server", NameserverError(code=nsErrorCodes.DUPLICATE_HOST, nameserver=value), diff --git a/src/registrar/tests/common.py b/src/registrar/tests/common.py index a0b0e774f..4b9461b65 100644 --- a/src/registrar/tests/common.py +++ b/src/registrar/tests/common.py @@ -1152,6 +1152,18 @@ class MockEppLib(TestCase): ], ) + infoDomainFourHosts = fakedEppObject( + "my-nameserver.gov", + cr_date=make_aware(datetime(2023, 5, 25, 19, 45, 35)), + contacts=[], + hosts=[ + "ns1.my-nameserver-1.com", + "ns1.my-nameserver-2.com", + "ns1.cats-are-superior3.com", + "ns1.explosive-chicken-nuggets.com", + ], + ) + infoDomainNoHost = fakedEppObject( "my-nameserver.gov", cr_date=make_aware(datetime(2023, 5, 25, 19, 45, 35)), @@ -1475,6 +1487,7 @@ class MockEppLib(TestCase): "namerserversubdomain.gov": (self.infoDomainCheckHostIPCombo, None), "freeman.gov": (self.InfoDomainWithContacts, None), "threenameserversDomain.gov": (self.infoDomainThreeHosts, None), + "fournameserversDomain.gov": (self.infoDomainFourHosts, None), "defaultsecurity.gov": (self.InfoDomainWithDefaultSecurityContact, None), "adomain2.gov": (self.InfoDomainWithVerisignSecurityContact, None), "defaulttechnical.gov": (self.InfoDomainWithDefaultTechnicalContact, None), diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py index ba229fc10..eeab00ae3 100644 --- a/src/registrar/tests/test_views_domain.py +++ b/src/registrar/tests/test_views_domain.py @@ -5,7 +5,7 @@ from django.conf import settings from django.urls import reverse from django.contrib.auth import get_user_model -from .common import MockSESClient, create_user # type: ignore +from .common import MockEppLib, MockSESClient, create_user # type: ignore from django_webtest import WebTest # type: ignore import boto3_mocking # type: ignore @@ -727,7 +727,7 @@ class TestDomainManagers(TestDomainOverview): self.assertContains(home_page, self.domain.name) -class TestDomainNameservers(TestDomainOverview): +class TestDomainNameservers(TestDomainOverview, MockEppLib): def test_domain_nameservers(self): """Can load domain's nameservers page.""" page = self.client.get(reverse("domain-dns-nameservers", kwargs={"pk": self.domain.id})) @@ -1036,6 +1036,57 @@ class TestDomainNameservers(TestDomainOverview): nameservers_page = result.follow() self.assertContains(nameservers_page, "The name servers for this domain have been updated") + @skip('wip') + def test_domain_nameservers_can_blank_out_first_and_second_one_if_enough_entries(self): + """Nameserver form submits successfully with 2 valid inputs, even if the first and + second entries are blanked out. + + Uses self.app WebTest because we need to interact with forms. + """ + + # Submit a formset with 3 valid forms + # The returned page (after the redirect) will have 4 forms that we can use to test + # our use case. + + + infoDomainFourHosts, _ = Domain.objects.get_or_create(name="fournameserversDomain.gov", state=Domain.State.READY) + UserDomainRole.objects.get_or_create(user=self.user, domain=infoDomainFourHosts) + DomainInformation.objects.get_or_create(creator=self.user, domain=infoDomainFourHosts) + self.client.force_login(self.user) + + nameserver1 = "" + nameserver2 = "" + nameserver3 = "ns3.igorville.gov" + nameserver4 = "ns4.igorville.gov" + valid_ip = "" + valid_ip_2 = "" + valid_ip_3 = "128.0.0.3" + valid_ip_4 = "128.0.0.4" + nameservers_page = self.app.get(reverse("domain-dns-nameservers", kwargs={"pk": infoDomainFourHosts.id})) + print(nameservers_page.content.decode('utf-8')) + session_id = self.app.cookies[settings.SESSION_COOKIE_NAME] + self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) + nameservers_page.form["form-0-server"] = nameserver1 + nameservers_page.form["form-0-ip"] = valid_ip + nameservers_page.form["form-1-server"] = nameserver2 + nameservers_page.form["form-1-ip"] = valid_ip_2 + nameservers_page.form["form-2-server"] = nameserver3 + nameservers_page.form["form-2-ip"] = valid_ip_3 + nameservers_page.form["form-3-server"] = nameserver4 + nameservers_page.form["form-3-ip"] = valid_ip_4 + with less_console_noise(): # swallow log warning message + result = nameservers_page.form.submit() + + # form submission was a successful post, response should be a 302 + self.assertEqual(result.status_code, 302) + self.assertEqual( + result["Location"], + reverse("domain-dns-nameservers", kwargs={"pk": self.domain.id}), + ) + self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) + nameservers_page = result.follow() + self.assertContains(nameservers_page, "The name servers for this domain have been updated") + def test_domain_nameservers_form_invalid(self): """Nameserver form does not submit with invalid data. From d05f016632252e0d1e97b7c27fdfeb5e8bb5edb7 Mon Sep 17 00:00:00 2001 From: Rachid Mrad Date: Fri, 12 Apr 2024 18:00:06 -0400 Subject: [PATCH 6/8] comment --- src/registrar/forms/domain.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/registrar/forms/domain.py b/src/registrar/forms/domain.py index 165d32fd8..b7c37277c 100644 --- a/src/registrar/forms/domain.py +++ b/src/registrar/forms/domain.py @@ -181,6 +181,9 @@ class BaseNameserverFormset(forms.BaseFormSet): for index, form in enumerate(self.forms): if form.cleaned_data: value = form.cleaned_data["server"] + # We need to make sure not to trigger the duplicate error in case the first and second nameservers are empty + # If there are enough records in the formset, that error is an unecessary blocker. If there aren't, the required + # error will block the submit. if value in data and not (form.cleaned_data.get("server", "").strip() == '' and index == 1): form.add_error( "server", From 2e86c167b9692b0e0f846f016f9bf2684320ef29 Mon Sep 17 00:00:00 2001 From: Rachid Mrad Date: Fri, 12 Apr 2024 21:40:41 -0400 Subject: [PATCH 7/8] Fix unit test for 2 empties --- src/registrar/forms/domain.py | 8 ++--- src/registrar/tests/common.py | 10 ++++--- src/registrar/tests/test_views_domain.py | 38 ++++++++++++++---------- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/registrar/forms/domain.py b/src/registrar/forms/domain.py index b7c37277c..8fc7a6497 100644 --- a/src/registrar/forms/domain.py +++ b/src/registrar/forms/domain.py @@ -181,10 +181,10 @@ class BaseNameserverFormset(forms.BaseFormSet): for index, form in enumerate(self.forms): if form.cleaned_data: value = form.cleaned_data["server"] - # We need to make sure not to trigger the duplicate error in case the first and second nameservers are empty - # If there are enough records in the formset, that error is an unecessary blocker. If there aren't, the required - # error will block the submit. - if value in data and not (form.cleaned_data.get("server", "").strip() == '' and index == 1): + # We need to make sure not to trigger the duplicate error in case the first and second nameservers + # are empty. If there are enough records in the formset, that error is an unecessary blocker. + # If there aren't, the required error will block the submit. + if value in data and not (form.cleaned_data.get("server", "").strip() == "" and index == 1): form.add_error( "server", NameserverError(code=nsErrorCodes.DUPLICATE_HOST, nameserver=value), diff --git a/src/registrar/tests/common.py b/src/registrar/tests/common.py index 4b9461b65..07dc08f8a 100644 --- a/src/registrar/tests/common.py +++ b/src/registrar/tests/common.py @@ -1153,7 +1153,7 @@ class MockEppLib(TestCase): ) infoDomainFourHosts = fakedEppObject( - "my-nameserver.gov", + "fournameserversDomain.gov", cr_date=make_aware(datetime(2023, 5, 25, 19, 45, 35)), contacts=[], hosts=[ @@ -1464,7 +1464,9 @@ class MockEppLib(TestCase): ) def mockInfoDomainCommands(self, _request, cleaned): - request_name = getattr(_request, "name", None) + request_name = getattr(_request, "name", None).lower() + + print(request_name) # Define a dictionary to map request names to data and extension values request_mappings = { @@ -1486,8 +1488,8 @@ class MockEppLib(TestCase): "nameserverwithip.gov": (self.infoDomainHasIP, None), "namerserversubdomain.gov": (self.infoDomainCheckHostIPCombo, None), "freeman.gov": (self.InfoDomainWithContacts, None), - "threenameserversDomain.gov": (self.infoDomainThreeHosts, None), - "fournameserversDomain.gov": (self.infoDomainFourHosts, None), + "threenameserversdomain.gov": (self.infoDomainThreeHosts, None), + "fournameserversdomain.gov": (self.infoDomainFourHosts, None), "defaultsecurity.gov": (self.InfoDomainWithDefaultSecurityContact, None), "adomain2.gov": (self.InfoDomainWithVerisignSecurityContact, None), "defaulttechnical.gov": (self.InfoDomainWithDefaultTechnicalContact, None), diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py index eeab00ae3..3a5ce7e7b 100644 --- a/src/registrar/tests/test_views_domain.py +++ b/src/registrar/tests/test_views_domain.py @@ -71,11 +71,14 @@ class TestWithDomainPermissions(TestWithUser): # that inherit this setUp self.domain_dnssec_none, _ = Domain.objects.get_or_create(name="dnssec-none.gov") + self.domain_with_four_nameservers, _ = Domain.objects.get_or_create(name="fournameserversDomain.gov") + self.domain_information, _ = DomainInformation.objects.get_or_create(creator=self.user, domain=self.domain) DomainInformation.objects.get_or_create(creator=self.user, domain=self.domain_dsdata) DomainInformation.objects.get_or_create(creator=self.user, domain=self.domain_multdsdata) DomainInformation.objects.get_or_create(creator=self.user, domain=self.domain_dnssec_none) + DomainInformation.objects.get_or_create(creator=self.user, domain=self.domain_with_four_nameservers) DomainInformation.objects.get_or_create(creator=self.user, domain=self.domain_with_ip) DomainInformation.objects.get_or_create(creator=self.user, domain=self.domain_just_nameserver) DomainInformation.objects.get_or_create(creator=self.user, domain=self.domain_on_hold) @@ -98,6 +101,11 @@ class TestWithDomainPermissions(TestWithUser): domain=self.domain_dnssec_none, role=UserDomainRole.Roles.MANAGER, ) + UserDomainRole.objects.get_or_create( + user=self.user, + domain=self.domain_with_four_nameservers, + role=UserDomainRole.Roles.MANAGER, + ) UserDomainRole.objects.get_or_create( user=self.user, domain=self.domain_with_ip, @@ -1036,7 +1044,6 @@ class TestDomainNameservers(TestDomainOverview, MockEppLib): nameservers_page = result.follow() self.assertContains(nameservers_page, "The name servers for this domain have been updated") - @skip('wip') def test_domain_nameservers_can_blank_out_first_and_second_one_if_enough_entries(self): """Nameserver form submits successfully with 2 valid inputs, even if the first and second entries are blanked out. @@ -1044,28 +1051,27 @@ class TestDomainNameservers(TestDomainOverview, MockEppLib): Uses self.app WebTest because we need to interact with forms. """ - # Submit a formset with 3 valid forms - # The returned page (after the redirect) will have 4 forms that we can use to test - # our use case. - - - infoDomainFourHosts, _ = Domain.objects.get_or_create(name="fournameserversDomain.gov", state=Domain.State.READY) - UserDomainRole.objects.get_or_create(user=self.user, domain=infoDomainFourHosts) - DomainInformation.objects.get_or_create(creator=self.user, domain=infoDomainFourHosts) - self.client.force_login(self.user) - + # We need to start with a domain with 4 nameservers otherwise the formset in the test environment + # will only have 3 forms nameserver1 = "" nameserver2 = "" nameserver3 = "ns3.igorville.gov" nameserver4 = "ns4.igorville.gov" valid_ip = "" valid_ip_2 = "" - valid_ip_3 = "128.0.0.3" - valid_ip_4 = "128.0.0.4" - nameservers_page = self.app.get(reverse("domain-dns-nameservers", kwargs={"pk": infoDomainFourHosts.id})) - print(nameservers_page.content.decode('utf-8')) + valid_ip_3 = "" + valid_ip_4 = "" + nameservers_page = self.app.get( + reverse("domain-dns-nameservers", kwargs={"pk": self.domain_with_four_nameservers.id}) + ) + session_id = self.app.cookies[settings.SESSION_COOKIE_NAME] self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) + + # Minimal check to ensure the form is loaded correctly + self.assertEqual(nameservers_page.form["form-0-server"].value, "ns1.my-nameserver-1.com") + self.assertEqual(nameservers_page.form["form-3-server"].value, "ns1.explosive-chicken-nuggets.com") + nameservers_page.form["form-0-server"] = nameserver1 nameservers_page.form["form-0-ip"] = valid_ip nameservers_page.form["form-1-server"] = nameserver2 @@ -1081,7 +1087,7 @@ class TestDomainNameservers(TestDomainOverview, MockEppLib): self.assertEqual(result.status_code, 302) self.assertEqual( result["Location"], - reverse("domain-dns-nameservers", kwargs={"pk": self.domain.id}), + reverse("domain-dns-nameservers", kwargs={"pk": self.domain_with_four_nameservers.id}), ) self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) nameservers_page = result.follow() From ffa7b59eb586d433d0aaa72a14be5e39e661949f Mon Sep 17 00:00:00 2001 From: Rachid Mrad Date: Fri, 12 Apr 2024 21:52:16 -0400 Subject: [PATCH 8/8] cleanup --- src/registrar/forms/domain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/forms/domain.py b/src/registrar/forms/domain.py index 8fc7a6497..da1462bdb 100644 --- a/src/registrar/forms/domain.py +++ b/src/registrar/forms/domain.py @@ -99,7 +99,7 @@ class DomainNameserverForm(forms.Form): ip_list = self.extract_ip_list(ip) # Capture the server_value - server_value = self.cleaned_data["server"] + server_value = self.cleaned_data.get("server") # Validate if the form has a server or an ip if (ip and ip_list) or server: