Add course overrides of waffle flags.
This commit is contained in:
@@ -231,18 +231,18 @@ class TestFieldOverrideMongoPerformance(FieldOverridePerformanceTestCase):
|
||||
# # of sql queries to default,
|
||||
# # of mongo queries,
|
||||
# )
|
||||
('no_overrides', 1, True, False): (24, 1),
|
||||
('no_overrides', 2, True, False): (24, 1),
|
||||
('no_overrides', 3, True, False): (24, 1),
|
||||
('ccx', 1, True, False): (24, 1),
|
||||
('ccx', 2, True, False): (24, 1),
|
||||
('ccx', 3, True, False): (24, 1),
|
||||
('no_overrides', 1, False, False): (24, 1),
|
||||
('no_overrides', 2, False, False): (24, 1),
|
||||
('no_overrides', 3, False, False): (24, 1),
|
||||
('ccx', 1, False, False): (24, 1),
|
||||
('ccx', 2, False, False): (24, 1),
|
||||
('ccx', 3, False, False): (24, 1),
|
||||
('no_overrides', 1, True, False): (25, 1),
|
||||
('no_overrides', 2, True, False): (25, 1),
|
||||
('no_overrides', 3, True, False): (25, 1),
|
||||
('ccx', 1, True, False): (25, 1),
|
||||
('ccx', 2, True, False): (25, 1),
|
||||
('ccx', 3, True, False): (25, 1),
|
||||
('no_overrides', 1, False, False): (25, 1),
|
||||
('no_overrides', 2, False, False): (25, 1),
|
||||
('no_overrides', 3, False, False): (25, 1),
|
||||
('ccx', 1, False, False): (25, 1),
|
||||
('ccx', 2, False, False): (25, 1),
|
||||
('ccx', 3, False, False): (25, 1),
|
||||
}
|
||||
|
||||
|
||||
@@ -254,19 +254,19 @@ class TestFieldOverrideSplitPerformance(FieldOverridePerformanceTestCase):
|
||||
__test__ = True
|
||||
|
||||
TEST_DATA = {
|
||||
('no_overrides', 1, True, False): (24, 3),
|
||||
('no_overrides', 2, True, False): (24, 3),
|
||||
('no_overrides', 3, True, False): (24, 3),
|
||||
('ccx', 1, True, False): (24, 3),
|
||||
('ccx', 2, True, False): (24, 3),
|
||||
('ccx', 3, True, False): (24, 3),
|
||||
('ccx', 1, True, True): (25, 3),
|
||||
('ccx', 2, True, True): (25, 3),
|
||||
('ccx', 3, True, True): (25, 3),
|
||||
('no_overrides', 1, False, False): (24, 3),
|
||||
('no_overrides', 2, False, False): (24, 3),
|
||||
('no_overrides', 3, False, False): (24, 3),
|
||||
('ccx', 1, False, False): (24, 3),
|
||||
('ccx', 2, False, False): (24, 3),
|
||||
('ccx', 3, False, False): (24, 3),
|
||||
('no_overrides', 1, True, False): (25, 3),
|
||||
('no_overrides', 2, True, False): (25, 3),
|
||||
('no_overrides', 3, True, False): (25, 3),
|
||||
('ccx', 1, True, False): (25, 3),
|
||||
('ccx', 2, True, False): (25, 3),
|
||||
('ccx', 3, True, False): (25, 3),
|
||||
('ccx', 1, True, True): (26, 3),
|
||||
('ccx', 2, True, True): (26, 3),
|
||||
('ccx', 3, True, True): (26, 3),
|
||||
('no_overrides', 1, False, False): (25, 3),
|
||||
('no_overrides', 2, False, False): (25, 3),
|
||||
('no_overrides', 3, False, False): (25, 3),
|
||||
('ccx', 1, False, False): (25, 3),
|
||||
('ccx', 2, False, False): (25, 3),
|
||||
('ccx', 3, False, False): (25, 3),
|
||||
}
|
||||
|
||||
@@ -2,15 +2,14 @@
|
||||
This module is essentially a broker to xmodule/tabs.py -- it was originally introduced to
|
||||
perform some LMS-specific tab display gymnastics for the Entrance Exams feature
|
||||
"""
|
||||
import waffle
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext as _, ugettext_noop
|
||||
|
||||
from courseware.access import has_access
|
||||
from courseware.entrance_exams import user_can_skip_entrance_exam
|
||||
from openedx.core.lib.course_tabs import CourseTabPluginManager
|
||||
from openedx.features.course_experience import default_course_url_name, UNIFIED_COURSE_EXPERIENCE_FLAG
|
||||
from openedx.features.course_experience import default_course_url_name
|
||||
from openedx.features.course_experience import UNIFIED_COURSE_TAB_FLAG
|
||||
from request_cache.middleware import RequestCache
|
||||
from student.models import CourseEnrollment
|
||||
from xmodule.tabs import CourseTab, CourseTabList, key_checker, link_reverse_func
|
||||
@@ -66,8 +65,7 @@ class CourseInfoTab(CourseTab):
|
||||
"""
|
||||
The "Home" tab is not shown for the new unified course experience.
|
||||
"""
|
||||
request = RequestCache.get_current_request()
|
||||
return not waffle.flag_is_active(request, UNIFIED_COURSE_EXPERIENCE_FLAG)
|
||||
return not UNIFIED_COURSE_TAB_FLAG.is_enabled(course.id)
|
||||
|
||||
|
||||
class SyllabusTab(EnrolledTab):
|
||||
|
||||
@@ -7,8 +7,6 @@ from django.core.urlresolvers import reverse
|
||||
from freezegun import freeze_time
|
||||
from nose.plugins.attrib import attr
|
||||
from pytz import utc
|
||||
from waffle.testutils import override_flag
|
||||
from openedx.features.course_experience import UNIFIED_COURSE_EXPERIENCE_FLAG
|
||||
|
||||
from commerce.models import CommerceConfiguration
|
||||
from course_modes.tests.factories import CourseModeFactory
|
||||
@@ -24,6 +22,8 @@ from courseware.date_summary import (
|
||||
)
|
||||
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
|
||||
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_experience import UNIFIED_COURSE_TAB_FLAG
|
||||
from student.tests.factories import CourseEnrollmentFactory, UserFactory
|
||||
from lms.djangoapps.verify_student.models import VerificationDeadline
|
||||
from lms.djangoapps.verify_student.tests.factories import SoftwareSecurePhotoVerificationFactory
|
||||
@@ -194,7 +194,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
'info',
|
||||
'openedx.course_experience.course_home',
|
||||
)
|
||||
@override_flag(UNIFIED_COURSE_EXPERIENCE_FLAG, active=True)
|
||||
@override_waffle_flag(UNIFIED_COURSE_TAB_FLAG, active=True)
|
||||
def test_todays_date_no_timezone(self, url_name):
|
||||
with freeze_time('2015-01-02'):
|
||||
self.setup_course_and_user()
|
||||
@@ -218,7 +218,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
'info',
|
||||
'openedx.course_experience.course_home',
|
||||
)
|
||||
@override_flag(UNIFIED_COURSE_EXPERIENCE_FLAG, active=True)
|
||||
@override_waffle_flag(UNIFIED_COURSE_TAB_FLAG, active=True)
|
||||
def test_todays_date_timezone(self, url_name):
|
||||
with freeze_time('2015-01-02'):
|
||||
self.setup_course_and_user()
|
||||
@@ -249,7 +249,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
'info',
|
||||
'openedx.course_experience.course_home',
|
||||
)
|
||||
@override_flag(UNIFIED_COURSE_EXPERIENCE_FLAG, active=True)
|
||||
@override_waffle_flag(UNIFIED_COURSE_TAB_FLAG, active=True)
|
||||
def test_start_date_render(self, url_name):
|
||||
with freeze_time('2015-01-02'):
|
||||
self.setup_course_and_user()
|
||||
@@ -267,7 +267,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
'info',
|
||||
'openedx.course_experience.course_home',
|
||||
)
|
||||
@override_flag(UNIFIED_COURSE_EXPERIENCE_FLAG, active=True)
|
||||
@override_waffle_flag(UNIFIED_COURSE_TAB_FLAG, active=True)
|
||||
def test_start_date_render_time_zone(self, url_name):
|
||||
with freeze_time('2015-01-02'):
|
||||
self.setup_course_and_user()
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
Test cases for tabs.
|
||||
"""
|
||||
|
||||
from waffle.testutils import override_flag
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.http import Http404
|
||||
from mock import MagicMock, Mock, patch
|
||||
@@ -18,7 +16,8 @@ from courseware.tests.helpers import LoginEnrollmentTestCase
|
||||
from courseware.tests.factories import InstructorFactory, StaffFactory
|
||||
from courseware.views.views import get_static_tab_fragment, StaticCourseTabView
|
||||
from openedx.core.djangolib.testing.utils import get_mock_request
|
||||
from openedx.features.course_experience import UNIFIED_COURSE_EXPERIENCE_FLAG
|
||||
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_flag
|
||||
from openedx.features.course_experience import UNIFIED_COURSE_TAB_FLAG
|
||||
from student.models import CourseEnrollment
|
||||
from student.tests.factories import UserFactory
|
||||
from util.milestones_helpers import (
|
||||
@@ -776,12 +775,13 @@ class CourseInfoTabTestCase(TabTestCase):
|
||||
self.user = self.create_mock_user()
|
||||
self.request = get_mock_request(self.user)
|
||||
|
||||
@override_waffle_flag(UNIFIED_COURSE_TAB_FLAG, active=False)
|
||||
def test_default_tab(self):
|
||||
# Verify that the course info tab is the first tab
|
||||
tabs = get_course_tab_list(self.request, self.course)
|
||||
self.assertEqual(tabs[0].type, 'course_info')
|
||||
|
||||
@override_flag(UNIFIED_COURSE_EXPERIENCE_FLAG, active=True)
|
||||
@override_waffle_flag(UNIFIED_COURSE_TAB_FLAG, active=True)
|
||||
def test_default_tab_for_new_course_experience(self):
|
||||
# Verify that the unified course experience hides the course info tab
|
||||
tabs = get_course_tab_list(self.request, self.course)
|
||||
|
||||
@@ -210,8 +210,8 @@ class IndexQueryTestCase(ModuleStoreTestCase):
|
||||
NUM_PROBLEMS = 20
|
||||
|
||||
@ddt.data(
|
||||
(ModuleStoreEnum.Type.mongo, 10, 142),
|
||||
(ModuleStoreEnum.Type.split, 4, 142),
|
||||
(ModuleStoreEnum.Type.mongo, 10, 143),
|
||||
(ModuleStoreEnum.Type.split, 4, 143),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_index_query_counts(self, store_type, expected_mongo_query_count, expected_mysql_query_count):
|
||||
@@ -1420,12 +1420,12 @@ class ProgressPageTests(ProgressPageBaseTests):
|
||||
"""Test that query counts remain the same for self-paced and instructor-paced courses."""
|
||||
SelfPacedConfiguration(enabled=self_paced_enabled).save()
|
||||
self.setup_course(self_paced=self_paced)
|
||||
with self.assertNumQueries(40), check_mongo_calls(1):
|
||||
with self.assertNumQueries(41), check_mongo_calls(1):
|
||||
self._get_progress_page()
|
||||
|
||||
@ddt.data(
|
||||
(False, 40, 26),
|
||||
(True, 33, 22)
|
||||
(False, 41, 27),
|
||||
(True, 34, 23)
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_progress_queries(self, enable_waffle, initial, subsequent):
|
||||
|
||||
@@ -86,9 +86,9 @@ from openedx.core.djangoapps.programs.utils import ProgramMarketingDataExtender
|
||||
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
|
||||
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
|
||||
from openedx.features.course_experience import (
|
||||
UNIFIED_COURSE_EXPERIENCE_FLAG,
|
||||
UNIFIED_COURSE_TAB_FLAG,
|
||||
UNIFIED_COURSE_VIEW_FLAG,
|
||||
course_home_url_name
|
||||
course_home_url_name,
|
||||
)
|
||||
from openedx.features.course_experience.views.course_dates import CourseDatesFragmentView
|
||||
from openedx.features.enterprise_support.api import data_sharing_consent_required
|
||||
@@ -263,11 +263,12 @@ def course_info(request, course_id):
|
||||
return url
|
||||
return None
|
||||
|
||||
# If the unified course experience is enabled, redirect to the "Course" tab
|
||||
if waffle.flag_is_active(request, UNIFIED_COURSE_EXPERIENCE_FLAG):
|
||||
return redirect(reverse(course_home_url_name(request), args=[course_id]))
|
||||
|
||||
course_key = CourseKey.from_string(course_id)
|
||||
|
||||
# If the unified course experience is enabled, redirect to the "Course" tab
|
||||
if UNIFIED_COURSE_TAB_FLAG.is_enabled(course_key):
|
||||
return redirect(reverse(course_home_url_name(course_key), args=[course_id]))
|
||||
|
||||
with modulestore().bulk_operations(course_key):
|
||||
course = get_course_by_id(course_key, depth=2)
|
||||
access_response = has_access(request.user, 'load', course, course_key)
|
||||
@@ -669,7 +670,7 @@ def course_about(request, course_id):
|
||||
modes = CourseMode.modes_for_course_dict(course_key)
|
||||
|
||||
if configuration_helpers.get_value('ENABLE_MKTG_SITE', settings.FEATURES.get('ENABLE_MKTG_SITE', False)):
|
||||
return redirect(reverse(course_home_url_name(request), args=[unicode(course.id)]))
|
||||
return redirect(reverse(course_home_url_name(course.id), args=[unicode(course.id)]))
|
||||
|
||||
registered = registered_for_course(course, request.user)
|
||||
|
||||
@@ -677,7 +678,7 @@ def course_about(request, course_id):
|
||||
studio_url = get_studio_url(course, 'settings/details')
|
||||
|
||||
if has_access(request.user, 'load', course):
|
||||
course_target = reverse(course_home_url_name(request), args=[course.id.to_deprecated_string()])
|
||||
course_target = reverse(course_home_url_name(course.id), args=[course.id.to_deprecated_string()])
|
||||
else:
|
||||
course_target = reverse('about_course', args=[course.id.to_deprecated_string()])
|
||||
|
||||
@@ -1241,7 +1242,7 @@ def course_survey(request, course_id):
|
||||
course_key = CourseKey.from_string(course_id)
|
||||
course = get_course_with_access(request.user, 'load', course_key)
|
||||
|
||||
redirect_url = reverse(course_home_url_name(request), args=[course_id])
|
||||
redirect_url = reverse(course_home_url_name(course.id), args=[course_id])
|
||||
|
||||
# if there is no Survey associated with this course,
|
||||
# then redirect to the course instead
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
This module contains various configuration settings via
|
||||
waffle switches for the Grades app.
|
||||
"""
|
||||
from openedx.core.djangolib.waffle_utils import WaffleSwitchPlus
|
||||
from openedx.core.djangoapps.waffle_utils import WaffleSwitchNamespace
|
||||
|
||||
|
||||
# Namespace
|
||||
@@ -18,4 +18,4 @@ def waffle():
|
||||
"""
|
||||
Returns the namespaced, cached, audited Waffle class for Grades.
|
||||
"""
|
||||
return WaffleSwitchPlus(namespace=WAFFLE_NAMESPACE, log_prefix=u'Grades: ')
|
||||
return WaffleSwitchNamespace(name=WAFFLE_NAMESPACE, log_prefix=u'Grades: ')
|
||||
|
||||
@@ -2211,6 +2211,9 @@ INSTALLED_APPS = (
|
||||
# Unusual migrations
|
||||
'database_fixups',
|
||||
|
||||
# Waffle related utilities
|
||||
'openedx.core.djangoapps.waffle_utils',
|
||||
|
||||
# Features
|
||||
'openedx.features.course_bookmarks',
|
||||
'openedx.features.course_experience',
|
||||
|
||||
@@ -56,7 +56,7 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_
|
||||
% endif
|
||||
<div class="course-container">
|
||||
<article class="course${mode_class}">
|
||||
<% course_target = reverse(course_home_url_name(), args=[unicode(course_overview.id)]) %>
|
||||
<% course_target = reverse(course_home_url_name(course_overview.id), args=[unicode(course_overview.id)]) %>
|
||||
<section class="details" aria-labelledby="details-heading-${course_overview.number}">
|
||||
<h2 class="hd hd-2 sr" id="details-heading-${course_overview.number}">${_('Course details')}</h2>
|
||||
<div class="wrapper-course-image" aria-hidden="true">
|
||||
|
||||
@@ -75,7 +75,7 @@ from openedx.features.course_experience import course_home_url_name
|
||||
</div>
|
||||
% if not reg_code_already_redeemed:
|
||||
%if redemption_success:
|
||||
<% course_url = reverse(course_home_url_name(), args=[course.id.to_deprecated_string()]) %>
|
||||
<% course_url = reverse(course_home_url_name(course.id), args=[course.id.to_deprecated_string()]) %>
|
||||
<a href="${course_url}" class="link-button course-link-bg-color">${_("View Course")} <span class="icon fa fa-caret-right" aria-hidden="true"></span></a>
|
||||
%elif not registered_for_course:
|
||||
<form method="post">
|
||||
|
||||
@@ -55,6 +55,6 @@ class HelpModalTests(ModuleStoreTestCase):
|
||||
Simple test to make sure that you don't get a 500 error when the modal
|
||||
is enabled.
|
||||
"""
|
||||
url = reverse(course_home_url_name(), args=[self.course.id.to_deprecated_string()])
|
||||
url = reverse(course_home_url_name(self.course.id), args=[self.course.id.to_deprecated_string()])
|
||||
resp = self.client.get(url)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
Reference in New Issue
Block a user