Added ccx enable/disable flag to advance settings and show hide ccx coach option on lms
This commit is contained in:
committed by
Amir Qayyum Khan
parent
d3dde8553c
commit
6a41cd7bfa
@@ -83,6 +83,10 @@ class CourseMetadata(object):
|
||||
if not settings.FEATURES.get('ENABLE_VIDEO_BUMPER'):
|
||||
filtered_list.append('video_bumper')
|
||||
|
||||
# Do not show enable_ccx if feature is not enabled.
|
||||
if not settings.FEATURES.get('CUSTOM_COURSES_EDX'):
|
||||
filtered_list.append('enable_ccx')
|
||||
|
||||
return filtered_list
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -386,6 +386,21 @@ class CourseFields(object):
|
||||
),
|
||||
scope=Scope.settings
|
||||
)
|
||||
enable_ccx = Boolean(
|
||||
# Translators: Custom Courses for edX (CCX) is an edX feature for re-using course content. CCX Coach is
|
||||
# a role created by a course Instructor to enable a person (the "Coach") to manage the custom course for
|
||||
# his students.
|
||||
display_name=_("Enable CCX"),
|
||||
# Translators: Custom Courses for edX (CCX) is an edX feature for re-using course content. CCX Coach is
|
||||
# a role created by a course Instructor to enable a person (the "Coach") to manage the custom course for
|
||||
# his students.
|
||||
help=_(
|
||||
"Allow course instructors to assign CCX Coach roles, and allow coaches to manage Custom Courses on edX."
|
||||
" When false, Custom Courses cannot be created, but existing Custom Courses will be preserved."
|
||||
),
|
||||
default=False,
|
||||
scope=Scope.settings
|
||||
)
|
||||
allow_anonymous = Boolean(
|
||||
display_name=_("Allow Anonymous Discussion Posts"),
|
||||
help=_("Enter true or false. If true, students can create discussion posts that are anonymous to all users."),
|
||||
|
||||
@@ -758,7 +758,7 @@ class CcxCoachTab(CourseTab):
|
||||
the user is one.
|
||||
"""
|
||||
user_is_coach = False
|
||||
if settings.FEATURES.get('CUSTOM_COURSES_EDX', False):
|
||||
if settings.FEATURES.get('CUSTOM_COURSES_EDX', False) and course.enable_ccx:
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from student.roles import CourseCcxCoachRole # pylint: disable=import-error
|
||||
from ccx.overrides import get_current_request # pylint: disable=import-error
|
||||
|
||||
@@ -5,7 +5,9 @@ import datetime
|
||||
import json
|
||||
import re
|
||||
import pytz
|
||||
from mock import patch
|
||||
import ddt
|
||||
import unittest
|
||||
from mock import patch, MagicMock
|
||||
from nose.plugins.attrib import attr
|
||||
|
||||
from capa.tests.response_xml_factory import StringResponseXMLFactory
|
||||
@@ -14,6 +16,7 @@ from courseware.tests.factories import StudentModuleFactory # pylint: disable=i
|
||||
from courseware.tests.helpers import LoginEnrollmentTestCase # pylint: disable=import-error
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.test.utils import override_settings
|
||||
from django.test import RequestFactory
|
||||
from edxmako.shortcuts import render_to_response # pylint: disable=import-error
|
||||
from student.roles import CourseCcxCoachRole # pylint: disable=import-error
|
||||
from student.tests.factories import ( # pylint: disable=import-error
|
||||
@@ -22,12 +25,14 @@ from student.tests.factories import ( # pylint: disable=import-error
|
||||
UserFactory,
|
||||
)
|
||||
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from xmodule.x_module import XModuleMixin
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import (
|
||||
CourseFactory,
|
||||
ItemFactory,
|
||||
)
|
||||
import xmodule.tabs as tabs
|
||||
from ..models import (
|
||||
CustomCourseForEdX,
|
||||
CcxMembership,
|
||||
@@ -56,6 +61,17 @@ def intercept_renderer(path, context):
|
||||
return response
|
||||
|
||||
|
||||
def ccx_dummy_request():
|
||||
"""
|
||||
Returns dummy request object for CCX coach tab test
|
||||
"""
|
||||
factory = RequestFactory()
|
||||
request = factory.get('ccx_coach_dashboard')
|
||||
request.user = MagicMock()
|
||||
|
||||
return request
|
||||
|
||||
|
||||
@attr('shard_1')
|
||||
class TestCoachDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
"""
|
||||
@@ -756,6 +772,48 @@ class TestSwitchActiveCCX(ModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
self.verify_active_ccx(self.client)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class CCXCoachTabTestCase(unittest.TestCase):
|
||||
"""
|
||||
Test case for CCX coach tab.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(CCXCoachTabTestCase, self).setUp()
|
||||
self.course = MagicMock()
|
||||
self.course.id = SlashSeparatedCourseKey('edX', 'toy', '2012_Fall')
|
||||
self.settings = MagicMock()
|
||||
self.settings.FEATURES = {}
|
||||
|
||||
def check_ccx_tab(self):
|
||||
"""Helper function for verifying the ccx tab."""
|
||||
tab = tabs.CcxCoachTab({'type': tabs.CcxCoachTab.type, 'name': 'CCX Coach'})
|
||||
return tab
|
||||
|
||||
@ddt.data(
|
||||
(True, True, True),
|
||||
(True, False, False),
|
||||
(False, True, False),
|
||||
(False, False, False),
|
||||
(True, None, False)
|
||||
)
|
||||
@patch('ccx.overrides.get_current_request', ccx_dummy_request)
|
||||
@ddt.unpack
|
||||
def test_coach_tab_for_ccx_advance_settings(self, ccx_feature_flag, enable_ccx, expected_result):
|
||||
"""
|
||||
Test ccx coach tab state (visible or hidden) depending on the value of enable_ccx flag, ccx feature flag.
|
||||
"""
|
||||
tab = self.check_ccx_tab()
|
||||
self.settings.FEATURES = {'CUSTOM_COURSES_EDX': ccx_feature_flag}
|
||||
|
||||
self.course.enable_ccx = enable_ccx
|
||||
self.assertEquals(
|
||||
expected_result,
|
||||
tab.can_display(
|
||||
self.course, self.settings, is_user_authenticated=True, is_user_staff=False, is_user_enrolled=True
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def flatten(seq):
|
||||
"""
|
||||
For [[1, 2], [3, 4]] returns [1, 2, 3, 4]. Does not recurse.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Unit tests for instructor_dashboard.py.
|
||||
"""
|
||||
import ddt
|
||||
from mock import patch
|
||||
|
||||
from django.conf import settings
|
||||
@@ -16,6 +17,7 @@ from course_modes.models import CourseMode
|
||||
from student.roles import CourseFinanceAdminRole
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
"""
|
||||
Tests for the instructor dashboard (not legacy).
|
||||
@@ -179,3 +181,29 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
total_amount = single_purchase_total + bulk_purchase_total
|
||||
response = self.client.get(self.url)
|
||||
self.assertIn('{currency}{amount}'.format(currency='$', amount=total_amount), response.content)
|
||||
|
||||
@ddt.data(
|
||||
(True, True, True),
|
||||
(True, False, False),
|
||||
(True, None, False),
|
||||
(False, True, False),
|
||||
(False, False, False),
|
||||
(False, None, False),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_ccx_coaches_option_on_admin_list_management_instructor(
|
||||
self, ccx_feature_flag, enable_ccx, expected_result
|
||||
):
|
||||
"""
|
||||
Test whether the "CCX Coaches" option is visible or hidden depending on the value of course.enable_ccx.
|
||||
"""
|
||||
with patch.dict(settings.FEATURES, {'CUSTOM_COURSES_EDX': ccx_feature_flag}):
|
||||
self.course.enable_ccx = enable_ccx
|
||||
self.store.update_item(self.course, self.instructor.id)
|
||||
|
||||
response = self.client.get(self.url)
|
||||
|
||||
self.assertEquals(
|
||||
expected_result,
|
||||
'CCX Coaches are able to create their own Custom Courses based on this course' in response.content
|
||||
)
|
||||
|
||||
@@ -324,10 +324,12 @@ def _section_course_info(course, access):
|
||||
def _section_membership(course, access):
|
||||
""" Provide data for the corresponding dashboard section """
|
||||
course_key = course.id
|
||||
ccx_enabled = settings.FEATURES.get('CUSTOM_COURSES_EDX', False) and course.enable_ccx
|
||||
section_data = {
|
||||
'section_key': 'membership',
|
||||
'section_display_name': _('Membership'),
|
||||
'access': access,
|
||||
'ccx_is_enabled': ccx_enabled,
|
||||
'enroll_button_url': reverse('students_update_enrollment', kwargs={'course_id': unicode(course_key)}),
|
||||
'unenroll_button_url': reverse('students_update_enrollment', kwargs={'course_id': unicode(course_key)}),
|
||||
'upload_student_csv_button_url': reverse('register_and_enroll_students', kwargs={'course_id': unicode(course_key)}),
|
||||
|
||||
@@ -243,8 +243,8 @@
|
||||
data-add-button-label="${_("Add Community TA")}"
|
||||
></div>
|
||||
%endif
|
||||
|
||||
%if section_data['access']['instructor'] and settings.FEATURES.get('CUSTOM_COURSES_EDX', False):
|
||||
|
||||
%if section_data['access']['instructor'] and section_data['ccx_is_enabled']:
|
||||
<div class="auth-list-container"
|
||||
data-rolename="ccx_coach"
|
||||
data-display-name="${_("CCX Coaches")}"
|
||||
|
||||
Reference in New Issue
Block a user