fix unit tests

This commit is contained in:
zandercymatics 2024-10-01 14:22:56 -06:00
parent 06e4daef6a
commit ad43fabbab
No known key found for this signature in database
GPG key ID: FF4636ABEC9682B7
5 changed files with 103 additions and 50 deletions

View file

@ -5,6 +5,7 @@ from django import forms
from django.db.models import Value, CharField, Q from django.db.models import Value, CharField, Q
from django.db.models.functions import Concat, Coalesce from django.db.models.functions import Concat, Coalesce
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from registrar.utility.admin_helpers import get_action_needed_reason_default_email, get_rejection_reason_default_email
from django.conf import settings from django.conf import settings
from django.shortcuts import redirect from django.shortcuts import redirect
from django_fsm import get_available_FIELD_transitions, FSMField from django_fsm import get_available_FIELD_transitions, FSMField
@ -1939,6 +1940,15 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin):
# Get the original domain request from the database. # Get the original domain request from the database.
original_obj = models.DomainRequest.objects.get(pk=obj.pk) original_obj = models.DomainRequest.objects.get(pk=obj.pk)
# == Handle action needed and rejected emails == #
# Edge case: this logic is handled by javascript, so contexts outside that must be handled
if obj.status == DomainRequest.DomainRequestStatus.ACTION_NEEDED:
if obj.action_needed_reason and not obj.action_needed_reason_email:
obj.action_needed_reason_email = get_action_needed_reason_default_email(obj, obj.action_needed_reason)
elif obj.status == DomainRequest.DomainRequestStatus.REJECTED:
if obj.rejection_reason and not obj.rejection_reason_email:
obj.rejection_reason_email = get_rejection_reason_default_email(obj, obj.rejection_reason)
# == Handle allowed emails == # # == Handle allowed emails == #
if obj.status in DomainRequest.get_statuses_that_send_emails() and not settings.IS_PRODUCTION: if obj.status in DomainRequest.get_statuses_that_send_emails() and not settings.IS_PRODUCTION:
self._check_for_valid_email(request, obj) self._check_for_valid_email(request, obj)

View file

@ -688,7 +688,8 @@ class DomainRequest(TimeStampedModel):
"cached_reason": self._cached_rejection_reason, "cached_reason": self._cached_rejection_reason,
"reason": self.rejection_reason, "reason": self.rejection_reason,
"email": self.rejection_reason_email, "email": self.rejection_reason_email,
"excluded_reasons": [DomainRequest.RejectionReasons.OTHER], "excluded_reasons": [],
# "excluded_reasons": [DomainRequest.RejectionReasons.OTHER],
}, },
} }
status_info = status_information.get(status) status_info = status_information.get(status)
@ -707,7 +708,7 @@ class DomainRequest(TimeStampedModel):
if status_info.get("cached_reason") != status_info.get("reason") or status_info.get("cached_reason") is None: if status_info.get("cached_reason") != status_info.get("reason") or status_info.get("cached_reason") is None:
bcc_address = settings.DEFAULT_FROM_EMAIL if settings.IS_PRODUCTION else "" bcc_address = settings.DEFAULT_FROM_EMAIL if settings.IS_PRODUCTION else ""
self._send_status_update_email( self._send_status_update_email(
new_status=status.label, new_status=status,
email_template=f"emails/includes/custom_email.txt", email_template=f"emails/includes/custom_email.txt",
email_template_subject=f"emails/status_change_subject.txt", email_template_subject=f"emails/status_change_subject.txt",
bcc_address=bcc_address, bcc_address=bcc_address,

View file

@ -46,7 +46,7 @@ Learn more about eligibility for .gov domains
<https://get.gov/domains/eligibility/>. <https://get.gov/domains/eligibility/>.
If you have questions or comments, reply to this email. If you have questions or comments, reply to this email.
{% elif reason == domain_request.RejectionReasons.DOMAIN_PURPOSE.NAMING_NOT_MET %} {% elif reason == domain_request.RejectionReasons.DOMAIN_PURPOSE.NAMING_REQUIREMENTS %}
Your domain request was rejected because it does not meet our naming requirements. Your domain request was rejected because it does not meet our naming requirements.
Domains should uniquely identify a government organization and be clear to the Domains should uniquely identify a government organization and be clear to the
general public. Learn more about naming requirements for your type of organization general public. Learn more about naming requirements for your type of organization

View file

@ -599,7 +599,6 @@ class TestDomainRequestAdmin(MockEppLib):
domain_request, domain_request,
status, status,
rejection_reason=None, rejection_reason=None,
rejection_reason_email=None,
action_needed_reason=None, action_needed_reason=None,
action_needed_reason_email=None, action_needed_reason_email=None,
): ):
@ -619,9 +618,6 @@ class TestDomainRequestAdmin(MockEppLib):
if rejection_reason: if rejection_reason:
domain_request.rejection_reason = rejection_reason domain_request.rejection_reason = rejection_reason
if rejection_reason_email:
domain_request.rejection_reason_email = rejection_reason_email
if action_needed_reason: if action_needed_reason:
domain_request.action_needed_reason = action_needed_reason domain_request.action_needed_reason = action_needed_reason
@ -697,6 +693,10 @@ class TestDomainRequestAdmin(MockEppLib):
self.assert_email_is_accurate("ORGANIZATION ALREADY HAS A .GOV DOMAIN", 0, EMAIL, bcc_email_address=BCC_EMAIL) self.assert_email_is_accurate("ORGANIZATION ALREADY HAS A .GOV DOMAIN", 0, EMAIL, bcc_email_address=BCC_EMAIL)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1) self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
# We use javascript to reset the content of this. It is only automatically set
# if the email itself is somehow None.
self._reset_action_needed_email(domain_request)
# Test the email sent out for bad_name # Test the email sent out for bad_name
bad_name = DomainRequest.ActionNeededReasons.BAD_NAME bad_name = DomainRequest.ActionNeededReasons.BAD_NAME
self.transition_state_and_send_email(domain_request, action_needed, action_needed_reason=bad_name) self.transition_state_and_send_email(domain_request, action_needed, action_needed_reason=bad_name)
@ -704,6 +704,7 @@ class TestDomainRequestAdmin(MockEppLib):
"DOMAIN NAME DOES NOT MEET .GOV REQUIREMENTS", 1, EMAIL, bcc_email_address=BCC_EMAIL "DOMAIN NAME DOES NOT MEET .GOV REQUIREMENTS", 1, EMAIL, bcc_email_address=BCC_EMAIL
) )
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2) self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
self._reset_action_needed_email(domain_request)
# Test the email sent out for eligibility_unclear # Test the email sent out for eligibility_unclear
eligibility_unclear = DomainRequest.ActionNeededReasons.ELIGIBILITY_UNCLEAR eligibility_unclear = DomainRequest.ActionNeededReasons.ELIGIBILITY_UNCLEAR
@ -712,6 +713,7 @@ class TestDomainRequestAdmin(MockEppLib):
"ORGANIZATION MAY NOT MEET ELIGIBILITY REQUIREMENTS", 2, EMAIL, bcc_email_address=BCC_EMAIL "ORGANIZATION MAY NOT MEET ELIGIBILITY REQUIREMENTS", 2, EMAIL, bcc_email_address=BCC_EMAIL
) )
self.assertEqual(len(self.mock_client.EMAILS_SENT), 3) self.assertEqual(len(self.mock_client.EMAILS_SENT), 3)
self._reset_action_needed_email(domain_request)
# Test that a custom email is sent out for questionable_so # Test that a custom email is sent out for questionable_so
questionable_so = DomainRequest.ActionNeededReasons.QUESTIONABLE_SENIOR_OFFICIAL questionable_so = DomainRequest.ActionNeededReasons.QUESTIONABLE_SENIOR_OFFICIAL
@ -720,6 +722,7 @@ class TestDomainRequestAdmin(MockEppLib):
"SENIOR OFFICIAL DOES NOT MEET ELIGIBILITY REQUIREMENTS", 3, _creator.email, bcc_email_address=BCC_EMAIL "SENIOR OFFICIAL DOES NOT MEET ELIGIBILITY REQUIREMENTS", 3, _creator.email, bcc_email_address=BCC_EMAIL
) )
self.assertEqual(len(self.mock_client.EMAILS_SENT), 4) self.assertEqual(len(self.mock_client.EMAILS_SENT), 4)
self._reset_action_needed_email(domain_request)
# Assert that no other emails are sent on OTHER # Assert that no other emails are sent on OTHER
other = DomainRequest.ActionNeededReasons.OTHER other = DomainRequest.ActionNeededReasons.OTHER
@ -727,6 +730,7 @@ class TestDomainRequestAdmin(MockEppLib):
# Should be unchanged from before # Should be unchanged from before
self.assertEqual(len(self.mock_client.EMAILS_SENT), 4) self.assertEqual(len(self.mock_client.EMAILS_SENT), 4)
self._reset_action_needed_email(domain_request)
# Tests if an analyst can override existing email content # Tests if an analyst can override existing email content
questionable_so = DomainRequest.ActionNeededReasons.QUESTIONABLE_SENIOR_OFFICIAL questionable_so = DomainRequest.ActionNeededReasons.QUESTIONABLE_SENIOR_OFFICIAL
@ -740,6 +744,7 @@ class TestDomainRequestAdmin(MockEppLib):
domain_request.refresh_from_db() domain_request.refresh_from_db()
self.assert_email_is_accurate("custom email content", 4, _creator.email, bcc_email_address=BCC_EMAIL) self.assert_email_is_accurate("custom email content", 4, _creator.email, bcc_email_address=BCC_EMAIL)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 5) self.assertEqual(len(self.mock_client.EMAILS_SENT), 5)
self._reset_action_needed_email(domain_request)
# Tests if a new email gets sent when just the email is changed. # Tests if a new email gets sent when just the email is changed.
# An email should NOT be sent out if we just modify the email content. # An email should NOT be sent out if we just modify the email content.
@ -751,6 +756,7 @@ class TestDomainRequestAdmin(MockEppLib):
) )
self.assertEqual(len(self.mock_client.EMAILS_SENT), 5) self.assertEqual(len(self.mock_client.EMAILS_SENT), 5)
self._reset_action_needed_email(domain_request)
# Set the request back to in review # Set the request back to in review
domain_request.in_review() domain_request.in_review()
@ -767,6 +773,12 @@ class TestDomainRequestAdmin(MockEppLib):
) )
self.assertEqual(len(self.mock_client.EMAILS_SENT), 6) self.assertEqual(len(self.mock_client.EMAILS_SENT), 6)
def _reset_action_needed_email(self, domain_request):
"""Sets the given action needed email back to none"""
domain_request.action_needed_reason_email = None
domain_request.save()
domain_request.refresh_from_db()
@override_settings(IS_PRODUCTION=True) @override_settings(IS_PRODUCTION=True)
@less_console_noise_decorator @less_console_noise_decorator
def test_rejected_sends_reason_email_prod_bcc(self): def test_rejected_sends_reason_email_prod_bcc(self):
@ -794,58 +806,20 @@ class TestDomainRequestAdmin(MockEppLib):
expected_emails = { expected_emails = {
DomainRequest.RejectionReasons.DOMAIN_PURPOSE: "You didnt provide enough information about how", DomainRequest.RejectionReasons.DOMAIN_PURPOSE: "You didnt provide enough information about how",
DomainRequest.RejectionReasons.REQUESTOR_NOT_ELIGIBLE: "You must be a government employee, or be", DomainRequest.RejectionReasons.REQUESTOR_NOT_ELIGIBLE: "You must be a government employee, or be",
DomainRequest.RejectionReasons.ORG_HAS_DOMAIN: "Our practice is to approve one domain", DomainRequest.RejectionReasons.ORG_HAS_DOMAIN: "practice is to approve one domain",
DomainRequest.RejectionReasons.CONTACTS_NOT_VERIFIED: "we could not verify the organizational", DomainRequest.RejectionReasons.CONTACTS_NOT_VERIFIED: "we could not verify the organizational",
DomainRequest.RejectionReasons.ORG_NOT_ELIGIBLE: ".Gov domains are only available to official U.S.-based", DomainRequest.RejectionReasons.ORG_NOT_ELIGIBLE: ".Gov domains are only available to official U.S.-based",
DomainRequest.RejectionReasons.NAMING_REQUIREMENTS: "does not meet our naming requirements", DomainRequest.RejectionReasons.NAMING_REQUIREMENTS: "does not meet our naming requirements",
# TODO - add back other? DomainRequest.RejectionReasons.OTHER: "YOU CAN SUBMIT A NEW REQUEST",
# DomainRequest.RejectionReasons.OTHER: "",
} }
for i, (reason, email_content) in enumerate(expected_emails.items()): for i, (reason, email_content) in enumerate(expected_emails.items()):
with self.subTest(reason=reason): with self.subTest(reason=reason):
self.transition_state_and_send_email(domain_request, status=rejected, rejection_reason=reason) self.transition_state_and_send_email(domain_request, status=rejected, rejection_reason=reason)
self.assert_email_is_accurate(email_content, i, EMAIL, bcc_email_address=BCC_EMAIL) self.assert_email_is_accurate(email_content, i, EMAIL, bcc_email_address=BCC_EMAIL)
self.assertEqual(len(self.mock_client.EMAILS_SENT), i + 1) self.assertEqual(len(self.mock_client.EMAILS_SENT), i + 1)
domain_request.rejection_reason_email = None
# Tests if an analyst can override existing email content domain_request.save()
domain_purpose = DomainRequest.RejectionReasons.DOMAIN_PURPOSE domain_request.refresh_from_db()
self.transition_state_and_send_email(
domain_request,
status=rejected,
rejection_reason=domain_purpose,
rejection_reason_email="custom email content",
)
logger.info(f"look: {len(self.mock_client.EMAILS_SENT)}")
domain_request.refresh_from_db()
self.assert_email_is_accurate("custom email content", 6, _creator.email, bcc_email_address=BCC_EMAIL)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 7)
# Tests if a new email gets sent when just the email is changed.
# An email should NOT be sent out if we just modify the email content.
self.transition_state_and_send_email(
domain_request,
status=rejected,
action_needed_reason=domain_purpose,
action_needed_reason_email="dummy email content",
)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 7)
# Set the request back to in review
domain_request.in_review()
# Try sending another email when changing states AND including content
self.transition_state_and_send_email(
domain_request,
status=rejected,
rejection_reason=domain_purpose,
rejection_reason_email="custom content when starting anew",
)
self.assert_email_is_accurate(
"custom content when starting anew", 7, _creator.email, bcc_email_address=BCC_EMAIL
)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 8)
@less_console_noise_decorator @less_console_noise_decorator
def test_save_model_sends_submitted_email(self): def test_save_model_sends_submitted_email(self):

