made expiration date readonly in django admin; expiration date setter not implemented; implemented renew_domain; wrote unit tests

This commit is contained in:
David Kennedy 2023-11-16 08:39:05 -05:00
parent 652086a771
commit 944c82b9f9
No known key found for this signature in database
GPG key ID: 6528A5386E66B96B
4 changed files with 95 additions and 3 deletions

View file

@ -736,7 +736,7 @@ class DomainAdmin(ListHeaderAdmin):
search_help_text = "Search by domain name."
change_form_template = "django/admin/domain_change_form.html"
change_list_template = "django/admin/domain_change_list.html"
readonly_fields = ["state"]
readonly_fields = ["state", "expiration_date"]
def export_data_type(self, request):
# match the CSV example with all the fields

View file

@ -216,7 +216,46 @@ class Domain(TimeStampedModel, DomainHelper):
@registry_expiration_date.setter # type: ignore
def registry_expiration_date(self, ex_date: date):
pass
"""
Direct setting of the expiration date in the registry is not implemented.
To update the expiration date, use renew_domain method."""
raise NotImplementedError()
def renew_domain(self, length: int = 1, unit: epp.Unit = epp.Unit.YEAR):
"""
Renew the domain to a length and unit of time relative to the current
expiration date.
Default length and unit of time are 1 year.
"""
# if no expiration date from registry, set to today
try:
cur_exp_date = self.registry_expiration_date
except KeyError:
cur_exp_date = date.today()
# create RenewDomain request
request = commands.RenewDomain(
name=self.name,
cur_exp_date=cur_exp_date,
period = epp.Period(length, unit)
)
try:
# update expiration date in registry, and set the updated
# expiration date in the registrar, and in the cache
self._cache["ex_date"] = registry.send(request, cleaned=True).res_data[0].ex_date
self.expiration_date = self._cache["ex_date"]
self.save()
except RegistryError as err:
# if registry error occurs, log the error, and raise it as well
logger.error(f"registry error renewing domain: {err}")
raise (err)
except Exception as e:
# exception raised during the save to registrar
logger.error(f"error updating expiration date in registrar: {e}")
raise (e)
@Cache
def password(self) -> str:

View file

@ -556,6 +556,7 @@ class MockEppLib(TestCase):
avail=...,
addrs=...,
registrant=...,
ex_date=...,
):
self.auth_info = auth_info
self.cr_date = cr_date
@ -565,6 +566,7 @@ class MockEppLib(TestCase):
self.avail = avail # use for CheckDomain
self.addrs = addrs
self.registrant = registrant
self.ex_date = ex_date
def dummyInfoContactResultData(
self,
@ -811,6 +813,11 @@ class MockEppLib(TestCase):
],
)
mockRenewedDomainExpDate = fakedEppObject(
"fake.gov",
ex_date=datetime.date(2023, 5, 25),
)
def _mockDomainName(self, _name, _avail=False):
return MagicMock(
res_data=[
@ -870,6 +877,8 @@ class MockEppLib(TestCase):
return self.mockCheckDomainCommand(_request, cleaned)
case commands.DeleteDomain:
return self.mockDeleteDomainCommands(_request, cleaned)
case commands.RenewDomain:
return self.mockRenewDomainCommand(_request, cleaned)
case _:
return MagicMock(res_data=[self.mockDataInfoHosts])
@ -890,6 +899,15 @@ class MockEppLib(TestCase):
raise RegistryError(code=ErrorCode.OBJECT_ASSOCIATION_PROHIBITS_OPERATION)
return None
def mockRenewDomainCommand(self, _request, cleaned):
if getattr(_request, "name", None) == "fake-error.gov":
raise RegistryError(code=ErrorCode.PARAMETER_VALUE_RANGE_ERROR)
else:
return MagicMock(
res_data=[self.mockRenewedDomainExpDate],
code=ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY,
)
def mockInfoDomainCommands(self, _request, cleaned):
request_name = getattr(_request, "name", None)

View file

@ -56,7 +56,7 @@ class TestDomainCache(MockEppLib):
self.assertFalse("avail" in domain._cache.keys())
# using a setter should clear the cache
domain.registry_expiration_date = datetime.date.today()
domain.dnssecdata = []
self.assertEquals(domain._cache, {})
# send should have been called only once
@ -1953,6 +1953,41 @@ class TestRegistrantDNSSEC(MockEppLib):
self.assertTrue(err.is_client_error() or err.is_session_error() or err.is_server_error())
class TestExpirationDate(MockEppLib):
"""User may renew expiration date by a number of units of time"""
def setUp(self):
"""
Domain exists in registry
"""
super().setUp()
# for the tests, need a domain in the ready state
self.domain, _ = Domain.objects.get_or_create(name="fake.gov", state=Domain.State.READY)
# for the test, need a domain that will raise an exception
self.domain_w_error, _ = Domain.objects.get_or_create(name="fake-error.gov", state=Domain.State.READY)
def tearDown(self):
Domain.objects.all().delete()
super().tearDown()
def test_expiration_date_setter_not_implemented(self):
"""assert that the setter for expiration date is not implemented and will raise error"""
with self.assertRaises(NotImplementedError) as err:
self.domain.registry_expiration_date = datetime.date.today()
def test_renew_domain(self):
"""assert that the renew_domain sets new expiration date in cache and saves to registrar"""
self.domain.renew_domain()
test_date = datetime.date(2023, 5, 25)
self.assertEquals(self.domain._cache["ex_date"], test_date)
self.assertEquals(self.domain.expiration_date, test_date)
def test_renew_domain_error(self):
"""assert that the renew_domain raises an exception when registry raises error"""
with self.assertRaises(RegistryError) as err:
self.domain_w_error.renew_domain()
class TestAnalystClientHold(MockEppLib):
"""Rule: Analysts may suspend or restore a domain by using client hold"""