Display federal and election questions conditionally

This commit is contained in:
Neil Martinsen-Burrell 2022-11-23 13:25:11 -06:00
parent e746cb2adc
commit 3fe00d1980
No known key found for this signature in database
GPG key ID: 6A3C818CC10D0184
4 changed files with 125 additions and 50 deletions

View file

@ -10,12 +10,14 @@ from django.urls import include, path
from django.views.generic import RedirectView
from registrar.views import health, index, profile, whoami
from registrar.forms import ApplicationWizard
from registrar.forms import ApplicationWizard, WIZARD_CONDITIONS
from api.views import available
APPLICATION_URL_NAME = "application_step"
application_wizard = ApplicationWizard.as_view(
url_name=APPLICATION_URL_NAME, done_step_name="finished"
url_name=APPLICATION_URL_NAME,
done_step_name="finished",
condition_dict=WIZARD_CONDITIONS,
)
urlpatterns = [

View file

@ -1,4 +1,4 @@
from .edit_profile import EditProfileForm
from .application_wizard import ApplicationWizard
from .application_wizard import ApplicationWizard, WIZARD_CONDITIONS
__all__ = ["EditProfileForm", "ApplicationWizard"]
__all__ = ["EditProfileForm", "ApplicationWizard", "WIZARD_CONDITIONS"]

View file

@ -1,5 +1,7 @@
"""Forms Wizard for creating a new domain application."""
from __future__ import annotations # allows forward references in annotations
import logging
from django import forms
@ -52,19 +54,6 @@ class OrganizationTypeForm(RegistrarForm):
],
widget=forms.RadioSelect,
)
federal_type = forms.ChoiceField(
required=False,
choices=DomainApplication.BRANCH_CHOICES,
widget=forms.RadioSelect,
)
is_election_board = forms.ChoiceField(
required=False,
choices=[
("Yes", "Yes"),
("No", "No"),
],
widget=forms.RadioSelect(attrs={"class": "usa-radio__input"}),
)
class OrganizationFederalForm(RegistrarForm):
@ -82,7 +71,8 @@ class OrganizationElectionForm(RegistrarForm):
(True, "Yes"),
(False, "No"),
],
)
),
required=False
)
@ -297,6 +287,41 @@ TITLES = {
}
def _get_organization_type(wizard: ApplicationWizard) -> Union[str, None]:
"""Extract the answer to the organization type question from the wizard."""
# using the step data from the storage is a workaround for this
# bug in django-formtools version 2.4
# https://github.com/jazzband/django-formtools/issues/220
type_data = wizard.storage.get_step_data("organization_type")
if type_data:
return type_data.get("organization_type-organization_type")
return None
def show_organization_federal(wizard: ApplicationWizard) -> Bool:
"""Show this step if the answer to the first question was "federal"."""
return _get_organization_type(wizard) == "Federal"
def show_organization_election(wizard: ApplicationWizard) -> Bool:
"""Show this step if the answer to the first question implies it.
This shows for answers that aren't "Federal" or "Interstate".
"""
type_answer = _get_organization_type(wizard)
if type_answer and type_answer not in ("Federal", "Interstate"):
return True
return False
# We can use a dictionary with step names and callables that return booleans
# to show or hide particular steps based on the state of the process.
WIZARD_CONDITIONS = {
"organization_federal": show_organization_federal,
"organization_election": show_organization_election,
}
class ApplicationWizard(LoginRequiredMixin, NamedUrlSessionWizardView):
"""Multi-page form ("wizard") for new domain applications.
@ -330,12 +355,16 @@ class ApplicationWizard(LoginRequiredMixin, NamedUrlSessionWizardView):
organization_type_data = form_dict["organization_type"].cleaned_data
application.organization_type = organization_type_data["organization_type"]
# federal branch information
federal_branch_data = form_dict["organization_federal"].cleaned_data
# federal branch information may not exist
federal_branch_data = form_dict.get("organization_federal")
if federal_branch_data is not None:
federal_branch_data = federal_branch_data.cleaned_data
application.federal_branch = federal_branch_data["federal_type"]
# election board information
election_board_data = form_dict["organization_election"].cleaned_data
# election board information may not exist.
election_board_data = form_dict.get("organization_election")
if election_board_data is not None:
election_board_data = election_board_data.cleaned_data
application.is_election_office = election_board_data["is_election_board"]
# contact information

View file

@ -6,6 +6,7 @@ from django.contrib.auth import get_user_model
from django_webtest import WebTest # type: ignore
from registrar.models import DomainApplication
from registrar.forms.application_wizard import TITLES
class TestViews(TestCase):
@ -96,15 +97,6 @@ class FormTests(TestWithUser, WebTest):
result = page.form.submit()
self.assertIn("What kind of government organization do you represent?", result)
def test_application_form_organization(self):
# 302 redirect to the first form
page = self.app.get(reverse("application")).follow()
form = page.form
form["organization_type-organization_type"] = "Federal"
result = page.form.submit().follow()
# Got the next form page
self.assertContains(result, "contact information")
def test_application_form_submission(self):
"""Can fill out the entire form and submit.
As we add additional form pages, we need to include them here to make
@ -130,10 +122,10 @@ class FormTests(TestWithUser, WebTest):
self.assertEquals(type_result.status_code, 302)
self.assertEquals(type_result["Location"], "/register/organization_federal/")
# TODO: In the future this should be conditionally dispalyed based on org type
# ---- FEDERAL BRANCH PAGE ----
# Follow the redirect to the next form page
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
federal_page = type_result.follow()
federal_form = federal_page.form
federal_form["organization_federal-federal_type"] = "Executive"
@ -144,26 +136,12 @@ class FormTests(TestWithUser, WebTest):
self.assertEquals(federal_result.status_code, 302)
self.assertEquals(
federal_result["Location"], "/register/organization_election/"
)
# ---- ELECTION BOARD BRANCH PAGE ----
# Follow the redirect to the next form page
election_page = federal_result.follow()
election_form = election_page.form
election_form["organization_election-is_election_board"] = True
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
election_result = election_form.submit()
self.assertEquals(election_result.status_code, 302)
self.assertEquals(
election_result["Location"], "/register/organization_contact/"
federal_result["Location"], "/register/organization_contact/"
)
# ---- ORG CONTACT PAGE ----
# Follow the redirect to the next form page
org_contact_page = election_result.follow()
org_contact_page = federal_result.follow()
org_contact_form = org_contact_page.form
org_contact_form["organization_contact-organization_name"] = "Testorg"
org_contact_form["organization_contact-address_line1"] = "address 1"
@ -322,3 +300,69 @@ class FormTests(TestWithUser, WebTest):
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
final_result = review_result.follow()
self.assertContains(final_result, "Thank you for your domain request")
def test_application_form_conditional_federal(self):
"""Federal branch question is shown for federal organizations."""
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 PAGE ----
# the conditional step titles shouldn't appear initially
self.assertNotContains(type_page, TITLES["organization_federal"])
self.assertNotContains(type_page, TITLES["organization_election"])
type_form = type_page.form
type_form["organization_type-organization_type"] = "Federal"
# set the session ID before .submit()
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
type_result = type_form.submit()
# the post request should return a redirect to the federal branch
# question
self.assertEquals(type_result.status_code, 302)
self.assertEquals(type_result["Location"], "/register/organization_federal/")
# and the step label should appear in the sidebar of the resulting page
# but the step label for the elections page should not appear
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
federal_page = type_result.follow()
self.assertContains(federal_page, TITLES["organization_federal"])
self.assertNotContains(federal_page, TITLES["organization_election"])
def test_application_form_conditional_elections(self):
"""Election question is shown for other organizations."""
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 PAGE ----
# the conditional step titles shouldn't appear initially
self.assertNotContains(type_page, TITLES["organization_federal"])
self.assertNotContains(type_page, TITLES["organization_election"])
type_form = type_page.form
type_form["organization_type-organization_type"] = "County"
# set the session ID before .submit()
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
type_result = type_form.submit()
# the post request should return a redirect to the federal branch
# question
self.assertEquals(type_result.status_code, 302)
self.assertEquals(type_result["Location"], "/register/organization_election/")
# and the step label should appear in the sidebar of the resulting page
# but the step label for the elections page should not appear
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
election_page = type_result.follow()
self.assertContains(election_page, TITLES["organization_election"])
self.assertNotContains(election_page, TITLES["organization_federal"])