Linter things / Rachid suggestions

This commit is contained in:
zandercymatics 2023-08-16 14:26:17 -06:00
parent 738b75a7df
commit f31258d2b0
No known key found for this signature in database
GPG key ID: FF4636ABEC9682B7
4 changed files with 157 additions and 73 deletions

View file

@ -13,8 +13,8 @@ audited_admin_item_names = ["submitter", "authorizing_official",
"investigator", "creator", "user"]
audited_admin_orderby_names = ['first_name', 'last_name']
contact_admin_item_names = ["domain", "requested_domain"]
contact_admin_orderby_names = ["name"]
special_audited_admin_item_names = ["domain", "requested_domain"]
special_audited_admin_orderby_names = ["name"]
# Used to keep track of how we want to order_by certain FKs
foreignkey_orderby_dict: list[SortingDictInterface] = [
# foreign_key - order_by
@ -22,9 +22,10 @@ foreignkey_orderby_dict: list[SortingDictInterface] = [
audited_admin_item_names,
audited_admin_orderby_names
).sorting_dict,
# Handles fields that are sorted by 'name'
SortingDictInterface(
contact_admin_item_names,
contact_admin_orderby_names
special_audited_admin_item_names,
special_audited_admin_orderby_names
).sorting_dict
]
@ -186,15 +187,9 @@ class DomainAdmin(ListHeaderAdmin):
class ContactAdmin(ListHeaderAdmin):
"""Custom contact admin class to add search."""
search_fields = ["email", "first_name", "last_name"]
search_help_text = "Search by firstname, lastname or email."
def formfield_for_foreignkey(self, db_field, request, **kwargs):
"""Used to sort dropdown fields alphabetically but can be expanded upon"""
form_field = super().formfield_for_foreignkey(db_field, request, **kwargs)
return form_field_order_helper(form_field, db_field)
class DomainApplicationAdmin(ListHeaderAdmin):
@ -333,7 +328,8 @@ class DomainApplicationAdmin(ListHeaderAdmin):
# For readability purposes, but can be replaced with a one liner
def form_field_order_helper(form_field, db_field):
"""A shorthand for AdminFormOrderHelper(foreignkey_orderby_dict).get_ordered_form_field(form_field, db_field)""" # noqa
"""A shorthand for AdminFormOrderHelper(foreignkey_orderby_dict)
.get_ordered_form_field(form_field, db_field)"""
form = AdminFormOrderHelper(foreignkey_orderby_dict)
return form.get_ordered_form_field(form_field, db_field)

View file

@ -18,16 +18,18 @@ class SortingDictInterface:
class AdminFormOrderHelper():
"""A helper class to order a dropdown field in Django Admin, takes the fields you want to order by as an array""" # noqa
"""A helper class to order a dropdown field in Django Admin,
takes the fields you want to order by as an array"""
# Used to keep track of how we want to order_by certain FKs
_sorting_dict: list[SortingDictInterface] = [] # noqa
_sorting_dict: list[SortingDictInterface] = []
def __init__(self, sort):
self._sorting_dict = sort
def get_ordered_form_field(self, form_field, db_field) -> (ModelChoiceField | None):
"""Orders the queryset for a ModelChoiceField based on the order_by_dict dictionary""" # noqa
"""Orders the queryset for a ModelChoiceField
based on the order_by_dict dictionary"""
_order_by_list = []
for item in self._sorting_dict:
@ -41,7 +43,7 @@ class AdminFormOrderHelper():
break
# Only order if we choose to do so
if not _order_by_list is None:
if _order_by_list is not None:
form_field.queryset = form_field.queryset.order_by(*_order_by_list)
return form_field

View file

@ -10,14 +10,13 @@ from typing import List, Dict
from django.conf import settings
from django.contrib.auth import get_user_model, login
from registrar.models import Contact, DraftDomain, Website, DomainApplication, DomainInvitation, User
import logging
from registrar.models.domain import Domain
from registrar.models.domain_information import DomainInformation
from registrar.models import Contact, DraftDomain, Website, DomainApplication
# For the linter
from registrar.models import DomainInvitation, User, DomainInformation, Domain
logger = logging.getLogger(__name__)
def get_handlers():
"""Obtain pointers to all StreamHandlers."""
handlers = {}
@ -103,14 +102,16 @@ class AuditedAdminMockData:
APPLICATION = "application"
INVITATION = "invitation"
# These all can likely be generalized more if necessary, particulary with shorthands.
# These all can likely be generalized more if necessary,
# particulary with shorthands.
# These are kept basic for now.
# As for why we have shorthands to begin with:
# .queryset returns a list of all objects of the same type,
# rather than by seperating out those fields.
# For such scenarios, the shorthand allows us to not only id a field,
# but append additional information to it.
# This is useful for that scenario and outside it for identifying if values swapped unexpectedly
# This is useful for that scenario and outside it for
# identifying if values swapped unexpectedly
def dummy_user(self, item_name, shorthand):
"""Creates a dummy user object,
but with a shorthand and support for multiple"""
@ -142,13 +143,21 @@ class AuditedAdminMockData:
def dummy_alt(self, item_name):
"""Creates a dummy website object for alternates"""
return Website.objects.get_or_create(website="cityalt{}.gov".format(item_name))[0]
return Website.objects.get_or_create(
website="cityalt{}.gov".format(item_name)
)[0]
def dummy_current(self, item_name):
"""Creates a dummy website object for current"""
return Website.objects.get_or_create(website="city{}.com".format(item_name))[0]
def get_common_domain_arg_dictionary(self, item_name, org_type="federal", federal_type="executive", purpose="Purpose of the site"):
def get_common_domain_arg_dictionary(
self,
item_name,
org_type="federal",
federal_type="executive",
purpose="Purpose of the site"
):
"""Generates a generic argument list for most domains"""
common_args = dict(
organization_type=org_type,
@ -169,9 +178,22 @@ class AuditedAdminMockData:
return common_args
# This can be boiled down more, though for our purposes this is OK
def dummy_kwarg_boilerplate(self, domain_type, item_name, status, org_type="federal", federal_type="executive", purpose="Purpose of the site"):
def dummy_kwarg_boilerplate(
self,
domain_type,
item_name,
status,
org_type="federal",
federal_type="executive",
purpose="Purpose of the site"
):
"""Returns kwargs for different domain object types"""
common_args = self.get_common_domain_arg_dictionary(item_name, org_type, federal_type, purpose)
common_args = self.get_common_domain_arg_dictionary(
item_name,
org_type,
federal_type,
purpose
)
full_arg_list = None
match domain_type:
case self.APPLICATION:
@ -182,10 +204,11 @@ class AuditedAdminMockData:
status=status,
)
case self.INFORMATION:
domain_app = self.create_full_dummy_domain_application(item_name)
full_arg_list = dict(
**common_args,
domain=self.dummy_domain(item_name),
domain_application = self.create_full_dummy_domain_application(item_name)
domain_application=domain_app
)
case self.INVITATION:
full_arg_list = dict(
@ -201,8 +224,14 @@ class AuditedAdminMockData:
status=DomainApplication.STARTED
):
"""Creates a dummy domain application object"""
domain_application_kwargs = self.dummy_kwarg_boilerplate(self.APPLICATION, object_name, status)
application = DomainApplication.objects.get_or_create(**domain_application_kwargs)[0]
domain_application_kwargs = self.dummy_kwarg_boilerplate(
self.APPLICATION,
object_name,
status
)
application = DomainApplication.objects.get_or_create(
**domain_application_kwargs
)[0]
return application
def create_full_dummy_domain_information(
@ -211,8 +240,14 @@ class AuditedAdminMockData:
status=DomainApplication.STARTED
):
"""Creates a dummy domain information object"""
domain_application_kwargs = self.dummy_kwarg_boilerplate(self.INFORMATION, object_name, status)
application = DomainInformation.objects.get_or_create(**domain_application_kwargs)[0]
domain_application_kwargs = self.dummy_kwarg_boilerplate(
self.INFORMATION,
object_name,
status
)
application = DomainInformation.objects.get_or_create(
**domain_application_kwargs
)[0]
return application
def create_full_dummy_domain_invitation(
@ -221,8 +256,14 @@ class AuditedAdminMockData:
status=DomainApplication.STARTED
):
"""Creates a dummy domain invitation object"""
domain_application_kwargs = self.dummy_kwarg_boilerplate(self.INVITATION, object_name, status)
application = DomainInvitation.objects.get_or_create(**domain_application_kwargs)[0]
domain_application_kwargs = self.dummy_kwarg_boilerplate(
self.INVITATION,
object_name,
status
)
application = DomainInvitation.objects.get_or_create(
**domain_application_kwargs
)[0]
return application
@ -239,11 +280,17 @@ class AuditedAdminMockData:
application = None
match domain_type:
case self.APPLICATION:
application = self.create_full_dummy_domain_application(object_name, status)
application = self.create_full_dummy_domain_application(
object_name, status
)
case self.INVITATION:
application = self.create_full_dummy_domain_invitation(object_name, status)
application = self.create_full_dummy_domain_invitation(
object_name, status
)
case self.INFORMATION:
application = self.create_full_dummy_domain_information(object_name, status)
application = self.create_full_dummy_domain_information(
object_name, status
)
case _:
raise ValueError("Invalid domain_type, must conform to given constants")
@ -259,6 +306,7 @@ class AuditedAdminMockData:
return application
def mock_user():
"""A simple user."""
user_kwargs = dict(
@ -361,7 +409,9 @@ def completed_application(
return application
def multiple_unalphabetical_domain_objects(domain_type = AuditedAdminMockData.APPLICATION):
def multiple_unalphabetical_domain_objects(
domain_type=AuditedAdminMockData.APPLICATION
):
"""Returns a list of generic domain objects for testing purposes"""
applications = []
list_of_letters = list(ascii_uppercase)
@ -372,4 +422,3 @@ def multiple_unalphabetical_domain_objects(domain_type = AuditedAdminMockData.AP
application = mock.create_full_dummy_domain_object(domain_type, object_name)
applications.append(application)
return applications

View file

@ -384,7 +384,13 @@ class AuditedAdminTest(TestCase):
self.factory = RequestFactory()
self.client = Client(HTTP_HOST="localhost:8080")
def order_by_desired_field_helper(self, obj_to_sort: AuditedAdmin, request, field_name, *obj_names):
def order_by_desired_field_helper(
self,
obj_to_sort: AuditedAdmin,
request,
field_name,
*obj_names
):
formatted_sort_fields = []
for obj in obj_names:
formatted_sort_fields.append("{}__{}".format(field_name, obj))
@ -408,7 +414,7 @@ class AuditedAdminTest(TestCase):
DomainApplication.creator.field,
]
# Create a sample application - review status does not matter
# Creates multiple domain applications - review status does not matter
applications = multiple_unalphabetical_domain_objects("application")
# Create a mock request
@ -424,7 +430,13 @@ class AuditedAdminTest(TestCase):
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")
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
)
@ -443,9 +455,11 @@ class AuditedAdminTest(TestCase):
if name_tuple:
current_sort_order_coerced_type.append((first, last))
self.assertEqual(desired_order,
self.assertEqual(
desired_order,
current_sort_order_coerced_type,
"{} is not ordered alphabetically".format(field.name))
"{} is not ordered alphabetically".format(field.name)
)
def test_alphabetically_sorted_fk_fields_domain_information(self):
tested_fields = [
@ -455,7 +469,7 @@ class AuditedAdminTest(TestCase):
DomainInformation.creator.field
]
# Create a sample application - review status does not matter
# Creates multiple domain applications - review status does not matter
applications = multiple_unalphabetical_domain_objects("information")
# Create a mock request
@ -477,7 +491,12 @@ class AuditedAdminTest(TestCase):
sorted_fields = ["first_name", "last_name"]
# 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, *sorted_fields)
desired_order = self.order_by_desired_field_helper(
model_admin,
request,
field.name,
*sorted_fields
)
current_sort_order = list(
model_admin.formfield_for_foreignkey(field, request).queryset
)
@ -497,17 +516,19 @@ class AuditedAdminTest(TestCase):
last = None
name_tuple = self.coerced_fk_field_helper(first, last, field.name, ':')
if not name_tuple is None:
if name_tuple is not None:
current_sort_order_coerced_type.append(name_tuple)
self.assertEqual(desired_order,
self.assertEqual(
desired_order,
current_sort_order_coerced_type,
"{} is not ordered alphabetically".format(field.name))
"{} is not ordered alphabetically".format(field.name)
)
def test_alphabetically_sorted_fk_fields_domain_invitation(self):
tested_fields = [DomainInvitation.domain.field]
# Create a sample application - review status does not matter
# Creates multiple domain applications - review status does not matter
applications = multiple_unalphabetical_domain_objects("invitation")
# Create a mock request
@ -525,7 +546,12 @@ class AuditedAdminTest(TestCase):
sorted_fields = ["name"]
# 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, *sorted_fields)
desired_order = self.order_by_desired_field_helper(
model_admin,
request,
field.name,
*sorted_fields
)
current_sort_order = list(
model_admin.formfield_for_foreignkey(field, request).queryset
)
@ -541,20 +567,31 @@ class AuditedAdminTest(TestCase):
last = None
name_tuple = self.coerced_fk_field_helper(first, last, field.name, ':')
if not name_tuple is None:
if name_tuple is not None:
current_sort_order_coerced_type.append(name_tuple)
self.assertEqual(desired_order,
self.assertEqual(
desired_order,
current_sort_order_coerced_type,
"{} is not ordered alphabetically".format(field.name))
"{} is not ordered alphabetically".format(field.name)
)
def coerced_fk_field_helper(
self,
first_name,
last_name,
field_name,
queryset_shorthand
):
if first_name is None:
raise ValueError('Invalid value for first_name, must be defined')
def coerced_fk_field_helper(self, first_name, last_name, field_name, queryset_shorthand): # noqa
returned_tuple = (first_name, last_name)
# Handles edge case for names - structured strangely
if last_name is None:
return (first_name,)
if(first_name and first_name.split(queryset_shorthand)[1] == field_name): # noqa
if(first_name.split(queryset_shorthand)[1] == field_name):
return returned_tuple
else:
return None