Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion openedx_filters/learning/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Package where filters related to the learning architectural subdomain are implemented.
"""

from typing import Any, Optional
from typing import Any, Optional, Union

from django.db.models.query import QuerySet
from django.http import HttpResponse, QueryDict
Expand Down Expand Up @@ -1445,3 +1445,45 @@ def run_filter(cls, schedules: QuerySet) -> QuerySet | None:
"""
data = super().run_pipeline(schedules=schedules)
return data.get("schedules")


class GradeEventContextRequested(OpenEdxPublicFilter):
"""
Filter used to enrich the context dict emitted with a grade analytics event.

Purpose:
This filter is triggered just before a grade-related analytics event is emitted,
allowing pipeline steps to inject additional key-value pairs into the event
tracking context.

Filter Type:
org.openedx.learning.grade.context.requested.v1

Trigger:
- Repository: openedx/edx-platform
- Path: lms/djangoapps/grades/events.py
- Function or Method: course_grade_passed_first_time
"""

filter_type = "org.openedx.learning.grade.context.requested.v1"

@classmethod
def run_filter(
cls,
context: dict,
user_id: int,
course_id: Union[str, Any],
) -> Optional[dict]:
"""
Process the context dict using the configured pipeline steps.

Arguments:
context (dict): the event tracking context dict to be enriched.
user_id (int): the ID of the user whose grade event is being emitted.
course_id (str or CourseKey): the course identifier for the grade event.

Returns:
dict: the context dict, possibly enriched by pipeline steps.
"""
data = super().run_pipeline(context=context, user_id=user_id, course_id=course_id)
return data.get("context")
33 changes: 33 additions & 0 deletions openedx_filters/learning/tests/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
CourseRunAPIRenderStarted,
CourseUnenrollmentStarted,
DashboardRenderStarted,
GradeEventContextRequested,
IDVPageURLRequested,
InstructorDashboardRenderStarted,
ORASubmissionViewRenderStarted,
Expand Down Expand Up @@ -801,3 +802,35 @@ def test_schedule_requested(self):
result = ScheduleQuerySetRequested.run_filter(schedules)

self.assertEqual(schedules, result)


class TestGradeEventContextRequestedFilter(TestCase):
"""
Tests for the GradeEventContextRequested filter.
"""

def test_run_filter_returns_context_unchanged_when_no_pipeline(self):
"""
When no pipeline steps are configured, run_filter returns the original context.
"""
context = {"course_id": "course-v1:org+course+run"}
user_id = 42
course_id = "course-v1:org+course+run"

with patch.object(GradeEventContextRequested, "run_pipeline", return_value={"context": context}):
result = GradeEventContextRequested.run_filter(
context=context,
user_id=user_id,
course_id=course_id,
)

self.assertEqual(result, context)

def test_filter_type(self):
"""
Confirm the filter type string is correct.
"""
self.assertEqual(
GradeEventContextRequested.filter_type,
"org.openedx.learning.grade.context.requested.v1",
)