mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-08-17 15:04:11 +02:00
Merge pull request #878 from cisagov/rjm/818-approved-domain-status-bug-2
818 - Fix the approve() sets status to None bug
This commit is contained in:
commit
81e380a5bf
3 changed files with 65 additions and 67 deletions
|
@ -274,22 +274,27 @@ class DomainApplicationAdmin(ListHeaderAdmin):
|
||||||
pass
|
pass
|
||||||
elif obj.status == models.DomainApplication.SUBMITTED:
|
elif obj.status == models.DomainApplication.SUBMITTED:
|
||||||
# This is an fsm in model which will throw an error if the
|
# This is an fsm in model which will throw an error if the
|
||||||
# transition condition is violated, so we call it on the
|
# transition condition is violated, so we roll back the
|
||||||
# original object which has the right status value, and pass
|
# status to what it was before the admin user changed it and
|
||||||
# the updated object which contains the up-to-date data
|
# let the fsm method set it. Same comment applies to
|
||||||
# for the side effects (like an email send). Same
|
# transition method calls below.
|
||||||
# comment applies to original_obj method calls below.
|
obj.status = original_obj.status
|
||||||
original_obj.submit(updated_domain_application=obj)
|
obj.submit()
|
||||||
elif obj.status == models.DomainApplication.IN_REVIEW:
|
elif obj.status == models.DomainApplication.IN_REVIEW:
|
||||||
original_obj.in_review(updated_domain_application=obj)
|
obj.status = original_obj.status
|
||||||
|
obj.in_review()
|
||||||
elif obj.status == models.DomainApplication.ACTION_NEEDED:
|
elif obj.status == models.DomainApplication.ACTION_NEEDED:
|
||||||
original_obj.action_needed(updated_domain_application=obj)
|
obj.status = original_obj.status
|
||||||
|
obj.action_needed()
|
||||||
elif obj.status == models.DomainApplication.APPROVED:
|
elif obj.status == models.DomainApplication.APPROVED:
|
||||||
original_obj.approve(updated_domain_application=obj)
|
obj.status = original_obj.status
|
||||||
|
obj.approve()
|
||||||
elif obj.status == models.DomainApplication.WITHDRAWN:
|
elif obj.status == models.DomainApplication.WITHDRAWN:
|
||||||
original_obj.withdraw()
|
obj.status = original_obj.status
|
||||||
|
obj.withdraw()
|
||||||
elif obj.status == models.DomainApplication.REJECTED:
|
elif obj.status == models.DomainApplication.REJECTED:
|
||||||
original_obj.reject(updated_domain_application=obj)
|
obj.status = original_obj.status
|
||||||
|
obj.reject()
|
||||||
else:
|
else:
|
||||||
logger.warning("Unknown status selected in django admin")
|
logger.warning("Unknown status selected in django admin")
|
||||||
|
|
||||||
|
|
|
@ -504,15 +504,10 @@ class DomainApplication(TimeStampedModel):
|
||||||
@transition(
|
@transition(
|
||||||
field="status", source=[STARTED, ACTION_NEEDED, WITHDRAWN], target=SUBMITTED
|
field="status", source=[STARTED, ACTION_NEEDED, WITHDRAWN], target=SUBMITTED
|
||||||
)
|
)
|
||||||
def submit(self, updated_domain_application=None):
|
def submit(self):
|
||||||
"""Submit an application that is started.
|
"""Submit an application that is started.
|
||||||
|
|
||||||
As a side effect, an email notification is sent.
|
As a side effect, an email notification is sent."""
|
||||||
|
|
||||||
This method is called in admin.py on the original application
|
|
||||||
which has the correct status value, but is passed the changed
|
|
||||||
application which has the up-to-date data that we'll use
|
|
||||||
in the email."""
|
|
||||||
|
|
||||||
# check our conditions here inside the `submit` method so that we
|
# check our conditions here inside the `submit` method so that we
|
||||||
# can raise more informative exceptions
|
# can raise more informative exceptions
|
||||||
|
@ -528,16 +523,6 @@ class DomainApplication(TimeStampedModel):
|
||||||
if not DraftDomain.string_could_be_domain(self.requested_domain.name):
|
if not DraftDomain.string_could_be_domain(self.requested_domain.name):
|
||||||
raise ValueError("Requested domain is not a valid domain name.")
|
raise ValueError("Requested domain is not a valid domain name.")
|
||||||
|
|
||||||
if updated_domain_application is not None:
|
|
||||||
# A DomainApplication is being passed to this method (ie from admin)
|
|
||||||
updated_domain_application._send_status_update_email(
|
|
||||||
"submission confirmation",
|
|
||||||
"emails/submission_confirmation.txt",
|
|
||||||
"emails/submission_confirmation_subject.txt",
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
# Or this method is called with the right application
|
|
||||||
# for context, ie from views/application.py
|
|
||||||
self._send_status_update_email(
|
self._send_status_update_email(
|
||||||
"submission confirmation",
|
"submission confirmation",
|
||||||
"emails/submission_confirmation.txt",
|
"emails/submission_confirmation.txt",
|
||||||
|
@ -545,29 +530,24 @@ class DomainApplication(TimeStampedModel):
|
||||||
)
|
)
|
||||||
|
|
||||||
@transition(field="status", source=SUBMITTED, target=IN_REVIEW)
|
@transition(field="status", source=SUBMITTED, target=IN_REVIEW)
|
||||||
def in_review(self, updated_domain_application):
|
def in_review(self):
|
||||||
"""Investigate an application that has been submitted.
|
"""Investigate an application that has been submitted.
|
||||||
|
|
||||||
As a side effect, an email notification is sent.
|
As a side effect, an email notification is sent."""
|
||||||
|
|
||||||
This method is called in admin.py on the original application
|
self._send_status_update_email(
|
||||||
which has the correct status value, but is passed the changed
|
|
||||||
application which has the up-to-date data that we'll use
|
|
||||||
in the email."""
|
|
||||||
|
|
||||||
updated_domain_application._send_status_update_email(
|
|
||||||
"application in review",
|
"application in review",
|
||||||
"emails/status_change_in_review.txt",
|
"emails/status_change_in_review.txt",
|
||||||
"emails/status_change_in_review_subject.txt",
|
"emails/status_change_in_review_subject.txt",
|
||||||
)
|
)
|
||||||
|
|
||||||
@transition(field="status", source=[IN_REVIEW, REJECTED], target=ACTION_NEEDED)
|
@transition(field="status", source=[IN_REVIEW, REJECTED], target=ACTION_NEEDED)
|
||||||
def action_needed(self, updated_domain_application):
|
def action_needed(self):
|
||||||
"""Send back an application that is under investigation or rejected.
|
"""Send back an application that is under investigation or rejected.
|
||||||
|
|
||||||
As a side effect, an email notification is sent, similar to in_review"""
|
As a side effect, an email notification is sent."""
|
||||||
|
|
||||||
updated_domain_application._send_status_update_email(
|
self._send_status_update_email(
|
||||||
"action needed",
|
"action needed",
|
||||||
"emails/status_change_action_needed.txt",
|
"emails/status_change_action_needed.txt",
|
||||||
"emails/status_change_action_needed_subject.txt",
|
"emails/status_change_action_needed_subject.txt",
|
||||||
|
@ -576,19 +556,13 @@ class DomainApplication(TimeStampedModel):
|
||||||
@transition(
|
@transition(
|
||||||
field="status", source=[SUBMITTED, IN_REVIEW, REJECTED], target=APPROVED
|
field="status", source=[SUBMITTED, IN_REVIEW, REJECTED], target=APPROVED
|
||||||
)
|
)
|
||||||
def approve(self, updated_domain_application=None):
|
def approve(self):
|
||||||
"""Approve an application that has been submitted.
|
"""Approve an application that has been submitted.
|
||||||
|
|
||||||
This has substantial side-effects because it creates another database
|
This has substantial side-effects because it creates another database
|
||||||
object for the approved Domain and makes the user who created the
|
object for the approved Domain and makes the user who created the
|
||||||
application into an admin on that domain. It also triggers an email
|
application into an admin on that domain. It also triggers an email
|
||||||
notification.
|
notification."""
|
||||||
|
|
||||||
This method is called in admin.py on the original application
|
|
||||||
which has the correct status value, but is passed the changed
|
|
||||||
application which has the up-to-date data that we'll use
|
|
||||||
in the email.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# create the domain
|
# create the domain
|
||||||
Domain = apps.get_model("registrar.Domain")
|
Domain = apps.get_model("registrar.Domain")
|
||||||
|
@ -607,14 +581,6 @@ class DomainApplication(TimeStampedModel):
|
||||||
user=self.creator, domain=created_domain, role=UserDomainRole.Roles.ADMIN
|
user=self.creator, domain=created_domain, role=UserDomainRole.Roles.ADMIN
|
||||||
)
|
)
|
||||||
|
|
||||||
if updated_domain_application is not None:
|
|
||||||
# A DomainApplication is being passed to this method (ie from admin)
|
|
||||||
updated_domain_application._send_status_update_email(
|
|
||||||
"application approved",
|
|
||||||
"emails/status_change_approved.txt",
|
|
||||||
"emails/status_change_approved_subject.txt",
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
self._send_status_update_email(
|
self._send_status_update_email(
|
||||||
"application approved",
|
"application approved",
|
||||||
"emails/status_change_approved.txt",
|
"emails/status_change_approved.txt",
|
||||||
|
@ -626,12 +592,12 @@ class DomainApplication(TimeStampedModel):
|
||||||
"""Withdraw an application that has been submitted."""
|
"""Withdraw an application that has been submitted."""
|
||||||
|
|
||||||
@transition(field="status", source=[IN_REVIEW, APPROVED], target=REJECTED)
|
@transition(field="status", source=[IN_REVIEW, APPROVED], target=REJECTED)
|
||||||
def reject(self, updated_domain_application):
|
def reject(self):
|
||||||
"""Reject an application that has been submitted.
|
"""Reject an application that has been submitted.
|
||||||
|
|
||||||
As a side effect, an email notification is sent, similar to in_review"""
|
As a side effect, an email notification is sent, similar to in_review"""
|
||||||
|
|
||||||
updated_domain_application._send_status_update_email(
|
self._send_status_update_email(
|
||||||
"action needed",
|
"action needed",
|
||||||
"emails/status_change_rejected.txt",
|
"emails/status_change_rejected.txt",
|
||||||
"emails/status_change_rejected_subject.txt",
|
"emails/status_change_rejected_subject.txt",
|
||||||
|
|
|
@ -153,6 +153,33 @@ class TestDomainApplicationAdmin(TestCase):
|
||||||
# Perform assertions on the mock call itself
|
# Perform assertions on the mock call itself
|
||||||
mock_client_instance.send_email.assert_called_once()
|
mock_client_instance.send_email.assert_called_once()
|
||||||
|
|
||||||
|
def test_save_model_sets_approved_domain(self):
|
||||||
|
# make sure 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.IN_REVIEW)
|
||||||
|
|
||||||
|
# Create a mock request
|
||||||
|
request = self.factory.post(
|
||||||
|
"/admin/registrar/domainapplication/{}/change/".format(application.pk)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create an instance of the model admin
|
||||||
|
model_admin = DomainApplicationAdmin(DomainApplication, self.site)
|
||||||
|
|
||||||
|
# Modify the application's property
|
||||||
|
application.status = DomainApplication.APPROVED
|
||||||
|
|
||||||
|
# Use the model admin's save_model method
|
||||||
|
model_admin.save_model(request, application, form=None, change=True)
|
||||||
|
|
||||||
|
# Test that approved domain exists and equals requested domain
|
||||||
|
self.assertEqual(
|
||||||
|
application.requested_domain.name, application.approved_domain.name
|
||||||
|
)
|
||||||
|
|
||||||
@boto3_mocking.patching
|
@boto3_mocking.patching
|
||||||
def test_save_model_sends_action_needed_email(self):
|
def test_save_model_sends_action_needed_email(self):
|
||||||
# make sure there is no user with this email
|
# make sure there is no user with this email
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue