mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-31 06:56:33 +02:00
merge latest
This commit is contained in:
commit
feed27153e
13 changed files with 376 additions and 37 deletions
|
@ -4,7 +4,7 @@ verify_ssl = true
|
|||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
django = "4.2.17"
|
||||
django = "4.2.20"
|
||||
cfenv = "*"
|
||||
django-cors-headers = "*"
|
||||
pycryptodomex = "*"
|
||||
|
@ -34,6 +34,7 @@ tblib = "*"
|
|||
django-admin-multiple-choice-list-filter = "*"
|
||||
django-import-export = "*"
|
||||
django-waffle = "*"
|
||||
cryptography = "*"
|
||||
|
||||
[dev-packages]
|
||||
django-debug-toolbar = "*"
|
||||
|
|
21
src/Pipfile.lock
generated
21
src/Pipfile.lock
generated
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "07f7bc9bda4099f96b18f8f063b487b121b82ae01de06a7f2e9013d56098a421"
|
||||
"sha256": "c854531923af84e93b0b26e64a0bf3b9d9c12870c4795b1afb667569ea740e2b"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {},
|
||||
|
@ -281,6 +281,7 @@
|
|||
"sha256:efcfe97d1b3c79e486554efddeb8f6f53a4cdd4cf6086642784fa31fc384e1d7",
|
||||
"sha256:f514ef4cd14bb6fb484b4a60203e912cfcb64f2ab139e88c2274511514bf7308"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.7' and python_full_version not in '3.9.0, 3.9.1'",
|
||||
"version": "==44.0.2"
|
||||
},
|
||||
|
@ -316,12 +317,12 @@
|
|||
},
|
||||
"django": {
|
||||
"hashes": [
|
||||
"sha256:3a93350214ba25f178d4045c0786c61573e7dbfa3c509b3551374f1e11ba8de0",
|
||||
"sha256:6b56d834cc94c8b21a8f4e775064896be3b4a4ca387f2612d4406a5927cd2fdc"
|
||||
"sha256:213381b6e4405f5c8703fffc29cd719efdf189dec60c67c04f76272b3dc845b9",
|
||||
"sha256:92bac5b4432a64532abb73b2ac27203f485e40225d2640a7fbef2b62b876e789"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==4.2.17"
|
||||
"version": "==4.2.20"
|
||||
},
|
||||
"django-admin-multiple-choice-list-filter": {
|
||||
"hashes": [
|
||||
|
@ -1389,11 +1390,11 @@
|
|||
},
|
||||
"botocore-stubs": {
|
||||
"hashes": [
|
||||
"sha256:937c9b787e4f784019f321fa1d88a505965c25f425e810bde45e23b7ca564282",
|
||||
"sha256:bb9a9e7cd2f48ecb429a7d0df0387f63399db8fb363bdfa38eba285854d622a2"
|
||||
"sha256:b9c3a1e8fb57fb70b49aa5380cabefab32ec028d8a1d8f5ac83dd836c5b429a8",
|
||||
"sha256:c6cb18979a86db311a365448b67e4a492a530c3f4fb313432d41deaee6268b95"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==1.37.18"
|
||||
"version": "==1.37.17"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
|
@ -1405,12 +1406,12 @@
|
|||
},
|
||||
"django": {
|
||||
"hashes": [
|
||||
"sha256:3a93350214ba25f178d4045c0786c61573e7dbfa3c509b3551374f1e11ba8de0",
|
||||
"sha256:6b56d834cc94c8b21a8f4e775064896be3b4a4ca387f2612d4406a5927cd2fdc"
|
||||
"sha256:213381b6e4405f5c8703fffc29cd719efdf189dec60c67c04f76272b3dc845b9",
|
||||
"sha256:92bac5b4432a64532abb73b2ac27203f485e40225d2640a7fbef2b62b876e789"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==4.2.17"
|
||||
"version": "==4.2.20"
|
||||
},
|
||||
"django-debug-toolbar": {
|
||||
"hashes": [
|
||||
|
|
|
@ -28,6 +28,8 @@ initFormNameservers();
|
|||
hookupYesNoListener("other_contacts-has_other_contacts",'other-employees', 'no-other-employees');
|
||||
hookupYesNoListener("additional_details-has_anything_else_text",'anything-else', null);
|
||||
hookupYesNoListener("additional_details-has_cisa_representative",'cisa-representative', null);
|
||||
hookupYesNoListener("portfolio_additional_details-working_with_eop", "eop-contact-container", null);
|
||||
hookupYesNoListener("portfolio_additional_details-has_anything_else_text", 'anything-else-details-container', null);
|
||||
hookupYesNoListener("dotgov_domain-feb_naming_requirements", null, "domain-naming-requirements-details-container");
|
||||
|
||||
hookupCallbacksToRadioToggler("purpose-feb_purpose_choice", domain_purpose_choice_callbacks);
|
||||
|
@ -35,7 +37,6 @@ hookupCallbacksToRadioToggler("purpose-feb_purpose_choice", domain_purpose_choic
|
|||
hookupYesNoListener("purpose-has_timeframe", "purpose-timeframe-details-container", null);
|
||||
hookupYesNoListener("purpose-is_interagency_initiative", "purpose-interagency-initaitive-details-container", null);
|
||||
|
||||
|
||||
initializeUrbanizationToggle();
|
||||
|
||||
userProfileListener();
|
||||
|
|
|
@ -615,7 +615,8 @@ class PurposeDetailsForm(BaseDeletableRegistrarForm):
|
|||
label="Purpose",
|
||||
widget=forms.Textarea(
|
||||
attrs={
|
||||
"aria-label": "What is the purpose of your requested domain? Describe how you’ll use your .gov domain. \
|
||||
"aria-label": "What is the purpose of your requested domain? \
|
||||
Describe how you’ll use your .gov domain. \
|
||||
Will it be used for a website, email, or something else?"
|
||||
}
|
||||
),
|
||||
|
@ -921,6 +922,7 @@ class AnythingElseYesNoForm(BaseYesNoForm):
|
|||
|
||||
|
||||
class RequirementsForm(RegistrarForm):
|
||||
|
||||
is_policy_acknowledged = forms.BooleanField(
|
||||
label="I read and agree to the requirements for operating a .gov domain.",
|
||||
error_messages={
|
||||
|
|
|
@ -121,3 +121,83 @@ class FEBInteragencyInitiativeDetailsForm(BaseDeletableRegistrarForm):
|
|||
],
|
||||
error_messages={"required": "Name the agencies that will be involved in this initiative."},
|
||||
)
|
||||
|
||||
|
||||
class WorkingWithEOPYesNoForm(BaseDeletableRegistrarForm, BaseYesNoForm):
|
||||
"""
|
||||
Form for determining if the Federal Executive Branch (FEB) agency is working with the
|
||||
Executive Office of the President (EOP) on the domain request.
|
||||
"""
|
||||
|
||||
field_name = "working_with_eop"
|
||||
|
||||
@property
|
||||
def form_is_checked(self):
|
||||
"""
|
||||
Determines the initial checked state of the form based on the domain_request's attributes.
|
||||
"""
|
||||
return self.domain_request.working_with_eop
|
||||
|
||||
|
||||
class EOPContactForm(BaseDeletableRegistrarForm):
|
||||
"""
|
||||
Form for contact information of the representative of the
|
||||
Executive Office of the President (EOP) that the Federal
|
||||
Executive Branch (FEB) agency is working with.
|
||||
"""
|
||||
|
||||
first_name = forms.CharField(
|
||||
label="First name / given name",
|
||||
error_messages={"required": "Enter the first name / given name of this contact."},
|
||||
required=True,
|
||||
)
|
||||
last_name = forms.CharField(
|
||||
label="Last name / family name",
|
||||
error_messages={"required": "Enter the last name / family name of this contact."},
|
||||
required=True,
|
||||
)
|
||||
email = forms.EmailField(
|
||||
label="Email",
|
||||
max_length=None,
|
||||
error_messages={
|
||||
"required": ("Enter an email address in the required format, like name@example.com."),
|
||||
"invalid": ("Enter an email address in the required format, like name@example.com."),
|
||||
},
|
||||
validators=[
|
||||
MaxLengthValidator(
|
||||
320,
|
||||
message="Response must be less than 320 characters.",
|
||||
)
|
||||
],
|
||||
required=True,
|
||||
help_text="Enter an email address in the required format, like name@example.com.",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_database(cls, obj):
|
||||
return {
|
||||
"first_name": obj.eop_stakeholder_first_name,
|
||||
"last_name": obj.eop_stakeholder_last_name,
|
||||
"email": obj.eop_stakeholder_email,
|
||||
}
|
||||
|
||||
def to_database(self, obj):
|
||||
# This function overrides the behavior of the BaseDeletableRegistrarForm.
|
||||
# in order to preserve deletable functionality, we need to call the
|
||||
# superclass's to_database method if the form is marked for deletion.
|
||||
if self.form_data_marked_for_deletion:
|
||||
super().to_database(obj)
|
||||
return
|
||||
if not self.is_valid():
|
||||
return
|
||||
obj.eop_stakeholder_first_name = self.cleaned_data["first_name"]
|
||||
obj.eop_stakeholder_last_name = self.cleaned_data["last_name"]
|
||||
obj.eop_stakeholder_email = self.cleaned_data["email"]
|
||||
obj.save()
|
||||
|
||||
|
||||
class FEBAnythingElseYesNoForm(BaseYesNoForm, BaseDeletableRegistrarForm):
|
||||
"""Yes/no toggle for the anything else question on additional details"""
|
||||
|
||||
form_is_checked = property(lambda self: self.domain_request.has_anything_else_text) # type: ignore
|
||||
field_name = "has_anything_else_text"
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
# Generated by Django 4.2.17 on 2025-03-17 20:44
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("registrar", "0143_create_groups_v18"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="domainrequest",
|
||||
name="eop_stakeholder_email",
|
||||
field=models.EmailField(blank=True, max_length=254, null=True, verbose_name="EOP Stakeholder Email"),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="domainrequest",
|
||||
name="eop_stakeholder_first_name",
|
||||
field=models.CharField(blank=True, null=True, verbose_name="EOP Stakeholder First Name"),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="domainrequest",
|
||||
name="eop_stakeholder_last_name",
|
||||
field=models.CharField(blank=True, null=True, verbose_name="EOP Stakeholder Last Name"),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="domainrequest",
|
||||
name="working_with_eop",
|
||||
field=models.BooleanField(blank=True, null=True),
|
||||
),
|
||||
]
|
|
@ -523,6 +523,29 @@ class DomainRequest(TimeStampedModel):
|
|||
choices=FEBPurposeChoices.choices,
|
||||
)
|
||||
|
||||
working_with_eop = models.BooleanField(
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
|
||||
eop_stakeholder_first_name = models.CharField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="EOP Stakeholder First Name",
|
||||
)
|
||||
|
||||
eop_stakeholder_last_name = models.CharField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="EOP Stakeholder Last Name",
|
||||
)
|
||||
|
||||
eop_stakeholder_email = models.EmailField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="EOP Stakeholder Email",
|
||||
)
|
||||
|
||||
# This field is alternately used for generic domain purpose explanations
|
||||
# and for explanations of the specific purpose chosen with feb_purpose_choice
|
||||
# by a Federal Executive Branch agency.
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
{% block form_instructions %}
|
||||
<p>Please read this page. Check the box at the bottom to show that you agree to the requirements for operating a .gov domain.</p>
|
||||
<p>The .gov domain space exists to support a broad diversity of government missions. Generally, we don’t review or audit how government organizations use their registered domains. However, misuse of a .gov domain can reflect upon the integrity of the entire .gov space. There are categories of misuse that are statutorily prohibited or abusive in nature.</p>
|
||||
<p>The .gov domain space exists to support a broad diversity of government missions. Generally, we don’t review or audit how government organizations use their registered domains. However, misuse of a .gov domain can reflect upon the integrity of the entire .gov space. There are categories of misuse that are statutorily prohibited or abusive in nature.</p>
|
||||
|
||||
|
||||
<h2>What you can’t do with a .gov domain</h2>
|
||||
|
@ -52,20 +52,41 @@
|
|||
<p>.Gov domains are registered for a one-year period. To renew your domain, you'll be asked to verify your organization’s eligibility and your contact information. </p>
|
||||
|
||||
<p>Though a domain may expire, it will not automatically be put on hold or deleted. We’ll make extensive efforts to contact your organization before holding or deleting a domain.</p>
|
||||
{% endblock %}
|
||||
|
||||
{% endblock %}
|
||||
{% block form_required_fields_help_text %}
|
||||
{# commented out so it does not appear on this page #}
|
||||
{% endblock %}
|
||||
|
||||
{% block form_fields %}
|
||||
{% if requires_feb_questions %}
|
||||
<h2>Required and prohibited activities</h2>
|
||||
<h3>Prohibitions on non-governmental use</h3>
|
||||
|
||||
{% block form_required_fields_help_text %}
|
||||
{# commented out so it does not appear on this page #}
|
||||
{% endblock %}
|
||||
|
||||
{% block form_fields %}
|
||||
<fieldset class="usa-fieldset">
|
||||
<legend>
|
||||
<h2>Acknowledgement of .gov domain requirements</h2>
|
||||
</legend>
|
||||
<p>Agencies may not use a .gov domain name:
|
||||
<ul class="usa-list">
|
||||
<li>On behalf of a non-federal executive branch entity</li>
|
||||
<li>For a non-governmental purpose</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h3>Compliance with the 21st Century IDEA Act is required</h3>
|
||||
<p>As required by the DOTGOV Act, agencies must ensure
|
||||
that any website or digital service that uses a .gov
|
||||
domain name is in compliance with the
|
||||
<a href="https://digital.gov/resources/delivering-digital-first-public-experience-act/" target="_blank" rel="noopener noreferrer">21st Century Integrated Digital Experience Act</a>.
|
||||
and
|
||||
<a href="https://bidenwhitehouse.gov/wp-content/uploads/2023/09/M-23-22-Delivering-a-Digital-First-Public-Experience.pdf" target="_blank" rel="noopener noreferrer">Guidance for Agencies</a>.
|
||||
</p>
|
||||
<h2>Acknowledgement of .gov domain requirements</h2>
|
||||
{% input_with_errors forms.0.is_policy_acknowledged %}
|
||||
{% else %}
|
||||
<fieldset class="usa-fieldset">
|
||||
<legend>
|
||||
<h2>Acknowledgement of .gov domain requirements</h2>
|
||||
</legend>
|
||||
|
||||
</fieldset>
|
||||
{% input_with_errors forms.0.is_policy_acknowledged %}
|
||||
</fieldset>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -6,16 +6,60 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block form_fields %}
|
||||
{% if requires_feb_questions %}
|
||||
{{forms.2.management_form}}
|
||||
{{forms.3.management_form}}
|
||||
{{forms.4.management_form}}
|
||||
{{forms.5.management_form}}
|
||||
<fieldset class="usa-fieldset">
|
||||
<h2 class="margin-top-0 margin-bottom-0">Are you working with someone in the Executive Office of the President (EOP) on this request?</h2>
|
||||
|
||||
<p class="margin-bottom-0 margin-top-1">
|
||||
<em>Select one. <abbr class="usa-hint usa-hint--required" title="required">*</abbr></em>
|
||||
</p>
|
||||
{% with add_class="usa-radio__input--tile" add_legend_class="usa-sr-only" %}
|
||||
{% input_with_errors forms.0.working_with_eop %}
|
||||
{% endwith %}
|
||||
|
||||
<fieldset class="usa-fieldset">
|
||||
<div id="eop-contact-container" class="conditional-panel display-none">
|
||||
<p class="margin-bottom-0 margin-top-1">
|
||||
Provide the name and email of the person you're working with.<span class="usa-label--required">*</span>
|
||||
</p>
|
||||
{% with add_class="usa-radio__input--tile" add_legend_class="usa-sr-only" %}
|
||||
{% input_with_errors forms.1.first_name %}
|
||||
{% input_with_errors forms.1.last_name %}
|
||||
{% input_with_errors forms.1.email %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
|
||||
<h2 class="margin-top-0 margin-bottom-0">Is there anything else you'd like us to know about your domain request?</h2>
|
||||
<p class="margin-bottom-0 margin-top-1">
|
||||
<em>Select one. <abbr class="usa-hint usa-hint--required" title="required">*</abbr></em>
|
||||
</p>
|
||||
{% with add_class="usa-radio__input--tile" add_legend_class="usa-sr-only" %}
|
||||
{% input_with_errors forms.2.has_anything_else_text %}
|
||||
{% endwith %}
|
||||
|
||||
<div id="anything-else-details-container" class="conditional-panel display-none">
|
||||
<p class="usa-label">
|
||||
<em>Provide details below <span class="usa-label--required">*</span></em>
|
||||
</p>
|
||||
{% with add_label_class="usa-sr-only" attr_required="required" attr_maxlength="2000" %}
|
||||
{% input_with_errors forms.3.anything_else %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
</fieldset>
|
||||
{% else %}
|
||||
<fieldset class="usa-fieldset">
|
||||
<h2 class="margin-top-0 margin-bottom-0">Is there anything else you’d like us to know about your domain request?</h2>
|
||||
</legend>
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
|
||||
<div id="anything-else">
|
||||
<p><em>This question is optional.</em></p>
|
||||
{% with attr_maxlength=2000 add_label_class="usa-sr-only" %}
|
||||
{% input_with_errors forms.0.anything_else %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
<div id="anything-else">
|
||||
<p><em>This question is optional.</em></p>
|
||||
{% with attr_maxlength=2000 add_label_class="usa-sr-only" %}
|
||||
{% input_with_errors forms.0.anything_else %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -2060,6 +2060,10 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
"feb_naming_requirements",
|
||||
"feb_naming_requirements_details",
|
||||
"feb_purpose_choice",
|
||||
"working_with_eop",
|
||||
"eop_stakeholder_first_name",
|
||||
"eop_stakeholder_last_name",
|
||||
"eop_stakeholder_email",
|
||||
"purpose",
|
||||
"has_timeframe",
|
||||
"time_frame_details",
|
||||
|
|
|
@ -2550,7 +2550,7 @@ class DomainRequestTests(TestWithUser, WebTest):
|
|||
|
||||
# @less_console_noise_decorator
|
||||
@override_flag("organization_feature", active=True)
|
||||
def test_domain_request_dotgov_domain_FEB_questions(self):
|
||||
def test_domain_request_FEB_questions(self):
|
||||
"""
|
||||
Test that for a member of a federal executive branch portfolio with org feature on, the dotgov domain page
|
||||
contains additional questions for OMB.
|
||||
|
@ -2612,7 +2612,6 @@ class DomainRequestTests(TestWithUser, WebTest):
|
|||
# separate out these tests for readability
|
||||
self.feb_dotgov_domain_tests(dotgov_page)
|
||||
|
||||
# Now proceed with the actual test
|
||||
domain_form = dotgov_page.forms[0]
|
||||
domain = "test.gov"
|
||||
domain_form["dotgov_domain-requested_domain"] = domain
|
||||
|
@ -2630,6 +2629,36 @@ class DomainRequestTests(TestWithUser, WebTest):
|
|||
|
||||
self.feb_purpose_page_tests(purpose_page)
|
||||
|
||||
purpose_form = purpose_page.forms[0]
|
||||
purpose_form["purpose-feb_purpose_choice"] = "redirect"
|
||||
purpose_form["purpose-purpose"] = "test"
|
||||
purpose_form["purpose-has_timeframe"] = "True"
|
||||
purpose_form["purpose-time_frame_details"] = "test"
|
||||
purpose_form["purpose-is_interagency_initiative"] = "True"
|
||||
purpose_form["purpose-interagency_initiative_details"] = "test"
|
||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||
purpose_result = purpose_form.submit()
|
||||
|
||||
# ---- ADDITIONAL DETAILS PAGE ----
|
||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||
additional_details_page = purpose_result.follow()
|
||||
self.feb_additional_details_page_tests(additional_details_page)
|
||||
|
||||
additional_details_form = additional_details_page.forms[0]
|
||||
additional_details_form["portfolio_additional_details-working_with_eop"] = "True"
|
||||
additional_details_form["portfolio_additional_details-first_name"] = "Testy"
|
||||
additional_details_form["portfolio_additional_details-last_name"] = "Tester"
|
||||
additional_details_form["portfolio_additional_details-email"] = "testy@town.com"
|
||||
additional_details_form["portfolio_additional_details-has_anything_else_text"] = "True"
|
||||
additional_details_form["portfolio_additional_details-anything_else"] = "test"
|
||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||
additional_details_result = additional_details_form.submit()
|
||||
|
||||
# ---- REQUIREMENTS PAGE ----
|
||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||
requirements_page = additional_details_result.follow()
|
||||
self.feb_requirements_page_tests(requirements_page)
|
||||
|
||||
def feb_purpose_page_tests(self, purpose_page):
|
||||
self.assertContains(purpose_page, "What is the purpose of your requested domain?")
|
||||
|
||||
|
@ -2670,6 +2699,40 @@ class DomainRequestTests(TestWithUser, WebTest):
|
|||
# Check that the details form was included
|
||||
self.assertContains(dotgov_page, "feb_naming_requirements_details")
|
||||
|
||||
def feb_additional_details_page_tests(self, additional_details_page):
|
||||
test_text = "Are you working with someone in the Executive Office of the President (EOP) on this request?"
|
||||
self.assertContains(additional_details_page, test_text)
|
||||
|
||||
# Make sure the EOP form is present
|
||||
self.assertContains(additional_details_page, "working_with_eop")
|
||||
|
||||
# Make sure the EOP contact form is present
|
||||
self.assertContains(additional_details_page, "eop-contact-container")
|
||||
self.assertContains(additional_details_page, "additional_details-first_name")
|
||||
self.assertContains(additional_details_page, "additional_details-last_name")
|
||||
self.assertContains(additional_details_page, "additional_details-email")
|
||||
|
||||
# Make sure the additional details form is present
|
||||
self.assertContains(additional_details_page, "additional_details-has_anything_else_text")
|
||||
self.assertContains(additional_details_page, "additional_details-anything_else")
|
||||
|
||||
def feb_requirements_page_tests(self, requirements_page):
|
||||
# Check for the 21st Century IDEA Act links
|
||||
self.assertContains(
|
||||
requirements_page, "https://digital.gov/resources/delivering-digital-first-public-experience-act/"
|
||||
)
|
||||
self.assertContains(
|
||||
requirements_page,
|
||||
"https://bidenwhitehouse.gov/wp-content/uploads/2023/09/M-23-22-Delivering-a-Digital-First-Public-Experience.pdf", # noqa
|
||||
)
|
||||
|
||||
# Check for the policy acknowledgement form
|
||||
self.assertContains(requirements_page, "is_policy_acknowledged")
|
||||
self.assertContains(
|
||||
requirements_page,
|
||||
"I read and understand the guidance outlined in the DOTGOV Act for operating a .gov domain.",
|
||||
)
|
||||
|
||||
@less_console_noise_decorator
|
||||
def test_domain_request_formsets(self):
|
||||
"""Users are able to add more than one of some fields."""
|
||||
|
|
|
@ -603,7 +603,49 @@ class RequestingEntity(DomainRequestWizard):
|
|||
class PortfolioAdditionalDetails(DomainRequestWizard):
|
||||
template_name = "portfolio_domain_request_additional_details.html"
|
||||
|
||||
forms = [forms.PortfolioAnythingElseForm]
|
||||
forms = [
|
||||
feb.WorkingWithEOPYesNoForm,
|
||||
feb.EOPContactForm,
|
||||
feb.FEBAnythingElseYesNoForm,
|
||||
forms.PortfolioAnythingElseForm,
|
||||
]
|
||||
|
||||
def get_context_data(self):
|
||||
context = super().get_context_data()
|
||||
context["requires_feb_questions"] = self.requires_feb_questions()
|
||||
return context
|
||||
|
||||
def is_valid(self, forms: list) -> bool:
|
||||
"""
|
||||
Validates the forms for portfolio additional details.
|
||||
|
||||
Expected order of forms_list:
|
||||
0: WorkingWithEOPYesNoForm
|
||||
1: EOPContactForm
|
||||
2: FEBAnythingElseYesNoForm
|
||||
3: PortfolioAnythingElseForm
|
||||
"""
|
||||
eop_forms_valid = True
|
||||
if not forms[0].is_valid():
|
||||
# If the user isn't working with EOP, don't validate the EOP contact form
|
||||
forms[1].mark_form_for_deletion()
|
||||
eop_forms_valid = False
|
||||
if forms[0].cleaned_data.get("working_with_eop"):
|
||||
eop_forms_valid = forms[1].is_valid()
|
||||
else:
|
||||
forms[1].mark_form_for_deletion()
|
||||
anything_else_forms_valid = True
|
||||
if not forms[2].is_valid():
|
||||
forms[3].mark_form_for_deletion()
|
||||
anything_else_forms_valid = False
|
||||
if forms[2].cleaned_data.get("has_anything_else_text"):
|
||||
forms[3].fields["anything_else"].required = True
|
||||
forms[3].fields["anything_else"].error_messages[
|
||||
"required"
|
||||
] = "Please provide additional details you'd like us to know. \
|
||||
If you have nothing to add, select 'No'."
|
||||
anything_else_forms_valid = forms[3].is_valid()
|
||||
return eop_forms_valid and anything_else_forms_valid
|
||||
|
||||
|
||||
# Non-portfolio pages
|
||||
|
@ -887,6 +929,29 @@ class Requirements(DomainRequestWizard):
|
|||
template_name = "domain_request_requirements.html"
|
||||
forms = [forms.RequirementsForm]
|
||||
|
||||
def get_context_data(self):
|
||||
context = super().get_context_data()
|
||||
context["requires_feb_questions"] = self.requires_feb_questions()
|
||||
return context
|
||||
|
||||
# Override the get_forms method to set the policy acknowledgement label conditionally based on feb status
|
||||
def get_forms(self, step=None, use_post=False, use_db=False, files=None):
|
||||
forms_list = super().get_forms(step, use_post, use_db, files)
|
||||
|
||||
# Pass the is_federal context to the form
|
||||
for form in forms_list:
|
||||
if isinstance(form, forms.RequirementsForm):
|
||||
if self.requires_feb_questions():
|
||||
form.fields["is_policy_acknowledged"].label = (
|
||||
"I read and understand the guidance outlined in the DOTGOV Act for operating a .gov domain." # noqa: E501
|
||||
)
|
||||
else:
|
||||
form.fields["is_policy_acknowledged"].label = (
|
||||
"I read and agree to the requirements for operating a .gov domain." # noqa: E501
|
||||
)
|
||||
|
||||
return forms_list
|
||||
|
||||
|
||||
class Review(DomainRequestWizard):
|
||||
template_name = "domain_request_review.html"
|
||||
|
@ -899,6 +964,7 @@ class Review(DomainRequestWizard):
|
|||
context = super().get_context_data()
|
||||
context["Step"] = self.get_step_enum().__members__
|
||||
context["domain_request"] = self.domain_request
|
||||
context["requires_feb_questions"] = self.requires_feb_questions()
|
||||
return context
|
||||
|
||||
def goto_next_step(self):
|
||||
|
|
|
@ -13,7 +13,7 @@ defusedxml==0.7.1; python_version >= '2.7' and python_version not in '3.0, 3.1,
|
|||
diff-match-patch==20241021; python_version >= '3.7'
|
||||
dj-database-url==2.3.0
|
||||
dj-email-url==1.0.6
|
||||
django==4.2.17; python_version >= '3.8'
|
||||
django==4.2.20; python_version >= '3.8'
|
||||
django-admin-multiple-choice-list-filter==0.1.1
|
||||
django-allow-cidr==0.7.1
|
||||
django-auditlog==3.0.0; python_version >= '3.8'
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue