From 38e5745e069ba87678aec26b256a9e156e8d76ed Mon Sep 17 00:00:00 2001 From: Jesper Hodge <19345795+jesperhodge@users.noreply.github.com> Date: Wed, 20 Nov 2024 15:51:46 -0500 Subject: [PATCH] feat: add course optimizer waffle flag (#35884) Description Add a waffle flag to toggle on or off the new Course Optimizer feature per course. Impact Course Author Context Course Optimizer is a much-requested feature that has been aligned with the OpenEdx community. The only component for now is a broken link checker that will return a list of all broken links in a course to the frontend. There will be a new page for this that is a bit similar to the export page. This PR only deals with adding a waffle flag. Supporting information Internal Ticket (2U): https://2u-internal.atlassian.net/browse/TNL-11808 --- .../v1/serializers/course_waffle_flags.py | 8 ++++++++ .../views/tests/test_course_waffle_flags.py | 19 +++++++++++++++++- cms/djangoapps/contentstore/toggles.py | 20 +++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/cms/djangoapps/contentstore/rest_api/v1/serializers/course_waffle_flags.py b/cms/djangoapps/contentstore/rest_api/v1/serializers/course_waffle_flags.py index b37254234663..33dd99792882 100644 --- a/cms/djangoapps/contentstore/rest_api/v1/serializers/course_waffle_flags.py +++ b/cms/djangoapps/contentstore/rest_api/v1/serializers/course_waffle_flags.py @@ -27,6 +27,7 @@ class CourseWaffleFlagsSerializer(serializers.Serializer): use_new_certificates_page = serializers.SerializerMethodField() use_new_textbooks_page = serializers.SerializerMethodField() use_new_group_configurations_page = serializers.SerializerMethodField() + enable_course_optimizer = serializers.SerializerMethodField() def get_course_key(self): """ @@ -144,3 +145,10 @@ def get_use_new_group_configurations_page(self, obj): """ course_key = self.get_course_key() return toggles.use_new_group_configurations_page(course_key) + + def get_enable_course_optimizer(self, obj): + """ + Method to get the enable_course_optimizer waffle flag + """ + course_key = self.get_course_key() + return toggles.enable_course_optimizer(course_key) diff --git a/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_course_waffle_flags.py b/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_course_waffle_flags.py index 0a713fb81cd1..f0332d7f2870 100644 --- a/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_course_waffle_flags.py +++ b/cms/djangoapps/contentstore/rest_api/v1/views/tests/test_course_waffle_flags.py @@ -36,6 +36,8 @@ class CourseWaffleFlagsViewTest(CourseTestCase): "use_new_group_configurations_page", ] + other_expected_waffle_flags = ["enable_course_optimizer"] + def setUp(self): """ Set up test data and state before each test method. @@ -46,6 +48,18 @@ def setUp(self): super().setUp() self.url = reverse("cms.djangoapps.contentstore:v1:course_waffle_flags") self.create_waffle_flags(self.course_waffle_flags) + self.create_custom_waffle_flags() + + def create_custom_waffle_flags(self, enabled=True): + """ + Helper method to create waffle flags that are not part of `course_waffle_flags` and have + a different format. + """ + WaffleFlagCourseOverrideModel.objects.create( + waffle_flag="contentstore.enable_course_optimizer", + course_id=self.course.id, + enabled=enabled, + ) def create_waffle_flags(self, flags, enabled=True): """ @@ -72,7 +86,10 @@ def expected_response(self, enabled=False): Returns: dict: A dictionary with each flag set to the value of `enabled`. """ - return {flag: enabled for flag in self.course_waffle_flags} + res = {flag: enabled for flag in self.course_waffle_flags} + for flag in self.other_expected_waffle_flags: + res[flag] = enabled + return res def test_get_course_waffle_flags_with_course_id(self): """ diff --git a/cms/djangoapps/contentstore/toggles.py b/cms/djangoapps/contentstore/toggles.py index 79c722e24d52..39b793f479a2 100644 --- a/cms/djangoapps/contentstore/toggles.py +++ b/cms/djangoapps/contentstore/toggles.py @@ -667,3 +667,23 @@ def libraries_v2_enabled(): search_api.is_meilisearch_enabled() and not DISABLE_NEW_LIBRARIES.is_enabled() ) + + +# .. toggle_name: contentstore.enable_course_optimizer +# .. toggle_implementation: CourseWaffleFlag +# .. toggle_default: False +# .. toggle_description: This flag enables the use of unique anonymous_user_id during studio preview +# .. toggle_use_cases: temporary +# .. toggle_creation_date: 2022-05-04 +# .. toggle_target_removal_date: 2022-05-30 +# .. toggle_tickets: MST-1455 +ENABLE_COURSE_OPTIMIZER = CourseWaffleFlag( + f'{CONTENTSTORE_NAMESPACE}.enable_course_optimizer', __name__ +) + + +def enable_course_optimizer(course_id): + """ + Returns a boolean if individualized anonymous_user_id is enabled on the course + """ + return ENABLE_COURSE_OPTIMIZER.is_enabled(course_id)