manage.get.gov/src/registrar/tests/common.py
2023-10-20 10:32:06 -06:00

1048 lines
36 KiB
Python

import datetime
import os
import logging
from contextlib import contextmanager
import random
from string import ascii_uppercase
from django.test import TestCase
from unittest.mock import MagicMock, Mock, patch
from typing import List, Dict
from django.conf import settings
from django.contrib.auth import get_user_model, login
from registrar.models import (
Contact,
DraftDomain,
Website,
DomainApplication,
DomainInvitation,
User,
UserGroup,
DomainInformation,
PublicContact,
Domain,
)
from epplibwrapper import (
commands,
common,
extensions,
info,
RegistryError,
ErrorCode,
responses,
)
from registrar.models.utility.contact_error import ContactError, ContactErrorCodes
logger = logging.getLogger(__name__)
def get_handlers():
"""Obtain pointers to all StreamHandlers."""
handlers = {}
rootlogger = logging.getLogger()
for h in rootlogger.handlers:
if isinstance(h, logging.StreamHandler):
handlers[h.name] = h
for logger in logging.Logger.manager.loggerDict.values():
if not isinstance(logger, logging.PlaceHolder):
for h in logger.handlers:
if isinstance(h, logging.StreamHandler):
handlers[h.name] = h
return handlers
@contextmanager
def less_console_noise():
"""
Context manager to use in tests to silence console logging.
This is helpful on tests which trigger console messages
(such as errors) which are normal and expected.
It can easily be removed to debug a failing test.
"""
restore = {}
handlers = get_handlers()
devnull = open(os.devnull, "w")
# redirect all the streams
for handler in handlers.values():
prior = handler.setStream(devnull)
restore[handler.name] = prior
try:
# run the test
yield
finally:
# restore the streams
for handler in handlers.values():
handler.setStream(restore[handler.name])
# close the file we opened
devnull.close()
class MockUserLogin:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
if request.user.is_anonymous:
user = None
UserModel = get_user_model()
username = "Testy"
args = {
UserModel.USERNAME_FIELD: username,
}
user, _ = UserModel.objects.get_or_create(**args)
user.is_staff = True
# Create or retrieve the group
group, _ = UserGroup.objects.get_or_create(name="full_access_group")
# Add the user to the group
user.groups.set([group])
user.save()
backend = settings.AUTHENTICATION_BACKENDS[-1]
login(request, user, backend=backend)
response = self.get_response(request)
return response
class MockSESClient(Mock):
EMAILS_SENT: List[Dict] = []
def send_email(self, *args, **kwargs):
self.EMAILS_SENT.append({"args": args, "kwargs": kwargs})
class AuditedAdminMockData:
"""Creates simple data mocks for AuditedAdminTest.
Can likely be more generalized, but the primary purpose of this class is to simplify
mock data creation, especially for lists of items,
by making the assumption that for most use cases we don't have to worry about
data 'accuracy' ('testy 2' is not an accurate first_name for example), we just care about
implementing some kind of patterning, especially with lists of items.
Two variables are used across multiple functions:
*item_name* - Used in patterning. Will be appended en masse to multiple str fields,
like first_name. For example, item_name 'egg' will return a user object of:
first_name: 'egg first_name:user',
last_name: 'egg last_name:user',
username: 'egg username:user'
where 'user' is the short_hand
*short_hand* - Used in patterning. Certain fields will have ':{shorthand}' appended to it,
as a way to optionally include metadata in the str itself. Can be further expanded on.
Came from a bug where different querysets used in testing would effectively be 'anonymized', wherein
it would only display a list of types, but not include the variable name.
""" # noqa
# Constants for different domain object types
INFORMATION = "information"
APPLICATION = "application"
INVITATION = "invitation"
def dummy_user(self, item_name, short_hand):
"""Creates a dummy user object,
but with a shorthand and support for multiple"""
user = User.objects.get_or_create(
first_name="{} first_name:{}".format(item_name, short_hand),
last_name="{} last_name:{}".format(item_name, short_hand),
username="{} username:{}".format(item_name, short_hand),
)[0]
return user
def dummy_contact(self, item_name, short_hand):
"""Creates a dummy contact object"""
contact = Contact.objects.get_or_create(
first_name="{} first_name:{}".format(item_name, short_hand),
last_name="{} last_name:{}".format(item_name, short_hand),
title="{} title:{}".format(item_name, short_hand),
email="{}testy@town.com".format(item_name),
phone="(555) 555 5555",
)[0]
return contact
def dummy_draft_domain(self, item_name, prebuilt=False):
"""
Creates a dummy DraftDomain object
Args:
item_name (str): Value for 'name' in a DraftDomain object.
prebuilt (boolean): Determines return type.
Returns:
DraftDomain: Where name = 'item_name'. If prebuilt = True, then
name will be "city{}.gov".format(item_name).
"""
if prebuilt:
item_name = "city{}.gov".format(item_name)
return DraftDomain.objects.get_or_create(name=item_name)[0]
def dummy_domain(self, item_name, prebuilt=False):
"""
Creates a dummy domain object
Args:
item_name (str): Value for 'name' in a Domain object.
prebuilt (boolean): Determines return type.
Returns:
Domain: Where name = 'item_name'. If prebuilt = True, then
domain name will be "city{}.gov".format(item_name).
"""
if prebuilt:
item_name = "city{}.gov".format(item_name)
return Domain.objects.get_or_create(name=item_name)[0]
def dummy_website(self, item_name):
"""
Creates a dummy website object
Args:
item_name (str): Value for 'website' in a Website object.
Returns:
Website: Where website = 'item_name'.
"""
return Website.objects.get_or_create(website=item_name)[0]
def dummy_alt(self, item_name):
"""
Creates a dummy website object for alternates
Args:
item_name (str): Value for 'website' in a Website object.
Returns:
Website: Where website = "cityalt{}.gov".format(item_name).
"""
return self.dummy_website(item_name="cityalt{}.gov".format(item_name))
def dummy_current(self, item_name):
"""
Creates a dummy website object for current
Args:
item_name (str): Value for 'website' in a Website object.
prebuilt (boolean): Determines return type.
Returns:
Website: Where website = "city{}.gov".format(item_name)
"""
return self.dummy_website(item_name="city{}.com".format(item_name))
def get_common_domain_arg_dictionary(
self,
item_name,
org_type="federal",
federal_type="executive",
purpose="Purpose of the site",
):
"""
Generates a generic argument dict for most domains
Args:
item_name (str): A shared str value appended to first_name, last_name,
organization_name, address_line1, address_line2,
title, email, and username.
org_type (str - optional): Sets a domains org_type
federal_type (str - optional): Sets a domains federal_type
purpose (str - optional): Sets a domains purpose
Returns:
Dictionary: {
organization_type: str,
federal_type: str,
purpose: str,
organization_name: str = "{} organization".format(item_name),
address_line1: str = "{} address_line1".format(item_name),
address_line2: str = "{} address_line2".format(item_name),
is_policy_acknowledged: boolean = True,
state_territory: str = "NY",
zipcode: str = "10002",
about_your_organization: str = "e-Government",
anything_else: str = "There is more",
authorizing_official: Contact = self.dummy_contact(item_name, "authorizing_official"),
submitter: Contact = self.dummy_contact(item_name, "submitter"),
creator: User = self.dummy_user(item_name, "creator"),
}
""" # noqa
common_args = dict(
organization_type=org_type,
federal_type=federal_type,
purpose=purpose,
organization_name="{} organization".format(item_name),
address_line1="{} address_line1".format(item_name),
address_line2="{} address_line2".format(item_name),
is_policy_acknowledged=True,
state_territory="NY",
zipcode="10002",
about_your_organization="e-Government",
anything_else="There is more",
authorizing_official=self.dummy_contact(item_name, "authorizing_official"),
submitter=self.dummy_contact(item_name, "submitter"),
creator=self.dummy_user(item_name, "creator"),
)
return common_args
def dummy_kwarg_boilerplate(
self,
domain_type,
item_name,
status=DomainApplication.STARTED,
org_type="federal",
federal_type="executive",
purpose="Purpose of the site",
):
"""
Returns a prebuilt kwarg dictionary for DomainApplication,
DomainInformation, or DomainInvitation.
Args:
domain_type (str): is either 'application', 'information',
or 'invitation'.
item_name (str): A shared str value appended to first_name, last_name,
organization_name, address_line1, address_line2,
title, email, and username.
status (str - optional): Defines the status for DomainApplication,
e.g. DomainApplication.STARTED
org_type (str - optional): Sets a domains org_type
federal_type (str - optional): Sets a domains federal_type
purpose (str - optional): Sets a domains purpose
Returns:
dict: Returns a dictionary structurally consistent with the expected input
of either DomainApplication, DomainInvitation, or DomainInformation
based on the 'domain_type' field.
""" # noqa
common_args = self.get_common_domain_arg_dictionary(
item_name, org_type, federal_type, purpose
)
full_arg_dict = None
match domain_type:
case self.APPLICATION:
full_arg_dict = dict(
**common_args,
requested_domain=self.dummy_draft_domain(item_name),
investigator=self.dummy_user(item_name, "investigator"),
status=status,
)
case self.INFORMATION:
domain_app = self.create_full_dummy_domain_application(item_name)
full_arg_dict = dict(
**common_args,
domain=self.dummy_domain(item_name, True),
domain_application=domain_app,
)
case self.INVITATION:
full_arg_dict = dict(
email="test_mail@mail.com",
domain=self.dummy_domain(item_name, True),
status=DomainInvitation.INVITED,
)
return full_arg_dict
def create_full_dummy_domain_application(
self, item_name, status=DomainApplication.STARTED
):
"""Creates a dummy domain application object"""
domain_application_kwargs = self.dummy_kwarg_boilerplate(
self.APPLICATION, item_name, status
)
application = DomainApplication.objects.get_or_create(
**domain_application_kwargs
)[0]
return application
def create_full_dummy_domain_information(
self, item_name, status=DomainApplication.STARTED
):
"""Creates a dummy domain information object"""
domain_application_kwargs = self.dummy_kwarg_boilerplate(
self.INFORMATION, item_name, status
)
application = DomainInformation.objects.get_or_create(
**domain_application_kwargs
)[0]
return application
def create_full_dummy_domain_invitation(
self, item_name, status=DomainApplication.STARTED
):
"""Creates a dummy domain invitation object"""
domain_application_kwargs = self.dummy_kwarg_boilerplate(
self.INVITATION, item_name, status
)
application = DomainInvitation.objects.get_or_create(
**domain_application_kwargs
)[0]
return application
def create_full_dummy_domain_object(
self,
domain_type,
item_name,
has_other_contacts=True,
has_current_website=True,
has_alternative_gov_domain=True,
status=DomainApplication.STARTED,
):
"""A helper to create a dummy domain application object"""
application = None
match domain_type:
case self.APPLICATION:
application = self.create_full_dummy_domain_application(
item_name, status
)
case self.INVITATION:
application = self.create_full_dummy_domain_invitation(
item_name, status
)
case self.INFORMATION:
application = self.create_full_dummy_domain_information(
item_name, status
)
case _:
raise ValueError("Invalid domain_type, must conform to given constants")
if has_other_contacts and domain_type != self.INVITATION:
other = self.dummy_contact(item_name, "other")
application.other_contacts.add(other)
if has_current_website and domain_type == self.APPLICATION:
current = self.dummy_current(item_name)
application.current_websites.add(current)
if has_alternative_gov_domain and domain_type == self.APPLICATION:
alt = self.dummy_alt(item_name)
application.alternative_domains.add(alt)
return application
def mock_user():
"""A simple user."""
user_kwargs = dict(
id=4,
first_name="Rachid",
last_name="Mrad",
)
mock_user, _ = User.objects.get_or_create(**user_kwargs)
return mock_user
def create_superuser():
User = get_user_model()
p = "adminpass"
user = User.objects.create_user(
username="superuser",
email="admin@example.com",
is_staff=True,
password=p,
)
# Retrieve the group or create it if it doesn't exist
group, _ = UserGroup.objects.get_or_create(name="full_access_group")
# Add the user to the group
user.groups.set([group])
return user
def create_user():
User = get_user_model()
p = "userpass"
user = User.objects.create_user(
username="staffuser",
email="user@example.com",
is_staff=True,
password=p,
)
# Retrieve the group or create it if it doesn't exist
group, _ = UserGroup.objects.get_or_create(name="cisa_analysts_group")
# Add the user to the group
user.groups.set([group])
return user
def create_ready_domain():
domain, _ = Domain.objects.get_or_create(name="city.gov", state=Domain.State.READY)
return domain
def completed_application(
has_other_contacts=True,
has_current_website=True,
has_alternative_gov_domain=True,
has_about_your_organization=True,
has_anything_else=True,
status=DomainApplication.STARTED,
user=False,
name="city.gov",
):
"""A completed domain application."""
if not user:
user = get_user_model().objects.create(username="username")
ao, _ = Contact.objects.get_or_create(
first_name="Testy",
last_name="Tester",
title="Chief Tester",
email="testy@town.com",
phone="(555) 555 5555",
)
domain, _ = DraftDomain.objects.get_or_create(name=name)
alt, _ = Website.objects.get_or_create(website="city1.gov")
current, _ = Website.objects.get_or_create(website="city.com")
you, _ = Contact.objects.get_or_create(
first_name="Testy2",
last_name="Tester2",
title="Admin Tester",
email="mayor@igorville.gov",
phone="(555) 555 5556",
)
other, _ = Contact.objects.get_or_create(
first_name="Testy",
last_name="Tester",
title="Another Tester",
email="testy2@town.com",
phone="(555) 555 5557",
)
domain_application_kwargs = dict(
organization_type="federal",
federal_type="executive",
purpose="Purpose of the site",
is_policy_acknowledged=True,
organization_name="Testorg",
address_line1="address 1",
address_line2="address 2",
state_territory="NY",
zipcode="10002",
authorizing_official=ao,
requested_domain=domain,
submitter=you,
creator=user,
status=status,
)
if has_about_your_organization:
domain_application_kwargs["about_your_organization"] = "e-Government"
if has_anything_else:
domain_application_kwargs["anything_else"] = "There is more"
application, _ = DomainApplication.objects.get_or_create(
**domain_application_kwargs
)
if has_other_contacts:
application.other_contacts.add(other)
if has_current_website:
application.current_websites.add(current)
if has_alternative_gov_domain:
application.alternative_domains.add(alt)
return application
def multiple_unalphabetical_domain_objects(
domain_type=AuditedAdminMockData.APPLICATION,
):
"""Returns a list of generic domain objects for testing purposes"""
applications = []
list_of_letters = list(ascii_uppercase)
random.shuffle(list_of_letters)
mock = AuditedAdminMockData()
for object_name in list_of_letters:
application = mock.create_full_dummy_domain_object(domain_type, object_name)
applications.append(application)
return applications
def generic_domain_object(domain_type, object_name):
"""Returns a generic domain object of
domain_type 'application', 'information', or 'invitation'"""
mock = AuditedAdminMockData()
application = mock.create_full_dummy_domain_object(domain_type, object_name)
return application
class MockEppLib(TestCase):
class fakedEppObject(object):
""""""
def __init__(
self,
auth_info=...,
cr_date=...,
contacts=...,
hosts=...,
statuses=...,
avail=...,
addrs=...,
registrant=...,
):
self.auth_info = auth_info
self.cr_date = cr_date
self.contacts = contacts
self.hosts = hosts
self.statuses = statuses
self.avail = avail # use for CheckDomain
self.addrs = addrs
self.registrant = registrant
def dummyInfoContactResultData(
self,
id,
email,
cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35),
pw="thisisnotapassword",
):
fake = info.InfoContactResultData(
id=id,
postal_info=common.PostalInfo(
name="Registry Customer Service",
addr=common.ContactAddr(
street=["4200 Wilson Blvd."],
city="Arlington",
pc="22201",
cc="US",
sp="VA",
),
org="Cybersecurity and Infrastructure Security Agency",
type="type",
),
voice="+1.8882820870",
fax="+1-212-9876543",
email=email,
auth_info=common.ContactAuthInfo(pw=pw),
roid=...,
statuses=[],
cl_id=...,
cr_id=...,
cr_date=cr_date,
up_id=...,
up_date=...,
tr_date=...,
disclose=...,
vat=...,
ident=...,
notify_email=...,
)
return fake
mockDataInfoDomain = fakedEppObject(
"fakePw",
cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35),
contacts=[
common.DomainContact(
contact="123", type=PublicContact.ContactTypeChoices.SECURITY
)
],
hosts=["fake.host.com"],
statuses=[
common.Status(state="serverTransferProhibited", description="", lang="en"),
common.Status(state="inactive", description="", lang="en"),
],
)
mockDataInfoContact = mockDataInfoDomain.dummyInfoContactResultData(
"123", "123@mail.gov", datetime.datetime(2023, 5, 25, 19, 45, 35), "lastPw"
)
InfoDomainWithContacts = fakedEppObject(
"fakepw",
cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35),
contacts=[
common.DomainContact(
contact="securityContact",
type=PublicContact.ContactTypeChoices.SECURITY,
),
common.DomainContact(
contact="technicalContact",
type=PublicContact.ContactTypeChoices.TECHNICAL,
),
common.DomainContact(
contact="adminContact",
type=PublicContact.ContactTypeChoices.ADMINISTRATIVE,
),
],
hosts=["fake.host.com"],
statuses=[
common.Status(state="serverTransferProhibited", description="", lang="en"),
common.Status(state="inactive", description="", lang="en"),
],
registrant="regContact",
)
InfoDomainWithDefaultSecurityContact = fakedEppObject(
"fakepw",
cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35),
contacts=[
common.DomainContact(
contact="defaultSec",
type=PublicContact.ContactTypeChoices.SECURITY,
)
],
hosts=["fake.host.com"],
statuses=[
common.Status(state="serverTransferProhibited", description="", lang="en"),
common.Status(state="inactive", description="", lang="en"),
],
)
InfoDomainWithDefaultTechnicalContact = fakedEppObject(
"fakepw",
cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35),
contacts=[
common.DomainContact(
contact="defaultTech",
type=PublicContact.ContactTypeChoices.TECHNICAL,
)
],
hosts=["fake.host.com"],
statuses=[
common.Status(state="serverTransferProhibited", description="", lang="en"),
common.Status(state="inactive", description="", lang="en"),
],
)
mockDefaultTechnicalContact = InfoDomainWithContacts.dummyInfoContactResultData(
"defaultTech", "dotgov@cisa.dhs.gov"
)
mockDefaultSecurityContact = InfoDomainWithContacts.dummyInfoContactResultData(
"defaultSec", "dotgov@cisa.dhs.gov"
)
mockSecurityContact = InfoDomainWithContacts.dummyInfoContactResultData(
"securityContact", "security@mail.gov"
)
mockTechnicalContact = InfoDomainWithContacts.dummyInfoContactResultData(
"technicalContact", "tech@mail.gov"
)
mockAdministrativeContact = InfoDomainWithContacts.dummyInfoContactResultData(
"adminContact", "admin@mail.gov"
)
mockRegistrantContact = InfoDomainWithContacts.dummyInfoContactResultData(
"regContact", "registrant@mail.gov"
)
infoDomainNoContact = fakedEppObject(
"security",
cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35),
contacts=[],
hosts=["fake.host.com"],
)
infoDomainThreeHosts = fakedEppObject(
"my-nameserver.gov",
cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35),
contacts=[],
hosts=[
"ns1.my-nameserver-1.com",
"ns1.my-nameserver-2.com",
"ns1.cats-are-superior3.com",
],
)
infoDomainNoHost = fakedEppObject(
"my-nameserver.gov",
cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35),
contacts=[],
hosts=[],
)
infoDomainTwoHosts = fakedEppObject(
"my-nameserver.gov",
cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35),
contacts=[],
hosts=["ns1.my-nameserver-1.com", "ns1.my-nameserver-2.com"],
)
mockDataInfoHosts = fakedEppObject(
"lastPw",
cr_date=datetime.datetime(2023, 8, 25, 19, 45, 35),
addrs=["1.2.3.4", "2.3.4.5"],
)
mockDataHostChange = fakedEppObject(
"lastPw", cr_date=datetime.datetime(2023, 8, 25, 19, 45, 35)
)
addDsData1 = {
"keyTag": 1234,
"alg": 3,
"digestType": 1,
"digest": "ec0bdd990b39feead889f0ba613db4adec0bdd99",
}
addDsData2 = {
"keyTag": 2345,
"alg": 3,
"digestType": 1,
"digest": "ec0bdd990b39feead889f0ba613db4adecb4adec",
}
keyDataDict = {
"flags": 257,
"protocol": 3,
"alg": 1,
"pubKey": "AQPJ////4Q==",
}
dnssecExtensionWithDsData = extensions.DNSSECExtension(
**{
"dsData": [
common.DSData(**addDsData1) # type: ignore
], # type: ignore
}
)
dnssecExtensionWithMultDsData = extensions.DNSSECExtension(
**{
"dsData": [
common.DSData(**addDsData1), # type: ignore
common.DSData(**addDsData2), # type: ignore
], # type: ignore
}
)
dnssecExtensionWithKeyData = extensions.DNSSECExtension(
**{
"keyData": [common.DNSSECKeyData(**keyDataDict)], # type: ignore
}
)
dnssecExtensionRemovingDsData = extensions.DNSSECExtension()
infoDomainHasIP = fakedEppObject(
"nameserverwithip.gov",
cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35),
contacts=[],
hosts=[
"ns1.nameserverwithip.gov",
"ns2.nameserverwithip.gov",
"ns3.nameserverwithip.gov",
],
addrs=["1.2.3.4", "2.3.4.5"],
)
infoDomainCheckHostIPCombo = fakedEppObject(
"nameserversubdomain.gov",
cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35),
contacts=[],
hosts=[
"ns1.nameserversubdomain.gov",
"ns2.nameserversubdomain.gov",
],
)
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"""
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,
)
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":
raise RegistryError(code=ErrorCode.PARAMETER_VALUE_RANGE_ERROR)
else:
return MagicMock(
res_data=[self.mockDataHostChange],
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)
# Define a dictionary to map request names to data and extension values
request_mappings = {
"security.gov": (self.infoDomainNoContact, None),
"dnssec-dsdata.gov": (
self.mockDataInfoDomain,
self.dnssecExtensionWithDsData,
),
"dnssec-multdsdata.gov": (
self.mockDataInfoDomain,
self.dnssecExtensionWithMultDsData,
),
"dnssec-keydata.gov": (
self.mockDataInfoDomain,
self.dnssecExtensionWithKeyData,
),
"dnssec-none.gov": (self.mockDataInfoDomain, None),
"my-nameserver.gov": (
self.infoDomainTwoHosts
if self.mockedSendFunction.call_count == 5
else self.infoDomainNoHost,
None,
),
"nameserverwithip.gov": (self.infoDomainHasIP, None),
"namerserversubdomain.gov": (self.infoDomainCheckHostIPCombo, None),
"freeman.gov": (self.InfoDomainWithContacts, None),
"threenameserversDomain.gov": (self.infoDomainThreeHosts, None),
"defaultsecurity.gov": (self.InfoDomainWithDefaultSecurityContact, None),
"defaulttechnical.gov": (self.InfoDomainWithDefaultTechnicalContact, None),
}
# Retrieve the corresponding values from the dictionary
res_data, extensions = request_mappings.get(
request_name, (self.mockDataInfoDomain, None)
)
return MagicMock(
res_data=[res_data],
extensions=[extensions] if extensions is not None else [],
)
def mockInfoContactCommands(self, _request, cleaned):
mocked_result: info.InfoContactResultData
# For testing contact types
match getattr(_request, "id", None):
case "securityContact":
mocked_result = self.mockSecurityContact
case "technicalContact":
mocked_result = self.mockTechnicalContact
case "adminContact":
mocked_result = self.mockAdministrativeContact
case "regContact":
mocked_result = self.mockRegistrantContact
case "defaultSec":
mocked_result = self.mockDefaultSecurityContact
case "defaultTech":
mocked_result = self.mockDefaultTechnicalContact
case _:
# Default contact return
mocked_result = self.mockDataInfoContact
return MagicMock(res_data=[mocked_result])
def mockCreateContactCommands(self, _request, cleaned):
if (
getattr(_request, "id", None) == "fail"
and self.mockedSendFunction.call_count == 3
):
# use this for when a contact is being updated
# sets the second send() to fail
raise RegistryError(code=ErrorCode.OBJECT_EXISTS)
elif getattr(_request, "email", None) == "test@failCreate.gov":
# use this for when a contact is being updated
# mocks a registry error on creation
raise RegistryError(code=None)
elif getattr(_request, "email", None) == "test@contactError.gov":
# use this for when a contact is being updated
# mocks a contact error on creation
raise ContactError(code=ContactErrorCodes.CONTACT_TYPE_NONE)
return MagicMock(res_data=[self.mockDataInfoHosts])
def setUp(self):
"""mock epp send function as this will fail locally"""
self.mockSendPatch = patch("registrar.models.domain.registry.send")
self.mockedSendFunction = self.mockSendPatch.start()
self.mockedSendFunction.side_effect = self.mockSend
def _convertPublicContactToEpp(
self, contact: PublicContact, disclose_email=False, createContact=True
):
DF = common.DiscloseField
fields = {DF.EMAIL}
di = common.Disclose(
flag=disclose_email,
fields=fields,
)
# check docs here looks like we may have more than one address field but
addr = common.ContactAddr(
[
getattr(contact, street)
for street in ["street1", "street2", "street3"]
if hasattr(contact, street)
], # type: ignore
city=contact.city,
pc=contact.pc,
cc=contact.cc,
sp=contact.sp,
) # type: ignore
pi = common.PostalInfo(
name=contact.name,
addr=addr,
org=contact.org,
type="loc",
)
ai = common.ContactAuthInfo(pw="2fooBAR123fooBaz")
if createContact:
return commands.CreateContact(
id=contact.registry_id,
postal_info=pi, # type: ignore
email=contact.email,
voice=contact.voice,
fax=contact.fax,
auth_info=ai,
disclose=di,
vat=None,
ident=None,
notify_email=None,
) # type: ignore
else:
return commands.UpdateContact(
id=contact.registry_id,
postal_info=pi,
email=contact.email,
voice=contact.voice,
fax=contact.fax,
)
def tearDown(self):
self.mockSendPatch.stop()