mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-08-02 16:02:15 +02:00
update deletion process and tests
This commit is contained in:
parent
ede01e3181
commit
b5e4f8b40c
3 changed files with 84 additions and 14 deletions
|
@ -254,7 +254,7 @@ class Domain(TimeStampedModel, DomainHelper):
|
|||
return not cls.available(domain)
|
||||
|
||||
@Cache
|
||||
def contacts(self) -> dict[str, str]:
|
||||
def registry_contacts(self) -> dict[str, str]:
|
||||
"""
|
||||
Get a dictionary of registry IDs for the contacts for this domain.
|
||||
|
||||
|
@ -263,7 +263,10 @@ class Domain(TimeStampedModel, DomainHelper):
|
|||
{ PublicContact.ContactTypeChoices.REGISTRANT: "jd1234",
|
||||
PublicContact.ContactTypeChoices.ADMINISTRATIVE: "sh8013",...}
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
if self._cache.get("contacts"):
|
||||
return self._cache.get("contacts")
|
||||
else:
|
||||
return self._get_property("contacts")
|
||||
|
||||
@Cache
|
||||
def creation_date(self) -> date:
|
||||
|
@ -1032,17 +1035,19 @@ class Domain(TimeStampedModel, DomainHelper):
|
|||
logger.error(f"registry error removing client hold: {err}")
|
||||
raise (err)
|
||||
|
||||
def _delete_contacts(self):
|
||||
"""Contacts associated with this domain will be deleted.
|
||||
RegistryErrors will be logged and raised. Additional
|
||||
error handling should be provided by the caller.
|
||||
def _delete_nonregistrant_contacts(self):
|
||||
"""Non-registrant contacts associated with this domain will be deleted.
|
||||
RegistryErrors will be logged and raised. Error
|
||||
handling should be provided by the caller.
|
||||
"""
|
||||
logger.info("Deleting contacts for %s", self.name)
|
||||
contacts = self._cache.get("contacts")
|
||||
contacts = self.registry_contacts
|
||||
logger.debug("Contacts to delete for %s inside _delete_contacts -> %s", self.name, contacts)
|
||||
if contacts:
|
||||
for contact in contacts:
|
||||
self._delete_contact(contact)
|
||||
for contact, id in contacts.items():
|
||||
# registrants have to be deleted after the domain
|
||||
if contact != PublicContact.ContactTypeChoices.REGISTRANT:
|
||||
self._delete_contact(contact, id)
|
||||
|
||||
|
||||
def _delete_subdomains(self):
|
||||
|
@ -1067,6 +1072,13 @@ class Domain(TimeStampedModel, DomainHelper):
|
|||
request = commands.DeleteDomain(name=self.name)
|
||||
registry.send(request, cleaned=True)
|
||||
|
||||
def _delete_domain_registrant(self):
|
||||
"""This domain's registrant should be deleted from the registry
|
||||
may raises RegistryError, should be caught or handled correctly by caller"""
|
||||
registrantID = self.registrant_contact.registry_id
|
||||
request = commands.DeleteContact(id=registrantID)
|
||||
registry.send(request, cleaned=True)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.name
|
||||
|
||||
|
@ -1475,8 +1487,9 @@ class Domain(TimeStampedModel, DomainHelper):
|
|||
try:
|
||||
logger.info("deletedInEpp()-> inside _delete_domain")
|
||||
self._delete_subdomains()
|
||||
self._delete_contacts()
|
||||
self._delete_nonregistrant_contacts()
|
||||
self._delete_domain()
|
||||
self._delete_domain_registrant()
|
||||
self.deleted = timezone.now()
|
||||
except RegistryError as err:
|
||||
logger.error(f"Could not delete domain. Registry returned error: {err}")
|
||||
|
@ -1678,15 +1691,15 @@ class Domain(TimeStampedModel, DomainHelper):
|
|||
|
||||
raise e
|
||||
|
||||
def _delete_contact(self, contact: PublicContact):
|
||||
def _delete_contact(self, contact_name: str, registry_id: str):
|
||||
"""Try to delete a contact from the registry.
|
||||
|
||||
raises:
|
||||
RegistryError: if the registry is unable to delete the contact
|
||||
"""
|
||||
logger.info("_delete_contact() -> Attempting to delete contact for %s from domain %s", contact.name, contact.domain)
|
||||
logger.info("_delete_contact() -> Attempting to delete contact for %s from domain %s", contact_name, self.name)
|
||||
try:
|
||||
req = commands.DeletContact(id=contact.registry_id)
|
||||
req = commands.DeleteContact(id=registry_id)
|
||||
return registry.send(req, cleaned=True).res_data[0]
|
||||
except RegistryError as error:
|
||||
logger.error(
|
||||
|
|
|
@ -1229,6 +1229,7 @@ class MockEppLib(TestCase):
|
|||
common.Status(state="serverTransferProhibited", description="", lang="en"),
|
||||
common.Status(state="inactive", description="", lang="en"),
|
||||
],
|
||||
registrant="regContact",
|
||||
ex_date=date(2023, 5, 25),
|
||||
)
|
||||
|
||||
|
@ -1610,6 +1611,8 @@ class MockEppLib(TestCase):
|
|||
return self.mockInfoContactCommands(_request, cleaned)
|
||||
case commands.CreateContact:
|
||||
return self.mockCreateContactCommands(_request, cleaned)
|
||||
case commands.DeleteContact:
|
||||
return self.mockDeleteContactCommands(_request, cleaned)
|
||||
case commands.UpdateDomain:
|
||||
return self.mockUpdateDomainCommands(_request, cleaned)
|
||||
case commands.CreateHost:
|
||||
|
@ -1731,6 +1734,7 @@ class MockEppLib(TestCase):
|
|||
|
||||
# Define a dictionary to map request names to data and extension values
|
||||
request_mappings = {
|
||||
"fake.gov": (self.mockDataInfoDomain, None),
|
||||
"security.gov": (self.infoDomainNoContact, None),
|
||||
"dnssec-dsdata.gov": (
|
||||
self.mockDataInfoDomain,
|
||||
|
@ -1811,6 +1815,15 @@ class MockEppLib(TestCase):
|
|||
# mocks a contact error on creation
|
||||
raise ContactError(code=ContactErrorCodes.CONTACT_TYPE_NONE)
|
||||
return MagicMock(res_data=[self.mockDataInfoHosts])
|
||||
|
||||
def mockDeleteContactCommands(self, _request, cleaned):
|
||||
if getattr(_request, "id", None) == "fail":
|
||||
raise RegistryError(code=ErrorCode.OBJECT_EXISTS)
|
||||
else:
|
||||
return MagicMock(
|
||||
res_data=[self.mockDataInfoContact],
|
||||
code=ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY,
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
"""mock epp send function as this will fail locally"""
|
||||
|
|
|
@ -2586,6 +2586,7 @@ class TestAnalystDelete(MockEppLib):
|
|||
|
||||
def tearDown(self):
|
||||
Host.objects.all().delete()
|
||||
PublicContact.objects.all().delete()
|
||||
Domain.objects.all().delete()
|
||||
super().tearDown()
|
||||
|
||||
|
@ -2643,7 +2644,7 @@ class TestAnalystDelete(MockEppLib):
|
|||
call(
|
||||
commands.DeleteHost(name=common.HostObjSet(hosts=['ns1.sharedhost.com'])),
|
||||
cleaned=True,
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
# Domain itself should not be deleted
|
||||
|
@ -2651,6 +2652,49 @@ class TestAnalystDelete(MockEppLib):
|
|||
# State should not have changed
|
||||
self.assertEqual(domain.state, Domain.State.ON_HOLD)
|
||||
|
||||
def test_deletion_with_host_and_contacts(self):
|
||||
"""
|
||||
Scenario: Domain with related Host and Contacts is Deleted
|
||||
When a contact and host exists that is tied to this domain
|
||||
Then `commands.DeleteHost` is sent to the registry
|
||||
Then `commands.DeleteContact` is sent to the registry
|
||||
Then `commands.DeleteDomain` is sent to the registry
|
||||
Then `commands.DeleteContact` is sent to the registry for the registrant contact
|
||||
And `state` is set to `DELETED`
|
||||
"""
|
||||
# with less_console_noise():
|
||||
# Desired domain
|
||||
domain, _ = Domain.objects.get_or_create(name="freeman.gov", state=Domain.State.ON_HOLD)
|
||||
# Put the domain in client hold
|
||||
domain.place_client_hold()
|
||||
# Delete it
|
||||
domain.deletedInEpp()
|
||||
domain.save()
|
||||
|
||||
# Check that the host and contacts are deleted, order doesn't matter
|
||||
self.mockedSendFunction.assert_has_calls(
|
||||
[
|
||||
call(commands.DeleteHost(name=common.HostObjSet(hosts=['fake.host.com'])), cleaned=True),
|
||||
call(commands.DeleteContact(id="securityContact"), cleaned=True),
|
||||
call(commands.DeleteContact(id="technicalContact"), cleaned=True),
|
||||
call(commands.DeleteContact(id="adminContact"),cleaned=True,)
|
||||
],
|
||||
any_order=True
|
||||
)
|
||||
|
||||
# These calls need to be in order
|
||||
self.mockedSendFunction.assert_has_calls(
|
||||
[
|
||||
call(commands.DeleteDomain(name="freeman.gov"), cleaned=True),
|
||||
call(commands.InfoContact(id="regContact"), cleaned=True),
|
||||
call(commands.DeleteContact(id="regContact"), cleaned=True),
|
||||
],
|
||||
)
|
||||
# Domain itself should not be deleted
|
||||
self.assertNotEqual(domain, None)
|
||||
# State should have changed
|
||||
self.assertEqual(domain.state, Domain.State.DELETED)
|
||||
|
||||
def test_deletion_ready_fsm_failure(self):
|
||||
"""
|
||||
Scenario: Domain deletion is unsuccessful due to FSM rules
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue