mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-05-20 03:19:24 +02:00
checking in updates
This commit is contained in:
parent
6584eb1547
commit
bec50b4e08
4 changed files with 195 additions and 6 deletions
|
@ -11,6 +11,7 @@ from django.conf import settings
|
|||
from django.shortcuts import redirect
|
||||
from django_fsm import get_available_FIELD_transitions, FSMField
|
||||
from registrar.models.domain_information import DomainInformation
|
||||
from registrar.models.domain_invitation import DomainInvitation
|
||||
from registrar.models.user_portfolio_permission import UserPortfolioPermission
|
||||
from registrar.models.utility.portfolio_helper import UserPortfolioPermissionChoices, UserPortfolioRoleChoices
|
||||
from waffle.decorators import flag_is_active
|
||||
|
@ -2340,11 +2341,12 @@ class DomainInformationInline(admin.StackedInline):
|
|||
template = "django/admin/includes/domain_info_inline_stacked.html"
|
||||
model = models.DomainInformation
|
||||
|
||||
fieldsets = DomainInformationAdmin.fieldsets
|
||||
readonly_fields = DomainInformationAdmin.readonly_fields
|
||||
fieldsets = list(DomainInformationAdmin.fieldsets)
|
||||
readonly_fields = list(DomainInformationAdmin.readonly_fields)
|
||||
analyst_readonly_fields = DomainInformationAdmin.analyst_readonly_fields
|
||||
autocomplete_fields = DomainInformationAdmin.autocomplete_fields
|
||||
|
||||
readonly_fields.extend(["domain_managers", "invited_domain_managers"]) # type: ignore
|
||||
# Removing specific fields from the first fieldset dynamically
|
||||
fieldsets[0][1]["fields"] = [
|
||||
field for field in fieldsets[0][1]["fields"] if field not in ["creator", "submitter", "domain_request", "notes"]
|
||||
|
@ -2352,9 +2354,71 @@ class DomainInformationInline(admin.StackedInline):
|
|||
fieldsets[2][1]["fields"] = [
|
||||
field for field in fieldsets[2][1]["fields"] if field not in ["other_contacts", "no_other_contacts_rationale"]
|
||||
]
|
||||
fieldsets[3][1]["fields"].extend(["other_contacts", "no_other_contacts_rationale"]) # type: ignore
|
||||
fieldsets[2][1]["fields"].extend(["domain_managers", "invited_domain_managers"]) # type: ignore
|
||||
fieldsets_to_move = fieldsets.pop(3)
|
||||
fieldsets.append(fieldsets_to_move)
|
||||
|
||||
|
||||
def get_domain_managers(self, obj):
|
||||
user_domain_roles = UserDomainRole.objects.filter(domain=obj.domain)
|
||||
user_ids = user_domain_roles.values_list("user_id", flat=True)
|
||||
domain_managers = User.objects.filter(id__in=user_ids)
|
||||
return domain_managers
|
||||
|
||||
def get_domain_invitations(self, obj):
|
||||
domain_invitations = DomainInvitation.objects.filter(
|
||||
domain=obj.domain, status=DomainInvitation.DomainInvitationStatus.INVITED
|
||||
)
|
||||
return domain_invitations
|
||||
|
||||
def domain_managers(self, obj):
|
||||
"""Get joined users who have roles/perms that are not Admin, unpack and return an HTML block.
|
||||
|
||||
DJA readonly can't handle querysets, so we need to unpack and return html here.
|
||||
Alternatively, we could return querysets in context but that would limit where this
|
||||
data would display in a custom change form without extensive template customization.
|
||||
|
||||
Will be used in the after_help_text block."""
|
||||
domain_managers = self.get_domain_managers(obj)
|
||||
if not domain_managers:
|
||||
return "No domain managers found."
|
||||
|
||||
domain_manager_details = "<table><thead><tr><th>UID</th><th>Name</th><th>Email</th>" + "</tr></thead><tbody>"
|
||||
for domain_manager in domain_managers:
|
||||
full_name = domain_manager.get_formatted_name()
|
||||
change_url = reverse("admin:registrar_user_change", args=[domain_manager.pk])
|
||||
domain_manager_details += "<tr>"
|
||||
domain_manager_details += f'<td><a href="{change_url}">{escape(domain_manager.username)}</a>'
|
||||
domain_manager_details += f"<td>{escape(full_name)}</td>"
|
||||
domain_manager_details += f"<td>{escape(domain_manager.email)}</td>"
|
||||
domain_manager_details += "</tr>"
|
||||
domain_manager_details += "</tbody></table>"
|
||||
return format_html(domain_manager_details)
|
||||
|
||||
domain_managers.short_description = "Domain Managers" # type: ignore
|
||||
|
||||
def invited_domain_managers(self, obj):
|
||||
"""Get emails which have been invited to the domain, unpack and return an HTML block.
|
||||
|
||||
DJA readonly can't handle querysets, so we need to unpack and return html here.
|
||||
Alternatively, we could return querysets in context but that would limit where this
|
||||
data would display in a custom change form without extensive template customization.
|
||||
|
||||
Will be used in the after_help_text block."""
|
||||
domain_invitations = self.get_domain_invitations(obj)
|
||||
if not domain_invitations:
|
||||
return "No invited domain managers found."
|
||||
|
||||
domain_invitation_details = "<table><thead><tr><th>Email</th><th>Status</th>" + "</tr></thead><tbody>"
|
||||
for domain_invitation in domain_invitations:
|
||||
domain_invitation_details += "<tr>"
|
||||
domain_invitation_details += f"<td>{escape(domain_invitation.email)}</td>"
|
||||
domain_invitation_details += f"<td>{escape(domain_invitation.status.capitalize())}</td>"
|
||||
domain_invitation_details += "</tr>"
|
||||
domain_invitation_details += "</tbody></table>"
|
||||
return format_html(domain_invitation_details)
|
||||
|
||||
invited_domain_managers.short_description = "Invited Domain Managers" # type: ignore
|
||||
|
||||
def has_change_permission(self, request, obj=None):
|
||||
"""Custom has_change_permission override so that we can specify that
|
||||
|
@ -2466,7 +2530,7 @@ class DomainAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
|||
|
||||
fieldsets = (
|
||||
(
|
||||
"Domain Information",
|
||||
None,
|
||||
{"fields": ["state", "expiration_date", "first_ready", "deleted", "dnssecdata", "nameservers"]},
|
||||
),
|
||||
)
|
||||
|
|
|
@ -137,7 +137,7 @@ This is using a custom implementation fieldset.html (see admin/fieldset.html)
|
|||
{% endfor %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
{% elif field.field.name == "display_admins" %}
|
||||
{% elif field.field.name == "display_admins" or field.field.name == "domain_managers" or field.field.namd == "invited_domain_managers" %}
|
||||
<div class="readonly">{{ field.contents|safe }}</div>
|
||||
{% elif field.field.name == "display_members" %}
|
||||
<div class="readonly">
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% extends 'admin/stacked_no_heading.html' %}
|
||||
{% extends 'admin/stacked.html' %}
|
||||
{% load i18n static %}
|
||||
|
||||
{% block fieldset %}
|
||||
|
|
|
@ -334,6 +334,131 @@ class TestDomainAdminAsStaff(MockEppLib):
|
|||
domain.delete()
|
||||
|
||||
|
||||
class TestDomainInformationInline(MockEppLib):
|
||||
"""Test DomainAdmin class, specifically the DomainInformationInline class, as staff user.
|
||||
|
||||
Notes:
|
||||
all tests share staffuser; do not change staffuser model in tests
|
||||
tests have available staffuser, client, and admin
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.staffuser = create_user()
|
||||
cls.site = AdminSite()
|
||||
cls.admin = DomainAdmin(model=Domain, admin_site=cls.site)
|
||||
cls.factory = RequestFactory()
|
||||
|
||||
def setUp(self):
|
||||
self.client = Client(HTTP_HOST="localhost:8080")
|
||||
self.client.force_login(self.staffuser)
|
||||
super().setUp()
|
||||
|
||||
def tearDown(self):
|
||||
super().tearDown()
|
||||
Host.objects.all().delete()
|
||||
UserDomainRole.objects.all().delete()
|
||||
Domain.objects.all().delete()
|
||||
DomainInformation.objects.all().delete()
|
||||
DomainRequest.objects.all().delete()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
User.objects.all().delete()
|
||||
super().tearDownClass()
|
||||
|
||||
@less_console_noise_decorator
|
||||
def test_domain_managers_display(self):
|
||||
"""Tests the custom domain managers field"""
|
||||
admin_user_1 = User.objects.create(
|
||||
username="testuser1",
|
||||
first_name="Gerald",
|
||||
last_name="Meoward",
|
||||
email="meoward@gov.gov",
|
||||
)
|
||||
|
||||
domain_request = completed_domain_request(
|
||||
status=DomainRequest.DomainRequestStatus.IN_REVIEW, user=self.staffuser, name="fake.gov"
|
||||
)
|
||||
domain_request.approve()
|
||||
_domain_info = DomainInformation.objects.filter(domain=domain_request.approved_domain).get()
|
||||
domain = Domain.objects.filter(domain_info=_domain_info).get()
|
||||
|
||||
UserDomainRole.objects.get_or_create(user=admin_user_1, domain=domain, role=UserDomainRole.Roles.MANAGER)
|
||||
|
||||
admin_user_2 = User.objects.create(
|
||||
username="testuser2",
|
||||
first_name="Arnold",
|
||||
last_name="Poopy",
|
||||
email="poopy@gov.gov",
|
||||
)
|
||||
|
||||
UserDomainRole.objects.get_or_create(user=admin_user_2, domain=domain, role=UserDomainRole.Roles.MANAGER)
|
||||
|
||||
# Get the first inline (DomainInformationInline)
|
||||
inline_instance = self.admin.inlines[0](self.admin.model, self.admin.admin_site)
|
||||
|
||||
# Call the domain_managers method
|
||||
domain_managers = inline_instance.domain_managers(domain.domain_info)
|
||||
|
||||
self.assertIn(
|
||||
f'<a href="/admin/registrar/user/{admin_user_1.pk}/change/">testuser1</a>',
|
||||
domain_managers,
|
||||
)
|
||||
self.assertIn("Gerald Meoward", domain_managers)
|
||||
self.assertIn("meoward@gov.gov", domain_managers)
|
||||
self.assertIn(f'<a href="/admin/registrar/user/{admin_user_2.pk}/change/">testuser2</a>', domain_managers)
|
||||
self.assertIn("Arnold Poopy", domain_managers)
|
||||
self.assertIn("poopy@gov.gov", domain_managers)
|
||||
|
||||
@less_console_noise_decorator
|
||||
def test_invited_domain_managers_display(self):
|
||||
"""Tests the custom invited domain managers field"""
|
||||
admin_user_1 = User.objects.create(
|
||||
username="testuser1",
|
||||
first_name="Gerald",
|
||||
last_name="Meoward",
|
||||
email="meoward@gov.gov",
|
||||
)
|
||||
|
||||
domain_request = completed_domain_request(
|
||||
status=DomainRequest.DomainRequestStatus.IN_REVIEW, user=self.staffuser, name="fake.gov"
|
||||
)
|
||||
domain_request.approve()
|
||||
_domain_info = DomainInformation.objects.filter(domain=domain_request.approved_domain).get()
|
||||
domain = Domain.objects.filter(domain_info=_domain_info).get()
|
||||
|
||||
# domain, _ = Domain.objects.get_or_create(name="fake.gov", state=Domain.State.READY)
|
||||
UserDomainRole.objects.get_or_create(user=admin_user_1, domain=domain, role=UserDomainRole.Roles.MANAGER)
|
||||
|
||||
admin_user_2 = User.objects.create(
|
||||
username="testuser2",
|
||||
first_name="Arnold",
|
||||
last_name="Poopy",
|
||||
email="poopy@gov.gov",
|
||||
)
|
||||
|
||||
UserDomainRole.objects.get_or_create(user=admin_user_2, domain=domain, role=UserDomainRole.Roles.MANAGER)
|
||||
|
||||
# Get the first inline (DomainInformationInline)
|
||||
inline_instance = self.admin.inlines[0](self.admin.model, self.admin.admin_site)
|
||||
|
||||
# Call the domain_managers method
|
||||
domain_managers = inline_instance.domain_managers(domain.domain_info)
|
||||
# domain_managers = self.admin.get_inlinesdomain_managers(self.domain)
|
||||
|
||||
self.assertIn(
|
||||
f'<a href="/admin/registrar/user/{admin_user_1.pk}/change/">testuser1</a>',
|
||||
domain_managers,
|
||||
)
|
||||
self.assertIn("Gerald Meoward", domain_managers)
|
||||
self.assertIn("meoward@gov.gov", domain_managers)
|
||||
self.assertIn(f'<a href="/admin/registrar/user/{admin_user_2.pk}/change/">testuser2</a>', domain_managers)
|
||||
self.assertIn("Arnold Poopy", domain_managers)
|
||||
self.assertIn("poopy@gov.gov", domain_managers)
|
||||
|
||||
|
||||
class TestDomainAdminWithClient(TestCase):
|
||||
"""Test DomainAdmin class as super user.
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue