diff --git a/openedx_filters/learning/filters.py b/openedx_filters/learning/filters.py index 6db44fd3..8772c0b3 100644 --- a/openedx_filters/learning/filters.py +++ b/openedx_filters/learning/filters.py @@ -1445,3 +1445,45 @@ def run_filter(cls, schedules: QuerySet) -> QuerySet | None: """ data = super().run_pipeline(schedules=schedules) return data.get("schedules") + + +class CoursewareViewRedirectURL(OpenEdxPublicFilter): + """ + Filter used to determine whether a courseware view should redirect the user. + + Purpose: + This filter is triggered before a courseware view is rendered, allowing pipeline + steps to append redirect URLs to ``redirect_urls``. If the list is non-empty after + the pipeline runs, the view redirects the user to the first URL in the list. + + Filter Type: + org.openedx.learning.courseware.view.redirect_url.requested.v1 + + Trigger: + - Repository: openedx/edx-platform + - Path: lms/djangoapps/courseware/decorators.py + - Function or Method: courseware_view_redirect + """ + + filter_type = "org.openedx.learning.courseware.view.redirect_url.requested.v1" + + @classmethod + def run_filter(cls, redirect_urls: list, request: Any, course_key: Any) -> tuple: + """ + Process the inputs using the configured pipeline steps. + + Arguments: + redirect_urls (list): initial list of redirect URLs (typically empty). + request (HttpRequest): the current Django HTTP request. + course_key (CourseKey): the course key for the view being accessed. + + Returns: + tuple[list, HttpRequest, CourseKey]: + - list: the (possibly extended) list of redirect URLs. + - HttpRequest: the request object (unchanged). + - CourseKey: the course key (unchanged). + """ + data = super().run_pipeline( + redirect_urls=redirect_urls, request=request, course_key=course_key + ) + return data.get("redirect_urls"), data.get("request"), data.get("course_key") diff --git a/openedx_filters/learning/tests/test_filters.py b/openedx_filters/learning/tests/test_filters.py index b4ccf69a..7fc166ca 100644 --- a/openedx_filters/learning/tests/test_filters.py +++ b/openedx_filters/learning/tests/test_filters.py @@ -21,6 +21,7 @@ CourseHomeUrlCreationStarted, CourseRunAPIRenderStarted, CourseUnenrollmentStarted, + CoursewareViewRedirectURL, DashboardRenderStarted, IDVPageURLRequested, InstructorDashboardRenderStarted, @@ -801,3 +802,29 @@ def test_schedule_requested(self): result = ScheduleQuerySetRequested.run_filter(schedules) self.assertEqual(schedules, result) + + +class TestCoursewareViewRedirectURL(TestCase): + """ + Test class to verify standard behavior of the CoursewareViewRedirectURL filter. + """ + + def test_returns_redirect_urls_unchanged_when_no_pipeline_steps(self): + """ + Test CoursewareViewRedirectURL filter behavior under normal conditions. + + Expected behavior: + - The filter returns the redirect_urls list unchanged when no pipeline steps modify it. + - The request and course_key are returned unchanged. + """ + redirect_urls = [] + request = Mock() + course_key = Mock() + + result_urls, result_request, result_course_key = CoursewareViewRedirectURL.run_filter( + redirect_urls, request, course_key + ) + + self.assertEqual(redirect_urls, result_urls) + self.assertEqual(request, result_request) + self.assertEqual(course_key, result_course_key)