mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-25 12:08:40 +02:00
merge main
This commit is contained in:
commit
22ef6ddc5b
82 changed files with 8270 additions and 7043 deletions
|
@ -14,11 +14,11 @@ from registrar.admin import (
|
|||
ContactAdmin,
|
||||
DomainInformationAdmin,
|
||||
UserDomainRoleAdmin,
|
||||
VeryImportantPersonAdmin,
|
||||
VerifiedByStaffAdmin,
|
||||
)
|
||||
from registrar.models import Domain, DomainApplication, DomainInformation, User, DomainInvitation, Contact, Website
|
||||
from registrar.models.user_domain_role import UserDomainRole
|
||||
from registrar.models.very_important_person import VeryImportantPerson
|
||||
from registrar.models.verified_by_staff import VerifiedByStaff
|
||||
from .common import (
|
||||
MockSESClient,
|
||||
AuditedAdminMockData,
|
||||
|
@ -59,22 +59,22 @@ class TestDomainAdmin(MockEppLib):
|
|||
"""
|
||||
Make sure the short name is displaying in admin on the list page
|
||||
"""
|
||||
self.client.force_login(self.superuser)
|
||||
application = completed_application(status=DomainApplication.ApplicationStatus.IN_REVIEW)
|
||||
mock_client = MockSESClient()
|
||||
with boto3_mocking.clients.handler_for("sesv2", mock_client):
|
||||
with less_console_noise():
|
||||
with less_console_noise():
|
||||
self.client.force_login(self.superuser)
|
||||
application = completed_application(status=DomainApplication.ApplicationStatus.IN_REVIEW)
|
||||
mock_client = MockSESClient()
|
||||
with boto3_mocking.clients.handler_for("sesv2", mock_client):
|
||||
application.approve()
|
||||
|
||||
response = self.client.get("/admin/registrar/domain/")
|
||||
response = self.client.get("/admin/registrar/domain/")
|
||||
|
||||
# There are 3 template references to Federal (3) plus one reference in the table
|
||||
# for our actual application
|
||||
self.assertContains(response, "Federal", count=4)
|
||||
# This may be a bit more robust
|
||||
self.assertContains(response, '<td class="field-organization_type">Federal</td>', count=1)
|
||||
# Now let's make sure the long description does not exist
|
||||
self.assertNotContains(response, "Federal: an agency of the U.S. government")
|
||||
# There are 3 template references to Federal (3) plus one reference in the table
|
||||
# for our actual application
|
||||
self.assertContains(response, "Federal", count=4)
|
||||
# This may be a bit more robust
|
||||
self.assertContains(response, '<td class="field-organization_type">Federal</td>', count=1)
|
||||
# Now let's make sure the long description does not exist
|
||||
self.assertNotContains(response, "Federal: an agency of the U.S. government")
|
||||
|
||||
@skip("Why did this test stop working, and is is a good test")
|
||||
def test_place_and_remove_hold(self):
|
||||
|
@ -120,40 +120,37 @@ class TestDomainAdmin(MockEppLib):
|
|||
Then a user-friendly success message is returned for displaying on the web
|
||||
And `state` is et to `DELETED`
|
||||
"""
|
||||
domain = create_ready_domain()
|
||||
# Put in client hold
|
||||
domain.place_client_hold()
|
||||
p = "userpass"
|
||||
self.client.login(username="staffuser", password=p)
|
||||
|
||||
# Ensure everything is displaying correctly
|
||||
response = self.client.get(
|
||||
"/admin/registrar/domain/{}/change/".format(domain.pk),
|
||||
follow=True,
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, domain.name)
|
||||
self.assertContains(response, "Remove from registry")
|
||||
|
||||
# Test the info dialog
|
||||
request = self.factory.post(
|
||||
"/admin/registrar/domain/{}/change/".format(domain.pk),
|
||||
{"_delete_domain": "Remove from registry", "name": domain.name},
|
||||
follow=True,
|
||||
)
|
||||
request.user = self.client
|
||||
|
||||
with patch("django.contrib.messages.add_message") as mock_add_message:
|
||||
self.admin.do_delete_domain(request, domain)
|
||||
mock_add_message.assert_called_once_with(
|
||||
request,
|
||||
messages.INFO,
|
||||
"Domain city.gov has been deleted. Thanks!",
|
||||
extra_tags="",
|
||||
fail_silently=False,
|
||||
with less_console_noise():
|
||||
domain = create_ready_domain()
|
||||
# Put in client hold
|
||||
domain.place_client_hold()
|
||||
p = "userpass"
|
||||
self.client.login(username="staffuser", password=p)
|
||||
# Ensure everything is displaying correctly
|
||||
response = self.client.get(
|
||||
"/admin/registrar/domain/{}/change/".format(domain.pk),
|
||||
follow=True,
|
||||
)
|
||||
|
||||
self.assertEqual(domain.state, Domain.State.DELETED)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, domain.name)
|
||||
self.assertContains(response, "Remove from registry")
|
||||
# Test the info dialog
|
||||
request = self.factory.post(
|
||||
"/admin/registrar/domain/{}/change/".format(domain.pk),
|
||||
{"_delete_domain": "Remove from registry", "name": domain.name},
|
||||
follow=True,
|
||||
)
|
||||
request.user = self.client
|
||||
with patch("django.contrib.messages.add_message") as mock_add_message:
|
||||
self.admin.do_delete_domain(request, domain)
|
||||
mock_add_message.assert_called_once_with(
|
||||
request,
|
||||
messages.INFO,
|
||||
"Domain city.gov has been deleted. Thanks!",
|
||||
extra_tags="",
|
||||
fail_silently=False,
|
||||
)
|
||||
self.assertEqual(domain.state, Domain.State.DELETED)
|
||||
|
||||
def test_deletion_ready_fsm_failure(self):
|
||||
"""
|
||||
|
@ -162,38 +159,36 @@ class TestDomainAdmin(MockEppLib):
|
|||
Then a user-friendly error message is returned for displaying on the web
|
||||
And `state` is not set to `DELETED`
|
||||
"""
|
||||
domain = create_ready_domain()
|
||||
p = "userpass"
|
||||
self.client.login(username="staffuser", password=p)
|
||||
|
||||
# Ensure everything is displaying correctly
|
||||
response = self.client.get(
|
||||
"/admin/registrar/domain/{}/change/".format(domain.pk),
|
||||
follow=True,
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, domain.name)
|
||||
self.assertContains(response, "Remove from registry")
|
||||
|
||||
# Test the error
|
||||
request = self.factory.post(
|
||||
"/admin/registrar/domain/{}/change/".format(domain.pk),
|
||||
{"_delete_domain": "Remove from registry", "name": domain.name},
|
||||
follow=True,
|
||||
)
|
||||
request.user = self.client
|
||||
|
||||
with patch("django.contrib.messages.add_message") as mock_add_message:
|
||||
self.admin.do_delete_domain(request, domain)
|
||||
mock_add_message.assert_called_once_with(
|
||||
request,
|
||||
messages.ERROR,
|
||||
"Error deleting this Domain: "
|
||||
"Can't switch from state 'ready' to 'deleted'"
|
||||
", must be either 'dns_needed' or 'on_hold'",
|
||||
extra_tags="",
|
||||
fail_silently=False,
|
||||
with less_console_noise():
|
||||
domain = create_ready_domain()
|
||||
p = "userpass"
|
||||
self.client.login(username="staffuser", password=p)
|
||||
# Ensure everything is displaying correctly
|
||||
response = self.client.get(
|
||||
"/admin/registrar/domain/{}/change/".format(domain.pk),
|
||||
follow=True,
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, domain.name)
|
||||
self.assertContains(response, "Remove from registry")
|
||||
# Test the error
|
||||
request = self.factory.post(
|
||||
"/admin/registrar/domain/{}/change/".format(domain.pk),
|
||||
{"_delete_domain": "Remove from registry", "name": domain.name},
|
||||
follow=True,
|
||||
)
|
||||
request.user = self.client
|
||||
with patch("django.contrib.messages.add_message") as mock_add_message:
|
||||
self.admin.do_delete_domain(request, domain)
|
||||
mock_add_message.assert_called_once_with(
|
||||
request,
|
||||
messages.ERROR,
|
||||
"Error deleting this Domain: "
|
||||
"Can't switch from state 'ready' to 'deleted'"
|
||||
", must be either 'dns_needed' or 'on_hold'",
|
||||
extra_tags="",
|
||||
fail_silently=False,
|
||||
)
|
||||
|
||||
self.assertEqual(domain.state, Domain.State.READY)
|
||||
|
||||
|
@ -205,62 +200,57 @@ class TestDomainAdmin(MockEppLib):
|
|||
Then `commands.DeleteDomain` is sent to the registry
|
||||
And Domain returns normally without an error dialog
|
||||
"""
|
||||
domain = create_ready_domain()
|
||||
# Put in client hold
|
||||
domain.place_client_hold()
|
||||
p = "userpass"
|
||||
self.client.login(username="staffuser", password=p)
|
||||
|
||||
# Ensure everything is displaying correctly
|
||||
response = self.client.get(
|
||||
"/admin/registrar/domain/{}/change/".format(domain.pk),
|
||||
follow=True,
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, domain.name)
|
||||
self.assertContains(response, "Remove from registry")
|
||||
|
||||
# Test the info dialog
|
||||
request = self.factory.post(
|
||||
"/admin/registrar/domain/{}/change/".format(domain.pk),
|
||||
{"_delete_domain": "Remove from registry", "name": domain.name},
|
||||
follow=True,
|
||||
)
|
||||
request.user = self.client
|
||||
|
||||
# Delete it once
|
||||
with patch("django.contrib.messages.add_message") as mock_add_message:
|
||||
self.admin.do_delete_domain(request, domain)
|
||||
mock_add_message.assert_called_once_with(
|
||||
request,
|
||||
messages.INFO,
|
||||
"Domain city.gov has been deleted. Thanks!",
|
||||
extra_tags="",
|
||||
fail_silently=False,
|
||||
with less_console_noise():
|
||||
domain = create_ready_domain()
|
||||
# Put in client hold
|
||||
domain.place_client_hold()
|
||||
p = "userpass"
|
||||
self.client.login(username="staffuser", password=p)
|
||||
# Ensure everything is displaying correctly
|
||||
response = self.client.get(
|
||||
"/admin/registrar/domain/{}/change/".format(domain.pk),
|
||||
follow=True,
|
||||
)
|
||||
|
||||
self.assertEqual(domain.state, Domain.State.DELETED)
|
||||
|
||||
# Try to delete it again
|
||||
# Test the info dialog
|
||||
request = self.factory.post(
|
||||
"/admin/registrar/domain/{}/change/".format(domain.pk),
|
||||
{"_delete_domain": "Remove from registry", "name": domain.name},
|
||||
follow=True,
|
||||
)
|
||||
request.user = self.client
|
||||
|
||||
with patch("django.contrib.messages.add_message") as mock_add_message:
|
||||
self.admin.do_delete_domain(request, domain)
|
||||
mock_add_message.assert_called_once_with(
|
||||
request,
|
||||
messages.INFO,
|
||||
"This domain is already deleted",
|
||||
extra_tags="",
|
||||
fail_silently=False,
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, domain.name)
|
||||
self.assertContains(response, "Remove from registry")
|
||||
# Test the info dialog
|
||||
request = self.factory.post(
|
||||
"/admin/registrar/domain/{}/change/".format(domain.pk),
|
||||
{"_delete_domain": "Remove from registry", "name": domain.name},
|
||||
follow=True,
|
||||
)
|
||||
request.user = self.client
|
||||
# Delete it once
|
||||
with patch("django.contrib.messages.add_message") as mock_add_message:
|
||||
self.admin.do_delete_domain(request, domain)
|
||||
mock_add_message.assert_called_once_with(
|
||||
request,
|
||||
messages.INFO,
|
||||
"Domain city.gov has been deleted. Thanks!",
|
||||
extra_tags="",
|
||||
fail_silently=False,
|
||||
)
|
||||
|
||||
self.assertEqual(domain.state, Domain.State.DELETED)
|
||||
self.assertEqual(domain.state, Domain.State.DELETED)
|
||||
# Try to delete it again
|
||||
# Test the info dialog
|
||||
request = self.factory.post(
|
||||
"/admin/registrar/domain/{}/change/".format(domain.pk),
|
||||
{"_delete_domain": "Remove from registry", "name": domain.name},
|
||||
follow=True,
|
||||
)
|
||||
request.user = self.client
|
||||
with patch("django.contrib.messages.add_message") as mock_add_message:
|
||||
self.admin.do_delete_domain(request, domain)
|
||||
mock_add_message.assert_called_once_with(
|
||||
request,
|
||||
messages.INFO,
|
||||
"This domain is already deleted",
|
||||
extra_tags="",
|
||||
fail_silently=False,
|
||||
)
|
||||
self.assertEqual(domain.state, Domain.State.DELETED)
|
||||
|
||||
@skip("Waiting on epp lib to implement")
|
||||
def test_place_and_remove_hold_epp(self):
|
||||
|
@ -669,6 +659,7 @@ class TestDomainApplicationAdmin(MockEppLib):
|
|||
"anything_else",
|
||||
"is_policy_acknowledged",
|
||||
"submission_date",
|
||||
"notes",
|
||||
"current_websites",
|
||||
"other_contacts",
|
||||
"alternative_domains",
|
||||
|
@ -686,6 +677,7 @@ class TestDomainApplicationAdmin(MockEppLib):
|
|||
"creator",
|
||||
"about_your_organization",
|
||||
"requested_domain",
|
||||
"approved_domain",
|
||||
"alternative_domains",
|
||||
"purpose",
|
||||
"submitter",
|
||||
|
@ -759,33 +751,13 @@ class TestDomainApplicationAdmin(MockEppLib):
|
|||
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
|
||||
def trigger_saving_approved_to_another_state(self, domain_is_active, another_state):
|
||||
"""Helper method that triggers domain request state changes from approved to another state,
|
||||
with an associated domain that can be either active (READY) or not.
|
||||
|
||||
# Define a custom implementation for is_active
|
||||
def custom_is_active(self):
|
||||
return True # Override to return True
|
||||
Used to test errors when saving a change with an active domain, also used to test side effects
|
||||
when saving a change goes through."""
|
||||
|
||||
# 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"))
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
with less_console_noise():
|
||||
# Simulate saving the model
|
||||
application.status = DomainApplication.ApplicationStatus.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.ApplicationStatus.APPROVED)
|
||||
domain = Domain.objects.create(name=application.requested_domain.name)
|
||||
|
@ -799,101 +771,60 @@ class TestDomainApplicationAdmin(MockEppLib):
|
|||
|
||||
# Define a custom implementation for is_active
|
||||
def custom_is_active(self):
|
||||
return False # Override to return False
|
||||
return domain_is_active # 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"))
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
with less_console_noise():
|
||||
# Simulate saving the model
|
||||
application.status = DomainApplication.ApplicationStatus.REJECTED
|
||||
self.admin.save_model(request, application, None, True)
|
||||
|
||||
# Assert that the error message was never called
|
||||
messages.error.assert_not_called()
|
||||
application.status = another_state
|
||||
self.admin.save_model(request, application, None, True)
|
||||
|
||||
self.assertEqual(application.approved_domain, None)
|
||||
# Assert that the error message was called with the correct argument
|
||||
if domain_is_active:
|
||||
messages.error.assert_called_once_with(
|
||||
request,
|
||||
"This action is not permitted. The domain " + "is already active.",
|
||||
)
|
||||
else:
|
||||
# Assert that the error message was never called
|
||||
messages.error.assert_not_called()
|
||||
|
||||
# Assert that Domain got Deleted
|
||||
with self.assertRaises(Domain.DoesNotExist):
|
||||
domain.refresh_from_db()
|
||||
self.assertEqual(application.approved_domain, None)
|
||||
|
||||
# Assert that DomainInformation got Deleted
|
||||
with self.assertRaises(DomainInformation.DoesNotExist):
|
||||
domain_information.refresh_from_db()
|
||||
# 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_in_review_and_domain_is_active(self):
|
||||
self.trigger_saving_approved_to_another_state(True, DomainApplication.ApplicationStatus.IN_REVIEW)
|
||||
|
||||
def test_error_when_saving_approved_to_action_needed_and_domain_is_active(self):
|
||||
self.trigger_saving_approved_to_another_state(True, DomainApplication.ApplicationStatus.ACTION_NEEDED)
|
||||
|
||||
def test_error_when_saving_approved_to_rejected_and_domain_is_active(self):
|
||||
self.trigger_saving_approved_to_another_state(True, DomainApplication.ApplicationStatus.REJECTED)
|
||||
|
||||
def test_error_when_saving_approved_to_ineligible_and_domain_is_active(self):
|
||||
# Create an instance of the model
|
||||
application = completed_application(status=DomainApplication.ApplicationStatus.APPROVED)
|
||||
domain = Domain.objects.create(name=application.requested_domain.name)
|
||||
application.approved_domain = domain
|
||||
application.save()
|
||||
self.trigger_saving_approved_to_another_state(True, DomainApplication.ApplicationStatus.INELIGIBLE)
|
||||
|
||||
# Create a request object with a superuser
|
||||
request = self.factory.post("/admin/registrar/domainapplication/{}/change/".format(application.pk))
|
||||
request.user = self.superuser
|
||||
def test_side_effects_when_saving_approved_to_in_review(self):
|
||||
self.trigger_saving_approved_to_another_state(False, DomainApplication.ApplicationStatus.IN_REVIEW)
|
||||
|
||||
# Define a custom implementation for is_active
|
||||
def custom_is_active(self):
|
||||
return True # Override to return True
|
||||
def test_side_effects_when_saving_approved_to_action_needed(self):
|
||||
self.trigger_saving_approved_to_another_state(False, DomainApplication.ApplicationStatus.ACTION_NEEDED)
|
||||
|
||||
# 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.ApplicationStatus.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_rejected(self):
|
||||
self.trigger_saving_approved_to_another_state(False, DomainApplication.ApplicationStatus.REJECTED)
|
||||
|
||||
def test_side_effects_when_saving_approved_to_ineligible(self):
|
||||
# Create an instance of the model
|
||||
application = completed_application(status=DomainApplication.ApplicationStatus.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.ApplicationStatus.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()
|
||||
self.trigger_saving_approved_to_another_state(False, DomainApplication.ApplicationStatus.INELIGIBLE)
|
||||
|
||||
def test_has_correct_filters(self):
|
||||
"""
|
||||
|
@ -1110,7 +1041,7 @@ class DomainInvitationAdminTest(TestCase):
|
|||
self.assertContains(response, retrieved_html, count=1)
|
||||
|
||||
|
||||
class DomainInformationAdminTest(TestCase):
|
||||
class TestDomainInformationAdmin(TestCase):
|
||||
def setUp(self):
|
||||
"""Setup environment for a mock admin user"""
|
||||
self.site = AdminSite()
|
||||
|
@ -1118,6 +1049,7 @@ class DomainInformationAdminTest(TestCase):
|
|||
self.admin = DomainInformationAdmin(model=DomainInformation, admin_site=self.site)
|
||||
self.client = Client(HTTP_HOST="localhost:8080")
|
||||
self.superuser = create_superuser()
|
||||
self.staffuser = create_user()
|
||||
self.mock_data_generator = AuditedAdminMockData()
|
||||
|
||||
self.test_helper = GenericTestHelper(
|
||||
|
@ -1161,6 +1093,27 @@ class DomainInformationAdminTest(TestCase):
|
|||
Contact.objects.all().delete()
|
||||
User.objects.all().delete()
|
||||
|
||||
def test_readonly_fields_for_analyst(self):
|
||||
"""Ensures that analysts have their permissions setup correctly"""
|
||||
request = self.factory.get("/")
|
||||
request.user = self.staffuser
|
||||
|
||||
readonly_fields = self.admin.get_readonly_fields(request)
|
||||
|
||||
expected_fields = [
|
||||
"creator",
|
||||
"type_of_work",
|
||||
"more_organization_information",
|
||||
"domain",
|
||||
"domain_application",
|
||||
"submitter",
|
||||
"no_other_contacts_rationale",
|
||||
"anything_else",
|
||||
"is_policy_acknowledged",
|
||||
]
|
||||
|
||||
self.assertEqual(readonly_fields, expected_fields)
|
||||
|
||||
def test_domain_sortable(self):
|
||||
"""Tests if DomainInformation sorts by domain correctly"""
|
||||
p = "adminpass"
|
||||
|
@ -1325,64 +1278,62 @@ class ListHeaderAdminTest(TestCase):
|
|||
self.superuser = create_superuser()
|
||||
|
||||
def test_changelist_view(self):
|
||||
# Have to get creative to get past linter
|
||||
p = "adminpass"
|
||||
self.client.login(username="superuser", password=p)
|
||||
|
||||
# Mock a user
|
||||
user = mock_user()
|
||||
|
||||
# Make the request using the Client class
|
||||
# which handles CSRF
|
||||
# Follow=True handles the redirect
|
||||
response = self.client.get(
|
||||
"/admin/registrar/domainapplication/",
|
||||
{
|
||||
"status__exact": "started",
|
||||
"investigator__id__exact": user.id,
|
||||
"q": "Hello",
|
||||
},
|
||||
follow=True,
|
||||
)
|
||||
|
||||
# Assert that the filters and search_query are added to the extra_context
|
||||
self.assertIn("filters", response.context)
|
||||
self.assertIn("search_query", response.context)
|
||||
# Assert the content of filters and search_query
|
||||
filters = response.context["filters"]
|
||||
search_query = response.context["search_query"]
|
||||
self.assertEqual(search_query, "Hello")
|
||||
self.assertEqual(
|
||||
filters,
|
||||
[
|
||||
{"parameter_name": "status", "parameter_value": "started"},
|
||||
with less_console_noise():
|
||||
# Have to get creative to get past linter
|
||||
p = "adminpass"
|
||||
self.client.login(username="superuser", password=p)
|
||||
# Mock a user
|
||||
user = mock_user()
|
||||
# Make the request using the Client class
|
||||
# which handles CSRF
|
||||
# Follow=True handles the redirect
|
||||
response = self.client.get(
|
||||
"/admin/registrar/domainapplication/",
|
||||
{
|
||||
"parameter_name": "investigator",
|
||||
"parameter_value": user.first_name + " " + user.last_name,
|
||||
"status__exact": "started",
|
||||
"investigator__id__exact": user.id,
|
||||
"q": "Hello",
|
||||
},
|
||||
],
|
||||
)
|
||||
follow=True,
|
||||
)
|
||||
# Assert that the filters and search_query are added to the extra_context
|
||||
self.assertIn("filters", response.context)
|
||||
self.assertIn("search_query", response.context)
|
||||
# Assert the content of filters and search_query
|
||||
filters = response.context["filters"]
|
||||
search_query = response.context["search_query"]
|
||||
self.assertEqual(search_query, "Hello")
|
||||
self.assertEqual(
|
||||
filters,
|
||||
[
|
||||
{"parameter_name": "status", "parameter_value": "started"},
|
||||
{
|
||||
"parameter_name": "investigator",
|
||||
"parameter_value": user.first_name + " " + user.last_name,
|
||||
},
|
||||
],
|
||||
)
|
||||
|
||||
def test_get_filters(self):
|
||||
# Create a mock request object
|
||||
request = self.factory.get("/admin/yourmodel/")
|
||||
# Set the GET parameters for testing
|
||||
request.GET = {
|
||||
"status": "started",
|
||||
"investigator": "Jeff Lebowski",
|
||||
"q": "search_value",
|
||||
}
|
||||
# Call the get_filters method
|
||||
filters = self.admin.get_filters(request)
|
||||
|
||||
# Assert the filters extracted from the request GET
|
||||
self.assertEqual(
|
||||
filters,
|
||||
[
|
||||
{"parameter_name": "status", "parameter_value": "started"},
|
||||
{"parameter_name": "investigator", "parameter_value": "Jeff Lebowski"},
|
||||
],
|
||||
)
|
||||
with less_console_noise():
|
||||
# Create a mock request object
|
||||
request = self.factory.get("/admin/yourmodel/")
|
||||
# Set the GET parameters for testing
|
||||
request.GET = {
|
||||
"status": "started",
|
||||
"investigator": "Jeff Lebowski",
|
||||
"q": "search_value",
|
||||
}
|
||||
# Call the get_filters method
|
||||
filters = self.admin.get_filters(request)
|
||||
# Assert the filters extracted from the request GET
|
||||
self.assertEqual(
|
||||
filters,
|
||||
[
|
||||
{"parameter_name": "status", "parameter_value": "started"},
|
||||
{"parameter_name": "investigator", "parameter_value": "Jeff Lebowski"},
|
||||
],
|
||||
)
|
||||
|
||||
def tearDown(self):
|
||||
# delete any applications too
|
||||
|
@ -1781,11 +1732,86 @@ class ContactAdminTest(TestCase):
|
|||
|
||||
self.assertEqual(readonly_fields, expected_fields)
|
||||
|
||||
def test_change_view_for_joined_contact_five_or_less(self):
|
||||
"""Create a contact, join it to 4 domain requests. The 5th join will be a user.
|
||||
Assert that the warning on the contact form lists 5 joins."""
|
||||
|
||||
self.client.force_login(self.superuser)
|
||||
|
||||
# Create an instance of the model
|
||||
contact, _ = Contact.objects.get_or_create(user=self.staffuser)
|
||||
|
||||
# join it to 4 domain requests. The 5th join will be a user.
|
||||
application1 = completed_application(submitter=contact, name="city1.gov")
|
||||
application2 = completed_application(submitter=contact, name="city2.gov")
|
||||
application3 = completed_application(submitter=contact, name="city3.gov")
|
||||
application4 = completed_application(submitter=contact, name="city4.gov")
|
||||
|
||||
with patch("django.contrib.messages.warning") as mock_warning:
|
||||
# Use the test client to simulate the request
|
||||
response = self.client.get(reverse("admin:registrar_contact_change", args=[contact.pk]))
|
||||
|
||||
# Assert that the error message was called with the correct argument
|
||||
# Note: The 5th join will be a user.
|
||||
mock_warning.assert_called_once_with(
|
||||
response.wsgi_request,
|
||||
"<ul class='messagelist_content-list--unstyled'>"
|
||||
"<li>Joined to DomainApplication: <a href='/admin/registrar/"
|
||||
f"domainapplication/{application1.pk}/change/'>city1.gov</a></li>"
|
||||
"<li>Joined to DomainApplication: <a href='/admin/registrar/"
|
||||
f"domainapplication/{application2.pk}/change/'>city2.gov</a></li>"
|
||||
"<li>Joined to DomainApplication: <a href='/admin/registrar/"
|
||||
f"domainapplication/{application3.pk}/change/'>city3.gov</a></li>"
|
||||
"<li>Joined to DomainApplication: <a href='/admin/registrar/"
|
||||
f"domainapplication/{application4.pk}/change/'>city4.gov</a></li>"
|
||||
"<li>Joined to User: <a href='/admin/registrar/"
|
||||
f"user/{self.staffuser.pk}/change/'>staff@example.com</a></li>"
|
||||
"</ul>",
|
||||
)
|
||||
|
||||
def test_change_view_for_joined_contact_five_or_more(self):
|
||||
"""Create a contact, join it to 5 domain requests. The 6th join will be a user.
|
||||
Assert that the warning on the contact form lists 5 joins and a '1 more' ellispsis."""
|
||||
with less_console_noise():
|
||||
self.client.force_login(self.superuser)
|
||||
# Create an instance of the model
|
||||
# join it to 5 domain requests. The 6th join will be a user.
|
||||
contact, _ = Contact.objects.get_or_create(user=self.staffuser)
|
||||
application1 = completed_application(submitter=contact, name="city1.gov")
|
||||
application2 = completed_application(submitter=contact, name="city2.gov")
|
||||
application3 = completed_application(submitter=contact, name="city3.gov")
|
||||
application4 = completed_application(submitter=contact, name="city4.gov")
|
||||
application5 = completed_application(submitter=contact, name="city5.gov")
|
||||
with patch("django.contrib.messages.warning") as mock_warning:
|
||||
# Use the test client to simulate the request
|
||||
response = self.client.get(reverse("admin:registrar_contact_change", args=[contact.pk]))
|
||||
logger.debug(mock_warning)
|
||||
# Assert that the error message was called with the correct argument
|
||||
# Note: The 6th join will be a user.
|
||||
mock_warning.assert_called_once_with(
|
||||
response.wsgi_request,
|
||||
"<ul class='messagelist_content-list--unstyled'>"
|
||||
"<li>Joined to DomainApplication: <a href='/admin/registrar/"
|
||||
f"domainapplication/{application1.pk}/change/'>city1.gov</a></li>"
|
||||
"<li>Joined to DomainApplication: <a href='/admin/registrar/"
|
||||
f"domainapplication/{application2.pk}/change/'>city2.gov</a></li>"
|
||||
"<li>Joined to DomainApplication: <a href='/admin/registrar/"
|
||||
f"domainapplication/{application3.pk}/change/'>city3.gov</a></li>"
|
||||
"<li>Joined to DomainApplication: <a href='/admin/registrar/"
|
||||
f"domainapplication/{application4.pk}/change/'>city4.gov</a></li>"
|
||||
"<li>Joined to DomainApplication: <a href='/admin/registrar/"
|
||||
f"domainapplication/{application5.pk}/change/'>city5.gov</a></li>"
|
||||
"</ul>"
|
||||
"<p class='font-sans-3xs'>And 1 more...</p>",
|
||||
)
|
||||
|
||||
def tearDown(self):
|
||||
DomainApplication.objects.all().delete()
|
||||
Contact.objects.all().delete()
|
||||
User.objects.all().delete()
|
||||
|
||||
|
||||
class VeryImportantPersonAdminTestCase(TestCase):
|
||||
class VerifiedByStaffAdminTestCase(TestCase):
|
||||
def setUp(self):
|
||||
self.superuser = create_superuser()
|
||||
self.factory = RequestFactory()
|
||||
|
@ -1794,13 +1820,13 @@ class VeryImportantPersonAdminTestCase(TestCase):
|
|||
self.client.force_login(self.superuser)
|
||||
|
||||
# Create an instance of the admin class
|
||||
admin_instance = VeryImportantPersonAdmin(model=VeryImportantPerson, admin_site=None)
|
||||
admin_instance = VerifiedByStaffAdmin(model=VerifiedByStaff, admin_site=None)
|
||||
|
||||
# Create a VeryImportantPerson instance
|
||||
vip_instance = VeryImportantPerson(email="test@example.com", notes="Test Notes")
|
||||
# Create a VerifiedByStaff instance
|
||||
vip_instance = VerifiedByStaff(email="test@example.com", notes="Test Notes")
|
||||
|
||||
# Create a request object
|
||||
request = self.factory.post("/admin/yourapp/veryimportantperson/add/")
|
||||
request = self.factory.post("/admin/yourapp/VerifiedByStaff/add/")
|
||||
request.user = self.superuser
|
||||
|
||||
# Call the save_model method
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue