Skip to content

Commit

Permalink
refactor(analytics): pass the flow in call chain
Browse files Browse the repository at this point in the history
hide the usage of flow.system_name from callers, this is an
implementation detail of the analytics code
  • Loading branch information
thekaveman committed Sep 21, 2024
1 parent bf2632a commit e3de3c5
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 29 deletions.
40 changes: 20 additions & 20 deletions benefits/eligibility/analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
The eligibility application: analytics implementation.
"""

from benefits.core import analytics as core
from benefits.core import analytics as core, models


class EligibilityEvent(core.Event):
"""Base analytics event for eligibility verification."""

def __init__(self, request, event_type, flow_name):
def __init__(self, request, event_type, flow: models.EnrollmentFlow):
super().__init__(request, event_type)
# pass a (converted from string to list) flow_name to preserve analytics reporting
enrollment_flows = [flow_name]
enrollment_flows = [flow.system_name]
# overwrite core.Event enrollment_flows
self.update_event_properties(enrollment_flows=enrollment_flows)
self.update_user_properties(enrollment_flows=enrollment_flows)
Expand All @@ -20,49 +20,49 @@ def __init__(self, request, event_type, flow_name):
class SelectedVerifierEvent(EligibilityEvent):
"""Analytics event representing the user selecting an enrollment flow."""

def __init__(self, request, enrollment_flows):
super().__init__(request, "selected enrollment flow", enrollment_flows)
def __init__(self, request, flow: models.EnrollmentFlow):
super().__init__(request, "selected enrollment flow", flow)


class StartedEligibilityEvent(EligibilityEvent):
"""Analytics event representing the beginning of an eligibility verification check."""

def __init__(self, request, enrollment_flows):
super().__init__(request, "started eligibility", enrollment_flows)
def __init__(self, request, flow: models.EnrollmentFlow):
super().__init__(request, "started eligibility", flow)


class ReturnedEligibilityEvent(EligibilityEvent):
"""Analytics event representing the end of an eligibility verification check."""

def __init__(self, request, enrollment_flows, status, error=None):
super().__init__(request, "returned eligibility", enrollment_flows)
def __init__(self, request, flow: models.EnrollmentFlow, status, error=None):
super().__init__(request, "returned eligibility", flow)
status = str(status).lower()
if status in ("error", "fail", "success"):
self.update_event_properties(status=status, error=error)
if status == "success":
self.update_user_properties(enrollment_flows=enrollment_flows)
self.update_user_properties(enrollment_flows=[flow.system_name])


def selected_verifier(request, enrollment_flows):
def selected_verifier(request, flow: models.EnrollmentFlow):
"""Send the "selected eligibility verifier" analytics event."""
core.send_event(SelectedVerifierEvent(request, enrollment_flows))
core.send_event(SelectedVerifierEvent(request, flow))


def started_eligibility(request, enrollment_flows):
def started_eligibility(request, flow: models.EnrollmentFlow):
"""Send the "started eligibility" analytics event."""
core.send_event(StartedEligibilityEvent(request, enrollment_flows))
core.send_event(StartedEligibilityEvent(request, flow))


def returned_error(request, enrollment_flows, error):
def returned_error(request, flow: models.EnrollmentFlow, error):
"""Send the "returned eligibility" analytics event with an error status."""
core.send_event(ReturnedEligibilityEvent(request, enrollment_flows, status="error", error=error))
core.send_event(ReturnedEligibilityEvent(request, flow, status="error", error=error))


def returned_fail(request, enrollment_flows):
def returned_fail(request, flow: models.EnrollmentFlow):
"""Send the "returned eligibility" analytics event with a fail status."""
core.send_event(ReturnedEligibilityEvent(request, enrollment_flows, status="fail"))
core.send_event(ReturnedEligibilityEvent(request, flow, status="fail"))


def returned_success(request, enrollment_flows):
def returned_success(request, flow: models.EnrollmentFlow):
"""Send the "returned eligibility" analytics event with a success status."""
core.send_event(ReturnedEligibilityEvent(request, enrollment_flows, status="success"))
core.send_event(ReturnedEligibilityEvent(request, flow, status="success"))
12 changes: 6 additions & 6 deletions benefits/eligibility/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def index(request):
flow = EnrollmentFlow.objects.get(id=flow_id)
session.update(request, flow=flow)

analytics.selected_verifier(request, flow.system_name)
analytics.selected_verifier(request, flow)

eligibility_start = reverse(routes.ELIGIBILITY_START)
response = redirect(eligibility_start)
Expand Down Expand Up @@ -83,7 +83,7 @@ def confirm(request):

# GET for OAuth verification
if request.method == "GET" and flow.uses_claims_verification:
analytics.started_eligibility(request, flow.system_name)
analytics.started_eligibility(request, flow)

is_verified = verify.eligibility_from_oauth(flow, session.oauth_claim(request), agency)

Expand All @@ -103,7 +103,7 @@ def confirm(request):
return TemplateResponse(request, TEMPLATE_CONFIRM, context)
# POST form submission, process form data, make Eligibility Verification API call
elif request.method == "POST":
analytics.started_eligibility(request, flow.system_name)
analytics.started_eligibility(request, flow)

form = flow.eligibility_form_instance(data=request.POST)
# form was not valid, allow for correction/resubmission
Expand All @@ -118,7 +118,7 @@ def confirm(request):

# form was not valid, allow for correction/resubmission
if is_verified is None:
analytics.returned_error(request, flow.system_name, form.errors)
analytics.returned_error(request, flow, form.errors)
context["form"] = form
return TemplateResponse(request, TEMPLATE_CONFIRM, context)
# no type was verified
Expand All @@ -135,7 +135,7 @@ def verified(request):
"""View handler for the verified eligibility page."""

flow = session.flow(request)
analytics.returned_success(request, flow.system_name)
analytics.returned_success(request, flow)

session.update(request, eligible=True)

Expand All @@ -149,6 +149,6 @@ def unverified(request):

flow = session.flow(request)

analytics.returned_fail(request, flow.system_name)
analytics.returned_fail(request, flow)

return TemplateResponse(request, flow.eligibility_unverified_template)
8 changes: 5 additions & 3 deletions tests/pytest/eligibility/test_analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
@pytest.mark.django_db
def test_EligibilityEvent_overwrites_enrollment_flows(app_request, mocker, model_EnrollmentFlow):
key, type1, type2 = "enrollment_flows", "type1", "type2"
model_EnrollmentFlow.system_name = type1
mocker.patch("benefits.core.analytics.session.flow", return_value=model_EnrollmentFlow)
mock_flow = mocker.Mock()
mock_flow.system_name = type1
mocker.patch("benefits.core.analytics.session.flow", return_value=mock_flow)

event = EligibilityEvent(app_request, "event_type", type2)
model_EnrollmentFlow.system_name = type2
event = EligibilityEvent(app_request, "event_type", model_EnrollmentFlow)

# event_properties should have been overwritten
assert key in event.event_properties
Expand Down

0 comments on commit e3de3c5

Please sign in to comment.