Merge pull request #514 from cisagov/nmb/request-email

Improve request received email
This commit is contained in:
Neil MartinsenBurrell 2023-04-11 13:50:49 -05:00 committed by GitHub
commit 5efa981cda
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 325 additions and 4 deletions

View file

@ -478,7 +478,7 @@ class DomainApplication(TimeStampedModel):
"emails/submission_confirmation.txt", "emails/submission_confirmation.txt",
"emails/submission_confirmation_subject.txt", "emails/submission_confirmation_subject.txt",
self.submitter.email, self.submitter.email,
context={"id": self.id, "domain_name": self.requested_domain.name}, context={"application": self},
) )
except EmailSendingError: except EmailSendingError:
logger.warning("Failed to send confirmation email", exc_info=True) logger.warning("Failed to send confirmation email", exc_info=True)

View file

@ -0,0 +1,4 @@
{{ contact.get_formatted_name }}
{% if contact.title %}{{ contact.title }}{% endif %}
{% if contact.email %}{{ contact.email }}{% endif %}
{% if contact.phone %}{{ contact.phone.as_national }}{% endif %}

View file

@ -1,4 +1,80 @@
Thank you for submitting an application for the domain name "{{ domain_name }}". {% autoescape off %}{# In a text file, we don't want to have HTML entities escaped #}
Hi {{ application.submitter.first_name }}.
If you need to make changes to your application, visit We received your .gov domain request.
<http://registrar.get.gov/application/{{ id }}/edit>.
DOMAIN REQUESTED: {{ application.requested_domain.name }}
REQUEST RECEIVED ON: {{ application.updated_at|date }}
REQUEST #: {{ application.id }}
STATUS: Received
NEED TO MAKE CHANGES?
If you need to change your request you have to first withdraw it. Once you
withdraw the request you can edit it and submit it again. Changing your request
might add to the wait time. Learn more about withdrawing your request.
NEXT STEPS
- Well review your request. This usually takes 20 business days.
- You can check the status of your request at any time.
<https://registrar.get.gov/application/{{ application.id }}>
- Well email you with questions or when we complete our review.
THANK YOU
.Gov helps the public identify official, trusted information. Thank you for
requesting a .gov domain.
----------------------------------------------------------------
SUMMARY OF YOUR DOMAIN REQUEST
Type of organization:
{{ application.get_organization_type_display }}
Organization name and mailing address:
{% 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 %}{% endspaceless %}
{% if application.type_of_work %}{# if block makes one newline if it's false #}
Type of work:
{% spaceless %}{{ application.type_of_work }}{% endspaceless %}
{% endif %}
Authorizing official:
{% 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 %}
{% spaceless %}{{ site.website }}{% endspaceless %}
{% endfor %}{% endif %}
.gov domain:
{{ application.requested_domain.name }}
{% for site in application.alternative_domains.all %}{% spaceless %}{{ site.website }}{% endspaceless %}
{% endfor %}
Purpose of your domain:
{{ application.purpose }}
Your contact information:
{% 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 %}
{% 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: <https://get.gov/contact/>
Visit <https://get.gov>
{% endautoescape %}

View file

@ -0,0 +1,241 @@
"""Test our email templates and sending."""
from unittest.mock import MagicMock
from django.contrib.auth import get_user_model
from django.test import TestCase
from registrar.models import Contact, Domain, Website, DomainApplication
import boto3_mocking # type: ignore
class TestEmails(TestCase):
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(
first_name="Testy",
last_name="Tester",
title="Chief Tester",
email="testy@town.com",
phone="(555) 555 5555",
)
domain, _ = Domain.objects.get_or_create(name="city.gov")
alt, _ = Website.objects.get_or_create(website="city1.gov")
current, _ = Website.objects.get_or_create(website="city.com")
you, _ = Contact.objects.get_or_create(
first_name="Testy you",
last_name="Tester you",
title="Admin Tester",
email="testy-admin@town.com",
phone="(555) 555 5556",
)
other, _ = Contact.objects.get_or_create(
first_name="Testy2",
last_name="Tester2",
title="Another Tester",
email="testy2@town.com",
phone="(555) 555 5557",
)
domain_application_kwargs = dict(
organization_type="federal",
federal_type="executive",
purpose="Purpose of the site",
is_policy_acknowledged=True,
organization_name="Testorg",
address_line1="address 1",
address_line2="address 2",
state_territory="NY",
zipcode="10002",
authorizing_official=ao,
requested_domain=domain,
submitter=you,
creator=user,
)
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()
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
application.submit()
# check that an email was sent
self.assertTrue(self.mock_client.send_email.called)
# check the call sequence for the email
args, kwargs = self.mock_client.send_email.call_args
self.assertIn("Content", kwargs)
self.assertIn("Simple", kwargs["Content"])
self.assertIn("Subject", kwargs["Content"]["Simple"])
self.assertIn("Body", kwargs["Content"]["Simple"])
# 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)
self.assertIn("Testy Tester", body)
self.assertIn(".gov domain:", body)
self.assertIn("city.gov", body)
self.assertIn("city1.gov", body)
# check for optional things
self.assertIn("Other employees from your organization:", body)
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----")