diff --git a/openedx_filters/learning/filters.py b/openedx_filters/learning/filters.py index 6db44fd3..0de5d884 100644 --- a/openedx_filters/learning/filters.py +++ b/openedx_filters/learning/filters.py @@ -1445,3 +1445,40 @@ def run_filter(cls, schedules: QuerySet) -> QuerySet | None: """ data = super().run_pipeline(schedules=schedules) return data.get("schedules") + + +class CourseModeCheckoutStarted(OpenEdxPublicFilter): + """ + Filter used to enrich the course mode checkout context before the checkout flow begins. + + Purpose: + This filter is triggered when a user selects a course mode and the checkout process + starts. Pipeline steps can modify the context dict to inject additional data required + by external systems (e.g. pricing APIs) to customise the checkout experience. + + Filter Type: + org.openedx.learning.course_mode.checkout.started.v1 + + Trigger: + - Repository: openedx/edx-platform + - Path: common/djangoapps/course_modes/views.py + - Function or Method: ChooseModeView.post + """ + + filter_type = "org.openedx.learning.course_mode.checkout.started.v1" + + @classmethod + def run_filter(cls, context: dict, request: Any, course_mode: Any) -> dict: + """ + Process the checkout context through the configured pipeline steps. + + Arguments: + context (dict): the checkout context dict. + request (HttpRequest): the current HTTP request. + course_mode (CourseMode): the selected course mode object. + + Returns: + dict: the (possibly enriched) checkout context. + """ + data = super().run_pipeline(context=context, request=request, course_mode=course_mode) + return data.get("context") diff --git a/openedx_filters/learning/tests/test_filters.py b/openedx_filters/learning/tests/test_filters.py index b4ccf69a..f88fcd20 100644 --- a/openedx_filters/learning/tests/test_filters.py +++ b/openedx_filters/learning/tests/test_filters.py @@ -19,6 +19,7 @@ CourseEnrollmentQuerysetRequested, CourseEnrollmentStarted, CourseHomeUrlCreationStarted, + CourseModeCheckoutStarted, CourseRunAPIRenderStarted, CourseUnenrollmentStarted, DashboardRenderStarted, @@ -801,3 +802,29 @@ def test_schedule_requested(self): result = ScheduleQuerySetRequested.run_filter(schedules) self.assertEqual(schedules, result) + + +@ddt +class TestCourseModeFilters(TestCase): + """ + Test class to verify standard behavior of the course mode filters. + + You'll find test suites for: + - `CourseModeCheckoutStarted` + """ + + def test_course_mode_checkout_started(self): + """ + Test CourseModeCheckoutStarted filter behavior under normal conditions. + + Expected behavior: + - The filter must have the signature specified. + - The filter should return the (possibly enriched) context dict. + """ + context = {"course_id": "course-v1:edX+DemoX+Demo_Course"} + request = Mock() + course_mode = Mock() + + result = CourseModeCheckoutStarted.run_filter(context, request, course_mode) + + self.assertEqual(context, result)