diff --git a/lms/djangoapps/courseware/courses.py b/lms/djangoapps/courseware/courses.py index b81b16ee6a..6b4b35f868 100644 --- a/lms/djangoapps/courseware/courses.py +++ b/lms/djangoapps/courseware/courses.py @@ -49,7 +49,7 @@ from openedx.core.djangoapps.enrollments.api import get_course_enrollment_detail from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers from openedx.core.lib.api.view_utils import LazySequence from openedx.features.course_duration_limits.access import AuditExpiredError -from openedx.features.course_experience import COURSE_ENABLE_UNENROLLED_ACCESS_FLAG, DATE_WIDGET_V2_FLAG +from openedx.features.course_experience import COURSE_ENABLE_UNENROLLED_ACCESS_FLAG, RELATIVE_DATES_FLAG from static_replace import replace_static_urls from student.models import CourseEnrollment from survey.utils import is_survey_required_and_unanswered @@ -413,7 +413,7 @@ def get_course_date_blocks(course, user, request=None, include_access=False, block_classes.insert(0, CertificateAvailableDate) blocks = [cls(course, user) for cls in block_classes] - if DATE_WIDGET_V2_FLAG.is_enabled(course.id): + if RELATIVE_DATES_FLAG.is_enabled(course.id): blocks.append(CourseExpiredDate(course, user)) blocks.extend(get_course_assignment_due_dates( course, user, request, num_return=num_assignments, diff --git a/lms/djangoapps/courseware/date_summary.py b/lms/djangoapps/courseware/date_summary.py index fab8e711bc..4877e13e74 100644 --- a/lms/djangoapps/courseware/date_summary.py +++ b/lms/djangoapps/courseware/date_summary.py @@ -28,7 +28,7 @@ from openedx.core.djangoapps.certificates.api import can_show_certificate_availa from openedx.core.djangolib.markup import HTML, Text from openedx.features.course_duration_limits.access import get_user_course_expiration_date from openedx.features.course_duration_limits.models import CourseDurationLimitConfig -from openedx.features.course_experience import DATE_WIDGET_V2_FLAG, UPGRADE_DEADLINE_MESSAGE, CourseHomeMessages +from openedx.features.course_experience import RELATIVE_DATES_FLAG, UPGRADE_DEADLINE_MESSAGE, CourseHomeMessages from student.models import CourseEnrollment from .context_processor import user_timezone_locale_prefs @@ -295,7 +295,7 @@ class CourseEndDate(DateSummary): @property def date(self): - if DATE_WIDGET_V2_FLAG.is_enabled(self.course_id) and self.course.self_paced: + if self.course.self_paced and RELATIVE_DATES_FLAG.is_enabled(self.course_id): weeks_to_complete = get_course_run_details(self.course.id, ['weeks_to_complete']).get('weeks_to_complete') if weeks_to_complete: course_duration = datetime.timedelta(weeks=weeks_to_complete) diff --git a/lms/djangoapps/courseware/tests/test_date_summary.py b/lms/djangoapps/courseware/tests/test_date_summary.py index 13792ecc70..56b1556aa5 100644 --- a/lms/djangoapps/courseware/tests/test_date_summary.py +++ b/lms/djangoapps/courseware/tests/test_date_summary.py @@ -4,6 +4,7 @@ from datetime import datetime, timedelta +import crum import ddt import waffle from django.contrib.messages.middleware import MessageMiddleware @@ -42,7 +43,7 @@ from openedx.core.djangoapps.user_api.preferences.api import set_user_preference from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_flag from openedx.features.course_duration_limits.models import CourseDurationLimitConfig from openedx.features.course_experience import ( - DATE_WIDGET_V2_FLAG, UNIFIED_COURSE_TAB_FLAG, UPGRADE_DEADLINE_MESSAGE, CourseHomeMessages + RELATIVE_DATES_FLAG, UNIFIED_COURSE_TAB_FLAG, UPGRADE_DEADLINE_MESSAGE, CourseHomeMessages ) from student.tests.factories import TEST_PASSWORD, CourseEnrollmentFactory, UserFactory from xmodule.modulestore import ModuleStoreEnum @@ -58,6 +59,13 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase): super(CourseDateSummaryTest, self).setUp() SelfPacedConfiguration.objects.create(enable_course_home_improvements=True) + def make_request(self, user): + request = RequestFactory().request() + request.user = user + self.addCleanup(crum.set_current_request, None) + crum.set_current_request(request) + return request + def test_course_info_feature_flag(self): SelfPacedConfiguration(enable_course_home_improvements=False).save() course = create_course_run() @@ -135,7 +143,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase): CourseEnrollmentFactory(course_id=course.id, user=user, mode=CourseMode.VERIFIED) self.assert_block_types(course, user, expected_blocks) - @override_waffle_flag(DATE_WIDGET_V2_FLAG, active=True) + @RELATIVE_DATES_FLAG.override(active=True) def test_enabled_block_types_with_assignments(self): # pylint: disable=too-many-statements """ Creates a course with multiple subsections to test all of the different @@ -144,8 +152,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase): """ course = create_course_run(days_till_start=-100) user = create_user() - request = RequestFactory().request() - request.user = user + request = self.make_request(user) CourseEnrollmentFactory(course_id=course.id, user=user, mode=CourseMode.VERIFIED) now = datetime.now(utc) assignment_title_html = [''] @@ -295,10 +302,11 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase): for html_tag in assignment_title_html: self.assertIn(html_tag, assignment_title) - @override_waffle_flag(DATE_WIDGET_V2_FLAG, active=True) + @RELATIVE_DATES_FLAG.override(active=True) def test_enabled_block_types_with_expired_course(self): course = create_course_run(days_till_start=-100) user = create_user() + self.make_request(user) # These two lines are to trigger the course expired block to be rendered CourseEnrollmentFactory(course_id=course.id, user=user, mode=CourseMode.AUDIT) CourseDurationLimitConfig.objects.create(enabled=True, enabled_as_of=datetime(2018, 1, 1, tzinfo=utc)) @@ -470,7 +478,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase): {'weeks_to_complete': 7}, # Weeks to complete > time til end (end date shown) {'weeks_to_complete': 4}, # Weeks to complete < time til end (end date not shown) ) - @override_waffle_flag(DATE_WIDGET_V2_FLAG, active=True) + @RELATIVE_DATES_FLAG.override(active=True) def test_course_end_date_self_paced(self, cr_details): """ In self-paced courses, the end date will now only show up if the learner @@ -484,6 +492,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase): course = CourseFactory.create( start=now + timedelta(days=-7), end=now + timedelta(weeks=end_timedelta_number), self_paced=True) user = create_user() + self.make_request(user) with patch('lms.djangoapps.courseware.date_summary.get_course_run_details') as mock_get_cr_details: mock_get_cr_details.return_value = cr_details block = CourseEndDate(course, user) diff --git a/lms/djangoapps/courseware/tests/test_views.py b/lms/djangoapps/courseware/tests/test_views.py index 8673a57878..319075aa3f 100644 --- a/lms/djangoapps/courseware/tests/test_views.py +++ b/lms/djangoapps/courseware/tests/test_views.py @@ -11,6 +11,7 @@ from datetime import datetime, timedelta from pytz import utc from uuid import uuid4 +import crum import ddt import six from completion.test_utils import CompletionWaffleTestMixin @@ -79,7 +80,7 @@ from openedx.features.course_duration_limits.models import CourseDurationLimitCo from openedx.features.course_experience import ( COURSE_ENABLE_UNENROLLED_ACCESS_FLAG, COURSE_OUTLINE_PAGE_FLAG, - DATE_WIDGET_V2_FLAG, + RELATIVE_DATES_FLAG, UNIFIED_COURSE_TAB_FLAG ) from openedx.features.course_experience.tests.views.helpers import add_course_mode @@ -3156,10 +3157,12 @@ class DatesTabTestCase(ModuleStoreTestCase): """ Returns the HTML for the progress page """ return self.client.get(reverse('dates', args=[six.text_type(course.id)])) - @override_waffle_flag(DATE_WIDGET_V2_FLAG, active=True) + @RELATIVE_DATES_FLAG.override(active=True) def test_defaults(self): request = RequestFactory().request() request.user = self.user + self.addCleanup(crum.set_current_request, None) + crum.set_current_request(request) enrollment = CourseEnrollmentFactory(course_id=self.course.id, user=self.user, mode=CourseMode.VERIFIED) now = datetime.now(utc) with self.store.bulk_operations(self.course.id): diff --git a/lms/djangoapps/experiments/flags.py b/lms/djangoapps/experiments/flags.py index 3d26e5cafa..31e90138e3 100644 --- a/lms/djangoapps/experiments/flags.py +++ b/lms/djangoapps/experiments/flags.py @@ -3,9 +3,10 @@ Feature flag support for experiments """ import logging -import pytz +from contextlib import contextmanager import dateutil +import pytz from crum import get_current_request from edx_django_utils.cache import RequestCache @@ -130,4 +131,11 @@ class ExperimentWaffleFlag(CourseWaffleFlag): return self.get_bucket(course_key) != 0 def is_enabled_without_course_context(self): - return self.get_bucket() != 0 + return self.is_enabled() + + @contextmanager + def override(self, active=True, bucket=1): # pylint: disable=arguments-differ + from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_flag + with override_waffle_flag(self, active): + with override_waffle_flag(self.bucket_flags[bucket], True): + yield diff --git a/lms/djangoapps/instructor/tests/test_api.py b/lms/djangoapps/instructor/tests/test_api.py index 4424cd6338..e75fc2b496 100644 --- a/lms/djangoapps/instructor/tests/test_api.py +++ b/lms/djangoapps/instructor/tests/test_api.py @@ -4524,7 +4524,7 @@ class TestDueDateExtensions(SharedModuleStoreTestCase, LoginEnrollmentTestCase): get_extended_due(self.course, self.week3, self.user1) ) - @override_waffle_flag(RELATIVE_DATES_FLAG, True) + @RELATIVE_DATES_FLAG.override(True) def test_reset_date(self): self.test_change_due_date() url = reverse('reset_due_date', kwargs={'course_id': text_type(self.course.id)}) @@ -4649,7 +4649,7 @@ class TestDueDateExtensionsDeletedDate(ModuleStoreTestCase, LoginEnrollmentTestC self.client.login(username=self.instructor.username, password='test') extract_dates(None, self.course.id) - @override_waffle_flag(RELATIVE_DATES_FLAG, True) + @RELATIVE_DATES_FLAG.override(True) def test_reset_extension_to_deleted_date(self): """ Test that we can delete a due date extension after deleting the normal diff --git a/openedx/features/course_experience/__init__.py b/openedx/features/course_experience/__init__.py index 4e48a961ff..a9449ff1ca 100644 --- a/openedx/features/course_experience/__init__.py +++ b/openedx/features/course_experience/__init__.py @@ -82,10 +82,6 @@ COURSE_ENABLE_UNENROLLED_ACCESS_FLAG = CourseWaffleFlag(SEO_WAFFLE_FLAG_NAMESPAC # Waffle flag to enable relative dates for course content RELATIVE_DATES_FLAG = ExperimentWaffleFlag(WAFFLE_FLAG_NAMESPACE, 'relative_dates', experiment_id=17) -# Waffle flag to enable showing FBE messaging, assignment due dates, and modified -# end date logic (for self-paced courses) in the date widget -DATE_WIDGET_V2_FLAG = CourseWaffleFlag(WAFFLE_FLAG_NAMESPACE, 'date_widget_v2') - def course_home_page_title(course): # pylint: disable=unused-argument """ diff --git a/openedx/features/course_experience/tests/views/test_course_home.py b/openedx/features/course_experience/tests/views/test_course_home.py index 37396e22ce..798f348d13 100644 --- a/openedx/features/course_experience/tests/views/test_course_home.py +++ b/openedx/features/course_experience/tests/views/test_course_home.py @@ -1023,7 +1023,7 @@ class CourseHomeFragmentViewTests(ModuleStoreTestCase): self.assertContains(response, "DISCOUNT_PRICE") - @override_waffle_flag(RELATIVE_DATES_FLAG, active=True) + @RELATIVE_DATES_FLAG.override(active=True) def test_reset_deadline_banner_is_present_on_course_tab(self): response = self.client.get(self.url) self.assertContains(response, '
')