Test cases and the like

This commit is contained in:
zandercymatics 2023-09-15 09:37:30 -06:00
parent 1edc21330d
commit aec32ca2ed
No known key found for this signature in database
GPG key ID: FF4636ABEC9682B7
4 changed files with 197 additions and 99 deletions

View file

@ -1,4 +1,4 @@
# Generated by Django 4.2.1 on 2023-09-13 22:25
# Generated by Django 4.2.1 on 2023-09-15 13:59
from django.db import migrations, models
import django_fsm

View file

@ -651,9 +651,16 @@ class Domain(TimeStampedModel, DomainHelper):
# Q: I don't like this function name much,
# what would be better here?
def map_epp_contact_to_public_contact(
self, contact: eppInfo.InfoContactResultData, contact_type
self, contact: eppInfo.InfoContactResultData, contact_id, contact_type
):
"""Maps the Epp contact representation to a PublicContact object"""
"""Maps the Epp contact representation to a PublicContact object.
contact -> eppInfo.InfoContactResultData: The converted contact object
contact_id -> str: The given registry_id of the object (i.e "cheese@cia.gov")
contact_type -> str: The given contact type, (i.e. "tech" or "registrant")
"""
if contact is None:
return None
@ -661,6 +668,9 @@ class Domain(TimeStampedModel, DomainHelper):
if contact_type is None:
raise ValueError("contact_type is None")
if contact_id is None:
raise ValueError("contact_id is None")
logger.debug(f"map_epp_contact_to_public_contact contact -> {contact}")
logger.debug(f"What is the type? {type(contact)}")
if not isinstance(contact, eppInfo.InfoContactResultData):
@ -671,7 +681,7 @@ class Domain(TimeStampedModel, DomainHelper):
addr = postal_info.addr
streets = {}
if addr is not None and addr.street is not None:
# 'zips' two lists together.
# 'zips' two lists together.
# For instance, (('street1', 'some_value_here'), ('street2', 'some_value_here'))
# Dict then converts this to a useable kwarg which we can pass in
streets = dict(
@ -685,7 +695,7 @@ class Domain(TimeStampedModel, DomainHelper):
desired_contact = PublicContact(
domain=self,
contact_type=contact_type,
registry_id=contact.id,
registry_id=contact_id,
email=contact.email,
voice=contact.voice,
fax=contact.fax,
@ -698,8 +708,6 @@ class Domain(TimeStampedModel, DomainHelper):
sp=addr.sp,
**streets,
)
logger.debug("lazy")
logger.debug(desired_contact.__dict__)
return desired_contact
def _request_contact_info(self, contact: PublicContact):
@ -716,6 +724,32 @@ class Domain(TimeStampedModel, DomainHelper):
)
raise error
def get_contact_default(
self, contact_type_choice: PublicContact.ContactTypeChoices
) -> PublicContact:
"""Returns a default contact based off the contact_type_choice.
Used
contact_type_choice is a literal in PublicContact.ContactTypeChoices,
for instance: PublicContact.ContactTypeChoices.SECURITY.
If you wanted to get the default contact for Security, you would call:
get_contact_default(PublicContact.ContactTypeChoices.SECURITY),
or get_contact_default("security")
"""
choices = PublicContact.ContactTypeChoices
contact: PublicContact
match (contact_type_choice):
case choices.ADMINISTRATIVE:
contact = self.get_default_administrative_contact()
case choices.SECURITY:
contact = self.get_default_security_contact()
case choices.TECHNICAL:
contact = self.get_default_technical_contact()
case choices.REGISTRANT:
contact = self.get_default_registrant_contact()
return contact
def generic_contact_getter(
self, contact_type_choice: PublicContact.ContactTypeChoices
) -> PublicContact:
@ -734,9 +768,12 @@ class Domain(TimeStampedModel, DomainHelper):
if contact_type_choice == PublicContact.ContactTypeChoices.REGISTRANT:
desired_property = "registrant"
contacts = self._get_property(desired_property)
if contact_type_choice == PublicContact.ContactTypeChoices.REGISTRANT:
contacts = [contacts]
except KeyError as error:
logger.error("Contact does not exist")
raise error
logger.warning("generic_contact_getter -> Contact does not exist")
logger.warning(error)
return self.get_contact_default(contact_type_choice)
else:
print(f"generic_contact_getter -> contacts?? {contacts}")
# --> Map to public contact
@ -745,9 +782,7 @@ class Domain(TimeStampedModel, DomainHelper):
raise ValueError("No contact was found in cache or the registry")
# Convert it from an EppLib object to PublicContact
return self.map_epp_contact_to_public_contact(
cached_contact, contact_type_choice
)
return cached_contact
def get_default_security_contact(self):
"""Gets the default security contact."""
@ -781,19 +816,17 @@ class Domain(TimeStampedModel, DomainHelper):
For example, check_type = 'security'
"""
for contact in contacts:
print(f"grab_contact_in_keys -> contact item {contact}")
print(f"grab_contact_in_keys -> contact item {contact.__dict__}")
if (
isinstance(contact, dict)
and "id" in contact.keys()
and "type" in contact.keys()
and contact["type"] == check_type
isinstance(contact, PublicContact)
and contact.registry_id is not None
and contact.contact_type is not None
and contact.contact_type == check_type
):
item = PublicContact(
registry_id=contact["id"],
contact_type=contact["type"],
)
full_contact = self._request_contact_info(item)
return full_contact
return contact
# If the for loop didn't do a return,
# then we know that it doesn't exist within cache
# ForeignKey on UserDomainRole creates a "permissions" member for
# all of the user-roles that are in place for this domain
@ -1075,10 +1108,11 @@ class Domain(TimeStampedModel, DomainHelper):
"tr_date": getattr(data, "tr_date", ...),
"up_date": getattr(data, "up_date", ...),
}
print(f"precleaned stuff {cache}")
# remove null properties (to distinguish between "a value of None" and null)
cleaned = {k: v for k, v in cache.items() if v is not ...}
l = getattr(data, "contacts", ...)
logger.debug(f"here are the contacts {l}")
# statuses can just be a list no need to keep the epp object
if "statuses" in cleaned.keys():
cleaned["statuses"] = [status.state for status in cleaned["statuses"]]
@ -1090,7 +1124,12 @@ class Domain(TimeStampedModel, DomainHelper):
registry_id=cleaned["registrant"],
contact_type=PublicContact.ContactTypeChoices.REGISTRANT,
)
cleaned["registrant"] = self._request_contact_info(contact)
# Grabs the expanded contact
full_object = self._request_contact_info(contact)
# Maps it to type PublicContact
cleaned["registrant"] = self.map_epp_contact_to_public_contact(
full_object, contact.registry_id, contact.contact_type
)
except RegistryError:
cleaned["registrant"] = None
# get contact info, if there are any
@ -1100,6 +1139,7 @@ class Domain(TimeStampedModel, DomainHelper):
and isinstance(cleaned["_contacts"], list)
and len(cleaned["_contacts"])
):
logger.debug("hit!")
cleaned["contacts"] = []
for domainContact in cleaned["_contacts"]:
# we do not use _get_or_create_* because we expect the object we
@ -1111,26 +1151,10 @@ class Domain(TimeStampedModel, DomainHelper):
req = commands.InfoContact(id=domainContact.contact)
data = registry.send(req, cleaned=True).res_data[0]
# extract properties from response
# (Ellipsis is used to mean "null")
# convert this to use PublicContactInstead
contact = {
"id": domainContact.contact,
"type": domainContact.type,
"auth_info": getattr(data, "auth_info", ...),
"cr_date": getattr(data, "cr_date", ...),
"disclose": getattr(data, "disclose", ...),
"email": getattr(data, "email", ...),
"fax": getattr(data, "fax", ...),
"postal_info": getattr(data, "postal_info", ...),
"statuses": getattr(data, "statuses", ...),
"tr_date": getattr(data, "tr_date", ...),
"up_date": getattr(data, "up_date", ...),
"voice": getattr(data, "voice", ...),
}
cleaned["contacts"].append(
{k: v for k, v in contact.items() if v is not ...}
self.map_epp_contact_to_public_contact(
data, domainContact.contact, domainContact.type
)
)
# get nameserver info, if there are any
@ -1182,6 +1206,8 @@ class Domain(TimeStampedModel, DomainHelper):
)
if property in self._cache:
logger.debug("hit here also!!")
logger.debug(self._cache[property])
return self._cache[property]
else:
raise KeyError(

View file

@ -557,25 +557,25 @@ class MockEppLib(TestCase):
self.hosts = hosts
self.registrant = registrant
def dummyInfoContactResultData(self, id, email, contact_type):
def dummyInfoContactResultData(id, email):
fake = info.InfoContactResultData(
id=id,
postal_info=common.PostalInfo(
name="Robert The Villain",
name="Registry Customer Service",
addr=common.ContactAddr(
street=["street1", "street2", "street3"],
city="city",
pc="pc",
cc="cc",
sp="sp",
street=["4200 Wilson Blvd."],
city="Arlington",
pc="VA",
cc="US",
sp="22201",
),
org="Skim Milk",
org="Cybersecurity and Infrastructure Security Agency",
type="type",
),
voice="voice",
voice="+1.8882820870",
fax="+1-212-9876543",
email=email,
auth_info=common.ContactAuthInfo(pw="fakepw"),
auth_info=common.ContactAuthInfo(pw="thisisnotapassword"),
roid=...,
statuses=[],
cl_id=...,
@ -591,9 +591,13 @@ class MockEppLib(TestCase):
)
return fake
mockSecurityContact = dummyInfoContactResultData("securityContact", "security@mail.gov")
mockTechnicalContact = dummyInfoContactResultData("technicalContact", "tech@mail.gov")
mockAdministrativeContact = dummyInfoContactResultData("administrativeContact", "admin@mail.gov")
mockRegistrantContact = dummyInfoContactResultData("registrantContact", "registrant@mail.gov")
mockDataInfoDomain = fakedEppObject(
"fakepw",
cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35),
cr_date=datetime.datetime(2023, 8, 25, 19, 45, 35),
contacts=[common.DomainContact(contact="123", type="security")],
hosts=["fake.host.com"],
)
@ -601,12 +605,12 @@ class MockEppLib(TestCase):
"fakepw",
cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35),
contacts=[
common.DomainContact(contact="security", type="security"),
common.DomainContact(contact="admin", type="admin"),
common.DomainContact(contact="tech", type="tech"),
common.DomainContact(contact="securityContact", type="security"),
common.DomainContact(contact="administrativeContact", type="admin"),
common.DomainContact(contact="technicalContact", type="tech"),
],
hosts=["fake.host.com"],
registrant="registrant",
registrant="registrantContact",
)
infoDomainNoContact = fakedEppObject(
"security",
@ -632,12 +636,20 @@ class MockEppLib(TestCase):
elif getattr(_request, "name", None) == "freeman.gov":
return MagicMock(res_data=[self.InfoDomainWithContacts])
elif isinstance(_request, commands.InfoContact):
# Default contact return
mocked_result = self.mockDataInfoContact
if getattr(_request, "id", None) in PublicContact.ContactTypeChoices:
desired_type = getattr(_request, "id", None)
mocked_result = self.dummyInfoContactResultData(
id=desired_type, email=f"{desired_type}@mail.gov"
)
# For testing contact types...
l = getattr(_request, "id", None)
logger.debug(f"get l'd {l}")
match getattr(_request, "id", None):
case "securityContact":
mocked_result = self.mockSecurityContact
case "technicalContact":
mocked_result = self.mockTechnicalContact
case "administrativeContact":
mocked_result = self.mockAdministrativeContact
case "registrantContact":
mocked_result = self.mockRegistrantContact
return MagicMock(res_data=[mocked_result])
elif (

View file

@ -185,11 +185,13 @@ class TestDomainCreation(TestCase):
DomainInformation.objects.all().delete()
DomainApplication.objects.all().delete()
Domain.objects.all().delete()
User.objects.all().delete()
DraftDomain.objects.all().delete()
class TestRegistrantContacts(MockEppLib):
"""Rule: Registrants may modify their WHOIS data"""
def setUp(self):
"""
Background:
@ -201,6 +203,10 @@ class TestRegistrantContacts(MockEppLib):
def tearDown(self):
super().tearDown()
PublicContact.objects.all().delete()
DomainInformation.objects.all().delete()
DomainApplication.objects.all().delete()
Domain.objects.all().delete()
# self.contactMailingAddressPatch.stop()
# self.createContactPatch.stop()
@ -447,62 +453,116 @@ class TestRegistrantContacts(MockEppLib):
Then a user-friendly error message is returned for displaying on the web
"""
raise
@skip("not implemented yet")
def test_contact_getters_cache(self):
"""
Scenario: A user is grabbing a domain that has multiple contact objects
When each contact is retrieved from cache
Then the user retrieves the correct contact objects
"""
domain, _ = Domain.objects.get_or_create(name="freeman.gov")
@skip("not implemented yet")
def test_epp_public_contact_mapper(self):
pass
def test_contact_getter_security(self):
domain_contacts, _ = Domain.objects.get_or_create(name="freeman.gov")
self.maxDiff = None
security = PublicContact.get_default_security()
security.email = "security@mail.gov"
security.domain = domain
security.domain = domain_contacts
security.save()
expected_security_contact = security
domain.security_contact = security
expected_security_contact = security
expected_security_contact = domain_contacts.map_epp_contact_to_public_contact(
self.mockSecurityContact, "securityContact", "security"
)
domain_contacts.security_contact = security
contact_dict = domain_contacts.security_contact.__dict__
expected_dict = expected_security_contact.__dict__
contact_dict.pop('_state')
expected_dict.pop('_state')
self.assertEqual(contact_dict, expected_dict)
def test_contact_getter_technical(self):
domain_contacts, _ = Domain.objects.get_or_create(name="freeman.gov")
technical = PublicContact.get_default_technical()
technical.email = "technical@mail.gov"
technical.domain = domain
technical.email = "tech@mail.gov"
technical.domain = domain_contacts
technical.save()
expected_technical_contact = technical
domain.technical_contact = technical
expected_technical_contact = domain_contacts.map_epp_contact_to_public_contact(
self.mockTechnicalContact, "technicalContact", "tech"
)
domain_contacts.technical_contact = technical
contact_dict = domain_contacts.technical_contact.__dict__
expected_dict = expected_technical_contact.__dict__
# There has to be a better way to do this.
# Since Cache creates a new object, it causes
# a desync between each instance. Basically,
# these two objects will never be the same.
contact_dict.pop('_state')
expected_dict.pop('_state')
self.assertEqual(contact_dict, expected_dict)
def test_contact_getter_administrative(self):
self.maxDiff = None
domain_contacts, _ = Domain.objects.get_or_create(name="freeman.gov")
administrative = PublicContact.get_default_administrative()
administrative.email = "administrative@mail.gov"
administrative.domain = domain
administrative.email = "admin@mail.gov"
administrative.domain = domain_contacts
administrative.save()
expected_administrative_contact = administrative
domain.administrative_contact = administrative
expected_administrative_contact = domain_contacts.map_epp_contact_to_public_contact(
self.mockAdministrativeContact, "administrativeContact", "admin"
)
domain_contacts.administrative_contact = administrative
contact_dict = domain_contacts.administrative_contact.__dict__
expected_dict = expected_administrative_contact.__dict__
contact_dict.pop('_state')
expected_dict.pop('_state')
self.assertEqual(contact_dict, expected_dict)
def test_contact_getter_registrant(self):
domain_contacts, _ = Domain.objects.get_or_create(name="freeman.gov")
registrant = PublicContact.get_default_registrant()
registrant.email = "registrant@mail.gov"
registrant.domain = domain
registrant.domain = domain_contacts
registrant.save()
expected_registrant_contact = registrant
domain.registrant_contact = registrant
domain_contacts.registrant_contact = registrant
logger.debug(f"domain obj: {domain.security_contact.__dict__}")
logger.debug(f"expected: {expected_security_contact.__dict__}")
self.assertEqual(domain.security_contact, expected_security_contact)
self.assertEqual(domain.technical_contact, expected_technical_contact)
self.assertEqual(domain.administrative_contact, expected_administrative_contact)
self.assertEqual(domain.registrant_contact, expected_registrant_contact)
expected_registrant_contact = domain_contacts.map_epp_contact_to_public_contact(
self.mockRegistrantContact, "registrantContact", "registrant"
)
domain_contacts.registrant_contact = registrant
@skip("not implemented yet")
def test_contact_getters_registry(self):
"""
Scenario: A user is grabbing a domain that has multiple contact objects
When the domain is retrieved from cache
Then the user retrieves the correct domain object
"""
# Create something using infocontact for that domain
# Then just grab the domain object normally
# That 'something' doesn't exist on the local domain,
# so registry should be called
raise
contact_dict = domain_contacts.registrant_contact.__dict__
expected_dict = expected_registrant_contact.__dict__
contact_dict.pop('_state')
expected_dict.pop('_state')
self.assertEqual(contact_dict, expected_dict)
class TestRegistrantNameservers(TestCase):