use shortened names for orgs in the choicefield which satisfies the admin requirement, replace short name with a long name in the user facing app in the form, summary page, manage app page

This commit is contained in:
Rachid Mrad 2023-10-12 15:32:10 -04:00
parent 1550fde832
commit 003db40e58
No known key found for this signature in database
GPG key ID: EF38E4CEC4A8F3CF
10 changed files with 171 additions and 20 deletions

View file

@ -219,9 +219,9 @@ class MyUserAdmin(BaseUserAdmin):
# (which should in theory be the ONLY group) # (which should in theory be the ONLY group)
def group(self, obj): def group(self, obj):
if obj.groups.filter(name="full_access_group").exists(): if obj.groups.filter(name="full_access_group").exists():
return "Full access" return "full_access_group"
elif obj.groups.filter(name="cisa_analysts_group").exists(): elif obj.groups.filter(name="cisa_analysts_group").exists():
return "Analyst" return "cisa_analysts_group"
return "" return ""
def get_list_display(self, request): def get_list_display(self, request):

View file

@ -153,7 +153,8 @@ class RegistrarFormSet(forms.BaseFormSet):
class OrganizationTypeForm(RegistrarForm): class OrganizationTypeForm(RegistrarForm):
organization_type = forms.ChoiceField( organization_type = forms.ChoiceField(
choices=DomainApplication.OrganizationChoices.choices, # use the long names in the application form
choices=DomainApplication.OrganizationChoicesVerbose.choices,
widget=forms.RadioSelect, widget=forms.RadioSelect,
error_messages={"required": "Select the type of organization you represent."}, error_messages={"required": "Select the type of organization you represent."},
) )

View file

@ -0,0 +1,52 @@
# Generated by Django 4.2.1 on 2023-10-12 19:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("registrar", "0037_create_groups_v01"),
]
operations = [
migrations.AlterField(
model_name="domainapplication",
name="organization_type",
field=models.CharField(
blank=True,
choices=[
("federal", "Federal"),
("interstate", "Interstate"),
("state_or_territory", "State or territory"),
("tribal", "Tribal"),
("county", "County"),
("city", "City"),
("special_district", "Special district"),
("school_district", "School district"),
],
help_text="Type of organization",
max_length=255,
null=True,
),
),
migrations.AlterField(
model_name="domaininformation",
name="organization_type",
field=models.CharField(
blank=True,
choices=[
("federal", "Federal"),
("interstate", "Interstate"),
("state_or_territory", "State or territory"),
("tribal", "Tribal"),
("county", "County"),
("city", "City"),
("special_district", "Special district"),
("school_district", "School district"),
],
help_text="Type of Organization",
max_length=255,
null=True,
),
),
]

View file

@ -105,28 +105,57 @@ class DomainApplication(TimeStampedModel):
ARMED_FORCES_AP = "AP", "Armed Forces Pacific (AP)" ARMED_FORCES_AP = "AP", "Armed Forces Pacific (AP)"
class OrganizationChoices(models.TextChoices): class OrganizationChoices(models.TextChoices):
"""
Primary organization choices:
For use in django admin
Keys need to match OrganizationChoicesVerbose
"""
FEDERAL = "federal", "Federal"
INTERSTATE = "interstate", "Interstate"
STATE_OR_TERRITORY = "state_or_territory", "State or territory"
TRIBAL = "tribal", "Tribal"
COUNTY = "county", "County"
CITY = "city", "City"
SPECIAL_DISTRICT = "special_district", "Special district"
SCHOOL_DISTRICT = "school_district", "School district"
class OrganizationChoicesVerbose(models.TextChoices):
"""
Secondary organization choices
For use in the application form and on the templates
Keys need to match OrganizationChoices
"""
FEDERAL = ( FEDERAL = (
"federal", "federal",
"Federal: an agency of the U.S. government's executive, legislative, " "Federal: an agency of the U.S. government's executive, "
"or judicial branches", "legislative, or judicial branches",
) )
INTERSTATE = "interstate", "Interstate: an organization of two or more states" INTERSTATE = "interstate", "Interstate: an organization of two or more states"
STATE_OR_TERRITORY = "state_or_territory", ( STATE_OR_TERRITORY = (
"State or territory: one of the 50 U.S. states, the District of " "state_or_territory",
"Columbia, American Samoa, Guam, Northern Mariana Islands, " "State or territory: one of the 50 U.S. states, the District of Columbia, "
"Puerto Rico, or the U.S. Virgin Islands" "American Samoa, Guam, Northern Mariana Islands, Puerto Rico, or the U.S. "
"Virgin Islands",
) )
TRIBAL = "tribal", ( TRIBAL = (
"Tribal: a tribal government recognized by the federal or " "tribal",
"a state government" "Tribal: a tribal government recognized by the federal or a state "
"government",
) )
COUNTY = "county", "County: a county, parish, or borough" COUNTY = "county", "County: a county, parish, or borough"
CITY = "city", "City: a city, town, township, village, etc." CITY = "city", "City: a city, town, township, village, etc."
SPECIAL_DISTRICT = "special_district", ( SPECIAL_DISTRICT = (
"Special district: an independent organization within a single state" "special_district",
"Special district: an independent organization within a single state",
) )
SCHOOL_DISTRICT = "school_district", ( SCHOOL_DISTRICT = (
"School district: a school district that is not part of a local government" "school_district",
"School district: a school district that is not part of a local "
"government",
) )
class BranchChoices(models.TextChoices): class BranchChoices(models.TextChoices):
@ -297,6 +326,7 @@ class DomainApplication(TimeStampedModel):
# ##### data fields from the initial form ##### # ##### data fields from the initial form #####
organization_type = models.CharField( organization_type = models.CharField(
max_length=255, max_length=255,
# use the short names in Django admin
choices=OrganizationChoices.choices, choices=OrganizationChoices.choices,
null=True, null=True,
blank=True, blank=True,

View file

@ -21,6 +21,7 @@ class DomainInformation(TimeStampedModel):
StateTerritoryChoices = DomainApplication.StateTerritoryChoices StateTerritoryChoices = DomainApplication.StateTerritoryChoices
# use the short names in Django admin
OrganizationChoices = DomainApplication.OrganizationChoices OrganizationChoices = DomainApplication.OrganizationChoices
BranchChoices = DomainApplication.BranchChoices BranchChoices = DomainApplication.BranchChoices

View file

@ -1,5 +1,6 @@
{% extends 'application_form.html' %} {% extends 'application_form.html' %}
{% load static url_helpers %} {% load static url_helpers %}
{% load custom_filters %}
{% block form_required_fields_help_text %} {% block form_required_fields_help_text %}
{# there are no required fields on this page so don't show this #} {# there are no required fields on this page so don't show this #}
@ -26,7 +27,13 @@
<div class="review__step__name">{{ form_titles|get_item:step }}</div> <div class="review__step__name">{{ form_titles|get_item:step }}</div>
<div> <div>
{% if step == Step.ORGANIZATION_TYPE %} {% if step == Step.ORGANIZATION_TYPE %}
{{ application.get_organization_type_display|default:"Incomplete" }} {% if application.organization_type is not None %}
{% with long_org_type=application.organization_type|get_organization_long_name %}
{{ long_org_type }}
{% endwith %}
{% else %}
Incomplete
{% endif %}
{% endif %} {% endif %}
{% if step == Step.TRIBAL_GOVERNMENT %} {% if step == Step.TRIBAL_GOVERNMENT %}
{{ application.tribe_name|default:"Incomplete" }} {{ application.tribe_name|default:"Incomplete" }}

View file

@ -1,5 +1,7 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load custom_filters %}
{% block title %}Domain request status | {{ domainapplication.requested_domain.name }} | {% endblock %} {% block title %}Domain request status | {{ domainapplication.requested_domain.name }} | {% endblock %}
{% load static url_helpers %} {% load static url_helpers %}
@ -50,7 +52,9 @@
<div class="grid-col desktop:grid-offset-2 maxw-tablet"> <div class="grid-col desktop:grid-offset-2 maxw-tablet">
<h2 class="text-primary-darker"> Summary of your domain request </h2> <h2 class="text-primary-darker"> Summary of your domain request </h2>
{% with heading_level='h3' %} {% with heading_level='h3' %}
{% include "includes/summary_item.html" with title='Type of organization' value=domainapplication.get_organization_type_display heading_level=heading_level %} {% with long_org_type=domainapplication.organization_type|get_organization_long_name %}
{% include "includes/summary_item.html" with title='Type of organization' value=long_org_type heading_level=heading_level %}
{% endwith %}
{% if domainapplication.tribe_name %} {% if domainapplication.tribe_name %}
{% include "includes/summary_item.html" with title='Tribal government' value=domainapplication.tribe_name heading_level=heading_level %} {% include "includes/summary_item.html" with title='Tribal government' value=domainapplication.tribe_name heading_level=heading_level %}

View file

@ -1,5 +1,6 @@
from django import template from django import template
import re import re
from registrar.models.domain_application import DomainApplication
register = template.Library() register = template.Library()
@ -48,3 +49,17 @@ def contains_checkbox(html_list):
if re.search(r'<input[^>]*type="checkbox"', html_string): if re.search(r'<input[^>]*type="checkbox"', html_string):
return True return True
return False return False
@register.filter
def get_organization_long_name(organization_type):
organization_choices_dict = {}
for name, value in DomainApplication.OrganizationChoicesVerbose.choices:
organization_choices_dict[name] = value
long_form_type = organization_choices_dict[organization_type]
if long_form_type is not None:
return long_form_type
return "Error"

View file

@ -300,6 +300,23 @@ class TestDomainApplicationAdmin(MockEppLib):
self.superuser = create_superuser() self.superuser = create_superuser()
self.staffuser = create_user() self.staffuser = create_user()
def test_short_org_name_in_applications_list(self):
"""
Make sure the short name is displaying in admin on the list page
"""
self.client.force_login(self.superuser)
completed_application()
response = self.client.get("/admin/registrar/domainapplication/")
# 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")
@boto3_mocking.patching @boto3_mocking.patching
def test_save_model_sends_submitted_email(self): def test_save_model_sends_submitted_email(self):
# make sure there is no user with this email # make sure there is no user with this email

View file

@ -141,9 +141,12 @@ class DomainApplicationTests(TestWithUser, WebTest):
@boto3_mocking.patching @boto3_mocking.patching
def test_application_form_submission(self): def test_application_form_submission(self):
"""Can fill out the entire form and submit. """
Can fill out the entire form and submit.
As we add additional form pages, we need to include them here to make As we add additional form pages, we need to include them here to make
this test work. this test work.
This test also looks for the long organization name on the summary page.
""" """
num_pages_tested = 0 num_pages_tested = 0
# elections, type_of_work, tribal_government, no_other_contacts # elections, type_of_work, tribal_government, no_other_contacts
@ -427,7 +430,8 @@ class DomainApplicationTests(TestWithUser, WebTest):
review_form = review_page.form review_form = review_page.form
# Review page contains all the previously entered data # Review page contains all the previously entered data
self.assertContains(review_page, "Federal") # Let's make sure the long org name is displayed
self.assertContains(review_page, "Federal: an agency of the U.S. government")
self.assertContains(review_page, "Executive") self.assertContains(review_page, "Executive")
self.assertContains(review_page, "Testorg") self.assertContains(review_page, "Testorg")
self.assertContains(review_page, "address 1") self.assertContains(review_page, "address 1")
@ -1065,6 +1069,26 @@ class DomainApplicationTests(TestWithUser, WebTest):
# page = self.app.get(url) # page = self.app.get(url)
# self.assertNotContains(page, "VALUE") # self.assertNotContains(page, "VALUE")
def test_long_org_name_in_application(self):
"""
Make sure the long name is displaying in the application form,
org step
"""
request = self.app.get(reverse("application:")).follow()
self.assertContains(request, "Federal: an agency of the U.S. government")
def test_long_org_name_in_application_manage(self):
"""
Make sure the long name is displaying in the application summary
page (manage your application)
"""
completed_application(status=DomainApplication.SUBMITTED, user=self.user)
home_page = self.app.get("/")
self.assertContains(home_page, "city.gov")
# click the "Edit" link
detail_page = home_page.click("Manage")
self.assertContains(detail_page, "Federal: an agency of the U.S. government")
class TestWithDomainPermissions(TestWithUser): class TestWithDomainPermissions(TestWithUser):
def setUp(self): def setUp(self):