mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-06-30 00:03:30 +02:00
Unit test the unallowed transitions, error message on admin, and side effects of successful transitions
This commit is contained in:
parent
324bea9868
commit
5fd84b534d
2 changed files with 195 additions and 1 deletions
|
@ -1,5 +1,8 @@
|
||||||
from django.test import TestCase, RequestFactory, Client
|
from django.test import TestCase, RequestFactory, Client
|
||||||
from django.contrib.admin.sites import AdminSite
|
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 (
|
from registrar.admin import (
|
||||||
DomainApplicationAdmin,
|
DomainApplicationAdmin,
|
||||||
|
@ -10,6 +13,7 @@ from registrar.admin import (
|
||||||
from registrar.models import (
|
from registrar.models import (
|
||||||
DomainApplication,
|
DomainApplication,
|
||||||
DomainInformation,
|
DomainInformation,
|
||||||
|
Domain,
|
||||||
User,
|
User,
|
||||||
DomainInvitation,
|
DomainInvitation,
|
||||||
)
|
)
|
||||||
|
@ -432,8 +436,159 @@ class TestDomainApplicationAdmin(TestCase):
|
||||||
request,
|
request,
|
||||||
"Cannot edit an application with a restricted creator.",
|
"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):
|
def tearDown(self):
|
||||||
|
Domain.objects.all().delete()
|
||||||
DomainInformation.objects.all().delete()
|
DomainInformation.objects.all().delete()
|
||||||
DomainApplication.objects.all().delete()
|
DomainApplication.objects.all().delete()
|
||||||
User.objects.all().delete()
|
User.objects.all().delete()
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.db.utils import IntegrityError
|
from django.db.utils import IntegrityError
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
from registrar.models import (
|
from registrar.models import (
|
||||||
Contact,
|
Contact,
|
||||||
|
@ -439,7 +440,26 @@ class TestDomainApplication(TestCase):
|
||||||
application = completed_application(status=DomainApplication.INELIGIBLE)
|
application = completed_application(status=DomainApplication.INELIGIBLE)
|
||||||
|
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
with self.assertRaises(TransitionNotAllowed):
|
||||||
application.reject_with_prejudice()
|
application.reject()
|
||||||
|
|
||||||
|
def test_transition_not_allowed_approved_rejected_when_domain_is_active(self):
|
||||||
|
"""Create an application with status approved, create a matching domain that
|
||||||
|
is active, and call reject against transition rules"""
|
||||||
|
|
||||||
|
application = completed_application(status=DomainApplication.APPROVED)
|
||||||
|
domain = Domain.objects.create(name=application.requested_domain.name)
|
||||||
|
application.approved_domain = domain
|
||||||
|
application.save()
|
||||||
|
|
||||||
|
# Define a custom implementation for is_active
|
||||||
|
def custom_is_active(self):
|
||||||
|
return True # Override to return True
|
||||||
|
|
||||||
|
# Use patch to temporarily replace is_active with the custom implementation
|
||||||
|
with patch.object(Domain, 'is_active', custom_is_active):
|
||||||
|
# Now, when you call is_active on Domain, it will return True
|
||||||
|
with self.assertRaises(TransitionNotAllowed):
|
||||||
|
application.reject()
|
||||||
|
|
||||||
def test_transition_not_allowed_started_ineligible(self):
|
def test_transition_not_allowed_started_ineligible(self):
|
||||||
"""Create an application with status started and call reject
|
"""Create an application with status started and call reject
|
||||||
|
@ -494,6 +514,25 @@ class TestDomainApplication(TestCase):
|
||||||
|
|
||||||
with self.assertRaises(TransitionNotAllowed):
|
with self.assertRaises(TransitionNotAllowed):
|
||||||
application.reject_with_prejudice()
|
application.reject_with_prejudice()
|
||||||
|
|
||||||
|
def test_transition_not_allowed_approved_ineligible_when_domain_is_active(self):
|
||||||
|
"""Create an application with status approved, create a matching domain that
|
||||||
|
is active, and call reject_with_prejudice against transition rules"""
|
||||||
|
|
||||||
|
application = completed_application(status=DomainApplication.APPROVED)
|
||||||
|
domain = Domain.objects.create(name=application.requested_domain.name)
|
||||||
|
application.approved_domain = domain
|
||||||
|
application.save()
|
||||||
|
|
||||||
|
# Define a custom implementation for is_active
|
||||||
|
def custom_is_active(self):
|
||||||
|
return True # Override to return True
|
||||||
|
|
||||||
|
# Use patch to temporarily replace is_active with the custom implementation
|
||||||
|
with patch.object(Domain, 'is_active', custom_is_active):
|
||||||
|
# Now, when you call is_active on Domain, it will return True
|
||||||
|
with self.assertRaises(TransitionNotAllowed):
|
||||||
|
application.reject_with_prejudice()
|
||||||
|
|
||||||
|
|
||||||
class TestPermissions(TestCase):
|
class TestPermissions(TestCase):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue