Merge pull request #16811 from edx/pacing/revert-schedule-waffle-removal
Revert removing CREATE_SCHEDULE_WAFFLE_FLAG "Merge pull request #16728"
This commit is contained in:
@@ -15,12 +15,12 @@ from course_modes.tests.factories import CourseModeFactory
|
|||||||
from courseware.course_tools import VerifiedUpgradeTool
|
from courseware.course_tools import VerifiedUpgradeTool
|
||||||
from courseware.models import DynamicUpgradeDeadlineConfiguration
|
from courseware.models import DynamicUpgradeDeadlineConfiguration
|
||||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
||||||
|
from openedx.core.djangoapps.schedules.config import CREATE_SCHEDULE_WAFFLE_FLAG
|
||||||
from openedx.core.djangoapps.site_configuration.tests.factories import SiteFactory
|
from openedx.core.djangoapps.site_configuration.tests.factories import SiteFactory
|
||||||
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_flag
|
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_flag
|
||||||
from student.tests.factories import CourseEnrollmentFactory, UserFactory
|
from student.tests.factories import CourseEnrollmentFactory, UserFactory
|
||||||
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
|
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
|
||||||
from xmodule.modulestore.tests.factories import CourseFactory
|
from xmodule.modulestore.tests.factories import CourseFactory
|
||||||
from openedx.core.djangoapps.schedules.tests.factories import ScheduleConfigFactory
|
|
||||||
|
|
||||||
|
|
||||||
@attr(shard=3)
|
@attr(shard=3)
|
||||||
@@ -40,6 +40,7 @@ class VerifiedUpgradeToolTest(SharedModuleStoreTestCase):
|
|||||||
)
|
)
|
||||||
cls.course_overview = CourseOverview.get_from_id(cls.course.id)
|
cls.course_overview = CourseOverview.get_from_id(cls.course.id)
|
||||||
|
|
||||||
|
@override_waffle_flag(CREATE_SCHEDULE_WAFFLE_FLAG, True)
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(VerifiedUpgradeToolTest, self).setUp()
|
super(VerifiedUpgradeToolTest, self).setUp()
|
||||||
|
|
||||||
@@ -56,11 +57,6 @@ class VerifiedUpgradeToolTest(SharedModuleStoreTestCase):
|
|||||||
|
|
||||||
DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
|
DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
|
||||||
|
|
||||||
ScheduleConfigFactory.create(
|
|
||||||
site=mock_get_current_site.return_value,
|
|
||||||
create_schedules=True
|
|
||||||
)
|
|
||||||
|
|
||||||
self.enrollment = CourseEnrollmentFactory(
|
self.enrollment = CourseEnrollmentFactory(
|
||||||
course_id=self.course.id,
|
course_id=self.course.id,
|
||||||
mode=CourseMode.AUDIT,
|
mode=CourseMode.AUDIT,
|
||||||
|
|||||||
@@ -32,12 +32,12 @@ from lms.djangoapps.commerce.models import CommerceConfiguration
|
|||||||
from lms.djangoapps.verify_student.models import VerificationDeadline
|
from lms.djangoapps.verify_student.models import VerificationDeadline
|
||||||
from lms.djangoapps.verify_student.tests.factories import SoftwareSecurePhotoVerificationFactory
|
from lms.djangoapps.verify_student.tests.factories import SoftwareSecurePhotoVerificationFactory
|
||||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
||||||
|
from openedx.core.djangoapps.schedules.signals import CREATE_SCHEDULE_WAFFLE_FLAG
|
||||||
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
|
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
|
||||||
from openedx.core.djangoapps.site_configuration.tests.factories import SiteFactory
|
from openedx.core.djangoapps.site_configuration.tests.factories import SiteFactory
|
||||||
from openedx.core.djangoapps.user_api.preferences.api import set_user_preference
|
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.core.djangoapps.waffle_utils.testutils import override_waffle_flag
|
||||||
from openedx.features.course_experience import UNIFIED_COURSE_TAB_FLAG, UPGRADE_DEADLINE_MESSAGE, CourseHomeMessages
|
from openedx.features.course_experience import UNIFIED_COURSE_TAB_FLAG, UPGRADE_DEADLINE_MESSAGE, CourseHomeMessages
|
||||||
from openedx.core.djangoapps.schedules.tests.factories import ScheduleConfigFactory
|
|
||||||
from student.tests.factories import TEST_PASSWORD, CourseEnrollmentFactory, UserFactory
|
from student.tests.factories import TEST_PASSWORD, CourseEnrollmentFactory, UserFactory
|
||||||
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
|
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
|
||||||
from xmodule.modulestore.tests.factories import CourseFactory
|
from xmodule.modulestore.tests.factories import CourseFactory
|
||||||
@@ -578,8 +578,8 @@ class TestScheduleOverrides(SharedModuleStoreTestCase):
|
|||||||
self.addCleanup(patcher.stop)
|
self.addCleanup(patcher.stop)
|
||||||
|
|
||||||
mock_get_current_site.return_value = SiteFactory.create()
|
mock_get_current_site.return_value = SiteFactory.create()
|
||||||
self.site = mock_get_current_site.return_value
|
|
||||||
|
|
||||||
|
@override_waffle_flag(CREATE_SCHEDULE_WAFFLE_FLAG, True)
|
||||||
def test_date_with_self_paced_with_enrollment_before_course_start(self):
|
def test_date_with_self_paced_with_enrollment_before_course_start(self):
|
||||||
""" Enrolling before a course begins should result in the upgrade deadline being set relative to the
|
""" Enrolling before a course begins should result in the upgrade deadline being set relative to the
|
||||||
course start date. """
|
course start date. """
|
||||||
@@ -587,7 +587,6 @@ class TestScheduleOverrides(SharedModuleStoreTestCase):
|
|||||||
course = create_self_paced_course_run(days_till_start=3)
|
course = create_self_paced_course_run(days_till_start=3)
|
||||||
overview = CourseOverview.get_from_id(course.id)
|
overview = CourseOverview.get_from_id(course.id)
|
||||||
expected = overview.start + timedelta(days=global_config.deadline_days)
|
expected = overview.start + timedelta(days=global_config.deadline_days)
|
||||||
ScheduleConfigFactory.create(site=self.site, enabled=True, create_schedules=True)
|
|
||||||
enrollment = CourseEnrollmentFactory(course_id=course.id, mode=CourseMode.AUDIT)
|
enrollment = CourseEnrollmentFactory(course_id=course.id, mode=CourseMode.AUDIT)
|
||||||
block = VerifiedUpgradeDeadlineDate(course, enrollment.user)
|
block = VerifiedUpgradeDeadlineDate(course, enrollment.user)
|
||||||
self.assertEqual(block.date, expected)
|
self.assertEqual(block.date, expected)
|
||||||
@@ -602,6 +601,7 @@ class TestScheduleOverrides(SharedModuleStoreTestCase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(upgrade_date_summary.relative_datestring, 'by {date}')
|
self.assertEqual(upgrade_date_summary.relative_datestring, 'by {date}')
|
||||||
|
|
||||||
|
@override_waffle_flag(CREATE_SCHEDULE_WAFFLE_FLAG, True)
|
||||||
def test_date_with_self_paced_with_enrollment_after_course_start(self):
|
def test_date_with_self_paced_with_enrollment_after_course_start(self):
|
||||||
""" Enrolling after a course begins should result in the upgrade deadline being set relative to the
|
""" Enrolling after a course begins should result in the upgrade deadline being set relative to the
|
||||||
enrollment date.
|
enrollment date.
|
||||||
@@ -611,7 +611,6 @@ class TestScheduleOverrides(SharedModuleStoreTestCase):
|
|||||||
"""
|
"""
|
||||||
global_config = DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
|
global_config = DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
|
||||||
course = create_self_paced_course_run(days_till_start=-1, org_id='TestOrg')
|
course = create_self_paced_course_run(days_till_start=-1, org_id='TestOrg')
|
||||||
ScheduleConfigFactory.create(site=self.site, enabled=True, create_schedules=True)
|
|
||||||
enrollment = CourseEnrollmentFactory(course_id=course.id, mode=CourseMode.AUDIT)
|
enrollment = CourseEnrollmentFactory(course_id=course.id, mode=CourseMode.AUDIT)
|
||||||
block = VerifiedUpgradeDeadlineDate(course, enrollment.user)
|
block = VerifiedUpgradeDeadlineDate(course, enrollment.user)
|
||||||
expected = enrollment.created + timedelta(days=global_config.deadline_days)
|
expected = enrollment.created + timedelta(days=global_config.deadline_days)
|
||||||
@@ -635,6 +634,7 @@ class TestScheduleOverrides(SharedModuleStoreTestCase):
|
|||||||
expected = enrollment.created + timedelta(days=course_config.deadline_days)
|
expected = enrollment.created + timedelta(days=course_config.deadline_days)
|
||||||
self.assertEqual(block.date, expected)
|
self.assertEqual(block.date, expected)
|
||||||
|
|
||||||
|
@override_waffle_flag(CREATE_SCHEDULE_WAFFLE_FLAG, True)
|
||||||
def test_date_with_self_paced_without_dynamic_upgrade_deadline(self):
|
def test_date_with_self_paced_without_dynamic_upgrade_deadline(self):
|
||||||
""" Disabling the dynamic upgrade deadline functionality should result in the verified mode's
|
""" Disabling the dynamic upgrade deadline functionality should result in the verified mode's
|
||||||
expiration date being returned. """
|
expiration date being returned. """
|
||||||
@@ -645,13 +645,13 @@ class TestScheduleOverrides(SharedModuleStoreTestCase):
|
|||||||
block = VerifiedUpgradeDeadlineDate(course, enrollment.user)
|
block = VerifiedUpgradeDeadlineDate(course, enrollment.user)
|
||||||
self.assertEqual(block.date, expected)
|
self.assertEqual(block.date, expected)
|
||||||
|
|
||||||
|
@override_waffle_flag(CREATE_SCHEDULE_WAFFLE_FLAG, True)
|
||||||
def test_date_with_existing_schedule(self):
|
def test_date_with_existing_schedule(self):
|
||||||
""" If a schedule is created while deadlines are disabled, they shouldn't magically appear once the feature is
|
""" If a schedule is created while deadlines are disabled, they shouldn't magically appear once the feature is
|
||||||
turned on. """
|
turned on. """
|
||||||
course = create_self_paced_course_run(days_till_start=-1)
|
course = create_self_paced_course_run(days_till_start=-1)
|
||||||
DynamicUpgradeDeadlineConfiguration.objects.create(enabled=False)
|
DynamicUpgradeDeadlineConfiguration.objects.create(enabled=False)
|
||||||
course_config = CourseDynamicUpgradeDeadlineConfiguration.objects.create(enabled=False, course_id=course.id)
|
course_config = CourseDynamicUpgradeDeadlineConfiguration.objects.create(enabled=False, course_id=course.id)
|
||||||
ScheduleConfigFactory.create(site=self.site, enabled=True, create_schedules=True)
|
|
||||||
enrollment = CourseEnrollmentFactory(course_id=course.id, mode=CourseMode.AUDIT)
|
enrollment = CourseEnrollmentFactory(course_id=course.id, mode=CourseMode.AUDIT)
|
||||||
|
|
||||||
# The enrollment has a schedule, but the upgrade deadline should be None
|
# The enrollment has a schedule, but the upgrade deadline should be None
|
||||||
@@ -705,6 +705,7 @@ class TestScheduleOverrides(SharedModuleStoreTestCase):
|
|||||||
(True, True, True, True, True, False),
|
(True, True, True, True, True, False),
|
||||||
)
|
)
|
||||||
@ddt.unpack
|
@ddt.unpack
|
||||||
|
@override_waffle_flag(CREATE_SCHEDULE_WAFFLE_FLAG, True)
|
||||||
def test_date_with_org_and_course_config_overrides(self, enroll_first, org_config_enabled, org_config_opt_out,
|
def test_date_with_org_and_course_config_overrides(self, enroll_first, org_config_enabled, org_config_opt_out,
|
||||||
course_config_enabled, course_config_opt_out,
|
course_config_enabled, course_config_opt_out,
|
||||||
expected_dynamic_deadline):
|
expected_dynamic_deadline):
|
||||||
@@ -712,7 +713,6 @@ class TestScheduleOverrides(SharedModuleStoreTestCase):
|
|||||||
and opt-out states to verify that course-level overrides the org-level config. """
|
and opt-out states to verify that course-level overrides the org-level config. """
|
||||||
course = create_self_paced_course_run(days_till_start=-1, org_id='TestOrg')
|
course = create_self_paced_course_run(days_till_start=-1, org_id='TestOrg')
|
||||||
DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
|
DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
|
||||||
ScheduleConfigFactory.create(site=self.site, enabled=True, create_schedules=True)
|
|
||||||
if enroll_first:
|
if enroll_first:
|
||||||
enrollment = CourseEnrollmentFactory(course_id=course.id, mode=CourseMode.AUDIT, course__self_paced=True)
|
enrollment = CourseEnrollmentFactory(course_id=course.id, mode=CourseMode.AUDIT, course__self_paced=True)
|
||||||
OrgDynamicUpgradeDeadlineConfiguration.objects.create(
|
OrgDynamicUpgradeDeadlineConfiguration.objects.create(
|
||||||
|
|||||||
@@ -3,6 +3,12 @@ from openedx.core.djangoapps.waffle_utils import WaffleFlagNamespace, CourseWaff
|
|||||||
|
|
||||||
WAFFLE_FLAG_NAMESPACE = WaffleFlagNamespace(name=u'schedules')
|
WAFFLE_FLAG_NAMESPACE = WaffleFlagNamespace(name=u'schedules')
|
||||||
|
|
||||||
|
CREATE_SCHEDULE_WAFFLE_FLAG = CourseWaffleFlag(
|
||||||
|
waffle_namespace=WAFFLE_FLAG_NAMESPACE,
|
||||||
|
flag_name=u'create_schedules_for_course',
|
||||||
|
flag_undefined_default=False
|
||||||
|
)
|
||||||
|
|
||||||
COURSE_UPDATE_WAFFLE_FLAG = CourseWaffleFlag(
|
COURSE_UPDATE_WAFFLE_FLAG = CourseWaffleFlag(
|
||||||
waffle_namespace=WAFFLE_FLAG_NAMESPACE,
|
waffle_namespace=WAFFLE_FLAG_NAMESPACE,
|
||||||
flag_name=u'send_updates_for_course',
|
flag_name=u'send_updates_for_course',
|
||||||
|
|||||||
@@ -250,6 +250,14 @@ and link it to the Site. Make sure to enable all of the settings:
|
|||||||
- ``hold_back_ratio``: ratio of all new Course Enrollments that should
|
- ``hold_back_ratio``: ratio of all new Course Enrollments that should
|
||||||
NOT have a Schedule created.
|
NOT have a Schedule created.
|
||||||
|
|
||||||
|
Roll-out Waffle Flag
|
||||||
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
There is one roll-out related course waffle flag that we plan to delete
|
||||||
|
called ``schedules.create_schedules_for_course``, which, if the
|
||||||
|
``ScheduleConfig.create_schedules`` is disabled, will enable schedule
|
||||||
|
creation on a per-course basis.
|
||||||
|
|
||||||
Self-paced Configuration
|
Self-paced Configuration
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ from openedx.core.djangoapps.schedules.content_highlights import course_has_high
|
|||||||
from openedx.core.djangoapps.signals.signals import COURSE_START_DATE_CHANGED
|
from openedx.core.djangoapps.signals.signals import COURSE_START_DATE_CHANGED
|
||||||
from openedx.core.djangoapps.theming.helpers import get_current_site
|
from openedx.core.djangoapps.theming.helpers import get_current_site
|
||||||
from student.models import CourseEnrollment
|
from student.models import CourseEnrollment
|
||||||
|
from .config import CREATE_SCHEDULE_WAFFLE_FLAG
|
||||||
from .models import Schedule, ScheduleConfig
|
from .models import Schedule, ScheduleConfig
|
||||||
from .tasks import update_course_schedules
|
from .tasks import update_course_schedules
|
||||||
|
|
||||||
@@ -38,7 +39,10 @@ def create_schedule(sender, **kwargs):
|
|||||||
|
|
||||||
enrollment = kwargs['instance']
|
enrollment = kwargs['instance']
|
||||||
schedule_config = ScheduleConfig.current(current_site)
|
schedule_config = ScheduleConfig.current(current_site)
|
||||||
if not schedule_config.create_schedules:
|
if (
|
||||||
|
not schedule_config.create_schedules
|
||||||
|
and not CREATE_SCHEDULE_WAFFLE_FLAG.is_enabled(enrollment.course_id)
|
||||||
|
):
|
||||||
log.debug('Schedules: Creation not enabled for this course or for this site')
|
log.debug('Schedules: Creation not enabled for this course or for this site')
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ from course_modes.models import CourseMode
|
|||||||
from course_modes.tests.factories import CourseModeFactory
|
from course_modes.tests.factories import CourseModeFactory
|
||||||
from courseware.models import DynamicUpgradeDeadlineConfiguration
|
from courseware.models import DynamicUpgradeDeadlineConfiguration
|
||||||
from openedx.core.djangoapps.schedules.models import ScheduleExperience
|
from openedx.core.djangoapps.schedules.models import ScheduleExperience
|
||||||
|
from openedx.core.djangoapps.schedules.signals import CREATE_SCHEDULE_WAFFLE_FLAG
|
||||||
from openedx.core.djangoapps.site_configuration.tests.factories import SiteFactory
|
from openedx.core.djangoapps.site_configuration.tests.factories import SiteFactory
|
||||||
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_flag
|
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_flag
|
||||||
from openedx.core.djangolib.testing.utils import skip_unless_lms
|
from openedx.core.djangolib.testing.utils import skip_unless_lms
|
||||||
@@ -43,28 +44,40 @@ class CreateScheduleTests(SharedModuleStoreTestCase):
|
|||||||
with self.assertRaises(Schedule.DoesNotExist):
|
with self.assertRaises(Schedule.DoesNotExist):
|
||||||
enrollment.schedule
|
enrollment.schedule
|
||||||
|
|
||||||
|
@override_waffle_flag(CREATE_SCHEDULE_WAFFLE_FLAG, True)
|
||||||
def test_create_schedule(self, mock_get_current_site):
|
def test_create_schedule(self, mock_get_current_site):
|
||||||
site = SiteFactory.create()
|
site = SiteFactory.create()
|
||||||
mock_get_current_site.return_value = site
|
mock_get_current_site.return_value = site
|
||||||
ScheduleConfigFactory.create(site=site)
|
ScheduleConfigFactory.create(site=site)
|
||||||
self.assert_schedule_created()
|
self.assert_schedule_created()
|
||||||
|
|
||||||
|
@override_waffle_flag(CREATE_SCHEDULE_WAFFLE_FLAG, True)
|
||||||
def test_no_current_site(self, mock_get_current_site):
|
def test_no_current_site(self, mock_get_current_site):
|
||||||
mock_get_current_site.return_value = None
|
mock_get_current_site.return_value = None
|
||||||
self.assert_schedule_not_created()
|
self.assert_schedule_not_created()
|
||||||
|
|
||||||
def test_schedule_config_enabled(self, mock_get_current_site):
|
@override_waffle_flag(CREATE_SCHEDULE_WAFFLE_FLAG, True)
|
||||||
|
def test_schedule_config_disabled_waffle_enabled(self, mock_get_current_site):
|
||||||
|
site = SiteFactory.create()
|
||||||
|
mock_get_current_site.return_value = site
|
||||||
|
ScheduleConfigFactory.create(site=site, create_schedules=False)
|
||||||
|
self.assert_schedule_created()
|
||||||
|
|
||||||
|
@override_waffle_flag(CREATE_SCHEDULE_WAFFLE_FLAG, False)
|
||||||
|
def test_schedule_config_enabled_waffle_disabled(self, mock_get_current_site):
|
||||||
site = SiteFactory.create()
|
site = SiteFactory.create()
|
||||||
mock_get_current_site.return_value = site
|
mock_get_current_site.return_value = site
|
||||||
ScheduleConfigFactory.create(site=site, create_schedules=True)
|
ScheduleConfigFactory.create(site=site, create_schedules=True)
|
||||||
self.assert_schedule_created()
|
self.assert_schedule_created()
|
||||||
|
|
||||||
def test_schedule_config_disabled(self, mock_get_current_site):
|
@override_waffle_flag(CREATE_SCHEDULE_WAFFLE_FLAG, False)
|
||||||
|
def test_schedule_config_disabled_waffle_disabled(self, mock_get_current_site):
|
||||||
site = SiteFactory.create()
|
site = SiteFactory.create()
|
||||||
mock_get_current_site.return_value = site
|
mock_get_current_site.return_value = site
|
||||||
ScheduleConfigFactory.create(site=site, create_schedules=False)
|
ScheduleConfigFactory.create(site=site, create_schedules=False)
|
||||||
self.assert_schedule_not_created()
|
self.assert_schedule_not_created()
|
||||||
|
|
||||||
|
@override_waffle_flag(CREATE_SCHEDULE_WAFFLE_FLAG, True)
|
||||||
def test_schedule_config_creation_enabled_instructor_paced(self, mock_get_current_site):
|
def test_schedule_config_creation_enabled_instructor_paced(self, mock_get_current_site):
|
||||||
site = SiteFactory.create()
|
site = SiteFactory.create()
|
||||||
mock_get_current_site.return_value = site
|
mock_get_current_site.return_value = site
|
||||||
@@ -74,14 +87,15 @@ class CreateScheduleTests(SharedModuleStoreTestCase):
|
|||||||
with self.assertRaises(Schedule.DoesNotExist):
|
with self.assertRaises(Schedule.DoesNotExist):
|
||||||
enrollment.schedule
|
enrollment.schedule
|
||||||
|
|
||||||
|
@override_waffle_flag(CREATE_SCHEDULE_WAFFLE_FLAG, True)
|
||||||
@patch('openedx.core.djangoapps.schedules.signals.course_has_highlights')
|
@patch('openedx.core.djangoapps.schedules.signals.course_has_highlights')
|
||||||
def test_create_schedule_course_updates_experience(self, mock_course_has_highlights, mock_get_current_site):
|
def test_create_schedule_course_updates_experience(self, mock_course_has_highlights, mock_get_current_site):
|
||||||
site = SiteFactory.create()
|
site = SiteFactory.create()
|
||||||
ScheduleConfigFactory.create(site=site, enabled=True, create_schedules=True)
|
|
||||||
mock_course_has_highlights.return_value = True
|
mock_course_has_highlights.return_value = True
|
||||||
mock_get_current_site.return_value = site
|
mock_get_current_site.return_value = site
|
||||||
self.assert_schedule_created(experience_type=ScheduleExperience.EXPERIENCES.course_updates)
|
self.assert_schedule_created(experience_type=ScheduleExperience.EXPERIENCES.course_updates)
|
||||||
|
|
||||||
|
@override_waffle_flag(CREATE_SCHEDULE_WAFFLE_FLAG, True)
|
||||||
@patch('analytics.track')
|
@patch('analytics.track')
|
||||||
@patch('random.random')
|
@patch('random.random')
|
||||||
@ddt.data(
|
@ddt.data(
|
||||||
|
|||||||
Reference in New Issue
Block a user