Unit test the unallowed transitions, error message on admin, and side effects of successful transitions

This commit is contained in:
Rachid Mrad 2023-09-06 15:19:32 -04:00
parent 324bea9868
commit 5fd84b534d
No known key found for this signature in database
GPG key ID: EF38E4CEC4A8F3CF
2 changed files with 195 additions and 1 deletions

View file

@ -1,5 +1,8 @@
from django.test import TestCase, RequestFactory, Client
from django.contrib.admin.sites import AdminSite
from unittest.mock import patch
from contextlib import ExitStack
from django.contrib import messages
from registrar.admin import (
DomainApplicationAdmin,
@ -10,6 +13,7 @@ from registrar.admin import (
from registrar.models import (
DomainApplication,
DomainInformation,
Domain,
User,
DomainInvitation,
)
@ -432,8 +436,159 @@ class TestDomainApplicationAdmin(TestCase):
request,
"Cannot edit an application with a restricted creator.",
)
def test_error_when_saving_approved_to_rejected_and_domain_is_active(self):
# Create an instance of the model
application = completed_application(status=DomainApplication.APPROVED)
domain = Domain.objects.create(name=application.requested_domain.name)
application.approved_domain = domain
application.save()
# Create a request object with a superuser
request = self.factory.post(
"/admin/registrar/domainapplication/{}/change/".format(application.pk)
)
request.user = self.superuser
# Define a custom implementation for is_active
def custom_is_active(self):
return True # Override to return True
# Use ExitStack to combine patch contexts
with ExitStack() as stack:
# Patch Domain.is_active and django.contrib.messages.error simultaneously
stack.enter_context(patch.object(Domain, 'is_active', custom_is_active))
stack.enter_context(patch.object(messages, 'error'))
# Simulate saving the model
application.status = DomainApplication.REJECTED
self.admin.save_model(request, application, None, True)
# Assert that the error message was called with the correct argument
messages.error.assert_called_once_with(
request,
"This action is not permitted, the domain "
+ "is already active.",
)
def test_side_effects_when_saving_approved_to_rejected(self):
# Create an instance of the model
application = completed_application(status=DomainApplication.APPROVED)
domain = Domain.objects.create(name=application.requested_domain.name)
domain_information = DomainInformation.objects.create(creator=self.superuser, domain=domain)
application.approved_domain = domain
application.save()
# Create a request object with a superuser
request = self.factory.post(
"/admin/registrar/domainapplication/{}/change/".format(application.pk)
)
request.user = self.superuser
# Define a custom implementation for is_active
def custom_is_active(self):
return False # Override to return False
# Use ExitStack to combine patch contexts
with ExitStack() as stack:
# Patch Domain.is_active and django.contrib.messages.error simultaneously
stack.enter_context(patch.object(Domain, 'is_active', custom_is_active))
stack.enter_context(patch.object(messages, 'error'))
# Simulate saving the model
application.status = DomainApplication.REJECTED
self.admin.save_model(request, application, None, True)
# Assert that the error message was never called
messages.error.assert_not_called()
self.assertEqual(application.approved_domain, None)
# Assert that Domain got Deleted
with self.assertRaises(Domain.DoesNotExist):
domain.refresh_from_db()
# Assert that DomainInformation got Deleted
with self.assertRaises(DomainInformation.DoesNotExist):
domain_information.refresh_from_db()
def test_error_when_saving_approved_to_ineligible_and_domain_is_active(self):
# Create an instance of the model
application = completed_application(status=DomainApplication.APPROVED)
domain = Domain.objects.create(name=application.requested_domain.name)
application.approved_domain = domain
application.save()
# Create a request object with a superuser
request = self.factory.post(
"/admin/registrar/domainapplication/{}/change/".format(application.pk)
)
request.user = self.superuser
# Define a custom implementation for is_active
def custom_is_active(self):
return True # Override to return True
# Use ExitStack to combine patch contexts
with ExitStack() as stack:
# Patch Domain.is_active and django.contrib.messages.error simultaneously
stack.enter_context(patch.object(Domain, 'is_active', custom_is_active))
stack.enter_context(patch.object(messages, 'error'))
# Simulate saving the model
application.status = DomainApplication.INELIGIBLE
self.admin.save_model(request, application, None, True)
# Assert that the error message was called with the correct argument
messages.error.assert_called_once_with(
request,
"This action is not permitted, the domain "
+ "is already active.",
)
def test_side_effects_when_saving_approved_to_ineligible(self):
# Create an instance of the model
application = completed_application(status=DomainApplication.APPROVED)
domain = Domain.objects.create(name=application.requested_domain.name)
domain_information = DomainInformation.objects.create(creator=self.superuser, domain=domain)
application.approved_domain = domain
application.save()
# Create a request object with a superuser
request = self.factory.post(
"/admin/registrar/domainapplication/{}/change/".format(application.pk)
)
request.user = self.superuser
# Define a custom implementation for is_active
def custom_is_active(self):
return False # Override to return False
# Use ExitStack to combine patch contexts
with ExitStack() as stack:
# Patch Domain.is_active and django.contrib.messages.error simultaneously
stack.enter_context(patch.object(Domain, 'is_active', custom_is_active))
stack.enter_context(patch.object(messages, 'error'))
# Simulate saving the model
application.status = DomainApplication.INELIGIBLE
self.admin.save_model(request, application, None, True)
# Assert that the error message was never called
messages.error.assert_not_called()
self.assertEqual(application.approved_domain, None)
# Assert that Domain got Deleted
with self.assertRaises(Domain.DoesNotExist):
domain.refresh_from_db()
# Assert that DomainInformation got Deleted
with self.assertRaises(DomainInformation.DoesNotExist):
domain_information.refresh_from_db()
def tearDown(self):
Domain.objects.all().delete()
DomainInformation.objects.all().delete()
DomainApplication.objects.all().delete()
User.objects.all().delete()