diff --git a/src/registrar/tests/common.py b/src/registrar/tests/common.py index 5efabdb47..caae195ac 100644 --- a/src/registrar/tests/common.py +++ b/src/registrar/tests/common.py @@ -743,6 +743,25 @@ class MockEppLib(TestCase): ], ) + mockVerisignDataInfoContact = mockDataInfoDomain.dummyInfoContactResultData( + "defaultVeri", "registrar@dotgov.gov", datetime.datetime(2023, 5, 25, 19, 45, 35), "lastPw" + ) + InfoDomainWithVerisignSecurityContact = fakedEppObject( + "fakepw", + cr_date=datetime.datetime(2023, 5, 25, 19, 45, 35), + contacts=[ + common.DomainContact( + contact="defaultVeri", + 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), @@ -1058,6 +1077,7 @@ class MockEppLib(TestCase): "freeman.gov": (self.InfoDomainWithContacts, None), "threenameserversDomain.gov": (self.infoDomainThreeHosts, None), "defaultsecurity.gov": (self.InfoDomainWithDefaultSecurityContact, None), + "adomain2.gov": (self.InfoDomainWithVerisignSecurityContact, None), "defaulttechnical.gov": (self.InfoDomainWithDefaultTechnicalContact, None), "justnameserver.com": (self.justNameserver, None), } @@ -1087,6 +1107,8 @@ class MockEppLib(TestCase): mocked_result = self.mockDefaultSecurityContact case "defaultTech": mocked_result = self.mockDefaultTechnicalContact + case "defaultVeri": + mocked_result = self.mockVerisignDataInfoContact case _: # Default contact return mocked_result = self.mockDataInfoContact diff --git a/src/registrar/tests/test_reports.py b/src/registrar/tests/test_reports.py index 4b854a0a0..938f4ed54 100644 --- a/src/registrar/tests/test_reports.py +++ b/src/registrar/tests/test_reports.py @@ -4,8 +4,10 @@ from django.test import Client, RequestFactory, TestCase from io import StringIO from registrar.models.domain_information import DomainInformation from registrar.models.domain import Domain +from registrar.models.public_contact import PublicContact from registrar.models.user import User from django.contrib.auth import get_user_model +from registrar.tests.common import MockEppLib from registrar.utility.csv_export import export_domains_to_writer from django.core.management import call_command from unittest.mock import MagicMock, call, mock_open, patch @@ -215,8 +217,9 @@ class CsvReportsTest(TestCase): self.assertEqual(expected_file_content, response.content) -class ExportDataTest(TestCase): +class ExportDataTest(MockEppLib): def setUp(self): + super().setUp() username = "test_user" first_name = "First" last_name = "Last" @@ -229,7 +232,6 @@ class ExportDataTest(TestCase): self.domain_2, _ = Domain.objects.get_or_create(name="adomain2.gov", state=Domain.State.DNS_NEEDED) self.domain_3, _ = Domain.objects.get_or_create(name="ddomain3.gov", state=Domain.State.ON_HOLD) self.domain_4, _ = Domain.objects.get_or_create(name="bdomain4.gov", state=Domain.State.UNKNOWN) - self.domain_4, _ = Domain.objects.get_or_create(name="bdomain4.gov", state=Domain.State.UNKNOWN) self.domain_information_1, _ = DomainInformation.objects.get_or_create( creator=self.user, @@ -257,6 +259,7 @@ class ExportDataTest(TestCase): ) def tearDown(self): + PublicContact.objects.all().delete() Domain.objects.all().delete() DomainInformation.objects.all().delete() User.objects.all().delete() @@ -323,6 +326,79 @@ class ExportDataTest(TestCase): self.assertEqual(csv_content, expected_content) + def test_export_domains_to_writer_security_emails(self): + """Test that export_domains_to_writer returns the + expected security email""" + # Create a CSV file in memory + csv_file = StringIO() + writer = csv.writer(csv_file) + + # Define columns, sort fields, and filter condition + columns = [ + "Domain name", + "Domain type", + "Agency", + "Organization name", + "City", + "State", + "AO", + "AO email", + "Submitter", + "Submitter title", + "Submitter email", + "Submitter phone", + "Security Contact Email", + "Status", + ] + sort_fields = ["domain__name"] + filter_condition = { + "domain__state__in": [ + Domain.State.READY, + Domain.State.DNS_NEEDED, + Domain.State.ON_HOLD, + ], + } + + # Add security email information + self.domain_1.name = "defaultsecurity.gov" + self.domain_1.save() + # Invoke setter + self.domain_1.security_contact + + # Invoke setter + self.domain_2.security_contact + + # Invoke setter + self.domain_3.security_contact + + # Call the export function + export_domains_to_writer(writer, columns, sort_fields, filter_condition) + + # Reset the CSV file's position to the beginning + csv_file.seek(0) + + # Read the content into a variable + csv_content = csv_file.read() + + # We expect READY domains, + # sorted alphabetially by domain name + expected_content = ( + "Domain name,Domain type,Agency,Organization name,City,State,AO," + "AO email,Submitter,Submitter title,Submitter email,Submitter phone," + "Security Contact Email,Status\n" + "adomain2.gov,Interstate,(blank),dnsneeded\n" + "ddomain3.gov,Federal,Armed Forces Retirement Home,123@mail.gov,onhold\n" + "defaultsecurity.gov,Federal - Executive,World War I Centennial Commission,(blank),ready\n" + ) + print(csv_content) + + # Normalize line endings and remove commas, + # spaces and leading/trailing whitespace + csv_content = csv_content.replace(",,", "").replace(",", "").replace(" ", "").replace("\r\n", "\n").strip() + expected_content = expected_content.replace(",,", "").replace(",", "").replace(" ", "").strip() + + self.assertEqual(csv_content, expected_content) + def test_export_domains_to_writer_additional(self): """An additional test for filters and multi-column sort""" # Create a CSV file in memory diff --git a/src/registrar/utility/csv_export.py b/src/registrar/utility/csv_export.py index 821a7e76b..8e9e40b2a 100644 --- a/src/registrar/utility/csv_export.py +++ b/src/registrar/utility/csv_export.py @@ -24,8 +24,9 @@ def export_domains_to_writer(writer, columns, sort_fields, filter_condition): if security_contacts: security_email = security_contacts[0].email + invalid_emails = {"registrar@dotgov.gov", "dotgov@cisa.dhs.gov"} # These are default emails that should not be displayed in the csv report - if security_email is not None and security_email.lower() == "registrar@dotgov.gov": + if security_email is not None and security_email.lower() in invalid_emails: security_email = "(blank)" # create a dictionary of fields which can be included in output