diff --git a/src/registrar/templates/emails/domain_invitation.txt b/src/registrar/templates/emails/domain_invitation.txt
index ed9c297f4..f0612a67f 100644
--- a/src/registrar/templates/emails/domain_invitation.txt
+++ b/src/registrar/templates/emails/domain_invitation.txt
@@ -1,7 +1,7 @@
{% autoescape off %}{# In a text file, we don't want to have HTML entities escaped #}
Hi.
-{{ full_name }} has added you as a manager on {{ domain.name }}.
+{{ requester_email }} has added you as a manager on {{ domain.name }}.
YOU NEED A LOGIN.GOV ACCOUNT
You’ll need a Login.gov account to manage your .gov domain. Login.gov provides
diff --git a/src/registrar/tests/test_views.py b/src/registrar/tests/test_views.py
index d34f1e2a5..2e1d29296 100644
--- a/src/registrar/tests/test_views.py
+++ b/src/registrar/tests/test_views.py
@@ -1,5 +1,5 @@
from unittest import skip
-from unittest.mock import MagicMock, patch
+from unittest.mock import MagicMock, ANY, call, patch
from django.conf import settings
from django.test import Client, TestCase
@@ -1416,35 +1416,136 @@ class TestDomainManagers(TestDomainOverview):
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
add_page.form.submit()
- expected_email_content = {
- "Simple": {
- "Subject": {"Data": "You’ve been added to a .gov domain"},
- "Body": {
- "Text": {
- "Data": "\nHi.\n\nFirst Last has added you as a manager on igorville.gov.\n\n"
- "YOU NEED A LOGIN.GOV ACCOUNT\nYou’ll need a Login.gov account to manage your .gov domain. "
- "Login.gov provides\na simple and secure process for signing into many government services with"
- " one\naccount. If you don’t already have one, follow these steps to create your\nLogin.gov "
- "account .\n\nDOMAIN MANAGEMENT\nAs a "
- ".gov domain manager you can add or update information about your domain.\nYou’ll also serve as"
- " a contact for your .gov domain. Please keep your contact\ninformation updated. "
- "Learn more about domain management .\n\nSOMETHING WRONG?\nIf you’re"
- "not affiliated with igorville.gov or think you received this\nmessage in error, contact the "
- ".gov team .\n\n\nTHANK YOU\n\n.Gov helps the public identify"
- " official, trusted information. "
- "Thank you for\nusing a .gov domain.\n\n-------------------------------------------------------"
- "---------\n\nThe .gov team\nContact us: \nVisit \n"
- }
- },
- }
- }
# check the mock instance to see if `send_email` was called right
mock_client_instance.send_email.assert_called_once_with(
FromEmailAddress=settings.DEFAULT_FROM_EMAIL,
Destination={"ToAddresses": [email_address]},
- Content=expected_email_content,
+ Content=ANY,
)
+ @boto3_mocking.patching
+ def test_domain_invitation_email_has_email_as_requester_non_existent(self):
+ """Inviting a non existent user sends them an email, with email as the name."""
+ # make sure there is no user with this email
+ email_address = "mayor@igorville.gov"
+ User.objects.filter(email=email_address).delete()
+
+ self.domain_information, _ = DomainInformation.objects.get_or_create(creator=self.user, domain=self.domain)
+
+ mock_client = MagicMock()
+ mock_client_instance = mock_client.return_value
+
+ with boto3_mocking.clients.handler_for("sesv2", mock_client):
+ add_page = self.app.get(reverse("domain-users-add", kwargs={"pk": self.domain.id}))
+ session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
+ add_page.form["email"] = email_address
+ self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
+ add_page.form.submit()
+
+ # check the mock instance to see if `send_email` was called right
+ mock_client_instance.send_email.assert_called_once_with(
+ FromEmailAddress=settings.DEFAULT_FROM_EMAIL,
+ Destination={"ToAddresses": [email_address]},
+ Content=ANY,
+ )
+
+ # Check the arguments passed to send_email method
+ _, kwargs = mock_client_instance.send_email.call_args
+
+ # Extract the email content, and check that the message is as we expect
+ email_content = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"]
+ self.assertIn("info@example.com", email_content)
+
+ # Check that the requesters first/last name do not exist
+ self.assertNotIn("First", email_content)
+ self.assertNotIn("Last", email_content)
+
+ @boto3_mocking.patching
+ def test_domain_invitation_email_has_email_as_requester(self):
+ """Inviting a user sends them an email, with email as the name."""
+ # Create a fake user object
+ email_address = "mayor@igorville.gov"
+ User.objects.get_or_create(email=email_address, username="fakeuser@fakeymail.com")
+
+ self.domain_information, _ = DomainInformation.objects.get_or_create(creator=self.user, domain=self.domain)
+
+ mock_client = MagicMock()
+ mock_client_instance = mock_client.return_value
+
+ with boto3_mocking.clients.handler_for("sesv2", mock_client):
+ add_page = self.app.get(reverse("domain-users-add", kwargs={"pk": self.domain.id}))
+ session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
+ add_page.form["email"] = email_address
+ self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
+ add_page.form.submit()
+
+ # check the mock instance to see if `send_email` was called right
+ mock_client_instance.send_email.assert_called_once_with(
+ FromEmailAddress=settings.DEFAULT_FROM_EMAIL,
+ Destination={"ToAddresses": [email_address]},
+ Content=ANY,
+ )
+
+ # Check the arguments passed to send_email method
+ _, kwargs = mock_client_instance.send_email.call_args
+
+ # Extract the email content, and check that the message is as we expect
+ email_content = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"]
+ self.assertIn("info@example.com", email_content)
+
+ # Check that the requesters first/last name do not exist
+ self.assertNotIn("First", email_content)
+ self.assertNotIn("Last", email_content)
+
+ @boto3_mocking.patching
+ def test_domain_invitation_email_throws_exception_non_existent(self):
+ """Inviting a non existent user sends them an email, with email as the name."""
+ # make sure there is no user with this email
+ email_address = "mayor@igorville.gov"
+ User.objects.filter(email=email_address).delete()
+
+ # Give the user who is sending the email an invalid email address
+ requester = User.objects.filter(email="info@example.com").get()
+ requester.email = ""
+ requester.save()
+
+ self.domain_information, _ = DomainInformation.objects.get_or_create(creator=self.user, domain=self.domain)
+
+ mock_client = MagicMock()
+
+ with boto3_mocking.clients.handler_for("sesv2", mock_client):
+ with self.assertRaisesMessage(ValueError, "Can't send email. No email exists for the requester"):
+ add_page = self.app.get(reverse("domain-users-add", kwargs={"pk": self.domain.id}))
+ session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
+ add_page.form["email"] = email_address
+ self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
+ add_page.form.submit()
+
+ @boto3_mocking.patching
+ def test_domain_invitation_email_throws_exception(self):
+ """Inviting a user sends them an email, with email as the name."""
+ # make sure there is no user with this email
+ # Create a fake user object
+ email_address = "mayor@igorville.gov"
+ User.objects.get_or_create(email=email_address, username="fakeuser@fakeymail.com")
+
+ # Give the user who is sending the email an invalid email address
+ requester = User.objects.filter(email="info@example.com").get()
+ requester.email = ""
+ requester.save()
+
+ self.domain_information, _ = DomainInformation.objects.get_or_create(creator=self.user, domain=self.domain)
+
+ mock_client = MagicMock()
+
+ with boto3_mocking.clients.handler_for("sesv2", mock_client):
+ with self.assertRaisesMessage(ValueError, "Can't send email. No email exists for the requester"):
+ add_page = self.app.get(reverse("domain-users-add", kwargs={"pk": self.domain.id}))
+ session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
+ add_page.form["email"] = email_address
+ self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
+ add_page.form.submit()
+
def test_domain_invitation_cancel(self):
"""Posting to the delete view deletes an invitation."""
email_address = "mayor@igorville.gov"
diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py
index 632530e71..7c3f175d3 100644
--- a/src/registrar/views/domain.py
+++ b/src/registrar/views/domain.py
@@ -651,32 +651,17 @@ class DomainAddUserView(DomainFormBaseView):
add_success: bool- default True indicates:
adding a success message to the view if the email sending succeeds"""
# created a new invitation in the database, so send an email
- domainInfoResults = DomainInformation.objects.filter(domain=self.object)
- domainInfo = domainInfoResults.first()
- first: str = ""
- last: str = ""
- if requester is not None:
- first = requester.first_name
- last = requester.last_name
- elif domainInfo is not None:
- first = domainInfo.creator.first_name
- last = domainInfo.creator.last_name
- else:
+ if requester is None:
# This edgecase would be unusual if encountered. We don't want to handle this here. Rather, we would
# want to fix this upstream where it is happening.
raise ValueError("Can't send email. The given DomainInformation object has no requestor or creator.")
- # Attempt to grab the first and last names. As a last resort, just use the email.
- if first and last:
- full_name = f"{first} {last}"
- elif requester.email is not None and requester.email.strip() != "":
- full_name = requester.email
- elif domainInfo.creator.email is not None and domainInfo.creator.email.strip() != "":
- full_name = domainInfo.creator.email
+ if requester.email is not None and requester.email.strip() != "":
+ requester_email = requester.email
else:
# This edgecase would be unusual if encountered. We don't want to handle this here. Rather, we would
# want to fix this upstream where it is happening.
- raise ValueError("Can't send email. First and last names, as well as the email, are none.")
+ raise ValueError("Can't send email. No email exists for the requester.")
try:
send_templated_email(
@@ -686,7 +671,7 @@ class DomainAddUserView(DomainFormBaseView):
context={
"domain_url": self._domain_abs_url(),
"domain": self.object,
- "full_name": full_name,
+ "requester_email": requester_email,
},
)
except EmailSendingError: