We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
update favicon
current dev has old Cal-ITP Logo as favicon. 

--- 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/discounts/views.py`
Content:
```
1 """
2 The discounts application: view definitions for the discounts association flow.
3 """
4 import logging
5 
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.translation import pgettext, ugettext as _
10 
11 from benefits.core import middleware, models, session, viewmodels
12 from benefits.core.views import PageTemplateResponse
13 from . import api, forms
14 
15 
16 logger = logging.getLogger(__name__)
17 
18 
19 def _check_access_token(request, agency):
20     """
21     Ensure the request's session is configured with an access token.
22     """
23     if not session.valid_token(request):
24         response = api.AccessTokenClient(agency).get()
25         session.update(request, token=response.access_token, token_exp=response.expiry)
26 
27 
28 def _index(request):
29     """Helper handles GET requests to discounts index."""
30     agency = session.agency(request)
31 
32     _check_access_token(request, agency)
33 
34     tokenize_button = "tokenize_card"
35     tokenize_retry_form = forms.CardTokenizeFailForm("discounts:retry")
36     tokenize_success_form = forms.CardTokenizeSuccessForm(auto_id=True, label_suffix="")
37 
38     page = viewmodels.Page(
39         title=_("discounts.index.title"),
40         content_title=_("discounts.index.content_title"),
41         icon=viewmodels.Icon("idcardcheck", pgettext("image alt text", "core.icons.idcardcheck")),
42         paragraphs=[_("discounts.index.p1"), _("discounts.index.p2")],
43         classes="text-lg-center",
44         forms=[tokenize_retry_form, tokenize_success_form],
45         buttons=[
46             viewmodels.Button.primary(
47                 text=_("discounts.buttons.paymentpartner"), id=tokenize_button, url=f"#{tokenize_button}"
48             ),
49             viewmodels.Button.link(
50                 classes="btn-sm", text=_("discounts.buttons.paymentoptions"), url=reverse("core:payment_options")
51             ),
52         ],
53     )
54     context = page.context_dict()
55 
56     # add agency details
57     agency_vm = viewmodels.TransitAgency(agency)
58     context.update(agency_vm.context_dict())
59 
60     # and discount provider details
61     provider_vm = viewmodels.DiscountProvider(
62         model=agency.discount_provider,
63         access_token=session.token(request),
64         element_id=f"#{tokenize_button}",
65         color="#046b99",
66         name=f"{agency.long_name} {_('partnered with')} {agency.discount_provider.name}",
67     )
68     context.update(provider_vm.context_dict())
69     logger.info(f"card_tokenize_url: {context['provider'].card_tokenize_url}")
70 
71     # the tokenize form URLs are injected to page-generated Javascript
72     context.update(
73         {
74             "forms": {
75                 "tokenize_retry": reverse(tokenize_retry_form.action_url),
76                 "tokenize_success": reverse(tokenize_success_form.action_url),
77             }
78         }
79     )
80 
81     return TemplateResponse(request, "discounts/index.html", context)
82 
83 
84 @decorator_from_middleware(middleware.AgencySessionRequired)
85 def index(request):
86     """View handler for the discounts landing page."""
87     if request.method == "POST":
88         response = _associate_discount(request)
89     else:
90         response = _index(request)
91 
92     return response
93 
94 
95 def _associate_discount(request):
96     """Helper calls the discount APIs."""
97     logger.debug("Read tokenized card")
98     form = forms.CardTokenizeSuccessForm(request.POST)
99     if not form.is_valid():
100         raise Exception("Invalid card token form")
101     card_token = form.cleaned_data.get("card_token")
102 
103     eligibility = session.eligibility(request)
104     if len(eligibility) > 0:
105         eligibility = eligibility[0]
106         if len(eligibility) == 1:
107             logger.debug(f"Session contains 1 {models.EligibilityType.__name__}")
108         else:
109             logger.debug(f"Session contains ({len(eligibility)}) {models.EligibilityType.__name__}s")
110     else:
111         raise Exception("Session contains no eligibility information")
112 
113     agency = session.agency(request)
114 
115     logger.debug("Call customer API")
116     response = api.CustomerClient(agency).get(card_token)
117     customer_id = response.id
118 
119     logger.debug("Call group API")
120     eligibility = models.EligibilityType.by_name(eligibility)
121     response = api.GroupClient(agency).enroll_customer(customer_id, eligibility.group_id)
122     if response.updated_customer_id == customer_id:
123         return success(request)
124     else:
125         raise Exception("Updated customer_id does not match enrolled customer_id")
126 
127 
128 @decorator_from_middleware(middleware.AgencySessionRequired)
129 def retry(request):
130     """View handler for a recoverable failure condition."""
131     if request.method == "POST":
132         form = forms.CardTokenizeFailForm(request.POST)
133         if form.is_valid():
134             agency = session.agency(request)
135             page = viewmodels.Page(
136                 title=_("discounts.retry.title"),
137                 icon=viewmodels.Icon("bankcardquestion", pgettext("image alt text", "core.icons.bankcardquestion")),
138                 content_title=_("discounts.retry.title"),
139                 paragraphs=[_("discounts.retry.p1")],
140                 buttons=[
141                     viewmodels.Button.agency_phone_link(agency),
142                     viewmodels.Button.primary(text=_("discounts.retry.button"), url=session.origin(request)),
143                 ],
144             )
145             return PageTemplateResponse(request, page)
146         else:
147             raise Exception("Invalid retry submission.")
148     else:
149         raise Exception("This view method only supports POST.")
150 
151 
152 def success(request):
153     """View handler for the final success page."""
154     page = viewmodels.Page(
155         title=_("discounts.success.title"),
156         icon=viewmodels.Icon("paymentcardcheck", pgettext("image alt text", "core.icons.bankcardcheck")),
157         content_title=_("discounts.success.title"),
158         paragraphs=[_("discounts.success.p1"), _("discounts.success.p2")],
159     )
160 
161     return TemplateResponse(request, "discounts/success.html", page.context_dict())
162
```

Path: `benefits/core/views.py`
Content:
```
1 """
2 The core application: view definition for the root of the webapp.
3 """
4 from django.http import HttpResponseBadRequest, HttpResponseNotFound, HttpResponseServerError
5 from django.template import loader
6 from django.template.response import TemplateResponse
7 from django.urls import reverse
8 from django.utils.translation import pgettext, ugettext as _
9 
10 from . import models, session, viewmodels
11 
12 
13 def PageTemplateResponse(request, page_vm):
14     """Helper returns a TemplateResponse using the common page template."""
15     return TemplateResponse(request, "core/page.html", page_vm.context_dict())
16 
17 
18 def _index_content_title():
19     """Helper returns the content title for the common index page."""
20     return _("core.index.content_title")
21 
22 
23 def _index_image():
24     """Helper returns a viewmodels.Image for the common index page."""
25     return viewmodels.Image("riderboardingbusandtapping.svg", pgettext("image alt text", "core.index.image"))
26 
27 
28 def _index_paragraphs():
29     """Helper returns the content paragraphs for the common index page."""
30     return [_("core.index.p1"), _("core.index.p2"), _("core.index.p3")]
31 
32 
33 def _index_url():
34     """Helper computes the index url path."""
35     return reverse("core:index")
36 
37 
38 def index(request):
39     """View handler for the main entry page."""
40     session.reset(request)
41 
42     # generate a button to the landing page for each active agency
43     agencies = models.TransitAgency.all_active()
44     buttons = [viewmodels.Button.outline_primary(text=a.short_name, url=a.index_url) for a in agencies]
45     buttons[0].classes.append("mt-3")
46     buttons[0].label = _("core.index.chooseprovider")
47 
48     page = viewmodels.Page(
49         content_title=_index_content_title(),
50         paragraphs=_index_paragraphs(),
51         image=_index_image(),
52         buttons=buttons,
53         classes="home",
54     )
55 
56     return PageTemplateResponse(request, page)
57 
58 
59 def agency_index(request, agency):
60     """View handler for an agency entry page."""
61     session.reset(request)
62     session.update(request, agency=agency, origin=agency.index_url)
63 
64     page = viewmodels.Page(
65         content_title=_index_content_title(),
66         paragraphs=_index_paragraphs(),
67         image=_index_image(),
68         button=viewmodels.Button.primary(text=_("core.index.continue"), url=reverse("eligibility:index")),
69         classes="home",
70     )
71 
72     return PageTemplateResponse(request, page)
73 
74 
75 def help(request):
76     """View handler for the help page."""
77     if session.active_agency(request):
78         agency = session.agency(request)
79         buttons = [viewmodels.Button.agency_phone_link(agency)]
80     else:
81         buttons = [viewmodels.Button.agency_phone_link(a) for a in models.TransitAgency.all_active()]
82 
83     buttons.append(viewmodels.Button.home(request, _("core.buttons.back")))
84 
85     page = viewmodels.Page(
86         title=_("core.help"),
87         content_title=_("core.help"),
88         paragraphs=[_("core.help.p1"), _("core.help.p2")],
89         buttons=buttons,
90         classes="text-lg-center",
91     )
92 
93     return TemplateResponse(request, "core/help.html", page.context_dict())
94 
95 
96 def payment_options(request):
97     """View handler for the Payment Options page."""
98     page = viewmodels.Page(
99         title=_("core.payment-options"),
100         icon=viewmodels.Icon("bankcard", pgettext("image alt text", "core.icons.bankcard")),
101         content_title=_("core.payment-options"),
102         buttons=viewmodels.Button.home(request, text=_("core.buttons.back")),
103     )
104 
105     return TemplateResponse(request, "core/payment-options.html", page.context_dict())
106 
107 
108 def bad_request(request, exception, template_name="400.html"):
109     """View handler for HTTP 400 Bad Request responses."""
110     if session.active_agency(request):
111         session.update(request, origin=session.agency(request).index_url)
112     else:
113         session.update(request, origin=_index_url())
114 
115     home = viewmodels.Button.home(request)
116     page = viewmodels.ErrorPage.error(button=home)
117     t = loader.get_template(template_name)
118 
119     return HttpResponseBadRequest(t.render(page.context_dict()))
120 
121 
122 def page_not_found(request, exception, template_name="404.html"):
123     """View handler for HTTP 404 Not Found responses."""
124     if session.active_agency(request):
125         session.update(request, origin=session.agency(request).index_url)
126     else:
127         session.update(request, origin=_index_url())
128 
129     home = viewmodels.Button.home(request)
130     page = viewmodels.ErrorPage.not_found(button=home, path=request.path)
131     t = loader.get_template(template_name)
132 
133     return HttpResponseNotFound(t.render(page.context_dict()))
134 
135 
136 def server_error(request, template_name="500.html"):
137     """View handler for HTTP 500 Server Error responses."""
138     if session.active_agency(request):
139         session.update(request, origin=session.agency(request).index_url)
140     else:
141         session.update(request, origin=_index_url())
142 
143     home = viewmodels.Button.home(request)
144     page = viewmodels.ErrorPage.error(button=home)
145     t = loader.get_template(template_name)
146 
147     return HttpResponseServerError(t.render(page.context_dict()))
148
```
--- 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/core/views.py b/benefits/core/views.py
--- a/benefits/core/views.py
+++ b/benefits/core/views.py
@@ -22,7 +22,7 @@
 
 def _index_image():
     """Helper returns a viewmodels.Image for the common index page."""
-    return viewmodels.Image("riderboardingbusandtapping.svg", pgettext("image alt text", "core.index.image"))
+    return viewmodels.Image("ridertappingbankcard.png", pgettext("image alt text", "core.index.image"))
 
 
 def _index_paragraphs():
diff --git a/benefits/discounts/views.py b/benefits/discounts/views.py
--- a/benefits/discounts/views.py
+++ b/benefits/discounts/views.py
@@ -153,7 +153,7 @@
     """View handler for the final success page."""
     page = viewmodels.Page(
         title=_("discounts.success.title"),
-        icon=viewmodels.Icon("paymentcardcheck", pgettext("image alt text", "core.icons.bankcardcheck")),
+        icon=viewmodels.Icon("bankcardcheck", pgettext("image alt text", "core.icons.bankcardcheck")),
         content_title=_("discounts.success.title"),
         paragraphs=[_("discounts.success.p1"), _("discounts.success.p2")],
     )

{"golden_diff": "diff --git a/benefits/core/views.py b/benefits/core/views.py\n--- a/benefits/core/views.py\n+++ b/benefits/core/views.py\n@@ -22,7 +22,7 @@\n \n def _index_image():\n     \"\"\"Helper returns a viewmodels.Image for the common index page.\"\"\"\n-    return viewmodels.Image(\"riderboardingbusandtapping.svg\", pgettext(\"image alt text\", \"core.index.image\"))\n+    return viewmodels.Image(\"ridertappingbankcard.png\", pgettext(\"image alt text\", \"core.index.image\"))\n \n \n def _index_paragraphs():\ndiff --git a/benefits/discounts/views.py b/benefits/discounts/views.py\n--- a/benefits/discounts/views.py\n+++ b/benefits/discounts/views.py\n@@ -153,7 +153,7 @@\n     \"\"\"View handler for the final success page.\"\"\"\n     page = viewmodels.Page(\n         title=_(\"discounts.success.title\"),\n-        icon=viewmodels.Icon(\"paymentcardcheck\", pgettext(\"image alt text\", \"core.icons.bankcardcheck\")),\n+        icon=viewmodels.Icon(\"bankcardcheck\", pgettext(\"image alt text\", \"core.icons.bankcardcheck\")),\n         content_title=_(\"discounts.success.title\"),\n         paragraphs=[_(\"discounts.success.p1\"), _(\"discounts.success.p2\")],\n     )\n", "issue": "update favicon\ncurrent dev has old Cal-ITP Logo as favicon. \n", "before_files": [{"content": "\"\"\"\nThe discounts application: view definitions for the discounts association flow.\n\"\"\"\nimport logging\n\nfrom django.template.response import TemplateResponse\nfrom django.urls import reverse\nfrom django.utils.decorators import decorator_from_middleware\nfrom django.utils.translation import pgettext, ugettext as _\n\nfrom benefits.core import middleware, models, session, viewmodels\nfrom benefits.core.views import PageTemplateResponse\nfrom . import api, forms\n\n\nlogger = logging.getLogger(__name__)\n\n\ndef _check_access_token(request, agency):\n    \"\"\"\n    Ensure the request's session is configured with an access token.\n    \"\"\"\n    if not session.valid_token(request):\n        response = api.AccessTokenClient(agency).get()\n        session.update(request, token=response.access_token, token_exp=response.expiry)\n\n\ndef _index(request):\n    \"\"\"Helper handles GET requests to discounts index.\"\"\"\n    agency = session.agency(request)\n\n    _check_access_token(request, agency)\n\n    tokenize_button = \"tokenize_card\"\n    tokenize_retry_form = forms.CardTokenizeFailForm(\"discounts:retry\")\n    tokenize_success_form = forms.CardTokenizeSuccessForm(auto_id=True, label_suffix=\"\")\n\n    page = viewmodels.Page(\n        title=_(\"discounts.index.title\"),\n        content_title=_(\"discounts.index.content_title\"),\n        icon=viewmodels.Icon(\"idcardcheck\", pgettext(\"image alt text\", \"core.icons.idcardcheck\")),\n        paragraphs=[_(\"discounts.index.p1\"), _(\"discounts.index.p2\")],\n        classes=\"text-lg-center\",\n        forms=[tokenize_retry_form, tokenize_success_form],\n        buttons=[\n            viewmodels.Button.primary(\n                text=_(\"discounts.buttons.paymentpartner\"), id=tokenize_button, url=f\"#{tokenize_button}\"\n            ),\n            viewmodels.Button.link(\n                classes=\"btn-sm\", text=_(\"discounts.buttons.paymentoptions\"), url=reverse(\"core:payment_options\")\n            ),\n        ],\n    )\n    context = page.context_dict()\n\n    # add agency details\n    agency_vm = viewmodels.TransitAgency(agency)\n    context.update(agency_vm.context_dict())\n\n    # and discount provider details\n    provider_vm = viewmodels.DiscountProvider(\n        model=agency.discount_provider,\n        access_token=session.token(request),\n        element_id=f\"#{tokenize_button}\",\n        color=\"#046b99\",\n        name=f\"{agency.long_name} {_('partnered with')} {agency.discount_provider.name}\",\n    )\n    context.update(provider_vm.context_dict())\n    logger.info(f\"card_tokenize_url: {context['provider'].card_tokenize_url}\")\n\n    # the tokenize form URLs are injected to page-generated Javascript\n    context.update(\n        {\n            \"forms\": {\n                \"tokenize_retry\": reverse(tokenize_retry_form.action_url),\n                \"tokenize_success\": reverse(tokenize_success_form.action_url),\n            }\n        }\n    )\n\n    return TemplateResponse(request, \"discounts/index.html\", context)\n\n\n@decorator_from_middleware(middleware.AgencySessionRequired)\ndef index(request):\n    \"\"\"View handler for the discounts landing page.\"\"\"\n    if request.method == \"POST\":\n        response = _associate_discount(request)\n    else:\n        response = _index(request)\n\n    return response\n\n\ndef _associate_discount(request):\n    \"\"\"Helper calls the discount APIs.\"\"\"\n    logger.debug(\"Read tokenized card\")\n    form = forms.CardTokenizeSuccessForm(request.POST)\n    if not form.is_valid():\n        raise Exception(\"Invalid card token form\")\n    card_token = form.cleaned_data.get(\"card_token\")\n\n    eligibility = session.eligibility(request)\n    if len(eligibility) > 0:\n        eligibility = eligibility[0]\n        if len(eligibility) == 1:\n            logger.debug(f\"Session contains 1 {models.EligibilityType.__name__}\")\n        else:\n            logger.debug(f\"Session contains ({len(eligibility)}) {models.EligibilityType.__name__}s\")\n    else:\n        raise Exception(\"Session contains no eligibility information\")\n\n    agency = session.agency(request)\n\n    logger.debug(\"Call customer API\")\n    response = api.CustomerClient(agency).get(card_token)\n    customer_id = response.id\n\n    logger.debug(\"Call group API\")\n    eligibility = models.EligibilityType.by_name(eligibility)\n    response = api.GroupClient(agency).enroll_customer(customer_id, eligibility.group_id)\n    if response.updated_customer_id == customer_id:\n        return success(request)\n    else:\n        raise Exception(\"Updated customer_id does not match enrolled customer_id\")\n\n\n@decorator_from_middleware(middleware.AgencySessionRequired)\ndef retry(request):\n    \"\"\"View handler for a recoverable failure condition.\"\"\"\n    if request.method == \"POST\":\n        form = forms.CardTokenizeFailForm(request.POST)\n        if form.is_valid():\n            agency = session.agency(request)\n            page = viewmodels.Page(\n                title=_(\"discounts.retry.title\"),\n                icon=viewmodels.Icon(\"bankcardquestion\", pgettext(\"image alt text\", \"core.icons.bankcardquestion\")),\n                content_title=_(\"discounts.retry.title\"),\n                paragraphs=[_(\"discounts.retry.p1\")],\n                buttons=[\n                    viewmodels.Button.agency_phone_link(agency),\n                    viewmodels.Button.primary(text=_(\"discounts.retry.button\"), url=session.origin(request)),\n                ],\n            )\n            return PageTemplateResponse(request, page)\n        else:\n            raise Exception(\"Invalid retry submission.\")\n    else:\n        raise Exception(\"This view method only supports POST.\")\n\n\ndef success(request):\n    \"\"\"View handler for the final success page.\"\"\"\n    page = viewmodels.Page(\n        title=_(\"discounts.success.title\"),\n        icon=viewmodels.Icon(\"paymentcardcheck\", pgettext(\"image alt text\", \"core.icons.bankcardcheck\")),\n        content_title=_(\"discounts.success.title\"),\n        paragraphs=[_(\"discounts.success.p1\"), _(\"discounts.success.p2\")],\n    )\n\n    return TemplateResponse(request, \"discounts/success.html\", page.context_dict())\n", "path": "benefits/discounts/views.py"}, {"content": "\"\"\"\nThe core application: view definition for the root of the webapp.\n\"\"\"\nfrom django.http import HttpResponseBadRequest, HttpResponseNotFound, HttpResponseServerError\nfrom django.template import loader\nfrom django.template.response import TemplateResponse\nfrom django.urls import reverse\nfrom django.utils.translation import pgettext, ugettext as _\n\nfrom . import models, session, viewmodels\n\n\ndef PageTemplateResponse(request, page_vm):\n    \"\"\"Helper returns a TemplateResponse using the common page template.\"\"\"\n    return TemplateResponse(request, \"core/page.html\", page_vm.context_dict())\n\n\ndef _index_content_title():\n    \"\"\"Helper returns the content title for the common index page.\"\"\"\n    return _(\"core.index.content_title\")\n\n\ndef _index_image():\n    \"\"\"Helper returns a viewmodels.Image for the common index page.\"\"\"\n    return viewmodels.Image(\"riderboardingbusandtapping.svg\", pgettext(\"image alt text\", \"core.index.image\"))\n\n\ndef _index_paragraphs():\n    \"\"\"Helper returns the content paragraphs for the common index page.\"\"\"\n    return [_(\"core.index.p1\"), _(\"core.index.p2\"), _(\"core.index.p3\")]\n\n\ndef _index_url():\n    \"\"\"Helper computes the index url path.\"\"\"\n    return reverse(\"core:index\")\n\n\ndef index(request):\n    \"\"\"View handler for the main entry page.\"\"\"\n    session.reset(request)\n\n    # generate a button to the landing page for each active agency\n    agencies = models.TransitAgency.all_active()\n    buttons = [viewmodels.Button.outline_primary(text=a.short_name, url=a.index_url) for a in agencies]\n    buttons[0].classes.append(\"mt-3\")\n    buttons[0].label = _(\"core.index.chooseprovider\")\n\n    page = viewmodels.Page(\n        content_title=_index_content_title(),\n        paragraphs=_index_paragraphs(),\n        image=_index_image(),\n        buttons=buttons,\n        classes=\"home\",\n    )\n\n    return PageTemplateResponse(request, page)\n\n\ndef agency_index(request, agency):\n    \"\"\"View handler for an agency entry page.\"\"\"\n    session.reset(request)\n    session.update(request, agency=agency, origin=agency.index_url)\n\n    page = viewmodels.Page(\n        content_title=_index_content_title(),\n        paragraphs=_index_paragraphs(),\n        image=_index_image(),\n        button=viewmodels.Button.primary(text=_(\"core.index.continue\"), url=reverse(\"eligibility:index\")),\n        classes=\"home\",\n    )\n\n    return PageTemplateResponse(request, page)\n\n\ndef help(request):\n    \"\"\"View handler for the help page.\"\"\"\n    if session.active_agency(request):\n        agency = session.agency(request)\n        buttons = [viewmodels.Button.agency_phone_link(agency)]\n    else:\n        buttons = [viewmodels.Button.agency_phone_link(a) for a in models.TransitAgency.all_active()]\n\n    buttons.append(viewmodels.Button.home(request, _(\"core.buttons.back\")))\n\n    page = viewmodels.Page(\n        title=_(\"core.help\"),\n        content_title=_(\"core.help\"),\n        paragraphs=[_(\"core.help.p1\"), _(\"core.help.p2\")],\n        buttons=buttons,\n        classes=\"text-lg-center\",\n    )\n\n    return TemplateResponse(request, \"core/help.html\", page.context_dict())\n\n\ndef payment_options(request):\n    \"\"\"View handler for the Payment Options page.\"\"\"\n    page = viewmodels.Page(\n        title=_(\"core.payment-options\"),\n        icon=viewmodels.Icon(\"bankcard\", pgettext(\"image alt text\", \"core.icons.bankcard\")),\n        content_title=_(\"core.payment-options\"),\n        buttons=viewmodels.Button.home(request, text=_(\"core.buttons.back\")),\n    )\n\n    return TemplateResponse(request, \"core/payment-options.html\", page.context_dict())\n\n\ndef bad_request(request, exception, template_name=\"400.html\"):\n    \"\"\"View handler for HTTP 400 Bad Request responses.\"\"\"\n    if session.active_agency(request):\n        session.update(request, origin=session.agency(request).index_url)\n    else:\n        session.update(request, origin=_index_url())\n\n    home = viewmodels.Button.home(request)\n    page = viewmodels.ErrorPage.error(button=home)\n    t = loader.get_template(template_name)\n\n    return HttpResponseBadRequest(t.render(page.context_dict()))\n\n\ndef page_not_found(request, exception, template_name=\"404.html\"):\n    \"\"\"View handler for HTTP 404 Not Found responses.\"\"\"\n    if session.active_agency(request):\n        session.update(request, origin=session.agency(request).index_url)\n    else:\n        session.update(request, origin=_index_url())\n\n    home = viewmodels.Button.home(request)\n    page = viewmodels.ErrorPage.not_found(button=home, path=request.path)\n    t = loader.get_template(template_name)\n\n    return HttpResponseNotFound(t.render(page.context_dict()))\n\n\ndef server_error(request, template_name=\"500.html\"):\n    \"\"\"View handler for HTTP 500 Server Error responses.\"\"\"\n    if session.active_agency(request):\n        session.update(request, origin=session.agency(request).index_url)\n    else:\n        session.update(request, origin=_index_url())\n\n    home = viewmodels.Button.home(request)\n    page = viewmodels.ErrorPage.error(button=home)\n    t = loader.get_template(template_name)\n\n    return HttpResponseServerError(t.render(page.context_dict()))\n", "path": "benefits/core/views.py"}], "after_files": [{"content": "\"\"\"\nThe discounts application: view definitions for the discounts association flow.\n\"\"\"\nimport logging\n\nfrom django.template.response import TemplateResponse\nfrom django.urls import reverse\nfrom django.utils.decorators import decorator_from_middleware\nfrom django.utils.translation import pgettext, ugettext as _\n\nfrom benefits.core import middleware, models, session, viewmodels\nfrom benefits.core.views import PageTemplateResponse\nfrom . import api, forms\n\n\nlogger = logging.getLogger(__name__)\n\n\ndef _check_access_token(request, agency):\n    \"\"\"\n    Ensure the request's session is configured with an access token.\n    \"\"\"\n    if not session.valid_token(request):\n        response = api.AccessTokenClient(agency).get()\n        session.update(request, token=response.access_token, token_exp=response.expiry)\n\n\ndef _index(request):\n    \"\"\"Helper handles GET requests to discounts index.\"\"\"\n    agency = session.agency(request)\n\n    _check_access_token(request, agency)\n\n    tokenize_button = \"tokenize_card\"\n    tokenize_retry_form = forms.CardTokenizeFailForm(\"discounts:retry\")\n    tokenize_success_form = forms.CardTokenizeSuccessForm(auto_id=True, label_suffix=\"\")\n\n    page = viewmodels.Page(\n        title=_(\"discounts.index.title\"),\n        content_title=_(\"discounts.index.content_title\"),\n        icon=viewmodels.Icon(\"idcardcheck\", pgettext(\"image alt text\", \"core.icons.idcardcheck\")),\n        paragraphs=[_(\"discounts.index.p1\"), _(\"discounts.index.p2\")],\n        classes=\"text-lg-center\",\n        forms=[tokenize_retry_form, tokenize_success_form],\n        buttons=[\n            viewmodels.Button.primary(\n                text=_(\"discounts.buttons.paymentpartner\"), id=tokenize_button, url=f\"#{tokenize_button}\"\n            ),\n            viewmodels.Button.link(\n                classes=\"btn-sm\", text=_(\"discounts.buttons.paymentoptions\"), url=reverse(\"core:payment_options\")\n            ),\n        ],\n    )\n    context = page.context_dict()\n\n    # add agency details\n    agency_vm = viewmodels.TransitAgency(agency)\n    context.update(agency_vm.context_dict())\n\n    # and discount provider details\n    provider_vm = viewmodels.DiscountProvider(\n        model=agency.discount_provider,\n        access_token=session.token(request),\n        element_id=f\"#{tokenize_button}\",\n        color=\"#046b99\",\n        name=f\"{agency.long_name} {_('partnered with')} {agency.discount_provider.name}\",\n    )\n    context.update(provider_vm.context_dict())\n    logger.info(f\"card_tokenize_url: {context['provider'].card_tokenize_url}\")\n\n    # the tokenize form URLs are injected to page-generated Javascript\n    context.update(\n        {\n            \"forms\": {\n                \"tokenize_retry\": reverse(tokenize_retry_form.action_url),\n                \"tokenize_success\": reverse(tokenize_success_form.action_url),\n            }\n        }\n    )\n\n    return TemplateResponse(request, \"discounts/index.html\", context)\n\n\n@decorator_from_middleware(middleware.AgencySessionRequired)\ndef index(request):\n    \"\"\"View handler for the discounts landing page.\"\"\"\n    if request.method == \"POST\":\n        response = _associate_discount(request)\n    else:\n        response = _index(request)\n\n    return response\n\n\ndef _associate_discount(request):\n    \"\"\"Helper calls the discount APIs.\"\"\"\n    logger.debug(\"Read tokenized card\")\n    form = forms.CardTokenizeSuccessForm(request.POST)\n    if not form.is_valid():\n        raise Exception(\"Invalid card token form\")\n    card_token = form.cleaned_data.get(\"card_token\")\n\n    eligibility = session.eligibility(request)\n    if len(eligibility) > 0:\n        eligibility = eligibility[0]\n        if len(eligibility) == 1:\n            logger.debug(f\"Session contains 1 {models.EligibilityType.__name__}\")\n        else:\n            logger.debug(f\"Session contains ({len(eligibility)}) {models.EligibilityType.__name__}s\")\n    else:\n        raise Exception(\"Session contains no eligibility information\")\n\n    agency = session.agency(request)\n\n    logger.debug(\"Call customer API\")\n    response = api.CustomerClient(agency).get(card_token)\n    customer_id = response.id\n\n    logger.debug(\"Call group API\")\n    eligibility = models.EligibilityType.by_name(eligibility)\n    response = api.GroupClient(agency).enroll_customer(customer_id, eligibility.group_id)\n    if response.updated_customer_id == customer_id:\n        return success(request)\n    else:\n        raise Exception(\"Updated customer_id does not match enrolled customer_id\")\n\n\n@decorator_from_middleware(middleware.AgencySessionRequired)\ndef retry(request):\n    \"\"\"View handler for a recoverable failure condition.\"\"\"\n    if request.method == \"POST\":\n        form = forms.CardTokenizeFailForm(request.POST)\n        if form.is_valid():\n            agency = session.agency(request)\n            page = viewmodels.Page(\n                title=_(\"discounts.retry.title\"),\n                icon=viewmodels.Icon(\"bankcardquestion\", pgettext(\"image alt text\", \"core.icons.bankcardquestion\")),\n                content_title=_(\"discounts.retry.title\"),\n                paragraphs=[_(\"discounts.retry.p1\")],\n                buttons=[\n                    viewmodels.Button.agency_phone_link(agency),\n                    viewmodels.Button.primary(text=_(\"discounts.retry.button\"), url=session.origin(request)),\n                ],\n            )\n            return PageTemplateResponse(request, page)\n        else:\n            raise Exception(\"Invalid retry submission.\")\n    else:\n        raise Exception(\"This view method only supports POST.\")\n\n\ndef success(request):\n    \"\"\"View handler for the final success page.\"\"\"\n    page = viewmodels.Page(\n        title=_(\"discounts.success.title\"),\n        icon=viewmodels.Icon(\"bankcardcheck\", pgettext(\"image alt text\", \"core.icons.bankcardcheck\")),\n        content_title=_(\"discounts.success.title\"),\n        paragraphs=[_(\"discounts.success.p1\"), _(\"discounts.success.p2\")],\n    )\n\n    return TemplateResponse(request, \"discounts/success.html\", page.context_dict())\n", "path": "benefits/discounts/views.py"}, {"content": "\"\"\"\nThe core application: view definition for the root of the webapp.\n\"\"\"\nfrom django.http import HttpResponseBadRequest, HttpResponseNotFound, HttpResponseServerError\nfrom django.template import loader\nfrom django.template.response import TemplateResponse\nfrom django.urls import reverse\nfrom django.utils.translation import pgettext, ugettext as _\n\nfrom . import models, session, viewmodels\n\n\ndef PageTemplateResponse(request, page_vm):\n    \"\"\"Helper returns a TemplateResponse using the common page template.\"\"\"\n    return TemplateResponse(request, \"core/page.html\", page_vm.context_dict())\n\n\ndef _index_content_title():\n    \"\"\"Helper returns the content title for the common index page.\"\"\"\n    return _(\"core.index.content_title\")\n\n\ndef _index_image():\n    \"\"\"Helper returns a viewmodels.Image for the common index page.\"\"\"\n    return viewmodels.Image(\"ridertappingbankcard.png\", pgettext(\"image alt text\", \"core.index.image\"))\n\n\ndef _index_paragraphs():\n    \"\"\"Helper returns the content paragraphs for the common index page.\"\"\"\n    return [_(\"core.index.p1\"), _(\"core.index.p2\"), _(\"core.index.p3\")]\n\n\ndef _index_url():\n    \"\"\"Helper computes the index url path.\"\"\"\n    return reverse(\"core:index\")\n\n\ndef index(request):\n    \"\"\"View handler for the main entry page.\"\"\"\n    session.reset(request)\n\n    # generate a button to the landing page for each active agency\n    agencies = models.TransitAgency.all_active()\n    buttons = [viewmodels.Button.outline_primary(text=a.short_name, url=a.index_url) for a in agencies]\n    buttons[0].classes.append(\"mt-3\")\n    buttons[0].label = _(\"core.index.chooseprovider\")\n\n    page = viewmodels.Page(\n        content_title=_index_content_title(),\n        paragraphs=_index_paragraphs(),\n        image=_index_image(),\n        buttons=buttons,\n        classes=\"home\",\n    )\n\n    return PageTemplateResponse(request, page)\n\n\ndef agency_index(request, agency):\n    \"\"\"View handler for an agency entry page.\"\"\"\n    session.reset(request)\n    session.update(request, agency=agency, origin=agency.index_url)\n\n    page = viewmodels.Page(\n        content_title=_index_content_title(),\n        paragraphs=_index_paragraphs(),\n        image=_index_image(),\n        button=viewmodels.Button.primary(text=_(\"core.index.continue\"), url=reverse(\"eligibility:index\")),\n        classes=\"home\",\n    )\n\n    return PageTemplateResponse(request, page)\n\n\ndef help(request):\n    \"\"\"View handler for the help page.\"\"\"\n    if session.active_agency(request):\n        agency = session.agency(request)\n        buttons = [viewmodels.Button.agency_phone_link(agency)]\n    else:\n        buttons = [viewmodels.Button.agency_phone_link(a) for a in models.TransitAgency.all_active()]\n\n    buttons.append(viewmodels.Button.home(request, _(\"core.buttons.back\")))\n\n    page = viewmodels.Page(\n        title=_(\"core.help\"),\n        content_title=_(\"core.help\"),\n        paragraphs=[_(\"core.help.p1\"), _(\"core.help.p2\")],\n        buttons=buttons,\n        classes=\"text-lg-center\",\n    )\n\n    return TemplateResponse(request, \"core/help.html\", page.context_dict())\n\n\ndef payment_options(request):\n    \"\"\"View handler for the Payment Options page.\"\"\"\n    page = viewmodels.Page(\n        title=_(\"core.payment-options\"),\n        icon=viewmodels.Icon(\"bankcard\", pgettext(\"image alt text\", \"core.icons.bankcard\")),\n        content_title=_(\"core.payment-options\"),\n        buttons=viewmodels.Button.home(request, text=_(\"core.buttons.back\")),\n    )\n\n    return TemplateResponse(request, \"core/payment-options.html\", page.context_dict())\n\n\ndef bad_request(request, exception, template_name=\"400.html\"):\n    \"\"\"View handler for HTTP 400 Bad Request responses.\"\"\"\n    if session.active_agency(request):\n        session.update(request, origin=session.agency(request).index_url)\n    else:\n        session.update(request, origin=_index_url())\n\n    home = viewmodels.Button.home(request)\n    page = viewmodels.ErrorPage.error(button=home)\n    t = loader.get_template(template_name)\n\n    return HttpResponseBadRequest(t.render(page.context_dict()))\n\n\ndef page_not_found(request, exception, template_name=\"404.html\"):\n    \"\"\"View handler for HTTP 404 Not Found responses.\"\"\"\n    if session.active_agency(request):\n        session.update(request, origin=session.agency(request).index_url)\n    else:\n        session.update(request, origin=_index_url())\n\n    home = viewmodels.Button.home(request)\n    page = viewmodels.ErrorPage.not_found(button=home, path=request.path)\n    t = loader.get_template(template_name)\n\n    return HttpResponseNotFound(t.render(page.context_dict()))\n\n\ndef server_error(request, template_name=\"500.html\"):\n    \"\"\"View handler for HTTP 500 Server Error responses.\"\"\"\n    if session.active_agency(request):\n        session.update(request, origin=session.agency(request).index_url)\n    else:\n        session.update(request, origin=_index_url())\n\n    home = viewmodels.Button.home(request)\n    page = viewmodels.ErrorPage.error(button=home)\n    t = loader.get_template(template_name)\n\n    return HttpResponseServerError(t.render(page.context_dict()))\n", "path": "benefits/core/views.py"}]}