From 3beb23262bed8044e1a0d8669507771936dc1893 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 18 Aug 2023 08:51:04 -0600 Subject: [PATCH] Sort on domain_application --- src/registrar/admin.py | 2 + src/registrar/tests/common.py | 26 +++---- src/registrar/tests/test_admin.py | 119 +++++++++++++++++------------- 3 files changed, 84 insertions(+), 63 deletions(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 63b57138b..a2c8e0c09 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -4,6 +4,7 @@ from django.contrib.auth.admin import UserAdmin as BaseUserAdmin from django.contrib.contenttypes.models import ContentType from django.http.response import HttpResponseRedirect from django.urls import reverse +from registrar.models.domain_application import DomainApplication from registrar.models.utility.admin_form_order_helper import ( AdminFormOrderHelper, SortingDict, @@ -22,6 +23,7 @@ foreignkey_orderby_dict: list[SortingDict] = [ ), # Handles fields that are sorted by 'name' SortingDict(["domain", "requested_domain"], ["name"]), + SortingDict(['domain_application'], ['requested_domain__name']), ] diff --git a/src/registrar/tests/common.py b/src/registrar/tests/common.py index 49c4d567f..ea22303ea 100644 --- a/src/registrar/tests/common.py +++ b/src/registrar/tests/common.py @@ -245,11 +245,11 @@ class AuditedAdminMockData: return full_arg_list def create_full_dummy_domain_application( - self, object_name, status=DomainApplication.STARTED + self, item_name, status=DomainApplication.STARTED ): """Creates a dummy domain application object""" domain_application_kwargs = self.dummy_kwarg_boilerplate( - self.APPLICATION, object_name, status + self.APPLICATION, item_name, status ) application = DomainApplication.objects.get_or_create( **domain_application_kwargs @@ -257,11 +257,11 @@ class AuditedAdminMockData: return application def create_full_dummy_domain_information( - self, object_name, status=DomainApplication.STARTED + self, item_name, status=DomainApplication.STARTED ): """Creates a dummy domain information object""" domain_application_kwargs = self.dummy_kwarg_boilerplate( - self.INFORMATION, object_name, status + self.INFORMATION, item_name, status ) application = DomainInformation.objects.get_or_create( **domain_application_kwargs @@ -269,11 +269,11 @@ class AuditedAdminMockData: return application def create_full_dummy_domain_invitation( - self, object_name, status=DomainApplication.STARTED + self, item_name, status=DomainApplication.STARTED ): """Creates a dummy domain invitation object""" domain_application_kwargs = self.dummy_kwarg_boilerplate( - self.INVITATION, object_name, status + self.INVITATION, item_name, status ) application = DomainInvitation.objects.get_or_create( **domain_application_kwargs @@ -284,7 +284,7 @@ class AuditedAdminMockData: def create_full_dummy_domain_object( self, domain_type, - object_name, + item_name, has_other_contacts=True, has_current_website=True, has_alternative_gov_domain=True, @@ -295,27 +295,27 @@ class AuditedAdminMockData: match domain_type: case self.APPLICATION: application = self.create_full_dummy_domain_application( - object_name, status + item_name, status ) case self.INVITATION: application = self.create_full_dummy_domain_invitation( - object_name, status + item_name, status ) case self.INFORMATION: application = self.create_full_dummy_domain_information( - object_name, status + item_name, status ) case _: raise ValueError("Invalid domain_type, must conform to given constants") if has_other_contacts and domain_type != self.INVITATION: - other = self.dummy_contact(object_name, "other") + other = self.dummy_contact(item_name, "other") application.other_contacts.add(other) if has_current_website and domain_type == self.APPLICATION: - current = self.dummy_current(object_name) + current = self.dummy_current(item_name) application.current_websites.add(current) if has_alternative_gov_domain and domain_type == self.APPLICATION: - alt = self.dummy_alt(object_name) + alt = self.dummy_alt(item_name) application.alternative_domains.add(alt) return application diff --git a/src/registrar/tests/test_admin.py b/src/registrar/tests/test_admin.py index a1c8486e7..f6ef7feeb 100644 --- a/src/registrar/tests/test_admin.py +++ b/src/registrar/tests/test_admin.py @@ -418,6 +418,7 @@ class AuditedAdminTest(TestCase): DomainApplication.submitter.field, DomainApplication.investigator.field, DomainApplication.creator.field, + DomainApplication.requested_domain.field, ] # Creates multiple domain applications - review status does not matter @@ -430,62 +431,13 @@ class AuditedAdminTest(TestCase): model_admin = AuditedAdmin(DomainApplication, self.site) - # Typically we wouldn't want two nested for fields, - # but both fields are of a fixed length. - # For test case purposes, this should be performant. - for field in tested_fields: - # We want both of these to be lists, as it is richer test wise. - desired_order = self.order_by_desired_field_helper( - model_admin, request, field.name, "first_name", "last_name" - ) - current_sort_order: Contact = list( - model_admin.formfield_for_foreignkey(field, request).queryset - ) - - # Conforms to the same object structure as desired_order - current_sort_order_coerced_type = [] - - # This is necessary as .queryset and get_queryset - # return lists of different types/structures. - # We need to parse this data and coerce them into the same type. - for contact in current_sort_order: - first = contact.first_name - last = contact.last_name - - name_tuple = self.coerced_fk_field_helper(first, last, field.name, ":") - if name_tuple: - current_sort_order_coerced_type.append((first, last)) - - self.assertEqual( - desired_order, - current_sort_order_coerced_type, - "{} is not ordered alphabetically".format(field.name), - ) - - def test_alphabetically_sorted_fk_fields_domain_information(self): - tested_fields = [ - DomainInformation.authorizing_official.field, - DomainInformation.submitter.field, - DomainInformation.domain.field, - DomainInformation.creator.field, - ] - - # Creates multiple domain applications - review status does not matter - applications = multiple_unalphabetical_domain_objects("information") - - # Create a mock request - request = self.factory.post( - "/admin/registrar/domaininformation/{}/change/".format(applications[0].pk) - ) - - model_admin = AuditedAdmin(DomainInformation, self.site) sorted_fields = [] # Typically we wouldn't want two nested for fields, # but both fields are of a fixed length. # For test case purposes, this should be performant. for field in tested_fields: - isNamefield: bool = field == DomainInformation.domain.field + isNamefield: bool = field == DomainApplication.requested_domain.field if isNamefield: sorted_fields = ["name"] else: @@ -523,6 +475,73 @@ class AuditedAdminTest(TestCase): "{} is not ordered alphabetically".format(field.name), ) + def test_alphabetically_sorted_fk_fields_domain_information(self): + tested_fields = [ + DomainInformation.authorizing_official.field, + DomainInformation.submitter.field, + DomainInformation.creator.field, + (DomainInformation.domain.field, ['name']), + (DomainInformation.domain_application.field, ['requested_domain__name']), + ] + # Creates multiple domain applications - review status does not matter + applications = multiple_unalphabetical_domain_objects("information") + + # Create a mock request + request = self.factory.post( + "/admin/registrar/domaininformation/{}/change/".format(applications[0].pk) + ) + + model_admin = AuditedAdmin(DomainInformation, self.site) + + sorted_fields = [] + # Typically we wouldn't want two nested for fields, + # but both fields are of a fixed length. + # For test case purposes, this should be performant. + for field in tested_fields: + isOtherOrderfield: bool = isinstance(field, tuple) + field_obj = None + if isOtherOrderfield: + sorted_fields = field[1] + field_obj = field[0] + else: + sorted_fields = ["first_name", "last_name"] + field_obj = field + # We want both of these to be lists, as it is richer test wise. + desired_order = self.order_by_desired_field_helper( + model_admin, request, field_obj.name, *sorted_fields + ) + current_sort_order = list( + model_admin.formfield_for_foreignkey(field_obj, request).queryset + ) + + # Conforms to the same object structure as desired_order + current_sort_order_coerced_type = [] + + # This is necessary as .queryset and get_queryset + # return lists of different types/structures. + # We need to parse this data and coerce them into the same type. + for obj in current_sort_order: + if not isOtherOrderfield: + first = obj.first_name + last = obj.last_name + elif field_obj == DomainInformation.domain.field: + first = obj.name + last = None + elif field_obj.name == DomainInformation.domain_application.field: + first = obj.requested_domain + last = None + + name_tuple = self.coerced_fk_field_helper(first, last, field_obj.name, ":") + if name_tuple is not None: + logger.debug(name_tuple) + current_sort_order_coerced_type.append(name_tuple) + + self.assertEqual( + desired_order, + current_sort_order_coerced_type, + "{} is not ordered alphabetically".format(field_obj.name), + ) + def test_alphabetically_sorted_fk_fields_domain_invitation(self): tested_fields = [DomainInvitation.domain.field]