diff --git a/src/api/tests/test_available.py b/src/api/tests/test_available.py index 0bbe01f03..9eab17bf7 100644 --- a/src/api/tests/test_available.py +++ b/src/api/tests/test_available.py @@ -3,19 +3,27 @@ import json from django.contrib.auth import get_user_model -from django.test import TestCase, RequestFactory +from django.test import RequestFactory -from ..views import available, _domains, in_domains +from ..views import available, in_domains from .common import less_console_noise +from registrar.tests.common import MockEppLib +from unittest.mock import call + +from epplibwrapper import ( + commands, + RegistryError, +) API_BASE_PATH = "/api/v1/available/" -class AvailableViewTest(TestCase): +class AvailableViewTest(MockEppLib): """Test that the view function works as expected.""" def setUp(self): + super().setUp() self.user = get_user_model().objects.create(username="username") self.factory = RequestFactory() @@ -29,26 +37,37 @@ class AvailableViewTest(TestCase): response_object = json.loads(response.content) self.assertIn("available", response_object) - def test_domain_list(self): - """Test the domain list that is returned from Github. + def test_in_domains_makes_calls_(self): + """Domain searches successfully make correct mock EPP calls""" + gsa_available = in_domains("gsa.gov") + igorville_available = in_domains("igorvilleremixed.gov") - This does not mock out the external file, it is actually fetched from - the internet. - """ - domains = _domains() - self.assertIn("gsa.gov", domains) - # entries are all lowercase so GSA.GOV is not in the set - self.assertNotIn("GSA.GOV", domains) - self.assertNotIn("igorvilleremixed.gov", domains) - # all the entries have dots - self.assertNotIn("gsa", domains) + """Domain searches successfully make mock EPP calls""" + self.mockedSendFunction.assert_has_calls( + [ + call( + commands.CheckDomain( + ["gsa.gov"], + ), + cleaned=True, + ), + call( + commands.CheckDomain( + ["igorvilleremixed.gov"], + ), + cleaned=True, + ), + ] + ) + """Domain searches return correct availability results""" + self.assertTrue(gsa_available) + self.assertFalse(igorville_available) - def test_in_domains(self): + def test_in_domains_capitalized(self): + """Domain searches work without case sensitivity""" self.assertTrue(in_domains("gsa.gov")) # input is lowercased so GSA.GOV should be found - self.assertTrue(in_domains("GSA.GOV")) - # This domain should not have been registered - self.assertFalse(in_domains("igorvilleremixed.gov")) + self.assertTrue(in_domains("GSA.gov")) def test_in_domains_dotgov(self): """Domain searches work without trailing .gov""" @@ -86,13 +105,18 @@ class AvailableViewTest(TestCase): request.user = self.user response = available(request, domain=bad_string) self.assertFalse(json.loads(response.content)["available"]) + # domain set to raise error successfully raises error + with self.assertRaises(RegistryError): + error_domain_available = available(request, "errordomain.gov") + self.assertFalse(json.loads(error_domain_available.content)["available"]) -class AvailableAPITest(TestCase): +class AvailableAPITest(MockEppLib): """Test that the API can be called as expected.""" def setUp(self): + super().setUp() self.user = get_user_model().objects.create(username="username") def test_available_get(self): diff --git a/src/api/views.py b/src/api/views.py index e19e060ef..02e419a91 100644 --- a/src/api/views.py +++ b/src/api/views.py @@ -59,12 +59,12 @@ def in_domains(domain): given domain doesn't end with .gov, ".gov" is added when looking for a match. """ - domain = domain.lower() + Domain = apps.get_model("registrar.Domain") if domain.endswith(".gov"): - return domain.lower() in _domains() + return Domain.available(domain) else: # domain search string doesn't end with .gov, add it on here - return (domain + ".gov") in _domains() + return Domain.available(domain + ".gov") @require_http_methods(["GET"]) diff --git a/src/registrar/tests/common.py b/src/registrar/tests/common.py index a9f38db03..f6539466d 100644 --- a/src/registrar/tests/common.py +++ b/src/registrar/tests/common.py @@ -31,6 +31,7 @@ from epplibwrapper import ( info, RegistryError, ErrorCode, + responses, ) from registrar.models.utility.contact_error import ContactError, ContactErrorCodes @@ -784,45 +785,63 @@ class MockEppLib(TestCase): ], ) + def _mockDomainName(self, _name, _avail=False): + return MagicMock( + res_data=[ + responses.check.CheckDomainResultData( + name=_name, avail=_avail, reason=None + ), + ] + ) + + def mockCheckDomainCommand(self, _request, cleaned): + if "gsa.gov" in getattr(_request, "names", None): + return self._mockDomainName("gsa.gov", True) + elif "GSA.gov" in getattr(_request, "names", None): + return self._mockDomainName("GSA.gov", True) + elif "igorvilleremixed.gov" in getattr(_request, "names", None): + return self._mockDomainName("igorvilleremixed.gov", False) + elif "errordomain.gov" in getattr(_request, "names", None): + raise RegistryError("Registry cannot find domain availability.") + else: + return self._mockDomainName("domainnotfound.gov", False) + def mockSend(self, _request, cleaned): """Mocks the registry.send function used inside of domain.py registry is imported from epplibwrapper returns objects that simulate what would be in a epp response but only relevant pieces for tests""" - if isinstance(_request, commands.InfoDomain): - return self.mockInfoDomainCommands(_request, cleaned) - elif isinstance(_request, commands.InfoContact): - return self.mockInfoContactCommands(_request, cleaned) - elif isinstance(_request, commands.UpdateDomain): - return self.mockUpdateDomainCommands(_request, cleaned) - elif isinstance(_request, commands.CreateContact): - return self.mockCreateContactCommands(_request, cleaned) - elif isinstance(_request, commands.CreateHost): - return MagicMock( - res_data=[self.mockDataHostChange], - code=ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY, - ) - elif isinstance(_request, commands.UpdateHost): - return MagicMock( - res_data=[self.mockDataHostChange], - code=ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY, - ) - elif isinstance(_request, commands.DeleteHost): - return MagicMock( - res_data=[self.mockDataHostChange], - code=ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY, - ) - elif ( - isinstance(_request, commands.DeleteDomain) - and getattr(_request, "name", None) == "failDelete.gov" - ): - name = getattr(_request, "name", None) - fake_nameserver = "ns1.failDelete.gov" - if name in fake_nameserver: - raise RegistryError( - code=ErrorCode.OBJECT_ASSOCIATION_PROHIBITS_OPERATION + + match type(_request): + case commands.InfoDomain: + return self.mockInfoDomainCommands(_request, cleaned) + case commands.InfoContact: + return self.mockInfoContactCommands(_request, cleaned) + case commands.CreateContact: + return self.mockCreateContactCommands(_request, cleaned) + case commands.UpdateDomain: + return self.mockUpdateDomainCommands(_request, cleaned) + case commands.CreateHost: + return MagicMock( + res_data=[self.mockDataHostChange], + code=ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY, ) - return MagicMock(res_data=[self.mockDataInfoHosts]) + case commands.UpdateHost: + return MagicMock( + res_data=[self.mockDataHostChange], + code=ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY, + ) + case commands.DeleteHost: + return MagicMock( + res_data=[self.mockDataHostChange], + code=ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY, + ) + case commands.CheckDomain: + return self.mockCheckDomainCommand(_request, cleaned) + case commands.DeleteDomain: + return self.mockDeleteDomainCommands(_request, cleaned) + case _: + return MagicMock(res_data=[self.mockDataInfoHosts]) def mockUpdateDomainCommands(self, _request, cleaned): if getattr(_request, "name", None) == "dnssec-invalid.gov": @@ -833,6 +852,16 @@ class MockEppLib(TestCase): code=ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY, ) + def mockDeleteDomainCommands(self, _request, cleaned): + if getattr(_request, "name", None) == "failDelete.gov": + name = getattr(_request, "name", None) + fake_nameserver = "ns1.failDelete.gov" + if name in fake_nameserver: + raise RegistryError( + code=ErrorCode.OBJECT_ASSOCIATION_PROHIBITS_OPERATION + ) + return None + def mockInfoDomainCommands(self, _request, cleaned): request_name = getattr(_request, "name", None) diff --git a/src/registrar/tests/test_forms.py b/src/registrar/tests/test_forms.py index 95be195ba..4b1aeb12c 100644 --- a/src/registrar/tests/test_forms.py +++ b/src/registrar/tests/test_forms.py @@ -1,6 +1,6 @@ """Test form validation requirements.""" -from django.test import TestCase +from django.test import TestCase, RequestFactory from registrar.forms.application_wizard import ( CurrentSitesForm, @@ -16,9 +16,16 @@ from registrar.forms.application_wizard import ( AboutYourOrganizationForm, ) from registrar.forms.domain import ContactForm +from registrar.tests.common import MockEppLib +from django.contrib.auth import get_user_model -class TestFormValidation(TestCase): +class TestFormValidation(MockEppLib): + def setUp(self): + super().setUp() + self.user = get_user_model().objects.create(username="username") + self.factory = RequestFactory() + def test_org_contact_zip_invalid(self): form = OrganizationContactForm(data={"zipcode": "nah"}) self.assertEqual(