View file

@ -177,3 +177,71 @@ class GetActionNeededEmailForUserJsonTest(TestCase):
}, },
) )
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
class GetRejectionEmailForUserJsonTest(TestCase):
def setUp(self):
self.client = Client()
self.superuser = create_superuser()
self.analyst_user = create_user()
self.agency = FederalAgency.objects.create(agency="Test Agency")
self.domain_request = completed_domain_request(
federal_agency=self.agency,
name="test.gov",
status=DomainRequest.DomainRequestStatus.ACTION_NEEDED,
)
self.api_url = reverse("get-action-needed-email-for-user-json")
def tearDown(self):
DomainRequest.objects.all().delete()
User.objects.all().delete()
FederalAgency.objects.all().delete()
@less_console_noise_decorator
def test_get_action_needed_email_for_user_json_superuser(self):
"""Test that a superuser can fetch the action needed email."""
self.client.force_login(self.superuser)
response = self.client.get(
self.api_url,
{
"reason": DomainRequest.ActionNeededReasons.ELIGIBILITY_UNCLEAR,
"domain_request_id": self.domain_request.id,
},
)
self.assertEqual(response.status_code, 200)
data = response.json()
self.assertIn("action_needed_email", data)
self.assertIn("ORGANIZATION MAY NOT MEET ELIGIBILITY REQUIREMENTS", data["action_needed_email"])
@less_console_noise_decorator
def test_get_action_needed_email_for_user_json_analyst(self):
"""Test that an analyst can fetch the action needed email."""
self.client.force_login(self.analyst_user)
response = self.client.get(
self.api_url,
{
"reason": DomainRequest.ActionNeededReasons.QUESTIONABLE_SENIOR_OFFICIAL,
"domain_request_id": self.domain_request.id,
},
)
self.assertEqual(response.status_code, 200)
data = response.json()
self.assertIn("action_needed_email", data)
self.assertIn("SENIOR OFFICIAL DOES NOT MEET ELIGIBILITY REQUIREMENTS", data["action_needed_email"])
@less_console_noise_decorator
def test_get_action_needed_email_for_user_json_regular(self):
"""Test that a regular user receives a 403 with an error message."""
p = "password"
self.client.login(username="testuser", password=p)
response = self.client.get(
self.api_url,
{
"reason": DomainRequest.ActionNeededReasons.QUESTIONABLE_SENIOR_OFFICIAL,
"domain_request_id": self.domain_request.id,
},
)
self.assertEqual(response.status_code, 302)