mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-27 04:58:42 +02:00
Merge branch 'main' into cb/3212-subissues
This commit is contained in:
commit
3c2e6f5c04
7 changed files with 342 additions and 12 deletions
|
@ -1261,6 +1261,13 @@ class HostIpAdmin(AuditedAdmin, ImportExportRegistrarModelAdmin):
|
||||||
resource_classes = [HostIpResource]
|
resource_classes = [HostIpResource]
|
||||||
model = models.HostIP
|
model = models.HostIP
|
||||||
|
|
||||||
|
search_fields = ["host__name", "address"]
|
||||||
|
search_help_text = "Search by host name or address."
|
||||||
|
list_display = (
|
||||||
|
"host",
|
||||||
|
"address",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ContactResource(resources.ModelResource):
|
class ContactResource(resources.ModelResource):
|
||||||
"""defines how each field in the referenced model should be mapped to the corresponding fields in the
|
"""defines how each field in the referenced model should be mapped to the corresponding fields in the
|
||||||
|
@ -4595,6 +4602,10 @@ class PublicContactAdmin(ListHeaderAdmin, ImportExportRegistrarModelAdmin):
|
||||||
|
|
||||||
change_form_template = "django/admin/email_clipboard_change_form.html"
|
change_form_template = "django/admin/email_clipboard_change_form.html"
|
||||||
autocomplete_fields = ["domain"]
|
autocomplete_fields = ["domain"]
|
||||||
|
list_display = ("registry_id", "contact_type", "domain", "name")
|
||||||
|
search_fields = ["registry_id", "domain__name", "name"]
|
||||||
|
search_help_text = "Search by registry id, domain, or name."
|
||||||
|
list_filter = ("contact_type",)
|
||||||
|
|
||||||
def changeform_view(self, request, object_id=None, form_url="", extra_context=None):
|
def changeform_view(self, request, object_id=None, form_url="", extra_context=None):
|
||||||
if extra_context is None:
|
if extra_context is None:
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
import logging
|
||||||
|
import argparse
|
||||||
|
from django.core.management import BaseCommand
|
||||||
|
from registrar.management.commands.utility.terminal_helper import PopulateScriptTemplate, TerminalColors
|
||||||
|
from registrar.models import PublicContact
|
||||||
|
from registrar.models.utility.generic_helper import normalize_string
|
||||||
|
from registrar.utility.enums import DefaultEmail
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand, PopulateScriptTemplate):
|
||||||
|
help = "Loops through each default PublicContact and updates some values on each"
|
||||||
|
|
||||||
|
def add_arguments(self, parser):
|
||||||
|
"""Adds command line arguments"""
|
||||||
|
parser.add_argument(
|
||||||
|
"--overwrite_updated_contacts",
|
||||||
|
action=argparse.BooleanOptionalAction,
|
||||||
|
help=(
|
||||||
|
"Loops over PublicContacts with an email of 'help@get.gov' when enabled."
|
||||||
|
"Use this setting if the record was updated in the DB but not correctly in EPP."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--target_domain",
|
||||||
|
help=(
|
||||||
|
"Updates the public contact on a given domain name (case insensitive). "
|
||||||
|
"Use this option to avoid doing a mass-update of every public contact record."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
def handle(self, **kwargs):
|
||||||
|
"""Loops through each valid User object and updates its verification_type value"""
|
||||||
|
overwrite_updated_contacts = kwargs.get("overwrite_updated_contacts")
|
||||||
|
target_domain = kwargs.get("target_domain")
|
||||||
|
default_emails = {email for email in DefaultEmail}
|
||||||
|
|
||||||
|
# Don't update records we've already updated
|
||||||
|
if not overwrite_updated_contacts:
|
||||||
|
default_emails.remove(DefaultEmail.PUBLIC_CONTACT_DEFAULT)
|
||||||
|
|
||||||
|
# We should only update DEFAULT records. This means that if all values are not default,
|
||||||
|
# we should skip as this could lead to data corruption.
|
||||||
|
# Since we check for all fields, we don't account for casing differences.
|
||||||
|
self.old_and_new_default_contact_values = {
|
||||||
|
"name": {
|
||||||
|
"csd/cb – attn: .gov tld",
|
||||||
|
"csd/cb – attn: cameron dixon",
|
||||||
|
"program manager",
|
||||||
|
"registry customer service",
|
||||||
|
},
|
||||||
|
"street1": {"1110 n. glebe rd", "cisa – ngr stop 0645", "4200 wilson blvd."},
|
||||||
|
"pc": {"22201", "20598-0645"},
|
||||||
|
"email": default_emails,
|
||||||
|
}
|
||||||
|
if not target_domain:
|
||||||
|
filter_condition = {"email__in": default_emails}
|
||||||
|
else:
|
||||||
|
filter_condition = {"email__in": default_emails, "domain__name__iexact": target_domain}
|
||||||
|
# This variable is decorative since we are skipping bulk update
|
||||||
|
fields_to_update = ["name", "street1", "pc", "email"]
|
||||||
|
self.mass_update_records(PublicContact, filter_condition, fields_to_update, show_record_count=True)
|
||||||
|
|
||||||
|
def bulk_update_fields(self, *args, **kwargs):
|
||||||
|
"""Skip bulk update since we need to manually save each field.
|
||||||
|
Our EPP logic is tied to an override of .save(), and this also associates
|
||||||
|
with our caching logic for this area of the code.
|
||||||
|
|
||||||
|
Since bulk update does not trigger .save() for each field, we have to
|
||||||
|
call it manually.
|
||||||
|
"""
|
||||||
|
return None
|
||||||
|
|
||||||
|
def update_record(self, record: PublicContact):
|
||||||
|
"""Defines how we update the verification_type field"""
|
||||||
|
record.name = "CSD/CB – Attn: .gov TLD"
|
||||||
|
record.street1 = "1110 N. Glebe Rd"
|
||||||
|
record.pc = "22201"
|
||||||
|
record.email = DefaultEmail.PUBLIC_CONTACT_DEFAULT
|
||||||
|
record.save()
|
||||||
|
logger.info(f"{TerminalColors.OKCYAN}Updated '{record}' in EPP.{TerminalColors.ENDC}")
|
||||||
|
|
||||||
|
def should_skip_record(self, record) -> bool: # noqa
|
||||||
|
"""Skips updating a public contact if it contains different default info."""
|
||||||
|
if record.registry_id and len(record.registry_id) < 16:
|
||||||
|
message = (
|
||||||
|
f"Skipping legacy verisign contact '{record}'. "
|
||||||
|
f"The registry_id field has a length less than 16 characters."
|
||||||
|
)
|
||||||
|
logger.warning(f"{TerminalColors.YELLOW}{message}{TerminalColors.ENDC}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
for key, expected_values in self.old_and_new_default_contact_values.items():
|
||||||
|
record_field = normalize_string(getattr(record, key))
|
||||||
|
if record_field not in expected_values:
|
||||||
|
message = (
|
||||||
|
f"Skipping '{record}' to avoid potential data corruption. "
|
||||||
|
f"The field '{key}' does not match the default.\n"
|
||||||
|
f"Details: DB value - {record_field}, expected value(s) - {expected_values}"
|
||||||
|
)
|
||||||
|
logger.warning(f"{TerminalColors.YELLOW}{message}{TerminalColors.ENDC}")
|
||||||
|
return True
|
||||||
|
return False
|
|
@ -86,7 +86,9 @@ class PopulateScriptTemplate(ABC):
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def mass_update_records(self, object_class, filter_conditions, fields_to_update, debug=True, verbose=False):
|
def mass_update_records(
|
||||||
|
self, object_class, filter_conditions, fields_to_update, debug=True, verbose=False, show_record_count=False
|
||||||
|
):
|
||||||
"""Loops through each valid "object_class" object - specified by filter_conditions - and
|
"""Loops through each valid "object_class" object - specified by filter_conditions - and
|
||||||
updates fields defined by fields_to_update using update_record.
|
updates fields defined by fields_to_update using update_record.
|
||||||
|
|
||||||
|
@ -106,6 +108,9 @@ class PopulateScriptTemplate(ABC):
|
||||||
verbose: Whether to print a detailed run summary *before* run confirmation.
|
verbose: Whether to print a detailed run summary *before* run confirmation.
|
||||||
Default: False.
|
Default: False.
|
||||||
|
|
||||||
|
show_record_count: Whether to show a 'Record 1/10' dialog when running update.
|
||||||
|
Default: False.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
NotImplementedError: If you do not define update_record before using this function.
|
NotImplementedError: If you do not define update_record before using this function.
|
||||||
TypeError: If custom_filter is not Callable.
|
TypeError: If custom_filter is not Callable.
|
||||||
|
@ -115,14 +120,16 @@ class PopulateScriptTemplate(ABC):
|
||||||
|
|
||||||
# apply custom filter
|
# apply custom filter
|
||||||
records = self.custom_filter(records)
|
records = self.custom_filter(records)
|
||||||
|
records_length = len(records)
|
||||||
|
|
||||||
readable_class_name = self.get_class_name(object_class)
|
readable_class_name = self.get_class_name(object_class)
|
||||||
|
|
||||||
# for use in the execution prompt.
|
# for use in the execution prompt.
|
||||||
proposed_changes = f"""==Proposed Changes==
|
proposed_changes = (
|
||||||
Number of {readable_class_name} objects to change: {len(records)}
|
"==Proposed Changes==\n"
|
||||||
These fields will be updated on each record: {fields_to_update}
|
f"Number of {readable_class_name} objects to change: {records_length}\n"
|
||||||
"""
|
f"These fields will be updated on each record: {fields_to_update}"
|
||||||
|
)
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
proposed_changes = f"""{proposed_changes}
|
proposed_changes = f"""{proposed_changes}
|
||||||
|
@ -140,7 +147,9 @@ class PopulateScriptTemplate(ABC):
|
||||||
to_update: List[object_class] = []
|
to_update: List[object_class] = []
|
||||||
to_skip: List[object_class] = []
|
to_skip: List[object_class] = []
|
||||||
failed_to_update: List[object_class] = []
|
failed_to_update: List[object_class] = []
|
||||||
for record in records:
|
for i, record in enumerate(records, start=1):
|
||||||
|
if show_record_count:
|
||||||
|
logger.info(f"{TerminalColors.BOLD}Record {i}/{records_length}{TerminalColors.ENDC}")
|
||||||
try:
|
try:
|
||||||
if not self.should_skip_record(record):
|
if not self.should_skip_record(record):
|
||||||
self.update_record(record)
|
self.update_record(record)
|
||||||
|
@ -154,7 +163,7 @@ class PopulateScriptTemplate(ABC):
|
||||||
logger.error(fail_message)
|
logger.error(fail_message)
|
||||||
|
|
||||||
# Do a bulk update on the desired field
|
# Do a bulk update on the desired field
|
||||||
ScriptDataHelper.bulk_update_fields(object_class, to_update, fields_to_update)
|
self.bulk_update_fields(object_class, to_update, fields_to_update)
|
||||||
|
|
||||||
# Log what happened
|
# Log what happened
|
||||||
TerminalHelper.log_script_run_summary(
|
TerminalHelper.log_script_run_summary(
|
||||||
|
@ -166,6 +175,10 @@ class PopulateScriptTemplate(ABC):
|
||||||
display_as_str=True,
|
display_as_str=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def bulk_update_fields(self, object_class, to_update, fields_to_update):
|
||||||
|
"""Bulk updates the given fields"""
|
||||||
|
ScriptDataHelper.bulk_update_fields(object_class, to_update, fields_to_update)
|
||||||
|
|
||||||
def get_class_name(self, sender) -> str:
|
def get_class_name(self, sender) -> str:
|
||||||
"""Returns the class name that we want to display for the terminal prompt.
|
"""Returns the class name that we want to display for the terminal prompt.
|
||||||
Example: DomainRequest => "Domain Request"
|
Example: DomainRequest => "Domain Request"
|
||||||
|
@ -463,4 +476,4 @@ class TerminalHelper:
|
||||||
terminal_color = color
|
terminal_color = color
|
||||||
|
|
||||||
colored_message = f"{terminal_color}{message}{TerminalColors.ENDC}"
|
colored_message = f"{terminal_color}{message}{TerminalColors.ENDC}"
|
||||||
log_method(colored_message, exc_info=exc_info)
|
return log_method(colored_message, exc_info=exc_info)
|
||||||
|
|
|
@ -164,4 +164,4 @@ class PublicContact(TimeStampedModel):
|
||||||
return cls._meta.get_field("registry_id").max_length
|
return cls._meta.get_field("registry_id").max_length
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.name} <{self.email}>" f"id: {self.registry_id} " f"type: {self.contact_type}"
|
return self.registry_id
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
|
|
||||||
<h2>Domain renewal</h2>
|
<h2>Domain renewal</h2>
|
||||||
|
|
||||||
<p>.Gov domains are registered for a one-year period. To renew your domain, you'll be asked to verify your organization’s eligibility and your contact information. </p>
|
<p>.Gov domains are registered for a one-year period. To renew the domain, you’ll be asked to verify your contact information and some details about the domain.</p>
|
||||||
|
|
||||||
<p>Though a domain may expire, it will not automatically be put on hold or deleted. We’ll make extensive efforts to contact your organization before holding or deleting a domain.</p>
|
<p>Though a domain may expire, it will not automatically be put on hold or deleted. We’ll make extensive efforts to contact your organization before holding or deleting a domain.</p>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1931,7 +1931,14 @@ class MockEppLib(TestCase):
|
||||||
return MagicMock(res_data=[mocked_result])
|
return MagicMock(res_data=[mocked_result])
|
||||||
|
|
||||||
def mockCreateContactCommands(self, _request, cleaned):
|
def mockCreateContactCommands(self, _request, cleaned):
|
||||||
if getattr(_request, "id", None) == "fail" and self.mockedSendFunction.call_count == 3:
|
ids_to_throw_already_exists = [
|
||||||
|
"failAdmin1234567",
|
||||||
|
"failTech12345678",
|
||||||
|
"failSec123456789",
|
||||||
|
"failReg123456789",
|
||||||
|
"fail",
|
||||||
|
]
|
||||||
|
if getattr(_request, "id", None) in ids_to_throw_already_exists and self.mockedSendFunction.call_count == 3:
|
||||||
# use this for when a contact is being updated
|
# use this for when a contact is being updated
|
||||||
# sets the second send() to fail
|
# sets the second send() to fail
|
||||||
raise RegistryError(code=ErrorCode.OBJECT_EXISTS)
|
raise RegistryError(code=ErrorCode.OBJECT_EXISTS)
|
||||||
|
@ -1946,7 +1953,14 @@ class MockEppLib(TestCase):
|
||||||
return MagicMock(res_data=[self.mockDataInfoHosts])
|
return MagicMock(res_data=[self.mockDataInfoHosts])
|
||||||
|
|
||||||
def mockDeleteContactCommands(self, _request, cleaned):
|
def mockDeleteContactCommands(self, _request, cleaned):
|
||||||
if getattr(_request, "id", None) == "fail":
|
ids_to_throw_already_exists = [
|
||||||
|
"failAdmin1234567",
|
||||||
|
"failTech12345678",
|
||||||
|
"failSec123456789",
|
||||||
|
"failReg123456789",
|
||||||
|
"fail",
|
||||||
|
]
|
||||||
|
if getattr(_request, "id", None) in ids_to_throw_already_exists:
|
||||||
raise RegistryError(code=ErrorCode.OBJECT_EXISTS)
|
raise RegistryError(code=ErrorCode.OBJECT_EXISTS)
|
||||||
else:
|
else:
|
||||||
return MagicMock(
|
return MagicMock(
|
||||||
|
|
|
@ -32,6 +32,7 @@ from registrar.models import (
|
||||||
Portfolio,
|
Portfolio,
|
||||||
Suborganization,
|
Suborganization,
|
||||||
)
|
)
|
||||||
|
from registrar.utility.enums import DefaultEmail
|
||||||
import tablib
|
import tablib
|
||||||
from unittest.mock import patch, call, MagicMock, mock_open
|
from unittest.mock import patch, call, MagicMock, mock_open
|
||||||
from epplibwrapper import commands, common
|
from epplibwrapper import commands, common
|
||||||
|
@ -2506,3 +2507,189 @@ class TestRemovePortfolios(TestCase):
|
||||||
|
|
||||||
# Check that the portfolio was deleted
|
# Check that the portfolio was deleted
|
||||||
self.assertFalse(Portfolio.objects.filter(organization_name="Test with suborg").exists())
|
self.assertFalse(Portfolio.objects.filter(organization_name="Test with suborg").exists())
|
||||||
|
|
||||||
|
|
||||||
|
class TestUpdateDefaultPublicContacts(MockEppLib):
|
||||||
|
"""Tests for the update_default_public_contacts management command."""
|
||||||
|
|
||||||
|
@less_console_noise_decorator
|
||||||
|
def setUp(self):
|
||||||
|
"""Setup test data with PublicContact records."""
|
||||||
|
super().setUp()
|
||||||
|
self.domain_request = completed_domain_request(
|
||||||
|
name="testdomain.gov",
|
||||||
|
status=DomainRequest.DomainRequestStatus.IN_REVIEW,
|
||||||
|
)
|
||||||
|
self.domain_request.approve()
|
||||||
|
self.domain = self.domain_request.approved_domain
|
||||||
|
|
||||||
|
# 1. PublicContact with all old default values
|
||||||
|
self.old_default_contact = self.domain.get_default_administrative_contact()
|
||||||
|
self.old_default_contact.registry_id = "failAdmin1234567"
|
||||||
|
self.old_default_contact.name = "CSD/CB – ATTN: Cameron Dixon"
|
||||||
|
self.old_default_contact.street1 = "CISA – NGR STOP 0645"
|
||||||
|
self.old_default_contact.pc = "20598-0645"
|
||||||
|
self.old_default_contact.email = DefaultEmail.OLD_PUBLIC_CONTACT_DEFAULT
|
||||||
|
self.old_default_contact.save()
|
||||||
|
|
||||||
|
# 2. PublicContact with current default email but old values for other fields
|
||||||
|
self.mixed_default_contact = self.domain.get_default_technical_contact()
|
||||||
|
self.mixed_default_contact.registry_id = "failTech12345678"
|
||||||
|
self.mixed_default_contact.save(skip_epp_save=True)
|
||||||
|
self.mixed_default_contact.name = "registry customer service"
|
||||||
|
self.mixed_default_contact.street1 = "4200 Wilson Blvd."
|
||||||
|
self.mixed_default_contact.pc = "22201"
|
||||||
|
self.mixed_default_contact.email = DefaultEmail.PUBLIC_CONTACT_DEFAULT
|
||||||
|
self.mixed_default_contact.save()
|
||||||
|
|
||||||
|
# 3. PublicContact with non-default values
|
||||||
|
self.non_default_contact = self.domain.get_default_security_contact()
|
||||||
|
self.non_default_contact.registry_id = "failSec123456789"
|
||||||
|
self.non_default_contact.domain = self.domain
|
||||||
|
self.non_default_contact.save(skip_epp_save=True)
|
||||||
|
self.non_default_contact.name = "Hotdogs"
|
||||||
|
self.non_default_contact.street1 = "123 hotdog town"
|
||||||
|
self.non_default_contact.pc = "22111"
|
||||||
|
self.non_default_contact.email = "thehotdogman@igorville.gov"
|
||||||
|
self.non_default_contact.save()
|
||||||
|
|
||||||
|
# 4. Create a default contact but with an old email
|
||||||
|
self.default_registrant_old_email = self.domain.get_default_registrant_contact()
|
||||||
|
self.default_registrant_old_email.registry_id = "failReg123456789"
|
||||||
|
self.default_registrant_old_email.email = DefaultEmail.LEGACY_DEFAULT
|
||||||
|
self.default_registrant_old_email.save()
|
||||||
|
DF = common.DiscloseField
|
||||||
|
excluded_disclose_fields = {DF.NOTIFY_EMAIL, DF.VAT, DF.IDENT}
|
||||||
|
self.all_disclose_fields = {field for field in DF} - excluded_disclose_fields
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
"""Clean up test data."""
|
||||||
|
super().tearDown()
|
||||||
|
PublicContact.objects.all().delete()
|
||||||
|
Domain.objects.all().delete()
|
||||||
|
DomainRequest.objects.all().delete()
|
||||||
|
DomainInformation.objects.all().delete()
|
||||||
|
User.objects.all().delete()
|
||||||
|
|
||||||
|
@patch("registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", return_value=True)
|
||||||
|
@less_console_noise_decorator
|
||||||
|
def run_update_default_public_contacts(self, mock_prompt, **kwargs):
|
||||||
|
"""Execute the update_default_public_contacts command with options."""
|
||||||
|
call_command("update_default_public_contacts", **kwargs)
|
||||||
|
|
||||||
|
# @less_console_noise_decorator
|
||||||
|
def test_updates_old_default_contact(self):
|
||||||
|
"""
|
||||||
|
Test that contacts with old default values are updated to new default values.
|
||||||
|
Also tests for string normalization.
|
||||||
|
"""
|
||||||
|
self.run_update_default_public_contacts()
|
||||||
|
self.old_default_contact.refresh_from_db()
|
||||||
|
|
||||||
|
# Verify updates occurred
|
||||||
|
self.assertEqual(self.old_default_contact.name, "CSD/CB – Attn: .gov TLD")
|
||||||
|
self.assertEqual(self.old_default_contact.street1, "1110 N. Glebe Rd")
|
||||||
|
self.assertEqual(self.old_default_contact.pc, "22201")
|
||||||
|
self.assertEqual(self.old_default_contact.email, DefaultEmail.PUBLIC_CONTACT_DEFAULT)
|
||||||
|
|
||||||
|
# Verify EPP create/update calls were made
|
||||||
|
expected_update = self._convertPublicContactToEpp(
|
||||||
|
self.old_default_contact,
|
||||||
|
disclose=False,
|
||||||
|
disclose_fields=self.all_disclose_fields - {"name", "email", "voice", "addr"},
|
||||||
|
)
|
||||||
|
self.mockedSendFunction.assert_any_call(expected_update, cleaned=True)
|
||||||
|
|
||||||
|
@less_console_noise_decorator
|
||||||
|
def test_updates_with_default_contact_values(self):
|
||||||
|
"""
|
||||||
|
Test that contacts created from the default helper function with old email are updated.
|
||||||
|
"""
|
||||||
|
self.run_update_default_public_contacts()
|
||||||
|
self.default_registrant_old_email.refresh_from_db()
|
||||||
|
|
||||||
|
# Verify updates occurred
|
||||||
|
self.assertEqual(self.default_registrant_old_email.name, "CSD/CB – Attn: .gov TLD")
|
||||||
|
self.assertEqual(self.default_registrant_old_email.street1, "1110 N. Glebe Rd")
|
||||||
|
self.assertEqual(self.default_registrant_old_email.pc, "22201")
|
||||||
|
self.assertEqual(self.default_registrant_old_email.email, DefaultEmail.PUBLIC_CONTACT_DEFAULT)
|
||||||
|
|
||||||
|
# Verify values match the default
|
||||||
|
default_reg = PublicContact.get_default_registrant()
|
||||||
|
self.assertEqual(self.default_registrant_old_email.name, default_reg.name)
|
||||||
|
self.assertEqual(self.default_registrant_old_email.street1, default_reg.street1)
|
||||||
|
self.assertEqual(self.default_registrant_old_email.pc, default_reg.pc)
|
||||||
|
self.assertEqual(self.default_registrant_old_email.email, default_reg.email)
|
||||||
|
|
||||||
|
# Verify EPP create/update calls were made
|
||||||
|
expected_update = self._convertPublicContactToEpp(
|
||||||
|
self.default_registrant_old_email, disclose=False, disclose_fields=self.all_disclose_fields
|
||||||
|
)
|
||||||
|
self.mockedSendFunction.assert_any_call(expected_update, cleaned=True)
|
||||||
|
|
||||||
|
@less_console_noise_decorator
|
||||||
|
def test_skips_non_default_contacts(self):
|
||||||
|
"""
|
||||||
|
Test that contacts with non-default values are skipped.
|
||||||
|
"""
|
||||||
|
original_name = self.non_default_contact.name
|
||||||
|
original_street1 = self.non_default_contact.street1
|
||||||
|
original_pc = self.non_default_contact.pc
|
||||||
|
original_email = self.non_default_contact.email
|
||||||
|
|
||||||
|
self.run_update_default_public_contacts()
|
||||||
|
self.non_default_contact.refresh_from_db()
|
||||||
|
|
||||||
|
# Verify no updates occurred
|
||||||
|
self.assertEqual(self.non_default_contact.name, original_name)
|
||||||
|
self.assertEqual(self.non_default_contact.street1, original_street1)
|
||||||
|
self.assertEqual(self.non_default_contact.pc, original_pc)
|
||||||
|
self.assertEqual(self.non_default_contact.email, original_email)
|
||||||
|
|
||||||
|
# Ensure that the update is still skipped even with the override flag
|
||||||
|
self.run_update_default_public_contacts(overwrite_updated_contacts=True)
|
||||||
|
self.non_default_contact.refresh_from_db()
|
||||||
|
|
||||||
|
# Verify no updates occurred
|
||||||
|
self.assertEqual(self.non_default_contact.name, original_name)
|
||||||
|
self.assertEqual(self.non_default_contact.street1, original_street1)
|
||||||
|
self.assertEqual(self.non_default_contact.pc, original_pc)
|
||||||
|
self.assertEqual(self.non_default_contact.email, original_email)
|
||||||
|
|
||||||
|
@less_console_noise_decorator
|
||||||
|
def test_skips_contacts_with_current_default_email_by_default(self):
|
||||||
|
"""
|
||||||
|
Test that contacts with the current default email are skipped when not using the override flag.
|
||||||
|
"""
|
||||||
|
# Get original values
|
||||||
|
original_name = self.mixed_default_contact.name
|
||||||
|
original_street1 = self.mixed_default_contact.street1
|
||||||
|
|
||||||
|
self.run_update_default_public_contacts()
|
||||||
|
self.mixed_default_contact.refresh_from_db()
|
||||||
|
|
||||||
|
# Verify no updates occurred
|
||||||
|
self.assertEqual(self.mixed_default_contact.name, original_name)
|
||||||
|
self.assertEqual(self.mixed_default_contact.street1, original_street1)
|
||||||
|
self.assertEqual(self.mixed_default_contact.email, DefaultEmail.PUBLIC_CONTACT_DEFAULT)
|
||||||
|
|
||||||
|
@less_console_noise_decorator
|
||||||
|
def test_updates_with_overwrite_flag(self):
|
||||||
|
"""
|
||||||
|
Test that contacts with the current default email are updated when using the override flag.
|
||||||
|
"""
|
||||||
|
# Run the command with the override flag
|
||||||
|
self.run_update_default_public_contacts(overwrite_updated_contacts=True)
|
||||||
|
self.mixed_default_contact.refresh_from_db()
|
||||||
|
|
||||||
|
# Verify updates occurred
|
||||||
|
self.assertEqual(self.mixed_default_contact.name, "CSD/CB – Attn: .gov TLD")
|
||||||
|
self.assertEqual(self.mixed_default_contact.street1, "1110 N. Glebe Rd")
|
||||||
|
self.assertEqual(self.mixed_default_contact.pc, "22201")
|
||||||
|
self.assertEqual(self.mixed_default_contact.email, DefaultEmail.PUBLIC_CONTACT_DEFAULT)
|
||||||
|
|
||||||
|
# Verify EPP create/update calls were made
|
||||||
|
expected_update = self._convertPublicContactToEpp(
|
||||||
|
self.mixed_default_contact, disclose=False, disclose_fields=self.all_disclose_fields
|
||||||
|
)
|
||||||
|
self.mockedSendFunction.assert_any_call(expected_update, cleaned=True)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue