diff --git a/src/registrar/templates/emails/submission_confirmation.txt b/src/registrar/templates/emails/submission_confirmation.txt index b028e1626..11bc666eb 100644 --- a/src/registrar/templates/emails/submission_confirmation.txt +++ b/src/registrar/templates/emails/submission_confirmation.txt @@ -1,4 +1,5 @@ -Hi {{ application.creator.first_name }}. +{% autoescape off %}{# In a text file, we don't want to have HTML entities escaped #} +Hi {{ application.submitter.first_name }}. We received your .gov domain request. @@ -20,7 +21,7 @@ NEXT STEPS - We’ll review your request. This usually takes 20 business days. - You can check the status of your request at any time. - + - We’ll email you with questions or when we complete our review. @@ -38,55 +39,42 @@ Type of organization: {{ application.get_organization_type_display }} Organization name and mailing address: -{{ application.organization_name }} -{{ application.address_line1 }} -{% if application.address_line2 %}{{ application.address_line2 }}{% endif %} +{% spaceless %}{{ application.organization_name }} +{{ application.address_line1 }}{% if application.address_line2 %} +{{ application.address_line2 }}{% endif %} {{ application.city }}, {{ application.state_territory }} -{{ application.zipcode }} -{% if application.urbanization %}{{ application.urbanization }}{% endif %} - -{% if application.type_of_work %} +{{ application.zipcode }}{% if application.urbanization %} +{{ application.urbanization }}{% endif %}{% endspaceless %} +{% if application.type_of_work %}{# if block makes one newline if it's false #} Type of work: -{{ application.type_of_work }} - +{% spaceless %}{{ application.type_of_work }}{% endspaceless %} {% endif %} Authorizing official: -{% include "emails/includes/contact.txt" with contact=application.authorizing_official %} - -{% if application.current_websites.exists %} -Current website for your organization: -{% for site in application.current_websites.all %} +{% spaceless %}{% include "emails/includes/contact.txt" with contact=application.authorizing_official %}{% endspaceless %} +{% if application.current_websites.exists %}{# if block makes a newline #} +Current website for your organization: {% for site in application.current_websites.all %} {{ site.website }} -{% endfor %} - -{% endif %} +{% endfor %}{% endif %} .gov domain: {{ application.requested_domain.name }} -{% for site in application.alternative_domains.all %} -{{ site.website }} +{% for site in application.alternative_domains.all %}{% spaceless %}{{ site.website }}{% endspaceless %} {% endfor %} - Purpose of your domain: {{ application.purpose }} Your contact information: -{% include "emails/includes/contact.txt" with contact=application.submitter %} - +{% spaceless %}{% include "emails/includes/contact.txt" with contact=application.submitter %}{% endspaceless %} {% if application.other_contacts.all %} Other employees from your organization: {% for other in application.other_contacts.all %} -{% include "emails/includes/contact.txt" with contact=other %} -{% endfor %} - -{% endif %} -{% if application.anything_else %} +{% spaceless %}{% include "emails/includes/contact.txt" with contact=other %}{% endspaceless %} +{% endfor %}{% endif %}{% if application.anything_else %} Anything else we should know? - {{ application.anything_else }} {% endif %} - ---------------------------------------------------------------- The .gov team Contact us: Visit +{% endautoescape %} diff --git a/src/registrar/tests/test_emails.py b/src/registrar/tests/test_emails.py index edbf5cdf8..44cb565e2 100644 --- a/src/registrar/tests/test_emails.py +++ b/src/registrar/tests/test_emails.py @@ -11,7 +11,14 @@ import boto3_mocking # type: ignore class TestEmails(TestCase): - def _completed_application(self): + def _completed_application( + self, + has_other_contacts=True, + has_current_website=True, + has_alternative_gov_domain=True, + has_type_of_work=True, + has_anything_else=True, + ): """A completed domain application.""" user = get_user_model().objects.create(username="username") ao, _ = Contact.objects.get_or_create( @@ -38,14 +45,14 @@ class TestEmails(TestCase): email="testy2@town.com", phone="(555) 555 5557", ) - application, _ = DomainApplication.objects.get_or_create( + domain_application_kwargs = dict( organization_type="federal", federal_type="executive", purpose="Purpose of the site", - anything_else="No", is_policy_acknowledged=True, organization_name="Testorg", address_line1="address 1", + address_line2="address 2", state_territory="NY", zipcode="10002", authorizing_official=ao, @@ -53,27 +60,41 @@ class TestEmails(TestCase): submitter=you, creator=user, ) - application.other_contacts.add(other) - application.current_websites.add(current) - application.alternative_domains.add(alt) + if has_type_of_work: + domain_application_kwargs["type_of_work"] = "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 setUp(self): + self.mock_client_class = MagicMock() + self.mock_client = self.mock_client_class.return_value + @boto3_mocking.patching def test_submission_confirmation(self): """Submission confirmation email works.""" application = self._completed_application() - mock_client_class = MagicMock() - mock_client = mock_client_class.return_value - with boto3_mocking.clients.handler_for("sesv2", mock_client_class): + with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class): application.submit() # check that an email was sent - self.assertTrue(mock_client.send_email.called) + self.assertTrue(self.mock_client.send_email.called) # check the call sequence for the email - args, kwargs = mock_client.send_email.call_args + args, kwargs = self.mock_client.send_email.call_args self.assertIn("Content", kwargs) self.assertIn("Simple", kwargs["Content"]) self.assertIn("Subject", kwargs["Content"]["Simple"]) @@ -81,6 +102,7 @@ class TestEmails(TestCase): # check for things in the email content (not an exhaustive list) body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"] + self.assertIn("Type of organization:", body) self.assertIn("Federal", body) self.assertIn("Authorizing official:", body) @@ -94,4 +116,126 @@ class TestEmails(TestCase): self.assertIn("Testy2 Tester2", body) self.assertIn("Current website for your organization:", body) self.assertIn("city.com", body) + self.assertIn("Type of work:", body) + self.assertIn("Anything else", body) + + @boto3_mocking.patching + def test_submission_confirmation_no_current_website_spacing(self): + """Test line spacing without current_website.""" + application = self._completed_application(has_current_website=False) + with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class): + application.submit() + _, kwargs = self.mock_client.send_email.call_args + body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"] + self.assertNotIn("Current website for your organization:", body) + # spacing should be right between adjacent elements + self.assertRegex(body, r"5555\n\n.gov domain:") + + @boto3_mocking.patching + def test_submission_confirmation_current_website_spacing(self): + """Test line spacing with current_website.""" + application = self._completed_application(has_current_website=True) + with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class): + application.submit() + _, kwargs = self.mock_client.send_email.call_args + body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"] + self.assertIn("Current website for your organization:", body) + # spacing should be right between adjacent elements + self.assertRegex(body, r"5555\n\nCurrent website for") + self.assertRegex(body, r"city.com\n\n.gov domain:") + + @boto3_mocking.patching + def test_submission_confirmation_other_contacts_spacing(self): + """Test line spacing with other contacts.""" + application = self._completed_application(has_other_contacts=True) + with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class): + application.submit() + _, kwargs = self.mock_client.send_email.call_args + body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"] + self.assertIn("Other employees from your organization:", body) + # spacing should be right between adjacent elements + self.assertRegex(body, r"5556\n\nOther employees") + self.assertRegex(body, r"5557\n\nAnything else") + + @boto3_mocking.patching + def test_submission_confirmation_no_other_contacts_spacing(self): + """Test line spacing without other contacts.""" + application = self._completed_application(has_other_contacts=False) + with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class): + application.submit() + _, kwargs = self.mock_client.send_email.call_args + body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"] + self.assertNotIn("Other employees from your organization:", body) + # spacing should be right between adjacent elements + self.assertRegex(body, r"5556\n\nAnything else") + + @boto3_mocking.patching + def test_submission_confirmation_alternative_govdomain_spacing(self): + """Test line spacing with alternative .gov domain.""" + application = self._completed_application(has_alternative_gov_domain=True) + with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class): + application.submit() + _, kwargs = self.mock_client.send_email.call_args + body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"] + self.assertIn("city1.gov", body) + # spacing should be right between adjacent elements + self.assertRegex(body, r"city.gov\ncity1.gov\n\nPurpose of your domain:") + + @boto3_mocking.patching + def test_submission_confirmation_no_alternative_govdomain_spacing(self): + """Test line spacing without alternative .gov domain.""" + application = self._completed_application(has_alternative_gov_domain=False) + with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class): + application.submit() + _, kwargs = self.mock_client.send_email.call_args + body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"] + self.assertNotIn("city1.gov", body) + # spacing should be right between adjacent elements + self.assertRegex(body, r"city.gov\n\nPurpose of your domain:") + + @boto3_mocking.patching + def test_submission_confirmation_type_of_work_spacing(self): + """Test line spacing with type of work.""" + application = self._completed_application(has_type_of_work=True) + with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class): + application.submit() + _, kwargs = self.mock_client.send_email.call_args + body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"] + self.assertIn("Type of work:", body) + # spacing should be right between adjacent elements + self.assertRegex(body, r"10002\n\nType of work:") + + @boto3_mocking.patching + def test_submission_confirmation_no_type_of_work_spacing(self): + """Test line spacing without type of work.""" + application = self._completed_application(has_type_of_work=False) + with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class): + application.submit() + _, kwargs = self.mock_client.send_email.call_args + body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"] self.assertNotIn("Type of work:", body) + # spacing should be right between adjacent elements + self.assertRegex(body, r"10002\n\nAuthorizing official:") + + @boto3_mocking.patching + def test_submission_confirmation_anything_else_spacing(self): + """Test line spacing with anything else.""" + application = self._completed_application(has_anything_else=True) + with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class): + application.submit() + _, kwargs = self.mock_client.send_email.call_args + body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"] + # spacing should be right between adjacent elements + self.assertRegex(body, r"5557\n\nAnything else we should know?") + + @boto3_mocking.patching + def test_submission_confirmation_no_anything_else_spacing(self): + """Test line spacing without anything else.""" + application = self._completed_application(has_anything_else=False) + with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class): + application.submit() + _, kwargs = self.mock_client.send_email.call_args + body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"] + self.assertNotIn("Anything else we should know", body) + # spacing should be right between adjacent elements + self.assertRegex(body, r"5557\n\n----")