Merge pull request #1157 from cisagov/es/1015-update-availability-api

Ticket #1015 Update availability API to use EPP availability check
This commit is contained in:
Erin Song 2023-10-20 09:12:30 -07:00 committed by GitHub
commit c1994a07e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 118 additions and 58 deletions

View file

@ -3,19 +3,27 @@
import json import json
from django.contrib.auth import get_user_model 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 .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/" API_BASE_PATH = "/api/v1/available/"
class AvailableViewTest(TestCase): class AvailableViewTest(MockEppLib):
"""Test that the view function works as expected.""" """Test that the view function works as expected."""
def setUp(self): def setUp(self):
super().setUp()
self.user = get_user_model().objects.create(username="username") self.user = get_user_model().objects.create(username="username")
self.factory = RequestFactory() self.factory = RequestFactory()
@ -29,26 +37,37 @@ class AvailableViewTest(TestCase):
response_object = json.loads(response.content) response_object = json.loads(response.content)
self.assertIn("available", response_object) self.assertIn("available", response_object)
def test_domain_list(self): def test_in_domains_makes_calls_(self):
"""Test the domain list that is returned from Github. """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 """Domain searches successfully make mock EPP calls"""
the internet. self.mockedSendFunction.assert_has_calls(
""" [
domains = _domains() call(
self.assertIn("gsa.gov", domains) commands.CheckDomain(
# entries are all lowercase so GSA.GOV is not in the set ["gsa.gov"],
self.assertNotIn("GSA.GOV", domains) ),
self.assertNotIn("igorvilleremixed.gov", domains) cleaned=True,
# all the entries have dots ),
self.assertNotIn("gsa", domains) 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")) self.assertTrue(in_domains("gsa.gov"))
# input is lowercased so GSA.GOV should be found # input is lowercased so GSA.GOV should be found
self.assertTrue(in_domains("GSA.GOV")) self.assertTrue(in_domains("GSA.gov"))
# This domain should not have been registered
self.assertFalse(in_domains("igorvilleremixed.gov"))
def test_in_domains_dotgov(self): def test_in_domains_dotgov(self):
"""Domain searches work without trailing .gov""" """Domain searches work without trailing .gov"""
@ -86,13 +105,18 @@ class AvailableViewTest(TestCase):
request.user = self.user request.user = self.user
response = available(request, domain=bad_string) response = available(request, domain=bad_string)
self.assertFalse(json.loads(response.content)["available"]) 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.""" """Test that the API can be called as expected."""
def setUp(self): def setUp(self):
super().setUp()
self.user = get_user_model().objects.create(username="username") self.user = get_user_model().objects.create(username="username")
def test_available_get(self): def test_available_get(self):

View file

@ -59,12 +59,12 @@ def in_domains(domain):
given domain doesn't end with .gov, ".gov" is added when looking for given domain doesn't end with .gov, ".gov" is added when looking for
a match. a match.
""" """
domain = domain.lower() Domain = apps.get_model("registrar.Domain")
if domain.endswith(".gov"): if domain.endswith(".gov"):
return domain.lower() in _domains() return Domain.available(domain)
else: else:
# domain search string doesn't end with .gov, add it on here # 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"]) @require_http_methods(["GET"])

View file

@ -31,6 +31,7 @@ from epplibwrapper import (
info, info,
RegistryError, RegistryError,
ErrorCode, ErrorCode,
responses,
) )
from registrar.models.utility.contact_error import ContactError, ContactErrorCodes 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): def mockSend(self, _request, cleaned):
"""Mocks the registry.send function used inside of domain.py """Mocks the registry.send function used inside of domain.py
registry is imported from epplibwrapper registry is imported from epplibwrapper
returns objects that simulate what would be in a epp response returns objects that simulate what would be in a epp response
but only relevant pieces for tests""" but only relevant pieces for tests"""
if isinstance(_request, commands.InfoDomain):
return self.mockInfoDomainCommands(_request, cleaned) match type(_request):
elif isinstance(_request, commands.InfoContact): case commands.InfoDomain:
return self.mockInfoContactCommands(_request, cleaned) return self.mockInfoDomainCommands(_request, cleaned)
elif isinstance(_request, commands.UpdateDomain): case commands.InfoContact:
return self.mockUpdateDomainCommands(_request, cleaned) return self.mockInfoContactCommands(_request, cleaned)
elif isinstance(_request, commands.CreateContact): case commands.CreateContact:
return self.mockCreateContactCommands(_request, cleaned) return self.mockCreateContactCommands(_request, cleaned)
elif isinstance(_request, commands.CreateHost): case commands.UpdateDomain:
return MagicMock( return self.mockUpdateDomainCommands(_request, cleaned)
res_data=[self.mockDataHostChange], case commands.CreateHost:
code=ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY, return MagicMock(
) res_data=[self.mockDataHostChange],
elif isinstance(_request, commands.UpdateHost): code=ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY,
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
) )
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): def mockUpdateDomainCommands(self, _request, cleaned):
if getattr(_request, "name", None) == "dnssec-invalid.gov": if getattr(_request, "name", None) == "dnssec-invalid.gov":
@ -833,6 +852,16 @@ class MockEppLib(TestCase):
code=ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY, 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): def mockInfoDomainCommands(self, _request, cleaned):
request_name = getattr(_request, "name", None) request_name = getattr(_request, "name", None)

View file

@ -1,6 +1,6 @@
"""Test form validation requirements.""" """Test form validation requirements."""
from django.test import TestCase from django.test import TestCase, RequestFactory
from registrar.forms.application_wizard import ( from registrar.forms.application_wizard import (
CurrentSitesForm, CurrentSitesForm,
@ -16,9 +16,16 @@ from registrar.forms.application_wizard import (
AboutYourOrganizationForm, AboutYourOrganizationForm,
) )
from registrar.forms.domain import ContactForm 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): def test_org_contact_zip_invalid(self):
form = OrganizationContactForm(data={"zipcode": "nah"}) form = OrganizationContactForm(data={"zipcode": "nah"})
self.assertEqual( self.assertEqual(