diff --git a/benefits/enrollment/templates/enrollment/reenrollment-error.html b/benefits/enrollment/templates/enrollment/reenrollment-error.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/benefits/enrollment/views.py b/benefits/enrollment/views.py index a5fe89e427..0d2fe59925 100644 --- a/benefits/enrollment/views.py +++ b/benefits/enrollment/views.py @@ -29,6 +29,7 @@ ROUTE_TOKEN = "enrollment:token" TEMPLATE_INDEX = "enrollment/index.html" +TEMPLATE_REENROLLMENT_ERROR = "enrollment/reenrollment-error.html" TEMPLATE_RETRY = "enrollment/retry.html" TEMPLATE_SUCCESS = "enrollment/success.html" @@ -141,7 +142,7 @@ def index(request): return _success(request, group_id) else: # re-enrollment error, return enrollment error with expiration and reenrollment_date - pass + return reenrollment_error(request) else: # eligibility does not support expiration if not already_enrolled: # enroll user with no expiration date, return success @@ -225,6 +226,11 @@ def _calculate_expiry(expiration_days): return expiry_datetime +def reenrollment_error(request): + analytics.returned_error(request, "Re-enrollment error") + return TemplateResponse(request, TEMPLATE_REENROLLMENT_ERROR) + + @decorator_from_middleware(EligibleSessionRequired) def retry(request): """View handler for a recoverable failure condition.""" diff --git a/tests/pytest/enrollment/test_views.py b/tests/pytest/enrollment/test_views.py index 75f4b36465..6e2a99defb 100644 --- a/tests/pytest/enrollment/test_views.py +++ b/tests/pytest/enrollment/test_views.py @@ -17,6 +17,7 @@ ROUTE_SUCCESS, ROUTE_RETRY, TEMPLATE_INDEX, + TEMPLATE_REENROLLMENT_ERROR, TEMPLATE_SUCCESS, TEMPLATE_RETRY, _calculate_expiry, @@ -500,6 +501,41 @@ def test_index_eligible_post_valid_form_success_supports_expiration_is_within_re assert model_EligibilityType_supports_expiration.group_id in mocked_analytics_module.returned_success.call_args.args +@pytest.mark.django_db +@pytest.mark.usefixtures( + "mocked_session_agency", + "mocked_session_verifier", + "mocked_session_eligibility", + "model_EligibilityType_supports_expiration", +) +def test_index_eligible_post_valid_form_success_supports_expiration_is_not_expired_yet( + mocker, + client, + card_tokenize_form_data, + mocked_analytics_module, + mocked_funding_source, + mocked_group_funding_source_with_expiration, +): + mock_client_cls = mocker.patch("benefits.enrollment.views.Client") + mock_client = mock_client_cls.return_value + mock_client.get_funding_source_by_token.return_value = mocked_funding_source + + # mock that a funding source already exists, doesn't matter what concession_expiry is + mocker.patch( + "benefits.enrollment.views._get_group_funding_source", return_value=mocked_group_funding_source_with_expiration + ) + + mocker.patch("benefits.enrollment.views._is_expired", return_value=False) + mocker.patch("benefits.enrollment.views._is_within_reenrollment_window", return_value=False) + + path = reverse(ROUTE_INDEX) + response = client.post(path, card_tokenize_form_data) + + assert response.status_code == 200 + assert response.template_name == TEMPLATE_REENROLLMENT_ERROR + mocked_analytics_module.returned_error.assert_called_once() + + @pytest.mark.django_db @pytest.mark.usefixtures("mocked_session_agency", "mocked_session_verifier", "mocked_session_eligibility") def test_index_eligible_post_valid_form_success_does_not_support_expiration_has_expiration_date(