refactor: AA-677: Switch relative dates to CourseWaffleFlag
We have been bucketing all users into the relative dates experiment since May 18, 2020. We no longer need to keep this as an ExperimentWaffleFlag and can convert to a CourseWaffleFlag (so it continues to support exemptions).
This commit is contained in:
@@ -234,7 +234,7 @@ class TestGetBlocksQueryCounts(TestGetBlocksQueryCountsBase):
|
||||
self._get_blocks(
|
||||
course,
|
||||
expected_mongo_queries=0,
|
||||
expected_sql_queries=11 if with_storage_backing else 10,
|
||||
expected_sql_queries=13 if with_storage_backing else 12,
|
||||
)
|
||||
|
||||
@ddt.data(
|
||||
@@ -251,9 +251,9 @@ class TestGetBlocksQueryCounts(TestGetBlocksQueryCountsBase):
|
||||
clear_course_from_cache(course.id)
|
||||
|
||||
if with_storage_backing:
|
||||
num_sql_queries = 21
|
||||
num_sql_queries = 23
|
||||
else:
|
||||
num_sql_queries = 11
|
||||
num_sql_queries = 13
|
||||
|
||||
self._get_blocks(
|
||||
course,
|
||||
|
||||
@@ -150,7 +150,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
CourseEnrollmentFactory(course_id=course.id, user=user, mode=CourseMode.VERIFIED)
|
||||
self.assert_block_types(course, user, expected_blocks)
|
||||
|
||||
@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
@override_waffle_flag(RELATIVE_DATES_FLAG, 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
|
||||
@@ -309,7 +309,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
for html_tag in assignment_title_html:
|
||||
assert html_tag in assignment_title
|
||||
|
||||
@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
@ddt.data(
|
||||
([], 3),
|
||||
([{
|
||||
@@ -375,7 +375,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
blocks = get_course_date_blocks(course, user, request, include_past_dates=True)
|
||||
assert len(blocks) == date_block_count
|
||||
|
||||
@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
def test_enabled_block_types_with_expired_course(self):
|
||||
course = create_course_run(days_till_start=-100)
|
||||
user = create_user()
|
||||
@@ -544,7 +544,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_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
@override_waffle_flag(RELATIVE_DATES_FLAG, 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
|
||||
@@ -727,7 +727,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
)
|
||||
@ddt.unpack
|
||||
@override_waffle_flag(DISABLE_UNIFIED_COURSE_TAB_FLAG, active=False)
|
||||
@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
def test_dates_tab_link_render(self, url_name, mfe_active):
|
||||
""" The dates tab link should only show for enrolled or staff users """
|
||||
course = create_course_run()
|
||||
|
||||
@@ -59,7 +59,6 @@ from lms.djangoapps.courseware.toggles import (
|
||||
)
|
||||
from lms.djangoapps.courseware.user_state_client import DjangoXBlockUserStateClient
|
||||
from lms.djangoapps.courseware.views.index import show_courseware_mfe_link
|
||||
from lms.djangoapps.experiments.testutils import override_experiment_waffle_flag
|
||||
from lms.djangoapps.grades.config.waffle import ASSUME_ZERO_GRADE_IF_ABSENT
|
||||
from lms.djangoapps.grades.config.waffle import waffle_switch as grades_waffle_switch
|
||||
from lms.djangoapps.verify_student.models import VerificationDeadline
|
||||
@@ -3152,7 +3151,7 @@ class DatesTabTestCase(ModuleStoreTestCase):
|
||||
response = self._get_response(self.course)
|
||||
assert response.status_code == 200
|
||||
|
||||
@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
@patch('edx_django_utils.monitoring.set_custom_attribute')
|
||||
def test_defaults(self, mock_set_custom_attribute):
|
||||
enrollment = CourseEnrollmentFactory(course_id=self.course.id, user=self.user, mode=CourseMode.VERIFIED)
|
||||
@@ -3213,7 +3212,7 @@ class DatesTabTestCase(ModuleStoreTestCase):
|
||||
# Make sure the assignment type is rendered
|
||||
self.assertContains(response, 'Homework:')
|
||||
|
||||
@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
def test_reset_deadlines_banner_displays(self):
|
||||
CourseEnrollmentFactory(course_id=self.course.id, user=self.user, mode=CourseMode.VERIFIED)
|
||||
now = datetime.now(utc)
|
||||
|
||||
@@ -162,10 +162,10 @@ class RecalculateSubsectionGradeTest(HasCourseWithProblemsMixin, ModuleStoreTest
|
||||
assert mock_block_structure_create.call_count == 1
|
||||
|
||||
@ddt.data(
|
||||
(ModuleStoreEnum.Type.mongo, 1, 38, True),
|
||||
(ModuleStoreEnum.Type.mongo, 1, 38, False),
|
||||
(ModuleStoreEnum.Type.split, 3, 38, True),
|
||||
(ModuleStoreEnum.Type.split, 3, 38, False),
|
||||
(ModuleStoreEnum.Type.mongo, 1, 40, True),
|
||||
(ModuleStoreEnum.Type.mongo, 1, 40, False),
|
||||
(ModuleStoreEnum.Type.split, 3, 40, True),
|
||||
(ModuleStoreEnum.Type.split, 3, 40, False),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_query_counts(self, default_store, num_mongo_calls, num_sql_calls, create_multiple_subsections):
|
||||
@@ -177,8 +177,8 @@ class RecalculateSubsectionGradeTest(HasCourseWithProblemsMixin, ModuleStoreTest
|
||||
self._apply_recalculate_subsection_grade()
|
||||
|
||||
@ddt.data(
|
||||
(ModuleStoreEnum.Type.mongo, 1, 38),
|
||||
(ModuleStoreEnum.Type.split, 3, 38),
|
||||
(ModuleStoreEnum.Type.mongo, 1, 40),
|
||||
(ModuleStoreEnum.Type.split, 3, 40),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_query_counts_dont_change_with_more_content(self, default_store, num_mongo_calls, num_sql_calls):
|
||||
@@ -223,8 +223,8 @@ class RecalculateSubsectionGradeTest(HasCourseWithProblemsMixin, ModuleStoreTest
|
||||
)
|
||||
|
||||
@ddt.data(
|
||||
(ModuleStoreEnum.Type.mongo, 1, 21),
|
||||
(ModuleStoreEnum.Type.split, 3, 21),
|
||||
(ModuleStoreEnum.Type.mongo, 1, 23),
|
||||
(ModuleStoreEnum.Type.split, 3, 23),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_persistent_grades_not_enabled_on_course(self, default_store, num_mongo_queries, num_sql_queries):
|
||||
@@ -238,8 +238,8 @@ class RecalculateSubsectionGradeTest(HasCourseWithProblemsMixin, ModuleStoreTest
|
||||
assert len(PersistentSubsectionGrade.bulk_read_grades(self.user.id, self.course.id)) == 0
|
||||
|
||||
@ddt.data(
|
||||
(ModuleStoreEnum.Type.mongo, 1, 39),
|
||||
(ModuleStoreEnum.Type.split, 3, 39),
|
||||
(ModuleStoreEnum.Type.mongo, 1, 41),
|
||||
(ModuleStoreEnum.Type.split, 3, 41),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_persistent_grades_enabled_on_course(self, default_store, num_mongo_queries, num_sql_queries):
|
||||
|
||||
@@ -23,6 +23,7 @@ from django.test import RequestFactory, TestCase
|
||||
from django.urls import reverse as django_reverse
|
||||
from django.utils.translation import ugettext as _
|
||||
from edx_when.api import get_dates_for_course, get_overrides_for_user, set_date_for_block
|
||||
from edx_toggles.toggles.testutils import override_waffle_flag
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from opaque_keys.edx.locator import UsageKey
|
||||
from pytz import UTC
|
||||
@@ -66,7 +67,6 @@ from lms.djangoapps.courseware.tests.factories import (
|
||||
StaffFactory,
|
||||
)
|
||||
from lms.djangoapps.courseware.tests.helpers import LoginEnrollmentTestCase
|
||||
from lms.djangoapps.experiments.testutils import override_experiment_waffle_flag
|
||||
from lms.djangoapps.instructor.tests.utils import FakeContentTask, FakeEmail, FakeEmailInfo
|
||||
from lms.djangoapps.instructor.views.api import (
|
||||
_get_certificate_for_user,
|
||||
@@ -3930,7 +3930,7 @@ class TestDueDateExtensions(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
assert response.status_code == 400, response.content
|
||||
assert get_extended_due(self.course, self.week3, self.user1) is None
|
||||
|
||||
@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
def test_reset_date(self):
|
||||
self.test_change_due_date()
|
||||
url = reverse('reset_due_date', kwargs={'course_id': str(self.course.id)})
|
||||
@@ -3941,7 +3941,7 @@ class TestDueDateExtensions(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
assert response.status_code == 200, response.content
|
||||
assert self.due == get_extended_due(self.course, self.week1, self.user1)
|
||||
|
||||
@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
def test_reset_date_only_in_edx_when(self):
|
||||
# Start with a unit that only has a date in edx-when
|
||||
assert get_date_for_block(self.course, self.week3, self.user1) is None
|
||||
@@ -4070,7 +4070,7 @@ class TestDueDateExtensionsDeletedDate(ModuleStoreTestCase, LoginEnrollmentTestC
|
||||
self.client.login(username=self.instructor.username, password='test')
|
||||
extract_dates(None, self.course.id)
|
||||
|
||||
@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
def test_reset_extension_to_deleted_date(self):
|
||||
"""
|
||||
Test that we can delete a due date extension after deleting the normal
|
||||
|
||||
@@ -248,7 +248,7 @@ class TestCourseNextSectionUpdateResolver(SchedulesResolverTestMixin, ModuleStor
|
||||
def test_schedule_context(self):
|
||||
resolver = self.create_resolver()
|
||||
# using this to make sure the select_related stays intact
|
||||
with self.assertNumQueries(15):
|
||||
with self.assertNumQueries(26):
|
||||
sc = resolver.get_schedules()
|
||||
schedules = list(sc)
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import ddt
|
||||
from django.test import RequestFactory
|
||||
from edx_toggles.toggles.testutils import override_waffle_flag
|
||||
|
||||
from lms.djangoapps.experiments.testutils import override_experiment_waffle_flag
|
||||
from openedx.features.calendar_sync.plugins import CalendarSyncToggleTool
|
||||
from openedx.features.course_experience import CALENDAR_SYNC_FLAG, RELATIVE_DATES_FLAG
|
||||
from xmodule.modulestore.tests.django_utils import CourseUserType, SharedModuleStoreTestCase
|
||||
@@ -35,7 +34,7 @@ class TestCalendarSyncToggleTool(SharedModuleStoreTestCase):
|
||||
)
|
||||
@ddt.unpack
|
||||
@override_waffle_flag(CALENDAR_SYNC_FLAG, active=True)
|
||||
@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
def test_calendar_sync_toggle_tool_is_enabled(self, user_type, should_be_enabled):
|
||||
request = RequestFactory().request()
|
||||
request.user = self.create_user_for_course(self.course, user_type)
|
||||
|
||||
@@ -7,7 +7,6 @@ from edx_django_utils.monitoring import set_custom_attribute
|
||||
from waffle import flag_is_active
|
||||
|
||||
from edx_toggles.toggles import LegacyWaffleFlag, LegacyWaffleFlagNamespace
|
||||
from lms.djangoapps.experiments.flags import ExperimentWaffleFlag
|
||||
from openedx.core.djangoapps.util.user_messages import UserMessageCollection
|
||||
from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag
|
||||
|
||||
@@ -73,16 +72,16 @@ COURSE_ENABLE_UNENROLLED_ACCESS_FLAG = CourseWaffleFlag(
|
||||
)
|
||||
|
||||
# .. toggle_name: course_experience.relative_dates
|
||||
# .. toggle_implementation: ExperimentWaffleFlag
|
||||
# .. toggle_implementation: CourseWaffleFlag
|
||||
# .. toggle_default: False
|
||||
# .. toggle_description: Waffle flag to enable relative dates for course content. A 'Dates' tab will be visible in the
|
||||
# course view showing key course dates.
|
||||
# course view showing key course dates. Was previously an ExperimentWaffleFlag with experiment_id=17.
|
||||
# .. toggle_use_cases: opt_in
|
||||
# .. toggle_creation_date: 2020-02-10
|
||||
# .. toggle_warnings: To set a relative due date for self-paced courses, the weeks_to_complete field for a course run
|
||||
# needs to be set. Currently it can be set through the publisher app.
|
||||
# .. toggle_tickets: https://openedx.atlassian.net/browse/AA-27
|
||||
RELATIVE_DATES_FLAG = ExperimentWaffleFlag(WAFFLE_FLAG_NAMESPACE, 'relative_dates', __name__, experiment_id=17)
|
||||
RELATIVE_DATES_FLAG = CourseWaffleFlag(WAFFLE_FLAG_NAMESPACE, 'relative_dates', __name__)
|
||||
|
||||
# .. toggle_name: course_experience.calendar_sync
|
||||
# .. toggle_implementation: CourseWaffleFlag
|
||||
|
||||
@@ -21,7 +21,7 @@ from openedx.features.course_experience import RELATIVE_DATES_FLAG
|
||||
<%
|
||||
course_sections = blocks.get('children')
|
||||
self_paced = context.get('self_paced', False)
|
||||
relative_dates_flag_is_enabled = RELATIVE_DATES_FLAG.is_enabled(str(course_key))
|
||||
relative_dates_flag_is_enabled = RELATIVE_DATES_FLAG.is_enabled(course_key)
|
||||
is_course_staff = bool(user and course and has_access(user, 'staff', course, course.id))
|
||||
dates_banner_displayed = False
|
||||
%>
|
||||
|
||||
@@ -15,7 +15,7 @@ from django.contrib.sites.models import Site
|
||||
from django.test import RequestFactory, override_settings
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from edx_toggles.toggles.testutils import override_waffle_switch
|
||||
from edx_toggles.toggles.testutils import override_waffle_flag, override_waffle_switch
|
||||
from milestones.tests.utils import MilestonesTestCaseMixin
|
||||
from mock import Mock, patch
|
||||
from opaque_keys.edx.keys import CourseKey, UsageKey
|
||||
@@ -30,7 +30,6 @@ from lms.djangoapps.course_api.blocks.transformers.milestones import MilestonesA
|
||||
from lms.djangoapps.gating import api as lms_gating_api
|
||||
from lms.djangoapps.courseware.tests.factories import StaffFactory
|
||||
from lms.djangoapps.courseware.tests.helpers import MasqueradeMixin
|
||||
from lms.djangoapps.experiments.testutils import override_experiment_waffle_flag
|
||||
from lms.urls import RESET_COURSE_DEADLINES_NAME
|
||||
from openedx.core.djangoapps.course_date_signals.models import SelfPacedRelativeDatesConfig
|
||||
from openedx.core.djangoapps.schedules.models import Schedule
|
||||
@@ -138,7 +137,7 @@ class TestCourseOutlinePage(SharedModuleStoreTestCase, MasqueradeMixin):
|
||||
super(TestCourseOutlinePage, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
self.client.login(username=self.user.username, password=TEST_PASSWORD)
|
||||
|
||||
@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
def test_outline_details(self):
|
||||
for course in self.courses:
|
||||
|
||||
@@ -193,7 +192,7 @@ class TestCourseOutlinePage(SharedModuleStoreTestCase, MasqueradeMixin):
|
||||
self.assertRegex(content, sequential2.display_name + r'\s*\(1 Question\)\s*</h4>')
|
||||
self.assertRegex(content, sequential3.display_name + r'\s*\(2 Questions\)\s*</h4>')
|
||||
|
||||
@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
@ddt.data(
|
||||
([CourseMode.AUDIT, CourseMode.VERIFIED], CourseMode.AUDIT, False, True),
|
||||
([CourseMode.AUDIT, CourseMode.VERIFIED], CourseMode.VERIFIED, False, True),
|
||||
@@ -232,7 +231,7 @@ class TestCourseOutlinePage(SharedModuleStoreTestCase, MasqueradeMixin):
|
||||
else:
|
||||
self.assertNotContains(response, '<div class="banner-cta-text"')
|
||||
|
||||
@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
def test_reset_course_deadlines(self):
|
||||
course = self.courses[0]
|
||||
|
||||
@@ -252,7 +251,7 @@ class TestCourseOutlinePage(SharedModuleStoreTestCase, MasqueradeMixin):
|
||||
updated_staff_schedule = Schedule.objects.get(enrollment__user=staff, enrollment__course_id=course.id)
|
||||
assert updated_staff_schedule.start_date == start_date
|
||||
|
||||
@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
def test_reset_course_deadlines_masquerade_generic_student(self):
|
||||
course = self.courses[0]
|
||||
|
||||
|
||||
@@ -4,11 +4,12 @@ import ddt
|
||||
from django.test import RequestFactory
|
||||
from django.test.utils import override_settings
|
||||
|
||||
from edx_toggles.toggles.testutils import override_waffle_flag
|
||||
|
||||
from common.lib.xmodule.xmodule.capa_base import SHOWANSWER
|
||||
from lms.djangoapps.ccx.tests.test_overrides import inject_field_overrides
|
||||
from lms.djangoapps.courseware.model_data import FieldDataCache
|
||||
from lms.djangoapps.courseware.module_render import get_module
|
||||
from lms.djangoapps.experiments.testutils import override_experiment_waffle_flag
|
||||
from openedx.features.course_experience import RELATIVE_DATES_FLAG
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
@@ -36,7 +37,7 @@ class ShowAnswerFieldOverrideTest(ModuleStoreTestCase):
|
||||
|
||||
@ddt.data(True, False)
|
||||
def test_override_enabled_for(self, active):
|
||||
with override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=active):
|
||||
with override_waffle_flag(RELATIVE_DATES_FLAG, active=active):
|
||||
# Instructor paced course will just have the default value
|
||||
ip_course = self.setup_course()
|
||||
course_module = self.get_course_module(ip_course)
|
||||
@@ -63,7 +64,7 @@ class ShowAnswerFieldOverrideTest(ModuleStoreTestCase):
|
||||
(SHOWANSWER.ALWAYS, SHOWANSWER.ALWAYS),
|
||||
)
|
||||
@ddt.unpack
|
||||
@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
@override_waffle_flag(RELATIVE_DATES_FLAG, active=True)
|
||||
def test_get(self, initial_value, expected_final_value):
|
||||
course = self.setup_course(self_paced=True, showanswer=initial_value)
|
||||
course_module = self.get_course_module(course)
|
||||
|
||||
Reference in New Issue
Block a user