manage.get.gov/src/registrar/tests/test_management_scripts.py
2024-05-01 09:17:22 -07:00

960 lines
42 KiB
Python

import copy
from datetime import date, datetime, time
from django.utils import timezone
from django.test import TestCase
from registrar.models import (
User,
Domain,
DomainRequest,
Contact,
Website,
DomainInvitation,
TransitionDomain,
DomainInformation,
UserDomainRole,
VerifiedByStaff,
PublicContact,
)
from django.core.management import call_command
from unittest.mock import patch, call
from epplibwrapper import commands, common
from .common import MockEppLib, less_console_noise, completed_domain_request
from api.tests.common import less_console_noise_decorator
class TestPopulateVerificationType(MockEppLib):
"""Tests for the populate_organization_type script"""
def setUp(self):
"""Creates a fake domain object"""
super().setUp()
# Get the domain requests
self.domain_request_1 = completed_domain_request(
name="lasers.gov",
generic_org_type=DomainRequest.OrganizationChoices.FEDERAL,
is_election_board=True,
status=DomainRequest.DomainRequestStatus.IN_REVIEW,
)
# Approve the request
self.domain_request_1.approve()
# Get the domains
self.domain_1 = Domain.objects.get(name="lasers.gov")
# Get users
self.regular_user, _ = User.objects.get_or_create(username="testuser@igormail.gov")
vip, _ = VerifiedByStaff.objects.get_or_create(email="vipuser@igormail.gov")
self.verified_by_staff_user, _ = User.objects.get_or_create(username="vipuser@igormail.gov")
grandfathered, _ = TransitionDomain.objects.get_or_create(
username="grandpa@igormail.gov", domain_name=self.domain_1.name
)
self.grandfathered_user, _ = User.objects.get_or_create(username="grandpa@igormail.gov")
invited, _ = DomainInvitation.objects.get_or_create(
email="invited@igormail.gov", domain=self.domain_1, status=DomainInvitation.DomainInvitationStatus.RETRIEVED
)
self.invited_user, _ = User.objects.get_or_create(username="invited@igormail.gov")
self.untouched_user, _ = User.objects.get_or_create(
username="iaminvincible@igormail.gov", verification_type=User.VerificationTypeChoices.GRANDFATHERED
)
# Fixture users should be untouched by the script. These will auto update once the
# user logs in / creates an account.
self.fixture_user, _ = User.objects.get_or_create(
username="fixture@igormail.gov", verification_type=User.VerificationTypeChoices.FIXTURE_USER
)
def tearDown(self):
"""Deletes all DB objects related to migrations"""
super().tearDown()
# Delete domains and related information
Domain.objects.all().delete()
DomainInformation.objects.all().delete()
DomainRequest.objects.all().delete()
User.objects.all().delete()
Contact.objects.all().delete()
Website.objects.all().delete()
@less_console_noise_decorator
def run_populate_verification_type(self):
"""
This method executes the populate_organization_type command.
The 'call_command' function from Django's management framework is then used to
execute the populate_organization_type command with the specified arguments.
"""
with patch(
"registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa
return_value=True,
):
call_command("populate_verification_type")
@less_console_noise_decorator
def test_verification_type_script_populates_data(self):
"""Ensures that the verification type script actually populates data"""
# Run the script
self.run_populate_verification_type()
# Scripts don't work as we'd expect in our test environment, we need to manually
# trigger the refresh event
self.regular_user.refresh_from_db()
self.grandfathered_user.refresh_from_db()
self.invited_user.refresh_from_db()
self.verified_by_staff_user.refresh_from_db()
self.untouched_user.refresh_from_db()
# Test all users
self.assertEqual(self.regular_user.verification_type, User.VerificationTypeChoices.REGULAR)
self.assertEqual(self.grandfathered_user.verification_type, User.VerificationTypeChoices.GRANDFATHERED)
self.assertEqual(self.invited_user.verification_type, User.VerificationTypeChoices.INVITED)
self.assertEqual(self.verified_by_staff_user.verification_type, User.VerificationTypeChoices.VERIFIED_BY_STAFF)
self.assertEqual(self.untouched_user.verification_type, User.VerificationTypeChoices.GRANDFATHERED)
self.assertEqual(self.fixture_user.verification_type, User.VerificationTypeChoices.FIXTURE_USER)
class TestPopulateOrganizationType(MockEppLib):
"""Tests for the populate_organization_type script"""
def setUp(self):
"""Creates a fake domain object"""
super().setUp()
# Get the domain requests
self.domain_request_1 = completed_domain_request(
name="lasers.gov",
generic_org_type=DomainRequest.OrganizationChoices.FEDERAL,
is_election_board=True,
status=DomainRequest.DomainRequestStatus.IN_REVIEW,
)
self.domain_request_2 = completed_domain_request(
name="readysetgo.gov",
generic_org_type=DomainRequest.OrganizationChoices.CITY,
status=DomainRequest.DomainRequestStatus.IN_REVIEW,
)
self.domain_request_3 = completed_domain_request(
name="manualtransmission.gov",
generic_org_type=DomainRequest.OrganizationChoices.TRIBAL,
status=DomainRequest.DomainRequestStatus.IN_REVIEW,
)
self.domain_request_4 = completed_domain_request(
name="saladandfries.gov",
generic_org_type=DomainRequest.OrganizationChoices.TRIBAL,
is_election_board=True,
status=DomainRequest.DomainRequestStatus.IN_REVIEW,
)
# Approve all three requests
self.domain_request_1.approve()
self.domain_request_2.approve()
self.domain_request_3.approve()
self.domain_request_4.approve()
# Get the domains
self.domain_1 = Domain.objects.get(name="lasers.gov")
self.domain_2 = Domain.objects.get(name="readysetgo.gov")
self.domain_3 = Domain.objects.get(name="manualtransmission.gov")
self.domain_4 = Domain.objects.get(name="saladandfries.gov")
# Get the domain infos
self.domain_info_1 = DomainInformation.objects.get(domain=self.domain_1)
self.domain_info_2 = DomainInformation.objects.get(domain=self.domain_2)
self.domain_info_3 = DomainInformation.objects.get(domain=self.domain_3)
self.domain_info_4 = DomainInformation.objects.get(domain=self.domain_4)
def tearDown(self):
"""Deletes all DB objects related to migrations"""
super().tearDown()
# Delete domains and related information
Domain.objects.all().delete()
DomainInformation.objects.all().delete()
DomainRequest.objects.all().delete()
User.objects.all().delete()
Contact.objects.all().delete()
Website.objects.all().delete()
@less_console_noise_decorator
def run_populate_organization_type(self):
"""
This method executes the populate_organization_type command.
The 'call_command' function from Django's management framework is then used to
execute the populate_organization_type command with the specified arguments.
"""
with patch(
"registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa
return_value=True,
):
call_command("populate_organization_type", "registrar/tests/data/fake_election_domains.csv")
def assert_expected_org_values_on_request_and_info(
self,
domain_request: DomainRequest,
domain_info: DomainInformation,
expected_values: dict,
):
"""
This is a helper function that tests the following conditions:
1. DomainRequest and DomainInformation (on given objects) are equivalent
2. That generic_org_type, is_election_board, and organization_type are equal to passed in values
Args:
domain_request (DomainRequest): The DomainRequest object to test
domain_info (DomainInformation): The DomainInformation object to test
expected_values (dict): Container for what we expect is_electionboard, generic_org_type,
and organization_type to be on DomainRequest and DomainInformation.
Example:
expected_values = {
"is_election_board": False,
"generic_org_type": DomainRequest.OrganizationChoices.CITY,
"organization_type": DomainRequest.OrgChoicesElectionOffice.CITY,
}
"""
# Test domain request
with self.subTest(field="DomainRequest"):
self.assertEqual(domain_request.generic_org_type, expected_values["generic_org_type"])
self.assertEqual(domain_request.is_election_board, expected_values["is_election_board"])
self.assertEqual(domain_request.organization_type, expected_values["organization_type"])
# Test domain info
with self.subTest(field="DomainInformation"):
self.assertEqual(domain_info.generic_org_type, expected_values["generic_org_type"])
self.assertEqual(domain_info.is_election_board, expected_values["is_election_board"])
self.assertEqual(domain_info.organization_type, expected_values["organization_type"])
def do_nothing(self):
"""Does nothing for mocking purposes"""
pass
def test_request_and_info_city_not_in_csv(self):
"""
Tests what happens to a city domain that is not defined in the CSV.
Scenario: A domain request (of type city) is made that is not defined in the CSV file.
When a domain request is made for a city that is not listed in the CSV,
Then the `is_election_board` value should remain False,
and the `generic_org_type` and `organization_type` should both be `city`.
Expected Result: The `is_election_board` and `generic_org_type` attributes should be unchanged.
The `organization_type` field should now be `city`.
"""
city_request = self.domain_request_2
city_info = self.domain_request_2
# Make sure that all data is correct before proceeding.
# Since the presave fixture is in effect, we should expect that
# is_election_board is equal to none, even though we tried to define it as "True"
expected_values = {
"is_election_board": False,
"generic_org_type": DomainRequest.OrganizationChoices.CITY,
"organization_type": DomainRequest.OrgChoicesElectionOffice.CITY,
}
self.assert_expected_org_values_on_request_and_info(city_request, city_info, expected_values)
# Run the populate script
try:
self.run_populate_organization_type()
except Exception as e:
self.fail(f"Could not run populate_organization_type script. Failed with exception: {e}")
# All values should be the same
self.assert_expected_org_values_on_request_and_info(city_request, city_info, expected_values)
def test_request_and_info_federal(self):
"""
Tests what happens to a federal domain after the script is run (should be unchanged).
Scenario: A domain request (of type federal) is processed after running the populate_organization_type script.
When a federal domain request is made,
Then the `is_election_board` value should remain None,
and the `generic_org_type` and `organization_type` fields should both be `federal`.
Expected Result: The `is_election_board` and `generic_org_type` attributes should be unchanged.
The `organization_type` field should now be `federal`.
"""
federal_request = self.domain_request_1
federal_info = self.domain_info_1
# Make sure that all data is correct before proceeding.
# Since the presave fixture is in effect, we should expect that
# is_election_board is equal to none, even though we tried to define it as "True"
expected_values = {
"is_election_board": None,
"generic_org_type": DomainRequest.OrganizationChoices.FEDERAL,
"organization_type": DomainRequest.OrgChoicesElectionOffice.FEDERAL,
}
self.assert_expected_org_values_on_request_and_info(federal_request, federal_info, expected_values)
# Run the populate script
try:
self.run_populate_organization_type()
except Exception as e:
self.fail(f"Could not run populate_organization_type script. Failed with exception: {e}")
# All values should be the same
self.assert_expected_org_values_on_request_and_info(federal_request, federal_info, expected_values)
def test_request_and_info_tribal_add_election_office(self):
"""
Tests if a tribal domain in the election csv changes organization_type to TRIBAL - ELECTION
for the domain request and the domain info
"""
# Set org type fields to none to mimic an environment without this data
tribal_request = self.domain_request_3
tribal_request.organization_type = None
tribal_info = self.domain_info_3
tribal_info.organization_type = None
with patch.object(DomainRequest, "sync_organization_type", self.do_nothing):
with patch.object(DomainInformation, "sync_organization_type", self.do_nothing):
tribal_request.save()
tribal_info.save()
# Make sure that all data is correct before proceeding.
expected_values = {
"is_election_board": False,
"generic_org_type": DomainRequest.OrganizationChoices.TRIBAL,
"organization_type": None,
}
self.assert_expected_org_values_on_request_and_info(tribal_request, tribal_info, expected_values)
# Run the populate script
try:
self.run_populate_organization_type()
except Exception as e:
self.fail(f"Could not run populate_organization_type script. Failed with exception: {e}")
tribal_request.refresh_from_db()
tribal_info.refresh_from_db()
# Because we define this in the "csv", we expect that is election board will switch to True,
# and organization_type will now be tribal_election
expected_values["is_election_board"] = True
expected_values["organization_type"] = DomainRequest.OrgChoicesElectionOffice.TRIBAL_ELECTION
self.assert_expected_org_values_on_request_and_info(tribal_request, tribal_info, expected_values)
def test_request_and_info_tribal_doesnt_remove_election_office(self):
"""
Tests if a tribal domain in the election csv changes organization_type to TRIBAL_ELECTION
when the is_election_board is True, and generic_org_type is Tribal when it is not
present in the CSV.
To avoid overwriting data, the script should not set any domain specified as
an election_office (that doesn't exist in the CSV) to false.
"""
# Set org type fields to none to mimic an environment without this data
tribal_election_request = self.domain_request_4
tribal_election_info = self.domain_info_4
tribal_election_request.organization_type = None
tribal_election_info.organization_type = None
with patch.object(DomainRequest, "sync_organization_type", self.do_nothing):
with patch.object(DomainInformation, "sync_organization_type", self.do_nothing):
tribal_election_request.save()
tribal_election_info.save()
# Make sure that all data is correct before proceeding.
# Because the presave fixture is in place when creating this, we should expect that the
# organization_type variable is already pre-populated. We will test what happens when
# it is not in another test.
expected_values = {
"is_election_board": True,
"generic_org_type": DomainRequest.OrganizationChoices.TRIBAL,
"organization_type": None,
}
self.assert_expected_org_values_on_request_and_info(
tribal_election_request, tribal_election_info, expected_values
)
# Run the populate script
try:
self.run_populate_organization_type()
except Exception as e:
self.fail(f"Could not run populate_organization_type script. Failed with exception: {e}")
# If we don't define this in the "csv", but the value was already true,
# we expect that is election board will stay True, and the org type will be tribal,
# and organization_type will now be tribal_election
expected_values["organization_type"] = DomainRequest.OrgChoicesElectionOffice.TRIBAL_ELECTION
tribal_election_request.refresh_from_db()
tribal_election_info.refresh_from_db()
self.assert_expected_org_values_on_request_and_info(
tribal_election_request, tribal_election_info, expected_values
)
class TestPopulateFirstReady(TestCase):
"""Tests for the populate_first_ready script"""
def setUp(self):
"""Creates a fake domain object"""
super().setUp()
self.ready_domain, _ = Domain.objects.get_or_create(name="fakeready.gov", state=Domain.State.READY)
self.dns_needed_domain, _ = Domain.objects.get_or_create(name="fakedns.gov", state=Domain.State.DNS_NEEDED)
self.deleted_domain, _ = Domain.objects.get_or_create(name="fakedeleted.gov", state=Domain.State.DELETED)
self.hold_domain, _ = Domain.objects.get_or_create(name="fakehold.gov", state=Domain.State.ON_HOLD)
self.unknown_domain, _ = Domain.objects.get_or_create(name="fakeunknown.gov", state=Domain.State.UNKNOWN)
# Set a ready_at date for testing purposes
self.ready_at_date = date(2022, 12, 31)
_ready_at_datetime = datetime.combine(self.ready_at_date, time.min)
self.ready_at_date_tz_aware = timezone.make_aware(_ready_at_datetime, timezone=timezone.utc)
def tearDown(self):
"""Deletes all DB objects related to migrations"""
super().tearDown()
# Delete domains
Domain.objects.all().delete()
def run_populate_first_ready(self):
"""
This method executes the populate_first_ready command.
The 'call_command' function from Django's management framework is then used to
execute the populate_first_ready command with the specified arguments.
"""
with less_console_noise():
with patch(
"registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa
return_value=True,
):
call_command("populate_first_ready")
def test_populate_first_ready_state_ready(self):
"""
Tests that the populate_first_ready works as expected for the state 'ready'
"""
with less_console_noise():
# Set the created at date
self.ready_domain.created_at = self.ready_at_date_tz_aware
self.ready_domain.save()
desired_domain = copy.deepcopy(self.ready_domain)
desired_domain.first_ready = self.ready_at_date
# Run the expiration date script
self.run_populate_first_ready()
self.assertEqual(desired_domain, self.ready_domain)
# Explicitly test the first_ready date
first_ready = Domain.objects.filter(name="fakeready.gov").get().first_ready
self.assertEqual(first_ready, self.ready_at_date)
def test_populate_first_ready_state_deleted(self):
"""
Tests that the populate_first_ready works as expected for the state 'deleted'
"""
with less_console_noise():
# Set the created at date
self.deleted_domain.created_at = self.ready_at_date_tz_aware
self.deleted_domain.save()
desired_domain = copy.deepcopy(self.deleted_domain)
desired_domain.first_ready = self.ready_at_date
# Run the expiration date script
self.run_populate_first_ready()
self.assertEqual(desired_domain, self.deleted_domain)
# Explicitly test the first_ready date
first_ready = Domain.objects.filter(name="fakedeleted.gov").get().first_ready
self.assertEqual(first_ready, self.ready_at_date)
def test_populate_first_ready_state_dns_needed(self):
"""
Tests that the populate_first_ready doesn't make changes when a domain's state is 'dns_needed'
"""
with less_console_noise():
# Set the created at date
self.dns_needed_domain.created_at = self.ready_at_date_tz_aware
self.dns_needed_domain.save()
desired_domain = copy.deepcopy(self.dns_needed_domain)
desired_domain.first_ready = None
# Run the expiration date script
self.run_populate_first_ready()
current_domain = self.dns_needed_domain
# The object should largely be unaltered (does not test first_ready)
self.assertEqual(desired_domain, current_domain)
first_ready = Domain.objects.filter(name="fakedns.gov").get().first_ready
# Explicitly test the first_ready date
self.assertNotEqual(first_ready, self.ready_at_date)
self.assertEqual(first_ready, None)
def test_populate_first_ready_state_on_hold(self):
"""
Tests that the populate_first_ready works as expected for the state 'on_hold'
"""
with less_console_noise():
self.hold_domain.created_at = self.ready_at_date_tz_aware
self.hold_domain.save()
desired_domain = copy.deepcopy(self.hold_domain)
desired_domain.first_ready = self.ready_at_date
# Run the update first ready_at script
self.run_populate_first_ready()
current_domain = self.hold_domain
self.assertEqual(desired_domain, current_domain)
# Explicitly test the first_ready date
first_ready = Domain.objects.filter(name="fakehold.gov").get().first_ready
self.assertEqual(first_ready, self.ready_at_date)
def test_populate_first_ready_state_unknown(self):
"""
Tests that the populate_first_ready works as expected for the state 'unknown'
"""
with less_console_noise():
# Set the created at date
self.unknown_domain.created_at = self.ready_at_date_tz_aware
self.unknown_domain.save()
desired_domain = copy.deepcopy(self.unknown_domain)
desired_domain.first_ready = None
# Run the expiration date script
self.run_populate_first_ready()
current_domain = self.unknown_domain
# The object should largely be unaltered (does not test first_ready)
self.assertEqual(desired_domain, current_domain)
# Explicitly test the first_ready date
first_ready = Domain.objects.filter(name="fakeunknown.gov").get().first_ready
self.assertNotEqual(first_ready, self.ready_at_date)
self.assertEqual(first_ready, None)
class TestPatchAgencyInfo(TestCase):
def setUp(self):
self.user, _ = User.objects.get_or_create(username="testuser")
self.domain, _ = Domain.objects.get_or_create(name="testdomain.gov")
self.domain_info, _ = DomainInformation.objects.get_or_create(domain=self.domain, creator=self.user)
self.transition_domain, _ = TransitionDomain.objects.get_or_create(
domain_name="testdomain.gov", federal_agency="test agency"
)
def tearDown(self):
Domain.objects.all().delete()
DomainInformation.objects.all().delete()
User.objects.all().delete()
TransitionDomain.objects.all().delete()
@patch("registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", return_value=True)
def call_patch_federal_agency_info(self, mock_prompt):
"""Calls the patch_federal_agency_info command and mimics a keypress"""
with less_console_noise():
call_command("patch_federal_agency_info", "registrar/tests/data/fake_current_full.csv", debug=True)
def test_patch_agency_info(self):
"""
Tests that the `patch_federal_agency_info` command successfully
updates the `federal_agency` field
of a `DomainInformation` object when the corresponding
`TransitionDomain` object has a valid `federal_agency`.
"""
with less_console_noise():
# Ensure that the federal_agency is None
self.assertEqual(self.domain_info.federal_agency, None)
self.call_patch_federal_agency_info()
# Reload the domain_info object from the database
self.domain_info.refresh_from_db()
# Check that the federal_agency field was updated
self.assertEqual(self.domain_info.federal_agency, "test agency")
def test_patch_agency_info_skip(self):
"""
Tests that the `patch_federal_agency_info` command logs a warning and
does not update the `federal_agency` field
of a `DomainInformation` object when the corresponding
`TransitionDomain` object does not exist.
"""
with less_console_noise():
# Set federal_agency to None to simulate a skip
self.transition_domain.federal_agency = None
self.transition_domain.save()
with self.assertLogs("registrar.management.commands.patch_federal_agency_info", level="WARNING") as context:
self.call_patch_federal_agency_info()
# Check that the correct log message was output
self.assertIn("SOME AGENCY DATA WAS NONE", context.output[0])
# Reload the domain_info object from the database
self.domain_info.refresh_from_db()
# Check that the federal_agency field was not updated
self.assertIsNone(self.domain_info.federal_agency)
def test_patch_agency_info_skip_updates_data(self):
"""
Tests that the `patch_federal_agency_info` command logs a warning but
updates the DomainInformation object, because a record exists in the
provided current-full.csv file.
"""
with less_console_noise():
# Set federal_agency to None to simulate a skip
self.transition_domain.federal_agency = None
self.transition_domain.save()
# Change the domain name to something parsable in the .csv
self.domain.name = "cdomain1.gov"
self.domain.save()
with self.assertLogs("registrar.management.commands.patch_federal_agency_info", level="WARNING") as context:
self.call_patch_federal_agency_info()
# Check that the correct log message was output
self.assertIn("SOME AGENCY DATA WAS NONE", context.output[0])
# Reload the domain_info object from the database
self.domain_info.refresh_from_db()
# Check that the federal_agency field was not updated
self.assertEqual(self.domain_info.federal_agency, "World War I Centennial Commission")
def test_patch_agency_info_skips_valid_domains(self):
"""
Tests that the `patch_federal_agency_info` command logs INFO and
does not update the `federal_agency` field
of a `DomainInformation` object
"""
with less_console_noise():
self.domain_info.federal_agency = "unchanged"
self.domain_info.save()
with self.assertLogs("registrar.management.commands.patch_federal_agency_info", level="INFO") as context:
self.call_patch_federal_agency_info()
# Check that the correct log message was output
self.assertIn("FINISHED", context.output[1])
# Reload the domain_info object from the database
self.domain_info.refresh_from_db()
# Check that the federal_agency field was not updated
self.assertEqual(self.domain_info.federal_agency, "unchanged")
class TestExtendExpirationDates(MockEppLib):
def setUp(self):
"""Defines the file name of migration_json and the folder its contained in"""
super().setUp()
# Create a valid domain that is updatable
Domain.objects.get_or_create(
name="waterbutpurple.gov", state=Domain.State.READY, expiration_date=date(2023, 11, 15)
)
TransitionDomain.objects.get_or_create(
username="testytester@mail.com",
domain_name="waterbutpurple.gov",
epp_expiration_date=date(2023, 11, 15),
)
# Create a domain with an invalid expiration date
Domain.objects.get_or_create(name="fake.gov", state=Domain.State.READY, expiration_date=date(2022, 5, 25))
TransitionDomain.objects.get_or_create(
username="themoonisactuallycheese@mail.com",
domain_name="fake.gov",
epp_expiration_date=date(2022, 5, 25),
)
# Create a domain with an invalid state
Domain.objects.get_or_create(
name="fakeneeded.gov", state=Domain.State.DNS_NEEDED, expiration_date=date(2023, 11, 15)
)
TransitionDomain.objects.get_or_create(
username="fakeneeded@mail.com",
domain_name="fakeneeded.gov",
epp_expiration_date=date(2023, 11, 15),
)
# Create a domain with a date greater than the maximum
Domain.objects.get_or_create(
name="fakemaximum.gov", state=Domain.State.READY, expiration_date=date(2024, 12, 31)
)
TransitionDomain.objects.get_or_create(
username="fakemaximum@mail.com",
domain_name="fakemaximum.gov",
epp_expiration_date=date(2024, 12, 31),
)
def tearDown(self):
"""Deletes all DB objects related to migrations"""
super().tearDown()
# Delete domain information
Domain.objects.all().delete()
DomainInformation.objects.all().delete()
DomainInvitation.objects.all().delete()
TransitionDomain.objects.all().delete()
# Delete users
User.objects.all().delete()
UserDomainRole.objects.all().delete()
def run_extend_expiration_dates(self):
"""
This method executes the extend_expiration_dates command.
The 'call_command' function from Django's management framework is then used to
execute the extend_expiration_dates command with the specified arguments.
"""
with less_console_noise():
with patch(
"registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa
return_value=True,
):
call_command("extend_expiration_dates")
def test_extends_expiration_date_correctly(self):
"""
Tests that the extend_expiration_dates method extends dates as expected
"""
with less_console_noise():
desired_domain = Domain.objects.filter(name="waterbutpurple.gov").get()
desired_domain.expiration_date = date(2024, 11, 15)
# Run the expiration date script
self.run_extend_expiration_dates()
current_domain = Domain.objects.filter(name="waterbutpurple.gov").get()
self.assertEqual(desired_domain, current_domain)
# Explicitly test the expiration date
self.assertEqual(current_domain.expiration_date, date(2024, 11, 15))
def test_extends_expiration_date_skips_non_current(self):
"""
Tests that the extend_expiration_dates method correctly skips domains
with an expiration date less than a certain threshold.
"""
with less_console_noise():
desired_domain = Domain.objects.filter(name="fake.gov").get()
desired_domain.expiration_date = date(2022, 5, 25)
# Run the expiration date script
self.run_extend_expiration_dates()
current_domain = Domain.objects.filter(name="fake.gov").get()
self.assertEqual(desired_domain, current_domain)
# Explicitly test the expiration date. The extend_expiration_dates script
# will skip all dates less than date(2023, 11, 15), meaning that this domain
# should not be affected by the change.
self.assertEqual(current_domain.expiration_date, date(2022, 5, 25))
def test_extends_expiration_date_skips_maximum_date(self):
"""
Tests that the extend_expiration_dates method correctly skips domains
with an expiration date more than a certain threshold.
"""
with less_console_noise():
desired_domain = Domain.objects.filter(name="fakemaximum.gov").get()
desired_domain.expiration_date = date(2024, 12, 31)
# Run the expiration date script
self.run_extend_expiration_dates()
current_domain = Domain.objects.filter(name="fakemaximum.gov").get()
self.assertEqual(desired_domain, current_domain)
# Explicitly test the expiration date. The extend_expiration_dates script
# will skip all dates less than date(2023, 11, 15), meaning that this domain
# should not be affected by the change.
self.assertEqual(current_domain.expiration_date, date(2024, 12, 31))
def test_extends_expiration_date_skips_non_ready(self):
"""
Tests that the extend_expiration_dates method correctly skips domains not in the state "ready"
"""
with less_console_noise():
desired_domain = Domain.objects.filter(name="fakeneeded.gov").get()
desired_domain.expiration_date = date(2023, 11, 15)
# Run the expiration date script
self.run_extend_expiration_dates()
current_domain = Domain.objects.filter(name="fakeneeded.gov").get()
self.assertEqual(desired_domain, current_domain)
# Explicitly test the expiration date. The extend_expiration_dates script
# will skip all dates less than date(2023, 11, 15), meaning that this domain
# should not be affected by the change.
self.assertEqual(current_domain.expiration_date, date(2023, 11, 15))
def test_extends_expiration_date_idempotent(self):
"""
Tests the idempotency of the extend_expiration_dates command.
Verifies that running the method multiple times does not change the expiration date
of a domain beyond the initial extension.
"""
with less_console_noise():
desired_domain = Domain.objects.filter(name="waterbutpurple.gov").get()
desired_domain.expiration_date = date(2024, 11, 15)
# Run the expiration date script
self.run_extend_expiration_dates()
current_domain = Domain.objects.filter(name="waterbutpurple.gov").get()
self.assertEqual(desired_domain, current_domain)
# Explicitly test the expiration date
self.assertEqual(desired_domain.expiration_date, date(2024, 11, 15))
# Run the expiration date script again
self.run_extend_expiration_dates()
# The old domain shouldn't have changed
self.assertEqual(desired_domain, current_domain)
# Explicitly test the expiration date - should be the same
self.assertEqual(desired_domain.expiration_date, date(2024, 11, 15))
class TestDiscloseEmails(MockEppLib):
def setUp(self):
super().setUp()
def tearDown(self):
super().tearDown()
PublicContact.objects.all().delete()
Domain.objects.all().delete()
def run_disclose_security_emails(self):
"""
This method executes the disclose_security_emails command.
The 'call_command' function from Django's management framework is then used to
execute the disclose_security_emails command.
"""
with less_console_noise():
with patch(
"registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa
return_value=True,
):
call_command("disclose_security_emails")
def test_disclose_security_emails(self):
"""
Tests that command disclose_security_emails runs successfully with
appropriate EPP calll to UpdateContact.
"""
with less_console_noise():
domain, _ = Domain.objects.get_or_create(name="testdisclose.gov", state=Domain.State.READY)
expectedSecContact = PublicContact.get_default_security()
expectedSecContact.domain = domain
expectedSecContact.email = "123@mail.gov"
# set domain security email to 123@mail.gov instead of default email
domain.security_contact = expectedSecContact
self.run_disclose_security_emails()
# running disclose_security_emails sends EPP call UpdateContact with disclose
self.mockedSendFunction.assert_has_calls(
[
call(
commands.UpdateContact(
id=domain.security_contact.registry_id,
postal_info=domain._make_epp_contact_postal_info(contact=domain.security_contact),
email=domain.security_contact.email,
voice=domain.security_contact.voice,
fax=domain.security_contact.fax,
auth_info=common.ContactAuthInfo(pw="2fooBAR123fooBaz"),
disclose=domain._disclose_fields(contact=domain.security_contact),
),
cleaned=True,
)
]
)
# TODO in #1793: Remove this whole test class
class TestPopulateDomainUpdatedFederalAgency(TestCase):
def setUp(self):
super().setUp()
# Get the domain requests
self.domain_request_1 = completed_domain_request(
name="stitches.gov",
generic_org_type=DomainRequest.OrganizationChoices.FEDERAL,
is_election_board=True,
status=DomainRequest.DomainRequestStatus.IN_REVIEW,
federal_agency="U.S. Peace Corps",
)
self.domain_request_2 = completed_domain_request(
name="fadoesntexist.gov",
generic_org_type=DomainRequest.OrganizationChoices.FEDERAL,
is_election_board=True,
status=DomainRequest.DomainRequestStatus.IN_REVIEW,
federal_agency="MEOWARDRULES",
)
self.domain_request_3 = completed_domain_request(
name="nullfederalagency.gov",
generic_org_type=DomainRequest.OrganizationChoices.FEDERAL,
is_election_board=True,
status=DomainRequest.DomainRequestStatus.IN_REVIEW,
federal_agency=None,
)
# Approve all three requests
self.domain_request_1.approve()
self.domain_request_2.approve()
self.domain_request_3.approve()
# Get the domains
self.domain_1 = Domain.objects.get(name="stitches.gov")
self.domain_2 = Domain.objects.get(name="fadoesntexist.gov")
self.domain_3 = Domain.objects.get(name="nullfederalagency.gov")
# Get the domain infos
self.domain_info_1 = DomainInformation.objects.get(domain=self.domain_1)
self.domain_info_2 = DomainInformation.objects.get(domain=self.domain_2)
self.domain_info_3 = DomainInformation.objects.get(domain=self.domain_3)
def tearDown(self):
super().tearDown()
DomainInformation.objects.all().delete()
DomainRequest.objects.all().delete()
Domain.objects.all().delete()
def run_populate_domain_updated_federal_agency(self):
"""
This method executes the populate_domain_updated_federal_agency command.
The 'call_command' function from Django's management framework is then used to
execute the populate_domain_updated_federal_agency command.
"""
with less_console_noise():
call_command("populate_domain_updated_federal_agency")
def test_domain_information_renaming_federal_agency_success(self):
"""
Domain Information updates successfully for an "outdated" Federal Agency
"""
self.run_populate_domain_updated_federal_agency()
self.domain_info_1.refresh_from_db()
previous_federal_agency_name = self.domain_info_1.federal_agency
updated_federal_agency_name = self.domain_info_1.updated_federal_agency.agency
self.assertEqual(previous_federal_agency_name, "U.S. Peace Corps")
self.assertEqual(updated_federal_agency_name, "Peace Corps")
def test_domain_information_does_not_exist(self):
"""
Update a Federal Agency that doesn't exist
(should return None bc the Federal Agency didn't exist before)
"""
self.run_populate_domain_updated_federal_agency()
self.domain_info_2.refresh_from_db()
self.assertEqual(self.domain_info_2.updated_federal_agency, None)
def test_domain_request_is_skipped(self):
"""
Update a Domain Request that doesn't exist
(should return None bc the Federal Agency didn't exist before)
"""
# Test case #2
self.run_populate_domain_updated_federal_agency()
self.domain_request_2.refresh_from_db()
self.assertEqual(self.domain_request_2.updated_federal_agency, None)
def test_domain_information_updating_null_federal_agency_to_non_federal_agency(self):
"""
Updating a Domain Information that was previously None
to Non-Federal Agency
"""
self.run_populate_domain_updated_federal_agency()
self.domain_info_3.refresh_from_db()
previous_federal_agency_name = self.domain_info_3.federal_agency
updated_federal_agency_name = self.domain_info_3.updated_federal_agency.agency
self.assertEqual(previous_federal_agency_name, None)
self.assertEqual(updated_federal_agency_name, "Non-Federal Agency")