mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-21 18:25:58 +02:00
Unrecognized tribal government more explanation
This commit is contained in:
parent
2c66b3728e
commit
2cd53dc4c8
6 changed files with 148 additions and 6 deletions
|
@ -25,6 +25,7 @@ for step, view in [
|
||||||
# add/remove steps here
|
# add/remove steps here
|
||||||
(Step.ORGANIZATION_TYPE, views.OrganizationType),
|
(Step.ORGANIZATION_TYPE, views.OrganizationType),
|
||||||
(Step.TRIBAL_GOVERNMENT, views.TribalGovernment),
|
(Step.TRIBAL_GOVERNMENT, views.TribalGovernment),
|
||||||
|
(Step.TRIBAL_EXPLANATION, views.TribalExplanation),
|
||||||
(Step.ORGANIZATION_FEDERAL, views.OrganizationFederal),
|
(Step.ORGANIZATION_FEDERAL, views.OrganizationFederal),
|
||||||
(Step.ORGANIZATION_ELECTION, views.OrganizationElection),
|
(Step.ORGANIZATION_ELECTION, views.OrganizationElection),
|
||||||
(Step.ORGANIZATION_CONTACT, views.OrganizationContact),
|
(Step.ORGANIZATION_CONTACT, views.OrganizationContact),
|
||||||
|
|
|
@ -83,11 +83,26 @@ class TribalGovernmentForm(RegistrarForm):
|
||||||
error_messages={"required": "Enter the tribe you represent."},
|
error_messages={"required": "Enter the tribe you represent."},
|
||||||
)
|
)
|
||||||
|
|
||||||
def clean(self):
|
|
||||||
"""Needs to be either state or federally recognized."""
|
class TribalExplanationForm(RegistrarForm):
|
||||||
if not (self.cleaned_data["federally_recognized_tribe"] or
|
|
||||||
self.cleaned_data["state_recognized_tribe"]):
|
# this overloads `more_organization_information` by using the existing field
|
||||||
raise forms.ValidationError("Only tribes recognized by the U.S. federal government or by a U.S. state government are eligible for .gov domains.", code="invalid")
|
# on the domain application object on a second form.
|
||||||
|
more_organization_information = forms.CharField(
|
||||||
|
# label has to end in a space to get the label_suffix to show
|
||||||
|
label=(
|
||||||
|
"Only tribes recognized by the U.S. federal government or by a"
|
||||||
|
" U.S. state government are eligible for .gov domains. Please tell"
|
||||||
|
" us more about your tribe and why you want a .gov domain. "
|
||||||
|
),
|
||||||
|
label_suffix=REQUIRED_SUFFIX,
|
||||||
|
widget=forms.Textarea(),
|
||||||
|
error_messages={
|
||||||
|
"required": (
|
||||||
|
"Please tell us more about your tribe and why you want a .gov domain."
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class OrganizationFederalForm(RegistrarForm):
|
class OrganizationFederalForm(RegistrarForm):
|
||||||
|
|
|
@ -495,6 +495,17 @@ class DomainApplication(TimeStampedModel):
|
||||||
user_choice = self.organization_type
|
user_choice = self.organization_type
|
||||||
return user_choice == DomainApplication.OrganizationChoices.TRIBAL
|
return user_choice == DomainApplication.OrganizationChoices.TRIBAL
|
||||||
|
|
||||||
|
def show_tribal_explanation(self) -> bool:
|
||||||
|
"""Show this step if the tribe is not federally or state recognized."""
|
||||||
|
user_choice = self.organization_type
|
||||||
|
if (user_choice == DomainApplication.OrganizationChoices.TRIBAL):
|
||||||
|
# did answer tribal, check the recognition answers
|
||||||
|
if self.federally_recognized_tribe is not None and self.state_recognized_tribe is not None:
|
||||||
|
# have answered these questions
|
||||||
|
if not self.federally_recognized_tribe and not self.state_recognized_tribe:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def show_organization_election(self) -> bool:
|
def show_organization_election(self) -> bool:
|
||||||
"""Show this step if the answer to the first question implies it.
|
"""Show this step if the answer to the first question implies it.
|
||||||
|
|
||||||
|
|
45
src/registrar/templates/application_tribal_explanation.html
Normal file
45
src/registrar/templates/application_tribal_explanation.html
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<!-- Test page -->
|
||||||
|
{% extends 'application_form.html' %}
|
||||||
|
|
||||||
|
{% block form_content %}
|
||||||
|
{% load widget_tweaks dynamic_question_tags field_helpers %}
|
||||||
|
|
||||||
|
{% include "includes/required_fields.html" %}
|
||||||
|
|
||||||
|
<form id="step__{{steps.current}}" class="usa-form usa-form--large" method="post" novalidate>
|
||||||
|
<div class="usa-form-group">
|
||||||
|
{% csrf_token %}
|
||||||
|
|
||||||
|
<div class="usa-character-count">
|
||||||
|
{% with field=forms.0.more_organization_information %}
|
||||||
|
{% if field.errors %}
|
||||||
|
<div class="usa-form-group usa-form-group--error">
|
||||||
|
{{ field|add_label_class:"usa-label usa-label--error" }}
|
||||||
|
{% for error in field.errors %}
|
||||||
|
<span class="usa-error-message" id="input-error-message" role="alert">
|
||||||
|
{{ error }}
|
||||||
|
</span>
|
||||||
|
{% endfor %}
|
||||||
|
{{ field|add_class:"usa-input--error usa-textarea usa-character-count__field"|attr:"aria-describedby:instructions"|attr:"maxlength=500"|attr:"aria-invalid:true" }}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
{{ field|add_label_class:"usa-label" }}
|
||||||
|
{{ field|add_class:"usa-textarea usa-character-count__field"|attr:"aria-describedby:instructions"|attr:"maxlength=500" }}
|
||||||
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
|
<span class="usa-character-count__message" id="with-hint-textarea-info with-hint-textarea-hint"> You c
|
||||||
|
an enter up to 500 characters </span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{# don't use the super-block's buttons? {{ block.super }} #}
|
||||||
|
<div class="stepnav">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="usa-button"
|
||||||
|
>Submit your domain request</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
|
@ -120,7 +120,7 @@ class DomainApplicationTests(TestWithUser, WebTest):
|
||||||
this test work.
|
this test work.
|
||||||
"""
|
"""
|
||||||
num_pages_tested = 0
|
num_pages_tested = 0
|
||||||
SKIPPED_PAGES = 3 # elections, type_of_work, tribal_government
|
SKIPPED_PAGES = 4 # elections, type_of_work, tribal_government, tribal_explanation
|
||||||
num_pages = len(self.TITLES) - SKIPPED_PAGES
|
num_pages = len(self.TITLES) - SKIPPED_PAGES
|
||||||
|
|
||||||
type_page = self.app.get(reverse("application:")).follow()
|
type_page = self.app.get(reverse("application:")).follow()
|
||||||
|
@ -742,6 +742,12 @@ class DomainApplicationTests(TestWithUser, WebTest):
|
||||||
|
|
||||||
def test_application_tribal_government(self):
|
def test_application_tribal_government(self):
|
||||||
"""Tribal organizations have to answer an additional question."""
|
"""Tribal organizations have to answer an additional question."""
|
||||||
|
type_page = self.app.get(reverse("application:")).follow()
|
||||||
|
# django-webtest does not handle cookie-based sessions well because it keeps
|
||||||
|
# resetting the session key on each new request, thus destroying the concept
|
||||||
|
# of a "session". We are going to do it manually, saving the session ID here
|
||||||
|
# and then setting the cookie on each request.
|
||||||
|
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
|
||||||
type_form = type_page.form
|
type_form = type_page.form
|
||||||
type_form[
|
type_form[
|
||||||
"organization_type-organization_type"
|
"organization_type-organization_type"
|
||||||
|
@ -757,6 +763,44 @@ class DomainApplicationTests(TestWithUser, WebTest):
|
||||||
# and the step is on the sidebar list.
|
# and the step is on the sidebar list.
|
||||||
self.assertContains(tribal_government_page, self.TITLES[Step.TRIBAL_GOVERNMENT])
|
self.assertContains(tribal_government_page, self.TITLES[Step.TRIBAL_GOVERNMENT])
|
||||||
|
|
||||||
|
def test_application_tribal_explanation(self):
|
||||||
|
"""Unrecognized tribes have to answer an additional question."""
|
||||||
|
type_page = self.app.get(reverse("application:")).follow()
|
||||||
|
# django-webtest does not handle cookie-based sessions well because it keeps
|
||||||
|
# resetting the session key on each new request, thus destroying the concept
|
||||||
|
# of a "session". We are going to do it manually, saving the session ID here
|
||||||
|
# and then setting the cookie on each request.
|
||||||
|
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
|
||||||
|
type_form = type_page.form
|
||||||
|
type_form[
|
||||||
|
"organization_type-organization_type"
|
||||||
|
] = DomainApplication.OrganizationChoices.TRIBAL
|
||||||
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
|
type_result = type_page.form.submit()
|
||||||
|
# the tribal government page comes immediately afterwards
|
||||||
|
self.assertIn("/tribal_government", type_result.headers["Location"])
|
||||||
|
# follow first redirect
|
||||||
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
|
tribal_government_page = type_result.follow()
|
||||||
|
|
||||||
|
# Enter a tribe name but don't check either state or federal recognition
|
||||||
|
tribal_government_page.form["tribal_government-tribe_name"] = "Tribe name"
|
||||||
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
|
tribal_government_result = tribal_government_page.form.submit()
|
||||||
|
|
||||||
|
# should be a redirect to tribal_more_information
|
||||||
|
self.assertIn("/tribal_more_information", tribal_government_result.headers["Location"])
|
||||||
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
|
tribal_more_information_page = tribal_government_result.follow()
|
||||||
|
|
||||||
|
# put an explanation and submit
|
||||||
|
tribal_more_information_page.form["tribal_more_information-more_organization_information"] = "Some explanation"
|
||||||
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
|
result = tribal_more_information_page.form.submit()
|
||||||
|
# result should be a success
|
||||||
|
self.assertEqual(result.status_code, 200)
|
||||||
|
|
||||||
|
|
||||||
def test_application_ao_dynamic_text(self):
|
def test_application_ao_dynamic_text(self):
|
||||||
type_page = self.app.get(reverse("application:")).follow()
|
type_page = self.app.get(reverse("application:")).follow()
|
||||||
# django-webtest does not handle cookie-based sessions well because it keeps
|
# django-webtest does not handle cookie-based sessions well because it keeps
|
||||||
|
|
|
@ -25,6 +25,7 @@ class Step(StrEnum):
|
||||||
|
|
||||||
ORGANIZATION_TYPE = "organization_type"
|
ORGANIZATION_TYPE = "organization_type"
|
||||||
TRIBAL_GOVERNMENT = "tribal_government"
|
TRIBAL_GOVERNMENT = "tribal_government"
|
||||||
|
TRIBAL_EXPLANATION = "tribal_more_information"
|
||||||
ORGANIZATION_FEDERAL = "organization_federal"
|
ORGANIZATION_FEDERAL = "organization_federal"
|
||||||
ORGANIZATION_ELECTION = "organization_election"
|
ORGANIZATION_ELECTION = "organization_election"
|
||||||
ORGANIZATION_CONTACT = "organization_contact"
|
ORGANIZATION_CONTACT = "organization_contact"
|
||||||
|
@ -70,6 +71,7 @@ class ApplicationWizard(LoginRequiredMixin, TemplateView):
|
||||||
TITLES = {
|
TITLES = {
|
||||||
Step.ORGANIZATION_TYPE: _("Type of organization"),
|
Step.ORGANIZATION_TYPE: _("Type of organization"),
|
||||||
Step.TRIBAL_GOVERNMENT: _("Tribal government"),
|
Step.TRIBAL_GOVERNMENT: _("Tribal government"),
|
||||||
|
Step.TRIBAL_EXPLANATION: _("More Information - Tribal government"),
|
||||||
Step.ORGANIZATION_FEDERAL: _("Type of organization — Federal"),
|
Step.ORGANIZATION_FEDERAL: _("Type of organization — Federal"),
|
||||||
Step.ORGANIZATION_ELECTION: _("Type of organization — Election board"),
|
Step.ORGANIZATION_ELECTION: _("Type of organization — Election board"),
|
||||||
Step.ORGANIZATION_CONTACT: _("Organization name and mailing address"),
|
Step.ORGANIZATION_CONTACT: _("Organization name and mailing address"),
|
||||||
|
@ -97,6 +99,9 @@ class ApplicationWizard(LoginRequiredMixin, TemplateView):
|
||||||
Step.TRIBAL_GOVERNMENT: lambda w: w.from_model(
|
Step.TRIBAL_GOVERNMENT: lambda w: w.from_model(
|
||||||
"show_tribal_government", False
|
"show_tribal_government", False
|
||||||
),
|
),
|
||||||
|
Step.TRIBAL_EXPLANATION: lambda w: w.from_model(
|
||||||
|
"show_tribal_explanation", False
|
||||||
|
),
|
||||||
Step.ORGANIZATION_ELECTION: lambda w: w.from_model(
|
Step.ORGANIZATION_ELECTION: lambda w: w.from_model(
|
||||||
"show_organization_election", False
|
"show_organization_election", False
|
||||||
),
|
),
|
||||||
|
@ -346,6 +351,27 @@ class TribalGovernment(ApplicationWizard):
|
||||||
forms = [forms.TribalGovernmentForm]
|
forms = [forms.TribalGovernmentForm]
|
||||||
|
|
||||||
|
|
||||||
|
class TribalExplanation(ApplicationWizard):
|
||||||
|
template_name = "application_tribal_explanation.html"
|
||||||
|
forms = [forms.TribalExplanationForm]
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
"""Custom submit method to skip directly to submit at this point."""
|
||||||
|
forms = self.get_forms(use_post=True)
|
||||||
|
if self.is_valid(forms):
|
||||||
|
# always save progress
|
||||||
|
self.save(forms)
|
||||||
|
else:
|
||||||
|
# unless there are errors
|
||||||
|
context = self.get_context_data()
|
||||||
|
context["forms"] = forms
|
||||||
|
return render(request, self.template_name, context)
|
||||||
|
|
||||||
|
# don't go to next step
|
||||||
|
# return self.goto_next_step()
|
||||||
|
return self.done()
|
||||||
|
|
||||||
|
|
||||||
class OrganizationFederal(ApplicationWizard):
|
class OrganizationFederal(ApplicationWizard):
|
||||||
template_name = "application_org_federal.html"
|
template_name = "application_org_federal.html"
|
||||||
forms = [forms.OrganizationFederalForm]
|
forms = [forms.OrganizationFederalForm]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue