internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: cal-itp/benefits

Issue:
Auto select Transit Agency when only 1 Active
Simplify the flow for a user, and avoid having to deal with the design of a single button on the `core:index` page.

When there is only 1 active transit agency, and user lands on `core:index`, forward to the active agency's `core:agency_index` page.


Discussion:

Resolving patch:
diff --git a/benefits/core/views.py b/benefits/core/views.py
--- a/benefits/core/views.py
+++ b/benefits/core/views.py
@@ -2,6 +2,7 @@
 The core application: view definition for the root of the webapp.
 """
 from django.http import HttpResponseBadRequest, HttpResponseNotFound, HttpResponseServerError
+from django.shortcuts import redirect
 from django.template import loader
 from django.template.response import TemplateResponse
 from django.urls import reverse
@@ -31,8 +32,13 @@ def index(request):
     """View handler for the main entry page."""
     session.reset(request)
 
-    # generate a button to the landing page for each active agency
     agencies = models.TransitAgency.all_active()
+
+    if len(agencies) == 1:
+        agency = agencies[0]
+        return redirect(agency.index_url)
+
+    # generate a button to the landing page for each active agency
     buttons = [viewmodels.Button.outline_primary(text=a.short_name, url=a.index_url) for a in agencies]
     buttons[0].classes.append("mt-3")
     buttons[0].label = _("core.pages.index.chooseprovider")


Test patch:
diff --git a/tests/pytest/core/test_views.py b/tests/pytest/core/test_views.py
--- a/tests/pytest/core/test_views.py
+++ b/tests/pytest/core/test_views.py
@@ -6,13 +6,24 @@
 
 
 @pytest.mark.django_db
-def test_homepage(client):
+def test_homepage_multiple_agencies(client):
+    """Assumes that fixture data contains multiple active agencies."""
     path = reverse("core:index")
     response = client.get(path)
     assert response.status_code == 200
     assert "transit" in str(response.content)
 
 
+@pytest.mark.django_db
+def test_homepage_single_agency(mocker, client):
+    agencies = TransitAgency.all_active()[:1]
+    mocker.patch("benefits.core.models.TransitAgency.all_active", return_value=agencies)
+    path = reverse("core:index")
+    response = client.get(path)
+    assert response.status_code == 302
+    assert response.url == agencies[0].index_url
+
+
 @pytest.mark.django_db
 def test_help(client):
     path = reverse("core:help")
Repository: cal-itp/benefits

Issue:
Enrollment: Success (signed out): Use the full-screen with no image
![image](https://user-images.githubusercontent.com/3673236/167704977-ba0cd831-ae56-488c-b720-cceeaba6707f.png)

Use the fullscreen view instead


Discussion:
This ticket could be paired with this refactor ticket for this same page: https://github.com/cal-itp/benefits/issues/513

Resolving patch:
diff --git a/benefits/enrollment/views.py b/benefits/enrollment/views.py
--- a/benefits/enrollment/views.py
+++ b/benefits/enrollment/views.py
@@ -145,32 +145,26 @@ def success(request):
     request.path = "/enrollment/success"
     session.update(request, origin=reverse("enrollment:success"))
     verifier = session.verifier(request)
+    icon = viewmodels.Icon("bankcardcheck", pgettext("image alt text", "core.icons.bankcardcheck"))
+    page = viewmodels.Page(
+        title=_("enrollment.pages.success.title"),
+        content_title=_("enrollment.pages.success.content_title"),
+    )
 
     if verifier.requires_authentication:
         if settings.OAUTH_CLIENT_NAME is None:
             raise Exception("EligibilityVerifier requires authentication, but OAUTH_CLIENT_NAME is None")
 
         if session.logged_in(request):
-            button = viewmodels.Button.logout()
-            page = viewmodels.Page(
-                title=_("enrollment.pages.success.title"),
-                icon=viewmodels.Icon("bankcardcheck", pgettext("image alt text", "core.icons.bankcardcheck")),
-                content_title=_("enrollment.pages.success.content_title"),
-                button=button,
-                classes="logged-in",
-            )
+            page.buttons = [viewmodels.Button.logout()]
+            page.classes = ["logged-in"]
+            page.icon = icon
         else:
-            page = viewmodels.Page(
-                title=_("enrollment.pages.success.title"),
-                content_title=_("enrollment.pages.success.logout.title"),
-                classes="logged-out",
-            )
+            page.classes = ["logged-out"]
+            page.content_title = _("enrollment.pages.success.logout.title")
+            page.noimage = True
     else:
-        page = viewmodels.Page(
-            title=_("enrollment.pages.success.title"),
-            content_title=_("enrollment.pages.success.content_title"),
-            icon=viewmodels.Icon("bankcardcheck", pgettext("image alt text", "core.icons.bankcardcheck")),
-        )
+        page.icon = icon
 
     help_link = reverse("core:help")
     context_dict = {**page.context_dict(), **{"help_link": help_link}}


Test patch:
Repository: cal-itp/benefits

Issue:
Engineering: Front-end - Redesign the `Get started with Login.gov` button
Redesign the `Get started with Login.gov` button to new specs:


- The text `Get started with` is moved into the button
- New font required: Public Sans https://github.com/uswds/public-sans
- Button should elegantly and responsively resize itself in 1-line mode and 2-line mode
- The fallback `Login.gov` text should also be there for screenreaders
- Desktop composition: 289px x 41px
<img width="334" alt="image" src="https://user-images.githubusercontent.com/3673236/172735124-93f631bc-d655-4aff-a6d9-faf07dcef0e2.png">

- Mobile composition: 2-line mobile size, 289px x 72px
<img width="363" alt="image" src="https://user-images.githubusercontent.com/3673236/172735067-3e785d8f-235b-4e32-af0a-bcf17eed6ca5.png">


https://www.figma.com/file/SeSd3LaLd6WkbEYhmtKpO3/Benefits-(IAL2-Login.gov)?node-id=3830%3A9882


Discussion:

Resolving patch:
diff --git a/benefits/settings.py b/benefits/settings.py
--- a/benefits/settings.py
+++ b/benefits/settings.py
@@ -267,7 +267,7 @@ def _filter_empty(ls):
 env_connect_src = _filter_empty(os.environ.get("DJANGO_CSP_CONNECT_SRC", "").split(","))
 CSP_CONNECT_SRC.extend(env_connect_src)
 
-CSP_FONT_SRC = ["https://california.azureedge.net/cdt/statetemplate/", "https://fonts.gstatic.com/"]
+CSP_FONT_SRC = ["'self'", "https://california.azureedge.net/cdt/statetemplate/", "https://fonts.gstatic.com/"]
 env_font_src = _filter_empty(os.environ.get("DJANGO_CSP_FONT_SRC", "").split(","))
 CSP_FONT_SRC.extend(env_font_src)
 


Test patch:
Repository: cal-itp/benefits

Issue:
Set up error monitoring
[Discussion](https://cal-itp.slack.com/archives/C013W8RUAMU/p1649779283917369)

_As a developer on the Benefits application, I want to know when users encounter errors so that I can ensure the service is reliable._

- [ ] Check with DMV about what they have set up
- [x] Write up what we're looking to do


Discussion:
[Writeup.](https://docs.google.com/document/d/1e79AHO5WkDbDwyGY2uDfiKKNvToPLxp7AIaIl_Ul4GQ/edit) Would love feedback!

Resolving patch:
diff --git a/benefits/core/middleware.py b/benefits/core/middleware.py
--- a/benefits/core/middleware.py
+++ b/benefits/core/middleware.py
@@ -147,3 +147,18 @@ def process_view(self, request, view_func, view_args, view_kwargs):
             return None
 
         return redirect("oauth:login")
+
+
+# https://github.com/census-instrumentation/opencensus-python/issues/766
+class LogErrorToAzure(MiddlewareMixin):
+    def __init__(self, get_response):
+        self.get_response = get_response
+        # wait to do this here to be sure the handler is initialized
+        self.azure_logger = logging.getLogger("azure")
+
+    def process_exception(self, request, exception):
+        # https://stackoverflow.com/a/45532289
+        msg = getattr(exception, "message", repr(exception))
+        self.azure_logger.exception(msg, exc_info=exception)
+
+        return None
diff --git a/benefits/settings.py b/benefits/settings.py
--- a/benefits/settings.py
+++ b/benefits/settings.py
@@ -73,7 +73,12 @@ def _filter_empty(ls):
 
 ENABLE_AZURE_INSIGHTS = "APPLICATIONINSIGHTS_CONNECTION_STRING" in os.environ
 if ENABLE_AZURE_INSIGHTS:
-    MIDDLEWARE.append("opencensus.ext.django.middleware.OpencensusMiddleware")
+    MIDDLEWARE.extend(
+        [
+            "opencensus.ext.django.middleware.OpencensusMiddleware",
+            "benefits.core.middleware.LogErrorToAzure",
+        ]
+    )
 
 # only used if enabled above
 OPENCENSUS = {


Test patch:
Repository: cal-itp/benefits

Issue:
Ensure relevant analytics events are fired for Login.gov IAL2 flow
Design to collaborate with Dev to ensure the behaviors they are interested in understanding are defined in Amplitude. 

- [x] `cancel_sign_in`


Discussion:

Resolving patch:
diff --git a/benefits/oauth/analytics.py b/benefits/oauth/analytics.py
--- a/benefits/oauth/analytics.py
+++ b/benefits/oauth/analytics.py
@@ -20,6 +20,13 @@ def __init__(self, request):
         super().__init__(request, "started sign in")
 
 
+class CanceledSignInEvent(OAuthEvent):
+    """Analytics event representing the canceling of application sign in."""
+
+    def __init__(self, request):
+        super().__init__(request, "canceled sign in")
+
+
 class FinishedSignInEvent(OAuthEvent):
     """Analytics event representing the end of the OAuth sign in flow."""
 
@@ -31,7 +38,7 @@ class StartedSignOutEvent(OAuthEvent):
     """Analytics event representing the beginning of application sign out."""
 
     def __init__(self, request):
-        super().__init__(request, "started signed out")
+        super().__init__(request, "started sign out")
 
 
 class FinishedSignOutEvent(OAuthEvent):
@@ -47,6 +54,11 @@ def started_sign_in(request):
     core.send_event(StartedSignInEvent(request))
 
 
+def canceled_sign_in(request):
+    """Send the "canceled sign in" analytics event."""
+    core.send_event(CanceledSignInEvent(request))
+
+
 def finished_sign_in(request):
     """Send the "finished sign in" analytics event."""
     core.send_event(FinishedSignInEvent(request))
diff --git a/benefits/oauth/views.py b/benefits/oauth/views.py
--- a/benefits/oauth/views.py
+++ b/benefits/oauth/views.py
@@ -80,6 +80,9 @@ def authorize(request):
 
 def cancel(request):
     """View implementing cancellation of OIDC authorization."""
+
+    analytics.canceled_sign_in(request)
+
     return redirect(ROUTE_UNVERIFIED)
 
 


Test patch:
diff --git a/tests/pytest/oauth/test_views.py b/tests/pytest/oauth/test_views.py
--- a/tests/pytest/oauth/test_views.py
+++ b/tests/pytest/oauth/test_views.py
@@ -135,11 +135,12 @@ def test_authorize_success_without_claim(mocked_session_verifier_auth_required,
     assert result.url == reverse(ROUTE_CONFIRM)
 
 
-def test_cancel(app_request):
+def test_cancel(mocked_analytics_module, app_request):
     unverified_route = reverse(ROUTE_UNVERIFIED)
 
     result = cancel(app_request)
 
+    mocked_analytics_module.canceled_sign_in.assert_called_once()
     assert result.status_code == 302
     assert result.url == unverified_route
Repository: cal-itp/benefits

Issue:
Update the unverified page to match mockup
Make `unverified` page match Figma mockup.

## Acceptance Criteria
- [ ] Page should not have an image
- [ ] Copy needs to match
- [ ] Match text centering

## Additional context
The error flows were updated in #643.

| **Current unverified page** | **Figma mockup** |
| ------------------------------ | --------------------- |
| ![image](https://user-images.githubusercontent.com/25497886/176710098-fc51bc48-5625-41bc-bd12-9cce41fd2bf0.png) | ![image](https://user-images.githubusercontent.com/25497886/176709960-739515c4-b0b4-4d77-b249-1140767554b6.png) |




Discussion:

Resolving patch:
diff --git a/benefits/core/viewmodels.py b/benefits/core/viewmodels.py
--- a/benefits/core/viewmodels.py
+++ b/benefits/core/viewmodels.py
@@ -48,8 +48,11 @@ def agency_contact_links(agency):
         ]
 
     @staticmethod
-    def home(request, text=_("core.buttons.return_home")):
+    def home(request, text=None):
         """Create a button back to this session's origin."""
+        if text is None:
+            text = _("core.buttons.return_home")
+
         return Button.primary(text=text, url=session.origin(request))
 
     @staticmethod
diff --git a/benefits/eligibility/views.py b/benefits/eligibility/views.py
--- a/benefits/eligibility/views.py
+++ b/benefits/eligibility/views.py
@@ -231,16 +231,17 @@ def unverified(request):
     # tel: link to agency phone number
     agency = session.agency(request)
     buttons = viewmodels.Button.agency_contact_links(agency)
-    buttons.append(viewmodels.Button.home(request, _("core.buttons.retry")))
+    buttons.append(viewmodels.Button.home(request))
 
     verifier = session.verifier(request)
 
     page = viewmodels.Page(
+        noimage=True,
         title=_(verifier.unverified_title),
         classes="with-agency-links",
         content_title=_(verifier.unverified_content_title),
         icon=viewmodels.Icon("idcardquestion", pgettext("image alt text", "core.icons.idcardquestion")),
-        paragraphs=[_(verifier.unverified_blurb), _("eligibility.pages.unverified.p[1]")],
+        paragraphs=[_(verifier.unverified_blurb)],
         buttons=buttons,
     )
 


Test patch:
Repository: cal-itp/benefits

Issue:
Use the common base Docker image
This is a corollary to work done in cal-itp/eligibility-server#123.

We have a new repository [`cal-itp/docker-python-web`](https://github.com/cal-itp/docker-python-web) that publishes a Docker image to GitHub Container Registry at [`ghcr.io/cal-itp/docker-python-web`](https://github.com/cal-itp/docker-python-web/pkgs/container/docker-python-web).

This image contains a baseline `nginx` and `gunicorn` setup and configuration. We can replace the Benefits app container's base image with this image to simplify the repository and build process for Benefits.

## Acceptance Criteria

<!-- Remember to consider edge cases -->

- [ ] the Benefits app container builds `FROM ghcr.io/cal-itp/docker-python-web`
- [ ] duplicate `nginx` and `gunicorn` setup in this repository is removed
- [ ] the app runs locally as a container `docker compose up client`
- [ ] the devcontainer starts up
- [ ] the app runs in DEBUG mode in the devcontainer with `F5`

## Additional context

See the [`docker-python-web` Docs](https://docs.calitp.org/docker-python-web/) for more information.


Discussion:
@angela-tran @machikoyasuda since I did the Eligibility Server side of this, I thought it might be interesting for one (or both) of you to work on the Benefits side. 

Thoughts?

Resolving patch:
diff --git a/.devcontainer/server/settings.py b/.devcontainer/server/settings.py
--- a/.devcontainer/server/settings.py
+++ b/.devcontainer/server/settings.py
@@ -11,7 +11,7 @@
 
 # Data settings
 
-IMPORT_FILE_PATH = "/.devcontainer/server/data.csv"
+IMPORT_FILE_PATH = "https://raw.githubusercontent.com/cal-itp/eligibility-server/main/data/server.csv"
 INPUT_HASH_ALGO = ""
 
 # CSV-specific settings
diff --git a/appcontainer/gunicorn.conf.py b/appcontainer/gunicorn.conf.py
deleted file mode 100644
--- a/appcontainer/gunicorn.conf.py
+++ /dev/null
@@ -1,21 +0,0 @@
-"""
-The Gunicorn configuration file
-More information: https://docs.gunicorn.org/en/stable/settings.html
-"""
-
-import multiprocessing
-
-# the unix socket defined in nginx.conf
-bind = "unix:/home/calitp/app/run/gunicorn.sock"
-
-# Recommend (2 x $num_cores) + 1 as the number of workers to start off with
-workers = multiprocessing.cpu_count() * 2 + 1
-
-# send logs to stdout and stderr
-accesslog = "-"
-errorlog = "-"
-
-# Preloading can save some RAM resources as well as speed up server boot times,
-# at the cost of not being able to reload app code by restarting workers
-# (in an ECS Fargate environment, this isn't possible anyway)
-preload_app = True


Test patch:
Repository: cal-itp/benefits

Issue:
Add verifier property to Events
Soon users will have multiple pathways to verify eligibility, and it would be useful to know how many users are taking which pathway(s) in our analytics. We can get ahead of this now by adding an event property with the user's selected verifier (if any).

Let's add this to the base Event definition so that we can later filter any event type by this property, similar to the Transit Agency information attached to each event.

Linking this Amplitude reference again: https://help.amplitude.com/hc/en-us/articles/115002380567-User-properties-and-event-properties

## Acceptance Criteria

<!-- Remember to consider edge cases -->

- [ ] The base Event has an `eligibility_verifier` event property that gets its value from the user's `session.verifier()`
- [ ] The Amplitude Tracking Plan is updated to accept this event property
- [ ] The Amplitude --> Warehouse --> Metabase pipeline is updated to ingest this property

## Additional context

This task was broken out from #342 and is focused on adding the verifier information to _existing_ events. #342 is now focused on introducing _new_ events for some forthcoming UI.



Discussion:

Resolving patch:
diff --git a/benefits/core/analytics.py b/benefits/core/analytics.py
--- a/benefits/core/analytics.py
+++ b/benefits/core/analytics.py
@@ -43,8 +43,10 @@ def __init__(self, request, event_type, **kwargs):
 
         agency = session.agency(request)
         agency_name = agency.long_name if agency else None
+        verifier = session.verifier(request)
+        verifier_name = verifier.name if verifier else None
 
-        self.update_event_properties(path=request.path, transit_agency=agency_name)
+        self.update_event_properties(path=request.path, transit_agency=agency_name, eligibility_verifier=verifier_name)
 
         uagent = request.headers.get("user-agent")
 
@@ -52,7 +54,13 @@ def __init__(self, request, event_type, **kwargs):
         match = Event._domain_re.match(ref) if ref else None
         refdom = match.group(1) if match else None
 
-        self.update_user_properties(referrer=ref, referring_domain=refdom, user_agent=uagent, transit_agency=agency_name)
+        self.update_user_properties(
+            referrer=ref,
+            referring_domain=refdom,
+            user_agent=uagent,
+            transit_agency=agency_name,
+            eligibility_verifier=verifier_name,
+        )
 
         # event is initialized, consume next counter
         self.event_id = next(Event._counter)


Test patch:
diff --git a/tests/pytest/conftest.py b/tests/pytest/conftest.py
--- a/tests/pytest/conftest.py
+++ b/tests/pytest/conftest.py
@@ -222,6 +222,7 @@ def mocked_session_verifier_oauth(mocker, model_EligibilityVerifier_AuthProvider
 @pytest.fixture
 def mocked_session_verifier_auth_required(mocker, model_EligibilityVerifier, mocked_session_verifier):
     mock_verifier = mocker.Mock(spec=model_EligibilityVerifier)
+    mock_verifier.name = model_EligibilityVerifier.name
     mock_verifier.is_auth_required = True
     mocked_session_verifier.return_value = mock_verifier
     return mocked_session_verifier
Repository: cal-itp/benefits

Issue:
Use 500 page for true application errors
A clear and concise description of the task.

## Acceptance Criteria

<!-- Remember to consider edge cases -->

- [ ] Use 500 / service is down for true application errors, EV server offline, Auth provider offline, etc.

## Additional context

<!-- Add any other context about the task here -->
Related to https://github.com/cal-itp/benefits/issues/913 https://github.com/cal-itp/benefits/issues/757 #914 


Discussion:

Resolving patch:
diff --git a/benefits/core/viewmodels.py b/benefits/core/viewmodels.py
--- a/benefits/core/viewmodels.py
+++ b/benefits/core/viewmodels.py
@@ -185,7 +185,7 @@ def user_error(
     def server_error(
         title=_("core.pages.server_error.title"),
         content_title=_("core.pages.server_error.title"),
-        paragraphs=[_("core.pages.server_error.p[0]"), _("core.pages.server_error.p[1]")],
+        paragraphs=[_("core.pages.server_error.p[0]")],
         **kwargs,
     ):
         """Create a new core.viewmodels.ErrorPage instance with defaults for a generic server error."""


Test patch:
diff --git a/tests/pytest/core/test_viewmodels.py b/tests/pytest/core/test_viewmodels.py
--- a/tests/pytest/core/test_viewmodels.py
+++ b/tests/pytest/core/test_viewmodels.py
@@ -12,7 +12,7 @@
             ErrorPage.server_error,
             "core.pages.server_error.title",
             "core.pages.server_error.title",
-            ["core.pages.server_error.p[0]", "core.pages.server_error.p[1]"],
+            ["core.pages.server_error.p[0]"],
             id="server_error",
         ),
         pytest.param(
Repository: cal-itp/benefits

Issue:
Make buttons use title-case
## Acceptance Criteria
- [ ] All buttons are using title case

## Additional context
This is according to the design in Figma


Discussion:

Resolving patch:
diff --git a/benefits/core/views.py b/benefits/core/views.py
--- a/benefits/core/views.py
+++ b/benefits/core/views.py
@@ -56,19 +56,15 @@ def agency_index(request, agency):
         return redirect(reverse(ROUTE_ELIGIBILITY))
 
     button = viewmodels.Button.primary(text=_("core.pages.index.continue"), url=reverse(ROUTE_ELIGIBILITY))
-    button.label = _("core.pages.agency_index.button.label")
 
     page = viewmodels.Page(
         title=_("core.pages.agency_index.title"),
-        content_title=_("core.pages.agency_index.content_title"),
+        content_title=_("core.pages.agency_index.mst_cc.content_title"),
         button=button,
         classes="home",
     )
 
-    help_page = reverse(ROUTE_HELP)
-    context_dict = {**page.context_dict(), **{"info_link": f"{help_page}#about"}}
-
-    return TemplateResponse(request, TEMPLATE_AGENCY, context_dict)
+    return TemplateResponse(request, TEMPLATE_AGENCY, page.context_dict())
 
 
 @pageview_decorator


Test patch: