Repository: cal-itp/benefits

Issue:
New `User enrollment error` page
![image](https://github.com/cal-itp/benefits/assets/25497886/22e984b8-ecb1-4f25-a9ce-c7a3eed5c5b0)


## Acceptance Criteria

<!-- Remember to consider edge cases -->

- [x] Headline copy updated
- [x] Body copy updated
- [x] 24px spacing between icon, headline, body, and agency info
- [x] 64px spacing between CTA and the thing above it
- [x] Login.gov and non-login.gov variants (with and without the Sign out button)


## Additional context

 - Handles the case of the user entering the wrong card information (e.g. expiration date, security code)
 - Littlepay responds with an error in Hosted Card Tokenization flow (Javascript)




Discussion:

Resolving patch:
diff --git a/benefits/enrollment/views.py b/benefits/enrollment/views.py
--- a/benefits/enrollment/views.py
+++ b/benefits/enrollment/views.py
@@ -212,17 +212,8 @@ def reenrollment_error(request):
 @decorator_from_middleware(EligibleSessionRequired)
 def retry(request):
     """View handler for a recoverable failure condition."""
-    if request.method == "POST":
-        analytics.returned_retry(request)
-        form = forms.CardTokenizeFailForm(request.POST)
-        if form.is_valid():
-            return TemplateResponse(request, TEMPLATE_RETRY)
-        else:
-            analytics.returned_error(request, "Invalid retry submission.")
-            raise Exception("Invalid retry submission.")
-    else:
-        analytics.returned_error(request, "This view method only supports POST.")
-        raise Exception("This view method only supports POST.")
+    analytics.returned_retry(request)
+    return TemplateResponse(request, TEMPLATE_RETRY)
 
 
 @pageview_decorator


Test patch:
diff --git a/tests/pytest/enrollment/test_views.py b/tests/pytest/enrollment/test_views.py
--- a/tests/pytest/enrollment/test_views.py
+++ b/tests/pytest/enrollment/test_views.py
@@ -623,28 +623,19 @@ def test_retry_ineligible(client):
 
 
 @pytest.mark.django_db
-@pytest.mark.usefixtures("mocked_session_eligibility")
-def test_retry_get(client):
+@pytest.mark.usefixtures("mocked_session_agency", "mocked_session_eligibility")
+def test_retry_get(client, mocked_analytics_module):
     path = reverse(ROUTE_RETRY)
-    with pytest.raises(Exception, match=r"POST"):
-        client.get(path)
-
-
-@pytest.mark.django_db
-@pytest.mark.usefixtures("mocked_session_eligibility")
-def test_retry_invalid_form(mocker, client):
-    mocker.patch("benefits.enrollment.views.forms.CardTokenizeFailForm.is_valid", return_value=False)
+    response = client.get(path)
 
-    path = reverse(ROUTE_RETRY)
-    with pytest.raises(Exception, match=r"Invalid"):
-        client.post(path)
+    assert response.status_code == 200
+    assert response.template_name == TEMPLATE_RETRY
+    mocked_analytics_module.returned_retry.assert_called_once()
 
 
 @pytest.mark.django_db
 @pytest.mark.usefixtures("mocked_session_agency", "mocked_session_eligibility")
-def test_retry_valid_form(mocker, client, mocked_analytics_module):
-    mocker.patch("benefits.enrollment.views.forms.CardTokenizeFailForm.is_valid", return_value=True)
-
+def test_retry_valid_form(client, mocked_analytics_module):
     path = reverse(ROUTE_RETRY)
     response = client.post(path)