We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Remove auto-forward for single-verifier agencies
In #337 we introduced handling for an eligibility verifier selection form, which supports choosing between e.g. verifying eligibility with Login.gov or with a Courtesy Card. We also added [a shortcut](https://github.com/cal-itp/benefits/blob/dev/benefits/eligibility/views.py#L77) for when an agency has only a single verifier -- to bypass this form and go straight to the next step in the flow.

We want to have a consistent user experience regardless of the number of verifiers, and so it's time to remove this shortcut and always show the verifier selection page, even with only 1 option.

## Acceptance Criteria

<!-- Remember to consider edge cases -->

- [ ] The user must always choose a verifier on `/eligibility`, regardless of the number of verifiers there are to choose from

## Additional context

Design sign-off on this approach: https://cal-itp.slack.com/archives/C013W8RUAMU/p1673542656882989


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `benefits/eligibility/views.py`
Content:
```
1 """
2 The eligibility application: view definitions for the eligibility verification flow.
3 """
4 from django.contrib import messages
5 from django.shortcuts import redirect
6 from django.template.response import TemplateResponse
7 from django.urls import reverse
8 from django.utils.decorators import decorator_from_middleware
9 from django.utils.html import format_html
10 from django.utils.translation import pgettext, gettext as _
11 
12 from benefits.core import recaptcha, session, viewmodels
13 from benefits.core.middleware import AgencySessionRequired, LoginRequired, RateLimit, RecaptchaEnabled, VerifierSessionRequired
14 from benefits.core.models import EligibilityVerifier
15 from benefits.core.views import ROUTE_HELP
16 from . import analytics, forms, verify
17 
18 
19 ROUTE_INDEX = "eligibility:index"
20 ROUTE_START = "eligibility:start"
21 ROUTE_LOGIN = "oauth:login"
22 ROUTE_CONFIRM = "eligibility:confirm"
23 ROUTE_UNVERIFIED = "eligibility:unverified"
24 ROUTE_ENROLLMENT = "enrollment:index"
25 
26 TEMPLATE_INDEX = "eligibility/index.html"
27 TEMPLATE_START = "eligibility/start.html"
28 TEMPLATE_CONFIRM = "eligibility/confirm.html"
29 TEMPLATE_UNVERIFIED = "eligibility/unverified.html"
30 
31 
32 @decorator_from_middleware(AgencySessionRequired)
33 @decorator_from_middleware(RecaptchaEnabled)
34 def index(request):
35     """View handler for the eligibility verifier selection form."""
36 
37     session.update(request, eligibility_types=[], origin=reverse(ROUTE_INDEX))
38     agency = session.agency(request)
39 
40     eligibility_start = reverse(ROUTE_START)
41 
42     help_page = reverse(ROUTE_HELP)
43 
44     agency_intro = _(agency.eligibility_index_intro) if isinstance(agency.eligibility_index_intro, str) else ""
45     common_intro = _("eligibility.pages.index.p[0]%(info_link)s") % {"info_link": f"{help_page}#what-is-cal-itp"}
46     intro = format_html(agency_intro + common_intro)
47     page = viewmodels.Page(
48         title=_("eligibility.pages.index.title"),
49         headline=_("eligibility.pages.index.headline"),
50         paragraphs=[intro],
51         forms=forms.EligibilityVerifierSelectionForm(agency=agency),
52     )
53 
54     ctx = page.context_dict()
55     ctx["help_page"] = help_page
56     ctx["help_text"] = format_html(_("eligibility.pages.index.help_text%(help_link)s") % {"help_link": help_page})
57 
58     if request.method == "POST":
59         form = forms.EligibilityVerifierSelectionForm(data=request.POST, agency=agency)
60 
61         if form.is_valid():
62             verifier_id = form.cleaned_data.get("verifier")
63             verifier = EligibilityVerifier.objects.get(id=verifier_id)
64             session.update(request, verifier=verifier)
65 
66             types_to_verify = agency.type_names_to_verify(verifier)
67             analytics.selected_verifier(request, types_to_verify)
68 
69             response = redirect(eligibility_start)
70         else:
71             # form was not valid, allow for correction/resubmission
72             if recaptcha.has_error(form):
73                 messages.error(request, "Recaptcha failed. Please try again.")
74             page.forms = [form]
75             response = TemplateResponse(request, TEMPLATE_INDEX, ctx)
76     else:
77         if agency.eligibility_verifiers.count() == 1:
78             verifier = agency.eligibility_verifiers.first()
79             session.update(request, verifier=verifier)
80             response = redirect(eligibility_start)
81         else:
82             response = TemplateResponse(request, TEMPLATE_INDEX, ctx)
83 
84     return response
85 
86 
87 @decorator_from_middleware(AgencySessionRequired)
88 @decorator_from_middleware(VerifierSessionRequired)
89 def start(request):
90     """View handler for the eligibility verification getting started screen."""
91 
92     verifier = session.verifier(request)
93     button = viewmodels.Button.primary(text=_("eligibility.buttons.continue"), url=reverse(ROUTE_CONFIRM))
94 
95     # define the verifier-specific required item
96     identity_item = viewmodels.MediaItem(
97         icon=viewmodels.Icon("idcardcheck", pgettext("image alt text", "core.icons.idcardcheck")),
98         heading=_(verifier.start_item_heading),
99         details=_(verifier.start_item_details),
100     )
101 
102     if verifier.is_auth_required:
103         if verifier.uses_auth_verification:
104             identity_item.bullets = [
105                 _("eligibility.pages.start.login_gov.required_items[0]"),
106                 _("eligibility.pages.start.login_gov.required_items[1]"),
107                 _("eligibility.pages.start.login_gov.required_items[2]"),
108             ]
109 
110         if not session.logged_in(request):
111             button = viewmodels.Button.login(
112                 text=_(verifier.auth_provider.sign_in_button_label),
113                 url=reverse(ROUTE_LOGIN),
114             )
115 
116     # define the bank card item
117     bank_card_item = viewmodels.MediaItem(
118         icon=viewmodels.Icon("bankcardcheck", pgettext("image alt text", "core.icons.bankcardcheck")),
119         heading=_("eligibility.pages.start.bankcard.title"),
120         details=_("eligibility.pages.start.bankcard.text"),
121     )
122 
123     media = [identity_item, bank_card_item]
124 
125     page = viewmodels.Page(
126         title=_(verifier.start_title),
127         headline=_(verifier.start_headline),
128         button=button,
129     )
130 
131     ctx = page.context_dict()
132     ctx["previous_page_button"] = viewmodels.Button.previous_page(url=reverse(ROUTE_INDEX))
133     ctx["start_sub_headline"] = _("eligibility.pages.start.sub_headline")
134     ctx["media"] = media
135     help_page = reverse(ROUTE_HELP)
136     ctx["help_link"] = f"{help_page}#{verifier.start_help_anchor}"
137 
138     # update origin now, after we've saved the previous page
139     session.update(request, eligibility_types=[], origin=reverse(ROUTE_START))
140 
141     return TemplateResponse(request, TEMPLATE_START, ctx)
142 
143 
144 @decorator_from_middleware(AgencySessionRequired)
145 @decorator_from_middleware(LoginRequired)
146 @decorator_from_middleware(RateLimit)
147 @decorator_from_middleware(RecaptchaEnabled)
148 @decorator_from_middleware(VerifierSessionRequired)
149 def confirm(request):
150     """View handler for the eligibility verification form."""
151 
152     # GET from an already verified user, no need to verify again
153     if request.method == "GET" and session.eligible(request):
154         eligibility = session.eligibility(request)
155         return verified(request, [eligibility.name])
156 
157     unverified_view = reverse(ROUTE_UNVERIFIED)
158 
159     agency = session.agency(request)
160     verifier = session.verifier(request)
161     types_to_verify = agency.type_names_to_verify(verifier)
162 
163     # GET for OAuth verification
164     if request.method == "GET" and verifier.uses_auth_verification:
165         analytics.started_eligibility(request, types_to_verify)
166 
167         verified_types = verify.eligibility_from_oauth(verifier, session.oauth_claim(request), agency)
168         if verified_types:
169             return verified(request, verified_types)
170         else:
171             return redirect(unverified_view)
172 
173     # GET/POST for Eligibility API verification
174     page = viewmodels.Page(
175         title=_(verifier.form_title),
176         headline=_(verifier.form_headline),
177         paragraphs=[_(verifier.form_blurb)],
178         form=forms.EligibilityVerificationForm(auto_id=True, label_suffix="", verifier=verifier),
179     )
180 
181     ctx = page.context_dict()
182     ctx["previous_page_button"] = viewmodels.Button.previous_page(url=reverse(ROUTE_START))
183 
184     # GET from an unverified user, present the form
185     if request.method == "GET":
186         return TemplateResponse(request, TEMPLATE_CONFIRM, ctx)
187     # POST form submission, process form data, make Eligibility Verification API call
188     elif request.method == "POST":
189         analytics.started_eligibility(request, types_to_verify)
190 
191         form = forms.EligibilityVerificationForm(data=request.POST, verifier=verifier)
192         # form was not valid, allow for correction/resubmission
193         if not form.is_valid():
194             if recaptcha.has_error(form):
195                 messages.error(request, "Recaptcha failed. Please try again.")
196 
197             page.forms = [form]
198             ctx.update(page.context_dict())
199             return TemplateResponse(request, TEMPLATE_CONFIRM, ctx)
200 
201         # form is valid, make Eligibility Verification request to get the verified types
202         verified_types = verify.eligibility_from_api(verifier, form, agency)
203 
204         # form was not valid, allow for correction/resubmission
205         if verified_types is None:
206             analytics.returned_error(request, types_to_verify, form.errors)
207             page.forms = [form]
208             ctx.update(page.context_dict())
209             return TemplateResponse(request, TEMPLATE_CONFIRM, ctx)
210         # no types were verified
211         elif len(verified_types) == 0:
212             return redirect(unverified_view)
213         # type(s) were verified
214         else:
215             return verified(request, verified_types)
216 
217 
218 @decorator_from_middleware(AgencySessionRequired)
219 @decorator_from_middleware(LoginRequired)
220 def verified(request, verified_types):
221     """View handler for the verified eligibility page."""
222 
223     analytics.returned_success(request, verified_types)
224 
225     session.update(request, eligibility_types=verified_types)
226 
227     return redirect(ROUTE_ENROLLMENT)
228 
229 
230 @decorator_from_middleware(AgencySessionRequired)
231 @decorator_from_middleware(VerifierSessionRequired)
232 def unverified(request):
233     """View handler for the unverified eligibility page."""
234 
235     agency = session.agency(request)
236     verifier = session.verifier(request)
237     types_to_verify = agency.type_names_to_verify(verifier)
238 
239     analytics.returned_fail(request, types_to_verify)
240 
241     # tel: link to agency phone number
242     buttons = viewmodels.Button.agency_contact_links(agency)
243     buttons.append(viewmodels.Button.home(request))
244 
245     page = viewmodels.Page(
246         title=_(verifier.unverified_title),
247         headline=_("eligibility.pages.unverified.headline"),
248         icon=viewmodels.Icon("idcardquestion", pgettext("image alt text", "core.icons.idcardquestion")),
249         paragraphs=[_(verifier.unverified_blurb)],
250         buttons=buttons,
251     )
252 
253     return TemplateResponse(request, TEMPLATE_UNVERIFIED, page.context_dict())
254
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/benefits/eligibility/views.py b/benefits/eligibility/views.py
--- a/benefits/eligibility/views.py
+++ b/benefits/eligibility/views.py
@@ -74,12 +74,7 @@
             page.forms = [form]
             response = TemplateResponse(request, TEMPLATE_INDEX, ctx)
     else:
-        if agency.eligibility_verifiers.count() == 1:
-            verifier = agency.eligibility_verifiers.first()
-            session.update(request, verifier=verifier)
-            response = redirect(eligibility_start)
-        else:
-            response = TemplateResponse(request, TEMPLATE_INDEX, ctx)
+        response = TemplateResponse(request, TEMPLATE_INDEX, ctx)
 
     return response

{"golden_diff": "diff --git a/benefits/eligibility/views.py b/benefits/eligibility/views.py\n--- a/benefits/eligibility/views.py\n+++ b/benefits/eligibility/views.py\n@@ -74,12 +74,7 @@\n             page.forms = [form]\n             response = TemplateResponse(request, TEMPLATE_INDEX, ctx)\n     else:\n-        if agency.eligibility_verifiers.count() == 1:\n-            verifier = agency.eligibility_verifiers.first()\n-            session.update(request, verifier=verifier)\n-            response = redirect(eligibility_start)\n-        else:\n-            response = TemplateResponse(request, TEMPLATE_INDEX, ctx)\n+        response = TemplateResponse(request, TEMPLATE_INDEX, ctx)\n \n     return response\n", "issue": "Remove auto-forward for single-verifier agencies\nIn #337 we introduced handling for an eligibility verifier selection form, which supports choosing between e.g. verifying eligibility with Login.gov or with a Courtesy Card. We also added [a shortcut](https://github.com/cal-itp/benefits/blob/dev/benefits/eligibility/views.py#L77) for when an agency has only a single verifier -- to bypass this form and go straight to the next step in the flow.\r\n\r\nWe want to have a consistent user experience regardless of the number of verifiers, and so it's time to remove this shortcut and always show the verifier selection page, even with only 1 option.\r\n\r\n## Acceptance Criteria\r\n\r\n<!-- Remember to consider edge cases -->\r\n\r\n- [ ] The user must always choose a verifier on `/eligibility`, regardless of the number of verifiers there are to choose from\r\n\r\n## Additional context\r\n\r\nDesign sign-off on this approach: https://cal-itp.slack.com/archives/C013W8RUAMU/p1673542656882989\r\n\n", "before_files": [{"content": "\"\"\"\nThe eligibility application: view definitions for the eligibility verification flow.\n\"\"\"\nfrom django.contrib import messages\nfrom django.shortcuts import redirect\nfrom django.template.response import TemplateResponse\nfrom django.urls import reverse\nfrom django.utils.decorators import decorator_from_middleware\nfrom django.utils.html import format_html\nfrom django.utils.translation import pgettext, gettext as _\n\nfrom benefits.core import recaptcha, session, viewmodels\nfrom benefits.core.middleware import AgencySessionRequired, LoginRequired, RateLimit, RecaptchaEnabled, VerifierSessionRequired\nfrom benefits.core.models import EligibilityVerifier\nfrom benefits.core.views import ROUTE_HELP\nfrom . import analytics, forms, verify\n\n\nROUTE_INDEX = \"eligibility:index\"\nROUTE_START = \"eligibility:start\"\nROUTE_LOGIN = \"oauth:login\"\nROUTE_CONFIRM = \"eligibility:confirm\"\nROUTE_UNVERIFIED = \"eligibility:unverified\"\nROUTE_ENROLLMENT = \"enrollment:index\"\n\nTEMPLATE_INDEX = \"eligibility/index.html\"\nTEMPLATE_START = \"eligibility/start.html\"\nTEMPLATE_CONFIRM = \"eligibility/confirm.html\"\nTEMPLATE_UNVERIFIED = \"eligibility/unverified.html\"\n\n\n@decorator_from_middleware(AgencySessionRequired)\n@decorator_from_middleware(RecaptchaEnabled)\ndef index(request):\n    \"\"\"View handler for the eligibility verifier selection form.\"\"\"\n\n    session.update(request, eligibility_types=[], origin=reverse(ROUTE_INDEX))\n    agency = session.agency(request)\n\n    eligibility_start = reverse(ROUTE_START)\n\n    help_page = reverse(ROUTE_HELP)\n\n    agency_intro = _(agency.eligibility_index_intro) if isinstance(agency.eligibility_index_intro, str) else \"\"\n    common_intro = _(\"eligibility.pages.index.p[0]%(info_link)s\") % {\"info_link\": f\"{help_page}#what-is-cal-itp\"}\n    intro = format_html(agency_intro + common_intro)\n    page = viewmodels.Page(\n        title=_(\"eligibility.pages.index.title\"),\n        headline=_(\"eligibility.pages.index.headline\"),\n        paragraphs=[intro],\n        forms=forms.EligibilityVerifierSelectionForm(agency=agency),\n    )\n\n    ctx = page.context_dict()\n    ctx[\"help_page\"] = help_page\n    ctx[\"help_text\"] = format_html(_(\"eligibility.pages.index.help_text%(help_link)s\") % {\"help_link\": help_page})\n\n    if request.method == \"POST\":\n        form = forms.EligibilityVerifierSelectionForm(data=request.POST, agency=agency)\n\n        if form.is_valid():\n            verifier_id = form.cleaned_data.get(\"verifier\")\n            verifier = EligibilityVerifier.objects.get(id=verifier_id)\n            session.update(request, verifier=verifier)\n\n            types_to_verify = agency.type_names_to_verify(verifier)\n            analytics.selected_verifier(request, types_to_verify)\n\n            response = redirect(eligibility_start)\n        else:\n            # form was not valid, allow for correction/resubmission\n            if recaptcha.has_error(form):\n                messages.error(request, \"Recaptcha failed. Please try again.\")\n            page.forms = [form]\n            response = TemplateResponse(request, TEMPLATE_INDEX, ctx)\n    else:\n        if agency.eligibility_verifiers.count() == 1:\n            verifier = agency.eligibility_verifiers.first()\n            session.update(request, verifier=verifier)\n            response = redirect(eligibility_start)\n        else:\n            response = TemplateResponse(request, TEMPLATE_INDEX, ctx)\n\n    return response\n\n\n@decorator_from_middleware(AgencySessionRequired)\n@decorator_from_middleware(VerifierSessionRequired)\ndef start(request):\n    \"\"\"View handler for the eligibility verification getting started screen.\"\"\"\n\n    verifier = session.verifier(request)\n    button = viewmodels.Button.primary(text=_(\"eligibility.buttons.continue\"), url=reverse(ROUTE_CONFIRM))\n\n    # define the verifier-specific required item\n    identity_item = viewmodels.MediaItem(\n        icon=viewmodels.Icon(\"idcardcheck\", pgettext(\"image alt text\", \"core.icons.idcardcheck\")),\n        heading=_(verifier.start_item_heading),\n        details=_(verifier.start_item_details),\n    )\n\n    if verifier.is_auth_required:\n        if verifier.uses_auth_verification:\n            identity_item.bullets = [\n                _(\"eligibility.pages.start.login_gov.required_items[0]\"),\n                _(\"eligibility.pages.start.login_gov.required_items[1]\"),\n                _(\"eligibility.pages.start.login_gov.required_items[2]\"),\n            ]\n\n        if not session.logged_in(request):\n            button = viewmodels.Button.login(\n                text=_(verifier.auth_provider.sign_in_button_label),\n                url=reverse(ROUTE_LOGIN),\n            )\n\n    # define the bank card item\n    bank_card_item = viewmodels.MediaItem(\n        icon=viewmodels.Icon(\"bankcardcheck\", pgettext(\"image alt text\", \"core.icons.bankcardcheck\")),\n        heading=_(\"eligibility.pages.start.bankcard.title\"),\n        details=_(\"eligibility.pages.start.bankcard.text\"),\n    )\n\n    media = [identity_item, bank_card_item]\n\n    page = viewmodels.Page(\n        title=_(verifier.start_title),\n        headline=_(verifier.start_headline),\n        button=button,\n    )\n\n    ctx = page.context_dict()\n    ctx[\"previous_page_button\"] = viewmodels.Button.previous_page(url=reverse(ROUTE_INDEX))\n    ctx[\"start_sub_headline\"] = _(\"eligibility.pages.start.sub_headline\")\n    ctx[\"media\"] = media\n    help_page = reverse(ROUTE_HELP)\n    ctx[\"help_link\"] = f\"{help_page}#{verifier.start_help_anchor}\"\n\n    # update origin now, after we've saved the previous page\n    session.update(request, eligibility_types=[], origin=reverse(ROUTE_START))\n\n    return TemplateResponse(request, TEMPLATE_START, ctx)\n\n\n@decorator_from_middleware(AgencySessionRequired)\n@decorator_from_middleware(LoginRequired)\n@decorator_from_middleware(RateLimit)\n@decorator_from_middleware(RecaptchaEnabled)\n@decorator_from_middleware(VerifierSessionRequired)\ndef confirm(request):\n    \"\"\"View handler for the eligibility verification form.\"\"\"\n\n    # GET from an already verified user, no need to verify again\n    if request.method == \"GET\" and session.eligible(request):\n        eligibility = session.eligibility(request)\n        return verified(request, [eligibility.name])\n\n    unverified_view = reverse(ROUTE_UNVERIFIED)\n\n    agency = session.agency(request)\n    verifier = session.verifier(request)\n    types_to_verify = agency.type_names_to_verify(verifier)\n\n    # GET for OAuth verification\n    if request.method == \"GET\" and verifier.uses_auth_verification:\n        analytics.started_eligibility(request, types_to_verify)\n\n        verified_types = verify.eligibility_from_oauth(verifier, session.oauth_claim(request), agency)\n        if verified_types:\n            return verified(request, verified_types)\n        else:\n            return redirect(unverified_view)\n\n    # GET/POST for Eligibility API verification\n    page = viewmodels.Page(\n        title=_(verifier.form_title),\n        headline=_(verifier.form_headline),\n        paragraphs=[_(verifier.form_blurb)],\n        form=forms.EligibilityVerificationForm(auto_id=True, label_suffix=\"\", verifier=verifier),\n    )\n\n    ctx = page.context_dict()\n    ctx[\"previous_page_button\"] = viewmodels.Button.previous_page(url=reverse(ROUTE_START))\n\n    # GET from an unverified user, present the form\n    if request.method == \"GET\":\n        return TemplateResponse(request, TEMPLATE_CONFIRM, ctx)\n    # POST form submission, process form data, make Eligibility Verification API call\n    elif request.method == \"POST\":\n        analytics.started_eligibility(request, types_to_verify)\n\n        form = forms.EligibilityVerificationForm(data=request.POST, verifier=verifier)\n        # form was not valid, allow for correction/resubmission\n        if not form.is_valid():\n            if recaptcha.has_error(form):\n                messages.error(request, \"Recaptcha failed. Please try again.\")\n\n            page.forms = [form]\n            ctx.update(page.context_dict())\n            return TemplateResponse(request, TEMPLATE_CONFIRM, ctx)\n\n        # form is valid, make Eligibility Verification request to get the verified types\n        verified_types = verify.eligibility_from_api(verifier, form, agency)\n\n        # form was not valid, allow for correction/resubmission\n        if verified_types is None:\n            analytics.returned_error(request, types_to_verify, form.errors)\n            page.forms = [form]\n            ctx.update(page.context_dict())\n            return TemplateResponse(request, TEMPLATE_CONFIRM, ctx)\n        # no types were verified\n        elif len(verified_types) == 0:\n            return redirect(unverified_view)\n        # type(s) were verified\n        else:\n            return verified(request, verified_types)\n\n\n@decorator_from_middleware(AgencySessionRequired)\n@decorator_from_middleware(LoginRequired)\ndef verified(request, verified_types):\n    \"\"\"View handler for the verified eligibility page.\"\"\"\n\n    analytics.returned_success(request, verified_types)\n\n    session.update(request, eligibility_types=verified_types)\n\n    return redirect(ROUTE_ENROLLMENT)\n\n\n@decorator_from_middleware(AgencySessionRequired)\n@decorator_from_middleware(VerifierSessionRequired)\ndef unverified(request):\n    \"\"\"View handler for the unverified eligibility page.\"\"\"\n\n    agency = session.agency(request)\n    verifier = session.verifier(request)\n    types_to_verify = agency.type_names_to_verify(verifier)\n\n    analytics.returned_fail(request, types_to_verify)\n\n    # tel: link to agency phone number\n    buttons = viewmodels.Button.agency_contact_links(agency)\n    buttons.append(viewmodels.Button.home(request))\n\n    page = viewmodels.Page(\n        title=_(verifier.unverified_title),\n        headline=_(\"eligibility.pages.unverified.headline\"),\n        icon=viewmodels.Icon(\"idcardquestion\", pgettext(\"image alt text\", \"core.icons.idcardquestion\")),\n        paragraphs=[_(verifier.unverified_blurb)],\n        buttons=buttons,\n    )\n\n    return TemplateResponse(request, TEMPLATE_UNVERIFIED, page.context_dict())\n", "path": "benefits/eligibility/views.py"}], "after_files": [{"content": "\"\"\"\nThe eligibility application: view definitions for the eligibility verification flow.\n\"\"\"\nfrom django.contrib import messages\nfrom django.shortcuts import redirect\nfrom django.template.response import TemplateResponse\nfrom django.urls import reverse\nfrom django.utils.decorators import decorator_from_middleware\nfrom django.utils.html import format_html\nfrom django.utils.translation import pgettext, gettext as _\n\nfrom benefits.core import recaptcha, session, viewmodels\nfrom benefits.core.middleware import AgencySessionRequired, LoginRequired, RateLimit, RecaptchaEnabled, VerifierSessionRequired\nfrom benefits.core.models import EligibilityVerifier\nfrom benefits.core.views import ROUTE_HELP\nfrom . import analytics, forms, verify\n\n\nROUTE_INDEX = \"eligibility:index\"\nROUTE_START = \"eligibility:start\"\nROUTE_LOGIN = \"oauth:login\"\nROUTE_CONFIRM = \"eligibility:confirm\"\nROUTE_UNVERIFIED = \"eligibility:unverified\"\nROUTE_ENROLLMENT = \"enrollment:index\"\n\nTEMPLATE_INDEX = \"eligibility/index.html\"\nTEMPLATE_START = \"eligibility/start.html\"\nTEMPLATE_CONFIRM = \"eligibility/confirm.html\"\nTEMPLATE_UNVERIFIED = \"eligibility/unverified.html\"\n\n\n@decorator_from_middleware(AgencySessionRequired)\n@decorator_from_middleware(RecaptchaEnabled)\ndef index(request):\n    \"\"\"View handler for the eligibility verifier selection form.\"\"\"\n\n    session.update(request, eligibility_types=[], origin=reverse(ROUTE_INDEX))\n    agency = session.agency(request)\n\n    eligibility_start = reverse(ROUTE_START)\n\n    help_page = reverse(ROUTE_HELP)\n\n    agency_intro = _(agency.eligibility_index_intro) if isinstance(agency.eligibility_index_intro, str) else \"\"\n    common_intro = _(\"eligibility.pages.index.p[0]%(info_link)s\") % {\"info_link\": f\"{help_page}#what-is-cal-itp\"}\n    intro = format_html(agency_intro + common_intro)\n    page = viewmodels.Page(\n        title=_(\"eligibility.pages.index.title\"),\n        headline=_(\"eligibility.pages.index.headline\"),\n        paragraphs=[intro],\n        forms=forms.EligibilityVerifierSelectionForm(agency=agency),\n    )\n\n    ctx = page.context_dict()\n    ctx[\"help_page\"] = help_page\n    ctx[\"help_text\"] = format_html(_(\"eligibility.pages.index.help_text%(help_link)s\") % {\"help_link\": help_page})\n\n    if request.method == \"POST\":\n        form = forms.EligibilityVerifierSelectionForm(data=request.POST, agency=agency)\n\n        if form.is_valid():\n            verifier_id = form.cleaned_data.get(\"verifier\")\n            verifier = EligibilityVerifier.objects.get(id=verifier_id)\n            session.update(request, verifier=verifier)\n\n            types_to_verify = agency.type_names_to_verify(verifier)\n            analytics.selected_verifier(request, types_to_verify)\n\n            response = redirect(eligibility_start)\n        else:\n            # form was not valid, allow for correction/resubmission\n            if recaptcha.has_error(form):\n                messages.error(request, \"Recaptcha failed. Please try again.\")\n            page.forms = [form]\n            response = TemplateResponse(request, TEMPLATE_INDEX, ctx)\n    else:\n        response = TemplateResponse(request, TEMPLATE_INDEX, ctx)\n\n    return response\n\n\n@decorator_from_middleware(AgencySessionRequired)\n@decorator_from_middleware(VerifierSessionRequired)\ndef start(request):\n    \"\"\"View handler for the eligibility verification getting started screen.\"\"\"\n\n    verifier = session.verifier(request)\n    button = viewmodels.Button.primary(text=_(\"eligibility.buttons.continue\"), url=reverse(ROUTE_CONFIRM))\n\n    # define the verifier-specific required item\n    identity_item = viewmodels.MediaItem(\n        icon=viewmodels.Icon(\"idcardcheck\", pgettext(\"image alt text\", \"core.icons.idcardcheck\")),\n        heading=_(verifier.start_item_heading),\n        details=_(verifier.start_item_details),\n    )\n\n    if verifier.is_auth_required:\n        if verifier.uses_auth_verification:\n            identity_item.bullets = [\n                _(\"eligibility.pages.start.login_gov.required_items[0]\"),\n                _(\"eligibility.pages.start.login_gov.required_items[1]\"),\n                _(\"eligibility.pages.start.login_gov.required_items[2]\"),\n            ]\n\n        if not session.logged_in(request):\n            button = viewmodels.Button.login(\n                text=_(verifier.auth_provider.sign_in_button_label),\n                url=reverse(ROUTE_LOGIN),\n            )\n\n    # define the bank card item\n    bank_card_item = viewmodels.MediaItem(\n        icon=viewmodels.Icon(\"bankcardcheck\", pgettext(\"image alt text\", \"core.icons.bankcardcheck\")),\n        heading=_(\"eligibility.pages.start.bankcard.title\"),\n        details=_(\"eligibility.pages.start.bankcard.text\"),\n    )\n\n    media = [identity_item, bank_card_item]\n\n    page = viewmodels.Page(\n        title=_(verifier.start_title),\n        headline=_(verifier.start_headline),\n        button=button,\n    )\n\n    ctx = page.context_dict()\n    ctx[\"previous_page_button\"] = viewmodels.Button.previous_page(url=reverse(ROUTE_INDEX))\n    ctx[\"start_sub_headline\"] = _(\"eligibility.pages.start.sub_headline\")\n    ctx[\"media\"] = media\n    help_page = reverse(ROUTE_HELP)\n    ctx[\"help_link\"] = f\"{help_page}#{verifier.start_help_anchor}\"\n\n    # update origin now, after we've saved the previous page\n    session.update(request, eligibility_types=[], origin=reverse(ROUTE_START))\n\n    return TemplateResponse(request, TEMPLATE_START, ctx)\n\n\n@decorator_from_middleware(AgencySessionRequired)\n@decorator_from_middleware(LoginRequired)\n@decorator_from_middleware(RateLimit)\n@decorator_from_middleware(RecaptchaEnabled)\n@decorator_from_middleware(VerifierSessionRequired)\ndef confirm(request):\n    \"\"\"View handler for the eligibility verification form.\"\"\"\n\n    # GET from an already verified user, no need to verify again\n    if request.method == \"GET\" and session.eligible(request):\n        eligibility = session.eligibility(request)\n        return verified(request, [eligibility.name])\n\n    unverified_view = reverse(ROUTE_UNVERIFIED)\n\n    agency = session.agency(request)\n    verifier = session.verifier(request)\n    types_to_verify = agency.type_names_to_verify(verifier)\n\n    # GET for OAuth verification\n    if request.method == \"GET\" and verifier.uses_auth_verification:\n        analytics.started_eligibility(request, types_to_verify)\n\n        verified_types = verify.eligibility_from_oauth(verifier, session.oauth_claim(request), agency)\n        if verified_types:\n            return verified(request, verified_types)\n        else:\n            return redirect(unverified_view)\n\n    # GET/POST for Eligibility API verification\n    page = viewmodels.Page(\n        title=_(verifier.form_title),\n        headline=_(verifier.form_headline),\n        paragraphs=[_(verifier.form_blurb)],\n        form=forms.EligibilityVerificationForm(auto_id=True, label_suffix=\"\", verifier=verifier),\n    )\n\n    ctx = page.context_dict()\n    ctx[\"previous_page_button\"] = viewmodels.Button.previous_page(url=reverse(ROUTE_START))\n\n    # GET from an unverified user, present the form\n    if request.method == \"GET\":\n        return TemplateResponse(request, TEMPLATE_CONFIRM, ctx)\n    # POST form submission, process form data, make Eligibility Verification API call\n    elif request.method == \"POST\":\n        analytics.started_eligibility(request, types_to_verify)\n\n        form = forms.EligibilityVerificationForm(data=request.POST, verifier=verifier)\n        # form was not valid, allow for correction/resubmission\n        if not form.is_valid():\n            if recaptcha.has_error(form):\n                messages.error(request, \"Recaptcha failed. Please try again.\")\n\n            page.forms = [form]\n            ctx.update(page.context_dict())\n            return TemplateResponse(request, TEMPLATE_CONFIRM, ctx)\n\n        # form is valid, make Eligibility Verification request to get the verified types\n        verified_types = verify.eligibility_from_api(verifier, form, agency)\n\n        # form was not valid, allow for correction/resubmission\n        if verified_types is None:\n            analytics.returned_error(request, types_to_verify, form.errors)\n            page.forms = [form]\n            ctx.update(page.context_dict())\n            return TemplateResponse(request, TEMPLATE_CONFIRM, ctx)\n        # no types were verified\n        elif len(verified_types) == 0:\n            return redirect(unverified_view)\n        # type(s) were verified\n        else:\n            return verified(request, verified_types)\n\n\n@decorator_from_middleware(AgencySessionRequired)\n@decorator_from_middleware(LoginRequired)\ndef verified(request, verified_types):\n    \"\"\"View handler for the verified eligibility page.\"\"\"\n\n    analytics.returned_success(request, verified_types)\n\n    session.update(request, eligibility_types=verified_types)\n\n    return redirect(ROUTE_ENROLLMENT)\n\n\n@decorator_from_middleware(AgencySessionRequired)\n@decorator_from_middleware(VerifierSessionRequired)\ndef unverified(request):\n    \"\"\"View handler for the unverified eligibility page.\"\"\"\n\n    agency = session.agency(request)\n    verifier = session.verifier(request)\n    types_to_verify = agency.type_names_to_verify(verifier)\n\n    analytics.returned_fail(request, types_to_verify)\n\n    # tel: link to agency phone number\n    buttons = viewmodels.Button.agency_contact_links(agency)\n    buttons.append(viewmodels.Button.home(request))\n\n    page = viewmodels.Page(\n        title=_(verifier.unverified_title),\n        headline=_(\"eligibility.pages.unverified.headline\"),\n        icon=viewmodels.Icon(\"idcardquestion\", pgettext(\"image alt text\", \"core.icons.idcardquestion\")),\n        paragraphs=[_(verifier.unverified_blurb)],\n        buttons=buttons,\n    )\n\n    return TemplateResponse(request, TEMPLATE_UNVERIFIED, page.context_dict())\n", "path": "benefits/eligibility/views.py"}]}