mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-06-02 02:28:32 +02:00
Reduce email sends to first-time transition for the applicable transitions
This commit is contained in:
parent
9b691affdc
commit
e2c965a915
3 changed files with 382 additions and 135 deletions
|
@ -1,4 +1,6 @@
|
|||
from __future__ import annotations
|
||||
from json import JSONDecodeError
|
||||
import json
|
||||
from typing import Union
|
||||
|
||||
import logging
|
||||
|
@ -12,6 +14,7 @@ from registrar.models.domain import Domain
|
|||
from .utility.time_stamped_model import TimeStampedModel
|
||||
from ..utility.email import send_templated_email, EmailSendingError
|
||||
from itertools import chain
|
||||
from auditlog.models import LogEntry # type: ignore
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -565,6 +568,25 @@ class DomainApplication(TimeStampedModel):
|
|||
except Exception:
|
||||
return ""
|
||||
|
||||
def has_previously_had_a_status_of(self, status):
|
||||
"""Return True if this request has previously had the status of {passed param}."""
|
||||
|
||||
log_entries = LogEntry.objects.get_for_object(self)
|
||||
|
||||
for entry in log_entries:
|
||||
try:
|
||||
changes_dict = json.loads(entry.changes)
|
||||
logger.info(changes_dict)
|
||||
# changes_dict will look like {'status': ['withdrawn', 'submitted']},
|
||||
# henceforth the len(changes_dict.get('status', [])) == 2
|
||||
if len(changes_dict.get("status", [])) == 2 and changes_dict.get("status", [])[1] == status:
|
||||
logger.info(f"found one instance where it had a status of {status}")
|
||||
return True
|
||||
except JSONDecodeError:
|
||||
pass
|
||||
|
||||
return False
|
||||
|
||||
def domain_is_not_active(self):
|
||||
if self.approved_domain:
|
||||
return not self.approved_domain.is_active()
|
||||
|
@ -633,11 +655,13 @@ class DomainApplication(TimeStampedModel):
|
|||
self.submission_date = timezone.now().date()
|
||||
self.save()
|
||||
|
||||
self._send_status_update_email(
|
||||
"submission confirmation",
|
||||
"emails/submission_confirmation.txt",
|
||||
"emails/submission_confirmation_subject.txt",
|
||||
)
|
||||
# Limit email notifications for this transition to the first time the request transitions to this status
|
||||
if not self.has_previously_had_a_status_of("submitted"):
|
||||
self._send_status_update_email(
|
||||
"submission confirmation",
|
||||
"emails/submission_confirmation.txt",
|
||||
"emails/submission_confirmation_subject.txt",
|
||||
)
|
||||
|
||||
@transition(
|
||||
field="status",
|
||||
|
@ -713,12 +737,14 @@ class DomainApplication(TimeStampedModel):
|
|||
user=self.creator, domain=created_domain, role=UserDomainRole.Roles.MANAGER
|
||||
)
|
||||
|
||||
self._send_status_update_email(
|
||||
"application approved",
|
||||
"emails/status_change_approved.txt",
|
||||
"emails/status_change_approved_subject.txt",
|
||||
send_email,
|
||||
)
|
||||
# Limit email notifications for this transition to the first time the request transitions to this status
|
||||
if not self.has_previously_had_a_status_of("approved"):
|
||||
self._send_status_update_email(
|
||||
"application approved",
|
||||
"emails/status_change_approved.txt",
|
||||
"emails/status_change_approved_subject.txt",
|
||||
send_email,
|
||||
)
|
||||
|
||||
@transition(
|
||||
field="status",
|
||||
|
@ -727,11 +753,14 @@ class DomainApplication(TimeStampedModel):
|
|||
)
|
||||
def withdraw(self):
|
||||
"""Withdraw an application that has been submitted."""
|
||||
self._send_status_update_email(
|
||||
"withdraw",
|
||||
"emails/domain_request_withdrawn.txt",
|
||||
"emails/domain_request_withdrawn_subject.txt",
|
||||
)
|
||||
|
||||
# Limit email notifications for this transition to the first time the request transitions to this status
|
||||
if not self.has_previously_had_a_status_of("withdrawn"):
|
||||
self._send_status_update_email(
|
||||
"withdraw",
|
||||
"emails/domain_request_withdrawn.txt",
|
||||
"emails/domain_request_withdrawn_subject.txt",
|
||||
)
|
||||
|
||||
@transition(
|
||||
field="status",
|
||||
|
@ -757,11 +786,13 @@ class DomainApplication(TimeStampedModel):
|
|||
logger.error(err)
|
||||
logger.error("Can't query an approved domain while attempting a DA reject()")
|
||||
|
||||
self._send_status_update_email(
|
||||
"action needed",
|
||||
"emails/status_change_rejected.txt",
|
||||
"emails/status_change_rejected_subject.txt",
|
||||
)
|
||||
# Limit email notifications for this transition to the first time the request transitions to this status
|
||||
if not self.has_previously_had_a_status_of("rejected"):
|
||||
self._send_status_update_email(
|
||||
"action needed",
|
||||
"emails/status_change_rejected.txt",
|
||||
"emails/status_change_rejected_subject.txt",
|
||||
)
|
||||
|
||||
@transition(
|
||||
field="status",
|
||||
|
|
|
@ -316,6 +316,7 @@ class TestDomainApplicationAdminForm(TestCase):
|
|||
)
|
||||
|
||||
|
||||
@boto3_mocking.patching
|
||||
class TestDomainApplicationAdmin(MockEppLib):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
@ -421,83 +422,143 @@ class TestDomainApplicationAdmin(MockEppLib):
|
|||
# Now let's make sure the long description does not exist
|
||||
self.assertNotContains(response, "Federal: an agency of the U.S. government")
|
||||
|
||||
@boto3_mocking.patching
|
||||
def transition_state_and_send_email(self, application, status):
|
||||
"""Helper method for the email test cases."""
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
with less_console_noise():
|
||||
# Create a mock request
|
||||
request = self.factory.post("/admin/registrar/domainapplication/{}/change/".format(application.pk))
|
||||
|
||||
# Modify the application's property
|
||||
application.status = status
|
||||
|
||||
# Use the model admin's save_model method
|
||||
self.admin.save_model(request, application, form=None, change=True)
|
||||
|
||||
def assert_email_is_accurate(self, expected_string, email_index, email_address):
|
||||
"""Helper method for the email test cases.
|
||||
email_index is the index of the email in mock_client."""
|
||||
|
||||
# Access the arguments passed to send_email
|
||||
call_args = self.mock_client.EMAILS_SENT
|
||||
kwargs = call_args[email_index]["kwargs"]
|
||||
|
||||
# Retrieve the email details from the arguments
|
||||
from_email = kwargs.get("FromEmailAddress")
|
||||
to_email = kwargs["Destination"]["ToAddresses"][0]
|
||||
email_content = kwargs["Content"]
|
||||
email_body = email_content["Simple"]["Body"]["Text"]["Data"]
|
||||
|
||||
# Assert or perform other checks on the email details
|
||||
self.assertEqual(from_email, settings.DEFAULT_FROM_EMAIL)
|
||||
self.assertEqual(to_email, email_address)
|
||||
self.assertIn(expected_string, email_body)
|
||||
|
||||
def test_save_model_sends_submitted_email(self):
|
||||
# make sure there is no user with this email
|
||||
"""When transitioning to submitted the first time (and the first time only) on a domain request,
|
||||
an email is sent out."""
|
||||
|
||||
# Ensure there is no user with this email
|
||||
EMAIL = "mayor@igorville.gov"
|
||||
User.objects.filter(email=EMAIL).delete()
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
with less_console_noise():
|
||||
# Create a sample application
|
||||
application = completed_application()
|
||||
|
||||
# Create a mock request
|
||||
request = self.factory.post("/admin/registrar/domainapplication/{}/change/".format(application.pk))
|
||||
|
||||
# Modify the application's property
|
||||
application.status = DomainApplication.ApplicationStatus.SUBMITTED
|
||||
|
||||
# Use the model admin's save_model method
|
||||
self.admin.save_model(request, application, form=None, change=True)
|
||||
|
||||
# Access the arguments passed to send_email
|
||||
call_args = self.mock_client.EMAILS_SENT
|
||||
kwargs = call_args[0]["kwargs"]
|
||||
|
||||
# Retrieve the email details from the arguments
|
||||
from_email = kwargs.get("FromEmailAddress")
|
||||
to_email = kwargs["Destination"]["ToAddresses"][0]
|
||||
email_content = kwargs["Content"]
|
||||
email_body = email_content["Simple"]["Body"]["Text"]["Data"]
|
||||
|
||||
# Assert or perform other checks on the email details
|
||||
expected_string = "We received your .gov domain request."
|
||||
self.assertEqual(from_email, settings.DEFAULT_FROM_EMAIL)
|
||||
self.assertEqual(to_email, EMAIL)
|
||||
self.assertIn(expected_string, email_body)
|
||||
# Create a sample application
|
||||
application = completed_application()
|
||||
|
||||
# Test Submitted Status
|
||||
self.transition_state_and_send_email(application, DomainApplication.ApplicationStatus.SUBMITTED)
|
||||
self.assert_email_is_accurate("We received your .gov domain request.", 0, EMAIL)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
|
||||
|
||||
@boto3_mocking.patching
|
||||
# Test Withdrawn Status
|
||||
self.transition_state_and_send_email(application, DomainApplication.ApplicationStatus.WITHDRAWN)
|
||||
self.assert_email_is_accurate(
|
||||
"Your .gov domain request has been withdrawn and will not be reviewed by our team.", 1, EMAIL
|
||||
)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
|
||||
|
||||
# Test Submitted Status Again (No new email should be sent)
|
||||
self.transition_state_and_send_email(application, DomainApplication.ApplicationStatus.SUBMITTED)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
|
||||
|
||||
def test_save_model_sends_approved_email(self):
|
||||
# make sure there is no user with this email
|
||||
"""When transitioning to approved the first time (and the first time only) on a domain request,
|
||||
an email is sent out."""
|
||||
|
||||
# Ensure there is no user with this email
|
||||
EMAIL = "mayor@igorville.gov"
|
||||
User.objects.filter(email=EMAIL).delete()
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
with less_console_noise():
|
||||
# Create a sample application
|
||||
application = completed_application(status=DomainApplication.ApplicationStatus.IN_REVIEW)
|
||||
|
||||
# Create a mock request
|
||||
request = self.factory.post("/admin/registrar/domainapplication/{}/change/".format(application.pk))
|
||||
|
||||
# Modify the application's property
|
||||
application.status = DomainApplication.ApplicationStatus.APPROVED
|
||||
|
||||
# Use the model admin's save_model method
|
||||
self.admin.save_model(request, application, form=None, change=True)
|
||||
|
||||
# Access the arguments passed to send_email
|
||||
call_args = self.mock_client.EMAILS_SENT
|
||||
kwargs = call_args[0]["kwargs"]
|
||||
|
||||
# Retrieve the email details from the arguments
|
||||
from_email = kwargs.get("FromEmailAddress")
|
||||
to_email = kwargs["Destination"]["ToAddresses"][0]
|
||||
email_content = kwargs["Content"]
|
||||
email_body = email_content["Simple"]["Body"]["Text"]["Data"]
|
||||
|
||||
# Assert or perform other checks on the email details
|
||||
expected_string = "Congratulations! Your .gov domain request has been approved."
|
||||
self.assertEqual(from_email, settings.DEFAULT_FROM_EMAIL)
|
||||
self.assertEqual(to_email, EMAIL)
|
||||
self.assertIn(expected_string, email_body)
|
||||
# Create a sample application
|
||||
application = completed_application(status=DomainApplication.ApplicationStatus.IN_REVIEW)
|
||||
|
||||
# Test Submitted Status
|
||||
self.transition_state_and_send_email(application, DomainApplication.ApplicationStatus.APPROVED)
|
||||
self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 0, EMAIL)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
|
||||
|
||||
@boto3_mocking.patching
|
||||
# Test Withdrawn Status
|
||||
self.transition_state_and_send_email(application, DomainApplication.ApplicationStatus.REJECTED)
|
||||
self.assert_email_is_accurate("Your .gov domain request has been rejected.", 1, EMAIL)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
|
||||
|
||||
# Test Submitted Status Again (No new email should be sent)
|
||||
self.transition_state_and_send_email(application, DomainApplication.ApplicationStatus.APPROVED)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
|
||||
|
||||
def test_save_model_sends_rejected_email(self):
|
||||
"""When transitioning to rejected the first time (and the first time only) on a domain request,
|
||||
an email is sent out."""
|
||||
|
||||
# Ensure there is no user with this email
|
||||
EMAIL = "mayor@igorville.gov"
|
||||
User.objects.filter(email=EMAIL).delete()
|
||||
|
||||
# Create a sample application
|
||||
application = completed_application(status=DomainApplication.ApplicationStatus.IN_REVIEW)
|
||||
|
||||
# Test Submitted Status
|
||||
self.transition_state_and_send_email(application, DomainApplication.ApplicationStatus.REJECTED)
|
||||
self.assert_email_is_accurate("Your .gov domain request has been rejected.", 0, EMAIL)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
|
||||
|
||||
# Test Withdrawn Status
|
||||
self.transition_state_and_send_email(application, DomainApplication.ApplicationStatus.APPROVED)
|
||||
self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, EMAIL)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
|
||||
|
||||
# Test Submitted Status Again (No new email should be sent)
|
||||
self.transition_state_and_send_email(application, DomainApplication.ApplicationStatus.REJECTED)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
|
||||
|
||||
def test_save_model_sends_withdrawn_email(self):
|
||||
"""When transitioning to withdrawn the first time (and the first time only) on a domain request,
|
||||
an email is sent out."""
|
||||
|
||||
# Ensure there is no user with this email
|
||||
EMAIL = "mayor@igorville.gov"
|
||||
User.objects.filter(email=EMAIL).delete()
|
||||
|
||||
# Create a sample application
|
||||
application = completed_application(status=DomainApplication.ApplicationStatus.IN_REVIEW)
|
||||
|
||||
# Test Submitted Status
|
||||
self.transition_state_and_send_email(application, DomainApplication.ApplicationStatus.WITHDRAWN)
|
||||
self.assert_email_is_accurate(
|
||||
"Your .gov domain request has been withdrawn and will not be reviewed by our team.", 0, EMAIL
|
||||
)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
|
||||
|
||||
# Test Withdrawn Status
|
||||
self.transition_state_and_send_email(application, DomainApplication.ApplicationStatus.SUBMITTED)
|
||||
self.assert_email_is_accurate("We received your .gov domain request.", 1, EMAIL)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
|
||||
|
||||
# Test Submitted Status Again (No new email should be sent)
|
||||
self.transition_state_and_send_email(application, DomainApplication.ApplicationStatus.WITHDRAWN)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
|
||||
|
||||
def test_save_model_sets_approved_domain(self):
|
||||
# make sure there is no user with this email
|
||||
EMAIL = "mayor@igorville.gov"
|
||||
|
@ -520,45 +581,6 @@ class TestDomainApplicationAdmin(MockEppLib):
|
|||
# Test that approved domain exists and equals requested domain
|
||||
self.assertEqual(application.requested_domain.name, application.approved_domain.name)
|
||||
|
||||
@boto3_mocking.patching
|
||||
def test_save_model_sends_rejected_email(self):
|
||||
# make sure there is no user with this email
|
||||
EMAIL = "mayor@igorville.gov"
|
||||
User.objects.filter(email=EMAIL).delete()
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
with less_console_noise():
|
||||
# Create a sample application
|
||||
application = completed_application(status=DomainApplication.ApplicationStatus.IN_REVIEW)
|
||||
|
||||
# Create a mock request
|
||||
request = self.factory.post("/admin/registrar/domainapplication/{}/change/".format(application.pk))
|
||||
|
||||
# Modify the application's property
|
||||
application.status = DomainApplication.ApplicationStatus.REJECTED
|
||||
|
||||
# Use the model admin's save_model method
|
||||
self.admin.save_model(request, application, form=None, change=True)
|
||||
|
||||
# Access the arguments passed to send_email
|
||||
call_args = self.mock_client.EMAILS_SENT
|
||||
kwargs = call_args[0]["kwargs"]
|
||||
|
||||
# Retrieve the email details from the arguments
|
||||
from_email = kwargs.get("FromEmailAddress")
|
||||
to_email = kwargs["Destination"]["ToAddresses"][0]
|
||||
email_content = kwargs["Content"]
|
||||
email_body = email_content["Simple"]["Body"]["Text"]["Data"]
|
||||
|
||||
# Assert or perform other checks on the email details
|
||||
expected_string = "Your .gov domain request has been rejected."
|
||||
self.assertEqual(from_email, settings.DEFAULT_FROM_EMAIL)
|
||||
self.assertEqual(to_email, EMAIL)
|
||||
self.assertIn(expected_string, email_body)
|
||||
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
|
||||
|
||||
@boto3_mocking.patching
|
||||
def test_save_model_sets_restricted_status_on_user(self):
|
||||
# make sure there is no user with this email
|
||||
EMAIL = "mayor@igorville.gov"
|
||||
|
@ -707,7 +729,6 @@ class TestDomainApplicationAdmin(MockEppLib):
|
|||
"Cannot edit an application with a restricted creator.",
|
||||
)
|
||||
|
||||
@boto3_mocking.patching
|
||||
def test_error_when_saving_approved_to_rejected_and_domain_is_active(self):
|
||||
# Create an instance of the model
|
||||
application = completed_application(status=DomainApplication.ApplicationStatus.APPROVED)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from django.test import TestCase
|
||||
from django.db.utils import IntegrityError
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from registrar.models import (
|
||||
Contact,
|
||||
|
@ -154,17 +154,34 @@ class TestDomainApplication(TestCase):
|
|||
application.submit()
|
||||
self.assertEqual(application.status, application.ApplicationStatus.SUBMITTED)
|
||||
|
||||
@patch("auditlog.models.LogEntry.objects.get_for_object")
|
||||
def test_has_previously_had_a_status_of_returns_true(self, mock_get_for_object):
|
||||
"""Set up mock LogEntry.objects.get_for_object to return a log entry with the desired status"""
|
||||
|
||||
log_entry_with_status = MagicMock(changes='{"status": ["previous_status", "desired_status"]}')
|
||||
mock_get_for_object.return_value = [log_entry_with_status]
|
||||
|
||||
result = self.started_application.has_previously_had_a_status_of("desired_status")
|
||||
|
||||
self.assertTrue(result)
|
||||
|
||||
@patch("auditlog.models.LogEntry.objects.get_for_object")
|
||||
def test_has_previously_had_a_status_of_returns_false(self, mock_get_for_object):
|
||||
"""Set up mock LogEntry.objects.get_for_object to return a log entry
|
||||
with a different status than the desired status"""
|
||||
|
||||
log_entry_with_status = MagicMock(changes='{"status": ["previous_status", "different_status"]}')
|
||||
mock_get_for_object.return_value = [log_entry_with_status]
|
||||
|
||||
result = self.started_application.has_previously_had_a_status_of("desired_status")
|
||||
|
||||
self.assertFalse(result)
|
||||
|
||||
def test_submit_sends_email(self):
|
||||
"""Create an application and submit it and see if email was sent."""
|
||||
user, _ = User.objects.get_or_create(username="testy")
|
||||
contact = Contact.objects.create(email="test@test.gov")
|
||||
domain, _ = DraftDomain.objects.get_or_create(name="igorville.gov")
|
||||
application = DomainApplication.objects.create(
|
||||
creator=user,
|
||||
requested_domain=domain,
|
||||
submitter=contact,
|
||||
)
|
||||
application.save()
|
||||
|
||||
# submitter's email is mayor@igorville.gov
|
||||
application = completed_application()
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
with less_console_noise():
|
||||
|
@ -176,7 +193,185 @@ class TestDomainApplication(TestCase):
|
|||
[
|
||||
email
|
||||
for email in MockSESClient.EMAILS_SENT
|
||||
if "test@test.gov" in email["kwargs"]["Destination"]["ToAddresses"]
|
||||
if "mayor@igorville.gov" in email["kwargs"]["Destination"]["ToAddresses"]
|
||||
]
|
||||
),
|
||||
0,
|
||||
)
|
||||
|
||||
@patch("auditlog.models.LogEntry.objects.get_for_object")
|
||||
def test_submit_does_not_send_email_if_submitted_previously(self, mock_get_for_object):
|
||||
"""Create an application, make it so it was submitted previously, submit it,
|
||||
and see that an email was not sent."""
|
||||
|
||||
# submitter's email is mayor@igorville.gov
|
||||
application = completed_application()
|
||||
|
||||
# Mock the logs
|
||||
log_entry_with_status = MagicMock(changes='{"status": ["started", "submitted"]}')
|
||||
mock_get_for_object.return_value = [log_entry_with_status]
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
with less_console_noise():
|
||||
application.submit()
|
||||
|
||||
# check to see if an email was sent
|
||||
self.assertEqual(
|
||||
len(
|
||||
[
|
||||
email
|
||||
for email in MockSESClient.EMAILS_SENT
|
||||
if "mayor@igorville.gov" in email["kwargs"]["Destination"]["ToAddresses"]
|
||||
]
|
||||
),
|
||||
0,
|
||||
)
|
||||
|
||||
def test_approve_sends_email(self):
|
||||
"""Create an application and approve it and see if email was sent."""
|
||||
|
||||
# submitter's email is mayor@igorville.gov
|
||||
application = completed_application(status=DomainApplication.ApplicationStatus.IN_REVIEW)
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
with less_console_noise():
|
||||
application.approve()
|
||||
|
||||
# check to see if an email was sent
|
||||
self.assertGreater(
|
||||
len(
|
||||
[
|
||||
email
|
||||
for email in MockSESClient.EMAILS_SENT
|
||||
if "mayor@igorville.gov" in email["kwargs"]["Destination"]["ToAddresses"]
|
||||
]
|
||||
),
|
||||
0,
|
||||
)
|
||||
|
||||
@patch("auditlog.models.LogEntry.objects.get_for_object")
|
||||
def test_approve_does_not_send_email_if_approved_previously(self, mock_get_for_object):
|
||||
"""Create an application, make it so it was approved previously, approve it,
|
||||
and see that an email was not sent."""
|
||||
|
||||
# submitter's email is mayor@igorville.gov
|
||||
application = completed_application(status=DomainApplication.ApplicationStatus.IN_REVIEW)
|
||||
|
||||
# Mock the logs
|
||||
log_entry_with_status = MagicMock(changes='{"status": ["submitted", "approved"]}')
|
||||
mock_get_for_object.return_value = [log_entry_with_status]
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
with less_console_noise():
|
||||
application.approve()
|
||||
|
||||
# check to see if an email was sent
|
||||
self.assertEqual(
|
||||
len(
|
||||
[
|
||||
email
|
||||
for email in MockSESClient.EMAILS_SENT
|
||||
if "mayor@igorville.gov" in email["kwargs"]["Destination"]["ToAddresses"]
|
||||
]
|
||||
),
|
||||
0,
|
||||
)
|
||||
|
||||
def test_withdraw_sends_email(self):
|
||||
"""Create an application and withdraw it and see if email was sent."""
|
||||
|
||||
# submitter's email is mayor@igorville.gov
|
||||
application = completed_application(status=DomainApplication.ApplicationStatus.IN_REVIEW)
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
with less_console_noise():
|
||||
application.withdraw()
|
||||
|
||||
# check to see if an email was sent
|
||||
self.assertGreater(
|
||||
len(
|
||||
[
|
||||
email
|
||||
for email in MockSESClient.EMAILS_SENT
|
||||
if "mayor@igorville.gov" in email["kwargs"]["Destination"]["ToAddresses"]
|
||||
]
|
||||
),
|
||||
0,
|
||||
)
|
||||
|
||||
@patch("auditlog.models.LogEntry.objects.get_for_object")
|
||||
def test_withdraw_does_not_send_email_if_withdrawn_previously(self, mock_get_for_object):
|
||||
"""Create an application, make it so it was withdrawn previously, withdraw it,
|
||||
and see that an email was not sent."""
|
||||
|
||||
# submitter's email is mayor@igorville.gov
|
||||
application = completed_application(status=DomainApplication.ApplicationStatus.IN_REVIEW)
|
||||
|
||||
# Mock the logs
|
||||
log_entry_with_status = MagicMock(changes='{"status": ["submitted", "withdrawn"]}')
|
||||
mock_get_for_object.return_value = [log_entry_with_status]
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
with less_console_noise():
|
||||
application.withdraw()
|
||||
|
||||
# check to see if an email was sent
|
||||
self.assertEqual(
|
||||
len(
|
||||
[
|
||||
email
|
||||
for email in MockSESClient.EMAILS_SENT
|
||||
if "mayor@igorville.gov" in email["kwargs"]["Destination"]["ToAddresses"]
|
||||
]
|
||||
),
|
||||
0,
|
||||
)
|
||||
|
||||
def test_reject_sends_email(self):
|
||||
"""Create an application and reject it and see if email was sent."""
|
||||
|
||||
# submitter's email is mayor@igorville.gov
|
||||
application = completed_application(status=DomainApplication.ApplicationStatus.APPROVED)
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
with less_console_noise():
|
||||
application.reject()
|
||||
|
||||
# check to see if an email was sent
|
||||
self.assertGreater(
|
||||
len(
|
||||
[
|
||||
email
|
||||
for email in MockSESClient.EMAILS_SENT
|
||||
if "mayor@igorville.gov" in email["kwargs"]["Destination"]["ToAddresses"]
|
||||
]
|
||||
),
|
||||
0,
|
||||
)
|
||||
|
||||
@patch("auditlog.models.LogEntry.objects.get_for_object")
|
||||
def test_reject_does_not_send_email_if_rejected_previously(self, mock_get_for_object):
|
||||
"""Create an application, make it so it was rejected previously, reject it,
|
||||
and see that an email was not sent."""
|
||||
|
||||
# submitter's email is mayor@igorville.gov
|
||||
application = completed_application(status=DomainApplication.ApplicationStatus.APPROVED)
|
||||
|
||||
# Mock the logs
|
||||
log_entry_with_status = MagicMock(changes='{"status": ["submitted", "rejected"]}')
|
||||
mock_get_for_object.return_value = [log_entry_with_status]
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
with less_console_noise():
|
||||
application.reject()
|
||||
|
||||
# check to see if an email was sent
|
||||
self.assertEqual(
|
||||
len(
|
||||
[
|
||||
email
|
||||
for email in MockSESClient.EMAILS_SENT
|
||||
if "mayor@igorville.gov" in email["kwargs"]["Destination"]["ToAddresses"]
|
||||
]
|
||||
),
|
||||
0,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue