This commit is contained in:
David Kennedy 2024-10-16 12:35:46 -04:00
commit 472186e9b4
No known key found for this signature in database
GPG key ID: 6528A5386E66B96B
16 changed files with 68 additions and 31 deletions

View file

@ -2473,7 +2473,10 @@ class DomainAdmin(ListHeaderAdmin, ImportExportModelAdmin):
generic_org_type.admin_order_field = "domain_info__generic_org_type" # type: ignore generic_org_type.admin_order_field = "domain_info__generic_org_type" # type: ignore
def federal_agency(self, obj): def federal_agency(self, obj):
return obj.domain_info.federal_agency if obj.domain_info else None if obj.domain_info:
return obj.domain_info.federal_agency
else:
return None
federal_agency.admin_order_field = "domain_info__federal_agency" # type: ignore federal_agency.admin_order_field = "domain_info__federal_agency" # type: ignore

View file

@ -1927,6 +1927,7 @@ class MembersTable extends LoadTableBase {
memberList.innerHTML = ''; memberList.innerHTML = '';
const UserPortfolioPermissionChoices = data.UserPortfolioPermissionChoices; const UserPortfolioPermissionChoices = data.UserPortfolioPermissionChoices;
const invited = 'Invited';
data.members.forEach(member => { data.members.forEach(member => {
const member_name = member.name; const member_name = member.name;
@ -1943,7 +1944,7 @@ class MembersTable extends LoadTableBase {
let last_active_sort_value = ''; let last_active_sort_value = '';
// Handle 'Invited' or null/empty values differently from valid dates // Handle 'Invited' or null/empty values differently from valid dates
if (last_active && last_active !== 'Invited') { if (last_active && last_active !== invited) {
try { try {
// Try to parse the last_active as a valid date // Try to parse the last_active as a valid date
last_active = new Date(last_active); last_active = new Date(last_active);
@ -1959,9 +1960,9 @@ class MembersTable extends LoadTableBase {
} }
} else { } else {
// Handle 'Invited' or null // Handle 'Invited' or null
last_active = 'Invited'; last_active = invited;
last_active_formatted = 'Invited'; last_active_formatted = invited;
last_active_sort_value = 'Invited'; // Keep 'Invited' as a sortable string last_active_sort_value = invited; // Keep 'Invited' as a sortable string
} }
const action_url = member.action_url; const action_url = member.action_url;

View file

@ -4,7 +4,7 @@ import logging
from django import forms from django import forms
from django.core.validators import MinValueValidator, MaxValueValidator, RegexValidator, MaxLengthValidator from django.core.validators import MinValueValidator, MaxValueValidator, RegexValidator, MaxLengthValidator
from django.forms import formset_factory from django.forms import formset_factory
from registrar.models import DomainRequest from registrar.models import DomainRequest, FederalAgency
from phonenumber_field.widgets import RegionalPhoneNumberWidget from phonenumber_field.widgets import RegionalPhoneNumberWidget
from registrar.models.suborganization import Suborganization from registrar.models.suborganization import Suborganization
from registrar.models.utility.domain_helper import DomainHelper from registrar.models.utility.domain_helper import DomainHelper
@ -35,7 +35,10 @@ class DomainAddUserForm(forms.Form):
email = forms.EmailField( email = forms.EmailField(
label="Email", label="Email",
max_length=None, max_length=None,
error_messages={"invalid": ("Enter your email address in the required format, like name@example.com.")}, error_messages={
"invalid": ("Enter an email address in the required format, like name@example.com."),
"required": ("Enter an email address in the required format, like name@example.com."),
},
validators=[ validators=[
MaxLengthValidator( MaxLengthValidator(
320, 320,
@ -285,7 +288,7 @@ class UserForm(forms.ModelForm):
"required": "Enter your title or role in your organization (e.g., Chief Information Officer)" "required": "Enter your title or role in your organization (e.g., Chief Information Officer)"
} }
self.fields["email"].error_messages = { self.fields["email"].error_messages = {
"required": "Enter your email address in the required format, like name@example.com." "required": "Enter an email address in the required format, like name@example.com."
} }
self.fields["phone"].error_messages["required"] = "Enter your phone number." self.fields["phone"].error_messages["required"] = "Enter your phone number."
self.domainInfo = None self.domainInfo = None
@ -342,7 +345,7 @@ class ContactForm(forms.ModelForm):
"required": "Enter your title or role in your organization (e.g., Chief Information Officer)" "required": "Enter your title or role in your organization (e.g., Chief Information Officer)"
} }
self.fields["email"].error_messages = { self.fields["email"].error_messages = {
"required": "Enter your email address in the required format, like name@example.com." "required": "Enter an email address in the required format, like name@example.com."
} }
self.fields["phone"].error_messages["required"] = "Enter your phone number." self.fields["phone"].error_messages["required"] = "Enter your phone number."
self.domainInfo = None self.domainInfo = None
@ -458,9 +461,12 @@ class DomainOrgNameAddressForm(forms.ModelForm):
validators=[ validators=[
RegexValidator( RegexValidator(
"^[0-9]{5}(?:-[0-9]{4})?$|^$", "^[0-9]{5}(?:-[0-9]{4})?$|^$",
message="Enter a zip code in the required format, like 12345 or 12345-6789.", message="Enter a 5-digit or 9-digit zip code, like 12345 or 12345-6789.",
) )
], ],
error_messages={
"required": "Enter a 5-digit or 9-digit zip code, like 12345 or 12345-6789.",
},
) )
class Meta: class Meta:
@ -529,17 +535,25 @@ class DomainOrgNameAddressForm(forms.ModelForm):
def save(self, commit=True): def save(self, commit=True):
"""Override the save() method of the BaseModelForm.""" """Override the save() method of the BaseModelForm."""
if self.has_changed(): if self.has_changed():
# This action should be blocked by the UI, as the text fields are readonly. # This action should be blocked by the UI, as the text fields are readonly.
# If they get past this point, we forbid it this way. # If they get past this point, we forbid it this way.
# This could be malicious, so lets reserve information for the backend only. # This could be malicious, so lets reserve information for the backend only.
if self.is_federal and not self._field_unchanged("federal_agency"):
raise ValueError("federal_agency cannot be modified when the generic_org_type is federal") if self.is_federal:
if not self._field_unchanged("federal_agency"):
raise ValueError("federal_agency cannot be modified when the generic_org_type is federal")
elif self.is_tribal and not self._field_unchanged("organization_name"): elif self.is_tribal and not self._field_unchanged("organization_name"):
raise ValueError("organization_name cannot be modified when the generic_org_type is tribal") raise ValueError("organization_name cannot be modified when the generic_org_type is tribal")
super().save() else: # If this error that means Non-Federal Agency is missing
non_federal_agency_instance = FederalAgency.get_non_federal_agency()
self.instance.federal_agency = non_federal_agency_instance
return super().save(commit=commit)
def _field_unchanged(self, field_name) -> bool: def _field_unchanged(self, field_name) -> bool:
""" """

View file

@ -144,10 +144,10 @@ class OrganizationContactForm(RegistrarForm):
validators=[ validators=[
RegexValidator( RegexValidator(
"^[0-9]{5}(?:-[0-9]{4})?$|^$", "^[0-9]{5}(?:-[0-9]{4})?$|^$",
message="Enter a zip code in the form of 12345 or 12345-6789.", message="Enter a 5-digit or 9-digit zip code, like 12345 or 12345-6789.",
) )
], ],
error_messages={"required": ("Enter a zip code in the form of 12345 or 12345-6789.")}, error_messages={"required": ("Enter a 5-digit or 9-digit zip code, like 12345 or 12345-6789.")},
) )
urbanization = forms.CharField( urbanization = forms.CharField(
required=False, required=False,
@ -233,7 +233,10 @@ class SeniorOfficialForm(RegistrarForm):
email = forms.EmailField( email = forms.EmailField(
label="Email", label="Email",
max_length=None, max_length=None,
error_messages={"invalid": ("Enter an email address in the required format, like name@example.com.")}, error_messages={
"invalid": ("Enter an email address in the required format, like name@example.com."),
"required": ("Enter an email address in the required format, like name@example.com."),
},
validators=[ validators=[
MaxLengthValidator( MaxLengthValidator(
320, 320,
@ -610,7 +613,8 @@ class CisaRepresentativeForm(BaseDeletableRegistrarForm):
max_length=None, max_length=None,
required=False, required=False,
error_messages={ error_messages={
"invalid": ("Enter your representatives email address in the required format, like name@example.com."), "invalid": ("Enter an email address in the required format, like name@example.com."),
"required": ("Enter an email address in the required format, like name@example.com."),
}, },
validators=[ validators=[
MaxLengthValidator( MaxLengthValidator(

View file

@ -24,9 +24,12 @@ class PortfolioOrgAddressForm(forms.ModelForm):
validators=[ validators=[
RegexValidator( RegexValidator(
"^[0-9]{5}(?:-[0-9]{4})?$|^$", "^[0-9]{5}(?:-[0-9]{4})?$|^$",
message="Enter a zip code in the required format, like 12345 or 12345-6789.", message="Enter a 5-digit or 9-digit zip code, like 12345 or 12345-6789.",
) )
], ],
error_messages={
"required": "Enter a 5-digit or 9-digit zip code, like 12345 or 12345-6789.",
},
) )
class Meta: class Meta:
@ -45,6 +48,7 @@ class PortfolioOrgAddressForm(forms.ModelForm):
"state_territory": { "state_territory": {
"required": "Select the state, territory, or military post where your organization is located." "required": "Select the state, territory, or military post where your organization is located."
}, },
"zipcode": {"required": "Enter a 5-digit or 9-digit zip code, like 12345 or 12345-6789."},
} }
widgets = { widgets = {
# We need to set the required attributed for State/territory # We need to set the required attributed for State/territory

View file

@ -58,7 +58,7 @@ class UserProfileForm(forms.ModelForm):
"required": "Enter your title or role in your organization (e.g., Chief Information Officer)" "required": "Enter your title or role in your organization (e.g., Chief Information Officer)"
} }
self.fields["email"].error_messages = { self.fields["email"].error_messages = {
"required": "Enter your email address in the required format, like name@example.com." "required": "Enter an email address in the required format, like name@example.com."
} }
self.fields["phone"].error_messages["required"] = "Enter your phone number." self.fields["phone"].error_messages["required"] = "Enter your phone number."

View file

@ -42,7 +42,7 @@
{% input_with_errors form.state_territory %} {% input_with_errors form.state_territory %}
{% with add_class="usa-input--small" sublabel_text="Enter a zip code in the required format, like 12345 or 12345-6789." %} {% with add_class="usa-input--small" sublabel_text="Enter a 5-digit or 9-digit zip code, like 12345 or 12345-6789." %}
{% input_with_errors form.zipcode %} {% input_with_errors form.zipcode %}
{% endwith %} {% endwith %}

View file

@ -33,7 +33,7 @@
{% input_with_errors forms.0.state_territory %} {% input_with_errors forms.0.state_territory %}
{% with add_class="usa-input--small" sublabel_text="Enter a zip code in the required format, like 12345 or 12345-6789." %} {% with add_class="usa-input--small" sublabel_text="Enter a 5-digit or 9-digit zip code, like 12345 or 12345-6789." %}
{% input_with_errors forms.0.zipcode %} {% input_with_errors forms.0.zipcode %}
{% endwith %} {% endwith %}

View file

@ -11,8 +11,13 @@
<p> <p>
The name of your suborganization will be publicly listed as the domain registrant. The name of your suborganization will be publicly listed as the domain registrant.
This list of suborganizations has been populated the .gov program. </p>
If you believe there is an error please contact <a href="mailto:help@get.gov" class="usa-link">help@get.gov</a>. <p>
When this field is blank, the domain registrant will be listed as the overarching organization: {{ portfolio }}.
</p>
<p>
If you dont see your suborganization in the menu or need to edit one of the options,
please contact <a href="mailto:help@get.gov" class="usa-link">help@get.gov</a>.
</p> </p>
{% if has_any_domains_portfolio_permission and has_edit_suborganization_portfolio_permission %} {% if has_any_domains_portfolio_permission and has_edit_suborganization_portfolio_permission %}

View file

@ -4,6 +4,11 @@
<div class="usa-modal__main"> <div class="usa-modal__main">
<h2 class="usa-modal__heading" id="modal-1-heading"> <h2 class="usa-modal__heading" id="modal-1-heading">
{{ modal_heading }} {{ modal_heading }}
{%if domain_name_modal is not None %}
<span class="domain-name-wrap">
{{ domain_name_modal }}
</span>
{%endif%}
{% if heading_value is not None %} {% if heading_value is not None %}
{# Add a breakpoint #} {# Add a breakpoint #}
<div aria-hidden="true"></div> <div aria-hidden="true"></div>

View file

@ -119,9 +119,9 @@
</address> </address>
{% if portfolio_permission %} {% if portfolio_permission %}
{% include "includes/summary_item.html" with title='Member access and permissions' permissions=True value=portfolio_permission member_has_view_all_requests_portfolio_permission=member_has_view_all_requests_portfolio_permission member_has_edit_request_portfolio_permission=member_has_edit_request_portfolio_permission member_has_view_members_portfolio_permission=member_has_view_members_portfolio_permission member_has_edit_members_portfolio_permission=member_has_edit_members_portfolio_permission edit_link=edit_url editable=has_edit_members_portfolio_permission %} {% include "includes/summary_item.html" with title='Member access and permissions' permissions=True value=portfolio_permission edit_link=edit_url editable=has_edit_members_portfolio_permission %}
{% elif portfolio_invitation %} {% elif portfolio_invitation %}
{% include "includes/summary_item.html" with title='Member access and permissions' permissions=True value=portfolio_invitation member_has_view_all_requests_portfolio_permission=member_has_view_all_requests_portfolio_permission member_has_edit_request_portfolio_permission=member_has_edit_request_portfolio_permission member_has_view_members_portfolio_permission=member_has_view_members_portfolio_permission member_has_edit_members_portfolio_permission=member_has_edit_members_portfolio_permission edit_link=edit_url editable=has_edit_members_portfolio_permission %} {% include "includes/summary_item.html" with title='Member access and permissions' permissions=True value=portfolio_invitation edit_link=edit_url editable=has_edit_members_portfolio_permission %}
{% endif %} {% endif %}
{% comment %}view_button is passed below as true in all cases. This is because manage_button logic will trump view_button logic; ie. if manage_button is true, view_button will never be looked at{% endcomment %} {% comment %}view_button is passed below as true in all cases. This is because manage_button logic will trump view_button logic; ie. if manage_button is true, view_button will never be looked at{% endcomment %}

View file

@ -45,7 +45,7 @@
{% input_with_errors form.address_line2 %} {% input_with_errors form.address_line2 %}
{% input_with_errors form.city %} {% input_with_errors form.city %}
{% input_with_errors form.state_territory %} {% input_with_errors form.state_territory %}
{% with add_class="usa-input--small" sublabel_text="Enter a zip code in the required format, like 12345 or 12345-6789." %} {% with add_class="usa-input--small" sublabel_text="Enter a 5-digit or 9-digit zip code, like 12345 or 12345-6789." %}
{% input_with_errors form.zipcode %} {% input_with_errors form.zipcode %}
{% endwith %} {% endwith %}
<button type="submit" class="usa-button"> <button type="submit" class="usa-button">

View file

@ -33,7 +33,7 @@ class TestFormValidation(MockEppLib):
form = OrganizationContactForm(data={"zipcode": "nah"}) form = OrganizationContactForm(data={"zipcode": "nah"})
self.assertEqual( self.assertEqual(
form.errors["zipcode"], form.errors["zipcode"],
["Enter a zip code in the form of 12345 or 12345-6789."], ["Enter a 5-digit or 9-digit zip code, like 12345 or 12345-6789."],
) )
def test_org_contact_zip_valid(self): def test_org_contact_zip_valid(self):

View file

@ -521,7 +521,8 @@ class DomainRequestTests(TestWithUser, WebTest):
# And the existence of the modal's data parked and ready for the js init. # And the existence of the modal's data parked and ready for the js init.
# The next assert also tests for the passed requested domain context from # The next assert also tests for the passed requested domain context from
# the view > domain_request_form > modal # the view > domain_request_form > modal
self.assertContains(review_page, "You are about to submit a domain request for city.gov") self.assertContains(review_page, "You are about to submit a domain request for")
self.assertContains(review_page, "city.gov")
# final submission results in a redirect to the "finished" URL # final submission results in a redirect to the "finished" URL
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)

View file

@ -240,7 +240,7 @@ class SecurityEmailError(Exception):
""" """
_error_mapping = { _error_mapping = {
SecurityEmailErrorCodes.BAD_DATA: ("Enter an email address in the required format, " "like name@example.com."), SecurityEmailErrorCodes.BAD_DATA: ("Enter an email address in the required format, like name@example.com."),
} }
def __init__(self, *args, code=None, **kwargs): def __init__(self, *args, code=None, **kwargs):

View file

@ -457,8 +457,8 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView):
"visited": self.storage.get("step_history", []), "visited": self.storage.get("step_history", []),
"is_federal": self.domain_request.is_federal(), "is_federal": self.domain_request.is_federal(),
"modal_button": modal_button, "modal_button": modal_button,
"modal_heading": "You are about to submit a domain request for " "modal_heading": "You are about to submit a domain request for ",
+ str(self.domain_request.requested_domain), "domain_name_modal": str(self.domain_request.requested_domain),
"modal_description": "Once you submit this request, you wont be able to edit it until we review it.\ "modal_description": "Once you submit this request, you wont be able to edit it until we review it.\
Youll only be able to withdraw your request.", Youll only be able to withdraw your request.",
"review_form_is_complete": True, "review_form_is_complete": True,