added tests

This commit is contained in:
Alysia Broddrick 2023-09-10 10:27:51 -07:00
parent e71b5b0bd4
commit 53e9d090d9
No known key found for this signature in database
GPG key ID: 03917052CD0F06B7
3 changed files with 343 additions and 162 deletions

View file

@ -227,9 +227,16 @@ class Domain(TimeStampedModel, DomainHelper):
Subordinate hosts (something.your-domain.gov) MUST have IP addresses,
while non-subordinate hosts MUST NOT.
"""
# TODO: call EPP to get this info instead of returning fake data.
# MISSING FROM DISPLAY
hosts = self._get_property("hosts")
hostList = []
for host in hosts:
logger.info(host)
# TODO - this should actually have a second tuple value with the ip address
# ignored because uncertain if we will even have a way to display mult.
# and adresses can be a list of mult address
hostList.append((host.name,))
print(hostList)
return [
("ns1.example.com",),
("ns2.example.com",),
@ -420,6 +427,8 @@ class Domain(TimeStampedModel, DomainHelper):
# ticket for error handling in epp
def _update_domain_with_contact(self, contact: PublicContact, rem=False):
# TODO - consider making this use both add and rem at the same time, separating it out may not be needed
logger.info("received type %s " % contact.contact_type)
domainContact = epp.DomainContact(
contact=contact.registry_id, type=contact.contact_type
@ -536,7 +545,7 @@ class Domain(TimeStampedModel, DomainHelper):
)
# make contact in registry, duplicate and errors handled there
errorCode = self._make_contact_in_registry(contact)
print("error code %s" % errorCode)
# if contact.contact_type==contact.ContactTypeChoices.REGISTRANT:
# logger.info("_set_singleton_contact()-> creating the registrant")
@ -552,6 +561,7 @@ class Domain(TimeStampedModel, DomainHelper):
# if domain has registrant and type is registrant this will be true,
# if type is anything else it should be in the contact list
alreadyExistsInRegistry = errorCode == ErrorCode.OBJECT_EXISTS
print("already exists is %s" % alreadyExistsInRegistry)
# if an error occured besides duplication, stop
if (
not alreadyExistsInRegistry
@ -566,6 +576,11 @@ class Domain(TimeStampedModel, DomainHelper):
logger.info(
"_set_singleton_contact()-> updating domain by removing old contact and adding new one"
)
if isEmptySecurity:
existing_contact = PublicContact.objects.filter(
domain=self, contact_type=contact.contact_type
).get()
else:
existing_contact = (
PublicContact.objects.exclude(registry_id=contact.registry_id)
.filter(domain=self, contact_type=contact.contact_type)
@ -579,14 +594,19 @@ class Domain(TimeStampedModel, DomainHelper):
# remove the old contact and add a new one
try:
self._update_domain_with_contact(contact=existing_contact, rem=True)
print("deleting %s "%existing_contact)
existing_contact.delete()
print("after deleting")
if isEmptySecurity:
# add new security
self.get_default_security_contact().save()
except Exception as err:
logger.error(
"Raising error after removing and adding a new contact"
)
raise (err)
# TODO- should this switch to just creating a list of ones to remove and a list of ones to add?
# other option, check if they are really singleton, can remove them?
# if just added to registry and not a registrant add contact to domain
if not isEmptySecurity:
if not alreadyExistsInRegistry and not isRegistrant:
@ -594,8 +614,26 @@ class Domain(TimeStampedModel, DomainHelper):
self._update_domain_with_contact(contact=contact, rem=False)
# if already exists just update
elif alreadyExistsInRegistry:
current_contact = PublicContact.objects.filter(
registry_id=contact.registry_id
).get()
print("updating the contact itself")
if current_contact.email != contact.email:
self._update_epp_contact(contact=contact)
else:
logger.info("removing security contact and setting default again")
# get the current contact registry id for security
current_contact = PublicContact.objects.filter(
registry_id=contact.registry_id
).get()
# don't let user delete the default without adding a new email
if current_contact.email != PublicContact.get_default_security().email:
# remove the contact
self._update_domain_with_contact(contact=current_contact, rem=True)
current_contact.delete()
# add new contact
security_contact = self.get_default_security_contact()
security_contact.save()
@security_contact.setter # type: ignore
def security_contact(self, contact: PublicContact):
@ -770,31 +808,30 @@ class Domain(TimeStampedModel, DomainHelper):
def addAllDefaults(self):
security_contact = self.get_default_security_contact()
security_contact.domain = self
security_contact.save()
technical_contact = PublicContact.get_default_technical()
technical_contact.domain = self
technical_contact.save()
administrative_contact = PublicContact.get_default_administrative()
administrative_contact.domain = self
technical_contact.save()
administrative_contact.save()
security_contact.save()
print("security contact")
print(security_contact)
def testSettingOtherContacts(self):
##delete this funciton
logger.info("testSettingAllContacts")
technical_contact = PublicContact.get_default_technical()
technical_contact.domain = self
administrative_contact = PublicContact.get_default_administrative()
administrative_contact.domain = self
# def testSettingOtherContacts(self):
# ##delete this funciton
# logger.info("testSettingAllContacts")
# technical_contact = PublicContact.get_default_technical()
# technical_contact.domain = self
# administrative_contact = PublicContact.get_default_administrative()
# administrative_contact.domain = self
# security_contact.save()
technical_contact.save()
administrative_contact.save()
# # security_contact.save()
# technical_contact.save()
# administrative_contact.save()
@transition(field="state", source=State.PENDING_CREATE, target=State.CLIENT_HOLD)
def clientHold(self):
@ -827,14 +864,22 @@ class Domain(TimeStampedModel, DomainHelper):
isSecurity = contact.contact_type == contact.ContactTypeChoices.SECURITY
DF = epp.DiscloseField
fields = {DF.FAX, DF.VOICE, DF.ADDR}
print("can you see me ho")
logger.info("isSecurity %s" % isSecurity)
logger.info("contact email %s" % contact.email)
logger.info(
"contact email is default %s" % isSecurity
and contact.email == PublicContact.get_default_security().email
)
if not isSecurity or (
isSecurity and contact.email == PublicContact.get_default_security().email
):
fields.add(DF.EMAIL)
print("added email, fields is %s" % fields)
print("fields is now %s " % fields)
return epp.Disclose(
flag=False,
fields={DF.FAX, DF.VOICE, DF.ADDR},
fields=fields,
types={DF.ADDR: "loc"},
)
@ -871,14 +916,16 @@ class Domain(TimeStampedModel, DomainHelper):
auth_info=epp.ContactAuthInfo(pw="2fooBAR123fooBaz"),
)
# security contacts should only show email addresses, for now
print("calling disclose fields")
create.disclose = self._disclose_fields(contact=contact)
try:
logger.info("sending contact")
registry.send(create, cleaned=True)
print("sendding successfully")
return ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY
except RegistryError as err:
# don't throw an error if it is just saying this is a duplicate contact
print("threw error")
if err.code != ErrorCode.OBJECT_EXISTS:
logger.error(
"Registry threw error for contact id %s contact type is %s, error code is\n %s full error is %s",

View file

@ -36,6 +36,7 @@ class PublicContact(TimeStampedModel):
case PublicContact.ContactTypeChoices.ADMINISTRATIVE:
self.domain.administrative_contact = self
case PublicContact.ContactTypeChoices.TECHNICAL:
print("in technical of the public contact class")
self.domain.technical_contact = self
case PublicContact.ContactTypeChoices.SECURITY:
self.domain.security_contact = self

View file

@ -5,12 +5,12 @@ This file tests the various ways in which the registrar interacts with the regis
"""
from django.test import TestCase
from django.db.utils import IntegrityError
from unittest.mock import patch, MagicMock
from unittest.mock import patch, MagicMock, call
import datetime
from registrar.models import Domain # add in DomainApplication, User,
from unittest import skip
from epplibwrapper import commands, common
from epplibwrapper import commands, common, RegistryError, ErrorCode
from registrar.models.domain_application import DomainApplication
from registrar.models.domain_information import DomainInformation
from registrar.models.draft_domain import DraftDomain
@ -49,13 +49,22 @@ class MockEppLib(TestCase):
def mockSend(self, _request, cleaned):
""""""
print("in mock send patch is ")
print(_request)
if isinstance(_request, commands.InfoDomain):
if getattr(_request, "name", None) == "security.gov":
return MagicMock(res_data=[self.infoDomainNoContact])
return MagicMock(res_data=[self.mockDataInfoDomain])
elif isinstance(_request, commands.InfoContact):
return MagicMock(res_data=[self.mockDataInfoContact])
elif (
isinstance(_request, commands.CreateContact)
and getattr(_request, "id", None) == "fail"
and self.mockedSendFunction.call_count == 3
):
print("raising error")
print()
raise RegistryError(code=ErrorCode.OBJECT_EXISTS)
return MagicMock(res_data=[self.mockDataInfoHosts])
def setUp(self):
@ -64,6 +73,60 @@ class MockEppLib(TestCase):
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.FAX, DF.VOICE, DF.ADDR}
if not disclose_email:
fields.add(DF.EMAIL)
di = common.Disclose(
flag=False,
fields=fields,
types={DF.ADDR: "loc"},
)
# check docs here looks like we may have more than one address field but
addr = common.ContactAddr(
street=[
contact.street1,
contact.street2,
contact.street3,
],
city=contact.city,
pc=contact.pc,
cc=contact.cc,
sp=contact.sp,
)
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,
email=contact.email,
voice=contact.voice,
fax=contact.fax,
auth_info=ai,
disclose=di,
vat=None,
ident=None,
notify_email=None,
)
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()
@ -227,29 +290,8 @@ class TestRegistrantContacts(MockEppLib):
And the registrant is the admin on a domain
"""
super().setUp()
# mock create contact email extension
self.contactMailingAddressPatch = patch(
"registrar.models.domain.commands.command_extensions.CreateContactMailingAddressExtension"
)
self.mockCreateContactExtension = self.contactMailingAddressPatch.start()
# mock create contact
self.createContactPatch = patch(
"registrar.models.domain.commands.CreateContact"
)
self.mockCreateContact = self.createContactPatch.start()
# mock the sending
self.domain, _ = Domain.objects.get_or_create(name="security.gov")
# draft_domain, _ = DraftDomain.objects.get_or_create(name="igorville.gov")
# user, _ = User.objects.get_or_create()
# self.application = DomainApplication.objects.create(
# creator=user, requested_domain=draft_domain
# )
# self.application.status = DomainApplication.SUBMITTED
# transition to approve state
def tearDown(self):
super().tearDown()
# self.contactMailingAddressPatch.stop()
@ -265,50 +307,29 @@ class TestRegistrantContacts(MockEppLib):
"""
# making a domain should make it domain
print(self.domain)
expectedSecContact = PublicContact.get_default_security()
expectedSecContact.domain = self.domain
self.domain.pendingCreate()
DF = common.DiscloseField
di = common.Disclose(
flag=False,
fields={DF.FAX, DF.VOICE, DF.ADDR, DF.EMAIL},
types={DF.ADDR: "loc"},
assert self.mockedSendFunction.call_count == 8
assert PublicContact.objects.filter(domain=self.domain).count() == 4
assert (
PublicContact.objects.get(
domain=self.domain,
contact_type=PublicContact.ContactTypeChoices.SECURITY,
).email
== expectedSecContact.email
)
# check docs here looks like we may have more than one address field but
addr = common.ContactAddr(
street=[
expectedSecContact.street1,
expectedSecContact.street2,
expectedSecContact.street3,
],
city=expectedSecContact.city,
pc=expectedSecContact.pc,
cc=expectedSecContact.cc,
sp=expectedSecContact.sp,
)
pi = common.PostalInfo(
name=expectedSecContact.name,
addr=addr,
org=expectedSecContact.org,
type="loc",
)
ai = common.ContactAuthInfo(pw="feedabee")
expectedCreateCommand = commands.CreateContact(
id=expectedSecContact.registry_id,
postal_info=pi,
email=expectedSecContact.email,
voice=expectedSecContact.voice,
fax=expectedSecContact.fax,
auth_info=ai,
disclose=di,
vat=None,
ident=None,
notify_email=None,
id = PublicContact.objects.get(
domain=self.domain,
contact_type=PublicContact.ContactTypeChoices.SECURITY,
).registry_id
expectedSecContact.registry_id = id
expectedCreateCommand = self._convertPublicContactToEpp(
expectedSecContact, disclose_email=False
)
expectedUpdateDomain = commands.UpdateDomain(
name=self.domain.name,
@ -318,30 +339,10 @@ class TestRegistrantContacts(MockEppLib):
)
],
)
# check that send has triggered the create command
# print(expectedCreateCommand)
print(self.mockedSendFunction.call_count)
print(
PublicContact.objects.filter(
domain=self.domain,
contact_type=PublicContact.ContactTypeChoices.SECURITY,
)
)
# assert( self.mockedSendFunction.call_count
assert PublicContact.objects.filter(domain=self.domain).count() == 4
assert (
PublicContact.objects.get(
domain=self.domain,
contact_type=PublicContact.ContactTypeChoices.SECURITY,
).email
== expectedSecContact.email
)
# assert()
# self.mockedSendFunction.assert_any_call(expectedCreateCommand,True)
# self.mockedSendFunction.assert_any_call(expectedUpdateDomain, True)
# check that the security contact sent is the same as the one recieved
# @skip("not implemented yet")
self.mockedSendFunction.assert_any_call(expectedCreateCommand, cleaned=True)
self.mockedSendFunction.assert_any_call(expectedUpdateDomain, cleaned=True)
def test_user_adds_security_email(self):
"""
Scenario: Registrant adds a security contact email
@ -352,53 +353,59 @@ class TestRegistrantContacts(MockEppLib):
created contact of type 'security'
"""
# make a security contact that is a PublicContact
self.domain.pendingCreate() ##make sure a security email already exists
expectedSecContact = PublicContact.get_default_security()
expectedSecContact.domain = self.domain
expectedSecContact.email = "newEmail@fake.com"
expectedSecContact.registry_id = "456"
expectedSecContact.name = "Fakey McPhakerson"
expectedSecContact.name = "Fakey McFakerson"
# calls the security contact setter as if you did
# self.domain.security_contact=expectedSecContact
expectedSecContact.save()
# check create contact sent with email
DF = common.DiscloseField
di = common.Disclose(
flag=False, fields={DF.FAX, DF.VOICE, DF.ADDR}, types={DF.ADDR: "loc"}
# DF = common.DiscloseField
# di = common.Disclose(
# flag=False, fields={DF.FAX, DF.VOICE, DF.ADDR, DF.EMAIL}, types={DF.ADDR: "loc"}
# )
# addr = common.ContactAddr(
# street=[
# expectedSecContact.street1,
# expectedSecContact.street2,
# expectedSecContact.street3,
# ],
# city=expectedSecContact.city,
# pc=expectedSecContact.pc,
# cc=expectedSecContact.cc,
# sp=expectedSecContact.sp,
# )
# pi = common.PostalInfo(
# name=expectedSecContact.name,
# addr=addr,
# org=expectedSecContact.org,
# type="loc",
# )
# ai = common.ContactAuthInfo(pw="2fooBAR123fooBaz")
# no longer the default email it should be disclosed!!
expectedCreateCommand = self._convertPublicContactToEpp(
expectedSecContact, disclose_email=True
)
addr = common.ContactAddr(
street=[
expectedSecContact.street1,
expectedSecContact.street2,
expectedSecContact.street3,
],
city=expectedSecContact.city,
pc=expectedSecContact.pc,
cc=expectedSecContact.cc,
sp=expectedSecContact.sp,
)
pi = common.PostalInfo(
name=expectedSecContact.name,
addr=addr,
org=expectedSecContact.org,
type="loc",
)
ai = common.ContactAuthInfo(pw="feedabee")
expectedCreateCommand = commands.CreateContact(
id=expectedSecContact.registry_id,
postal_info=pi,
email=expectedSecContact.email,
voice=expectedSecContact.voice,
fax=expectedSecContact.fax,
auth_info=ai,
disclose=di,
vat=None,
ident=None,
notify_email=None,
)
# commands.CreateContact(
# id=expectedSecContact.registry_id,
# postal_info=pi,
# email=expectedSecContact.email,
# voice=expectedSecContact.voice,
# fax=expectedSecContact.fax,
# auth_info=ai,
# disclose=di,
# vat=None,
# ident=None,
# notify_email=None,
# )
expectedUpdateDomain = commands.UpdateDomain(
name=self.domain.name,
add=[
@ -415,11 +422,14 @@ class TestRegistrantContacts(MockEppLib):
receivedSecurityContact = PublicContact.objects.get(
domain=self.domain, contact_type=PublicContact.ContactTypeChoices.SECURITY
)
print(self.mockedSendFunction.call_count)
assert self.mockedSendFunction.call_count == 2
assert receivedSecurityContact == expectedSecContact
@skip("not implemented yet")
print(self.mockedSendFunction.call_count)
print(self.mockedSendFunction.call_args_list)
# assert( self.mockedSendFunction.call_count == 3)
assert receivedSecurityContact == expectedSecContact
self.mockedSendFunction.assert_any_call(expectedCreateCommand, cleaned=True)
self.mockedSendFunction.assert_any_call(expectedUpdateDomain, cleaned=True)
def test_security_email_is_idempotent(self):
"""
Scenario: Registrant adds a security contact email twice, due to a UI glitch
@ -427,16 +437,34 @@ class TestRegistrantContacts(MockEppLib):
to the registry twice with identical data
Then no errors are raised in Domain
"""
# implementation note: this requires seeing what happens when these are actually
# sent like this, and then implementing appropriate mocks for any errors the
# registry normally sends in this case
# will send epplibwrapper.errors.RegistryError with code 2302 for a duplicate contact
# self.domain.pendingCreate() ##make sure a security email already exists
security_contact = self.domain.get_default_security_contact()
security_contact.registry_id = "fail"
security_contact.save()
# set the smae fake contact to the email
# show no errors
raise
self.domain.security_contact = security_contact
print(self.mockedSendFunction.call_args_list)
expectedCreateCommand = self._convertPublicContactToEpp(
security_contact, disclose_email=False
)
print(expectedCreateCommand)
expectedUpdateDomain = commands.UpdateDomain(
name=self.domain.name,
add=[
common.DomainContact(
contact=security_contact.registry_id, type="security"
)
],
)
expected_calls = [
call(expectedCreateCommand, cleaned=True),
call(expectedCreateCommand, cleaned=True),
call(expectedUpdateDomain, cleaned=True),
]
self.mockedSendFunction.assert_has_calls(expected_calls, any_order=True)
assert PublicContact.objects.filter(domain=self.domain).count() == 1
@skip("not implemented yet")
def test_user_deletes_security_email(self):
"""
Scenario: Registrant clears out an existing security contact email
@ -448,9 +476,81 @@ class TestRegistrantContacts(MockEppLib):
And the domain has a valid security contact with CISA defaults
And disclose flags are set to keep the email address hidden
"""
raise
old_contact = self.domain.get_default_security_contact()
old_contact.registry_id = "fail"
old_contact.email = "user.entered@email.com"
old_contact.save()
new_contact = self.domain.get_default_security_contact()
new_contact.registry_id = "fail"
new_contact.email = ""
self.domain.security_contact=new_contact
print("old contact %s email is %s" % (str(old_contact), str(old_contact.email)))
print("new contact %s " % new_contact)
firstCreateContactCall = self._convertPublicContactToEpp(
old_contact, disclose_email=True
)
updateDomainAddCall = commands.UpdateDomain(
name=self.domain.name,
add=[
common.DomainContact(contact=old_contact.registry_id, type="security")
],
)
print( PublicContact.objects.filter(domain=self.domain))
print("just printed the objects for public contact!!")
assert (
PublicContact.objects.filter(domain=self.domain).get().email
== PublicContact.get_default_security().email
)
# this one triggers the fail
secondCreateContact = self._convertPublicContactToEpp(
new_contact, disclose_email=True
)
updateDomainRemCall = commands.UpdateDomain(
name=self.domain.name,
rem=[
common.DomainContact(contact=old_contact.registry_id, type="security")
],
)
args = self.mockedSendFunction.call_args_list
print("actualy args printing ******")
print(args)
print(len(args))
defaultSecID = (
PublicContact.objects.filter(domain=self.domain).get().registry_id
)
default_security = PublicContact.get_default_security()
default_security.registry_id = defaultSecID
createDefaultContact = self._convertPublicContactToEpp(
default_security, disclose_email=False
)
updateDomainWDefault = commands.UpdateDomain(
name=self.domain.name,
add=[common.DomainContact(contact=defaultSecID, type="security")],
)
expected_calls = [
call(firstCreateContactCall, cleaned=True),
call(updateDomainAddCall, cleaned=True),
call(secondCreateContact, cleaned=True),
call(updateDomainRemCall, cleaned=True),
call(createDefaultContact, cleaned=True),
call(updateDomainWDefault, cleaned=True),
]
args = self.mockedSendFunction.call_args_list
print("actualy args printing ******")
print(args)
print(len(args))
print(len(expected_calls))
print("\n\n\n expected calls now printing\n")
print(expected_calls)
self.mockedSendFunction.assert_has_calls(expected_calls, any_order=True)
@skip("not implemented yet")
def test_updates_security_email(self):
"""
Scenario: Registrant replaces one valid security contact email with another
@ -459,7 +559,40 @@ class TestRegistrantContacts(MockEppLib):
security contact email
Then Domain sends `commands.UpdateContact` to the registry
"""
raise
security_contact = self.domain.get_default_security_contact()
security_contact.email="originalUserEmail@gmail.com"
security_contact.registry_id = "fail"
security_contact.save()
expectedCreateCommand = self._convertPublicContactToEpp(
security_contact, disclose_email=True
)
print(expectedCreateCommand)
expectedUpdateDomain = commands.UpdateDomain(
name=self.domain.name,
add=[
common.DomainContact(
contact=security_contact.registry_id, type="security"
)
],
)
security_contact.email="changedEmail@email.com"
expectedSecondCreateCommand = self._convertPublicContactToEpp(
security_contact, disclose_email=True
)
updateContact=self._convertPublicContactToEpp(security_contact,disclose_email=True,createContact=False)
print(expectedSecondCreateCommand)
print(self.mockedSendFunction.call_args_list)
expected_calls = [
call(expectedCreateCommand, cleaned=True),
call(expectedUpdateDomain, cleaned=True),
call(expectedSecondCreateCommand,cleaned=True),
call(updateContact, cleaned=True),
]
self.mockedSendFunction.assert_has_calls(expected_calls, any_order=True)
assert PublicContact.objects.filter(domain=self.domain).count() == 1
@skip("not implemented yet")
def test_update_is_unsuccessful(self):