diff --git a/benefits/oauth/analytics.py b/benefits/oauth/analytics.py index 4565d9fa3..5f1b60ddf 100644 --- a/benefits/oauth/analytics.py +++ b/benefits/oauth/analytics.py @@ -32,8 +32,10 @@ def __init__(self, request): class FinishedSignInEvent(OAuthEvent): """Analytics event representing the end of the OAuth sign in flow.""" - def __init__(self, request): + def __init__(self, request, error=None): super().__init__(request, "finished sign in") + if error is not None: + self.update_event_properties(error_code=error) class StartedSignOutEvent(OAuthEvent): @@ -61,9 +63,9 @@ def canceled_sign_in(request): core.send_event(CanceledSignInEvent(request)) -def finished_sign_in(request): +def finished_sign_in(request, error=None): """Send the "finished sign in" analytics event.""" - core.send_event(FinishedSignInEvent(request)) + core.send_event(FinishedSignInEvent(request, error)) def started_sign_out(request): diff --git a/benefits/oauth/views.py b/benefits/oauth/views.py index ae24c2f40..3c0c5c0f4 100644 --- a/benefits/oauth/views.py +++ b/benefits/oauth/views.py @@ -64,6 +64,8 @@ def authorize(request): verifier_claim = verifier.auth_provider.claim stored_claim = None + error_claim = None + if verifier_claim: userinfo = token.get("userinfo") @@ -76,10 +78,11 @@ def authorize(request): elif claim_value == 1: # if userinfo contains our claim and the flag is 1 (true), store the *claim* stored_claim = verifier_claim + elif claim_value >= 10: + error_claim = claim_value session.update(request, oauth_token=id_token, oauth_claim=stored_claim) - - analytics.finished_sign_in(request) + analytics.finished_sign_in(request, error=error_claim) return redirect(ROUTE_CONFIRM) diff --git a/tests/pytest/oauth/test_analytics.py b/tests/pytest/oauth/test_analytics.py index 61d1afbfa..26f80a1b6 100644 --- a/tests/pytest/oauth/test_analytics.py +++ b/tests/pytest/oauth/test_analytics.py @@ -1,6 +1,6 @@ import pytest -from benefits.oauth.analytics import OAuthEvent +from benefits.oauth.analytics import OAuthEvent, FinishedSignInEvent @pytest.mark.django_db @@ -22,3 +22,15 @@ def test_OAuthEvent_verifier_no_client_name_when_does_not_use_auth_verification( event = OAuthEvent(app_request, "event type") assert "auth_provider" not in event.event_properties + + +@pytest.mark.django_db +def test_FinishedSignInEvent_with_error(app_request): + event = FinishedSignInEvent(app_request, error=10) + assert event.event_properties["error_code"] == 10 + + +@pytest.mark.django_db +def test_FinishedSignInEvent_without_error(app_request): + event = FinishedSignInEvent(app_request) + assert "error_code" not in event.event_properties diff --git a/tests/pytest/oauth/test_views.py b/tests/pytest/oauth/test_views.py index ab54c7a1a..2aa4b7900 100644 --- a/tests/pytest/oauth/test_views.py +++ b/tests/pytest/oauth/test_views.py @@ -137,6 +137,27 @@ def test_authorize_success_with_claim_false( assert result.url == reverse(ROUTE_CONFIRM) +@pytest.mark.django_db +def test_authorize_success_with_claim_error( + mocked_session_verifier_uses_auth_verification, + mocked_oauth_create_client, + mocked_analytics_module, + app_request, +): + verifier = mocked_session_verifier_uses_auth_verification.return_value + verifier.auth_provider.claim = "claim" + mocked_oauth_client = mocked_oauth_create_client.return_value + mocked_oauth_client.authorize_access_token.return_value = {"id_token": "token", "userinfo": {"claim": "10"}} + + result = authorize(app_request) + + mocked_oauth_client.authorize_access_token.assert_called_with(app_request) + mocked_analytics_module.finished_sign_in.assert_called_with(app_request, error=10) + assert session.oauth_claim(app_request) is None + assert result.status_code == 302 + assert result.url == reverse(ROUTE_CONFIRM) + + @pytest.mark.django_db @pytest.mark.usefixtures("mocked_analytics_module") def test_authorize_success_without_verifier_claim(