def from_json(tab_dict): """ Deserializes a CourseTab from a json-like representation. The subclass that is instantiated is determined by the value of the 'type' key in the given dict-type tab. The given dict-type tab is validated before instantiating the CourseTab object. If the tab_type is not recognized, then an exception is logged and None is returned. The intention is that the user should still be able to use the course even if a particular tab is not found for some reason. Args: tab: a dictionary with keys for the properties of the tab. Raises: InvalidTabsException if the given tab doesn't have the right keys. """ # TODO: don't import openedx capabilities from common from openedx.core.lib.course_tabs import CourseTabPluginManager tab_type_name = tab_dict.get('type') if tab_type_name is None: log.error('No type included in tab_dict: %r', tab_dict) return None try: tab_type = CourseTabPluginManager.get_plugin(tab_type_name) except PluginError: log.exception( "Unknown tab type %r Known types: %r.", tab_type_name, CourseTabPluginManager.get_tab_types() ) return None tab_type.validate(tab_dict) return tab_type(tab_dict=tab_dict)
def test_get_plugin(self): """ Verify that get_plugin works as expected. """ tab_type = CourseTabPluginManager.get_plugin("instructor") self.assertEqual(tab_type.title, "Instructor") with self.assertRaises(PluginError): CourseTabPluginManager.get_plugin("no_such_type")
def test_get_plugin(self): """ Verify that get_plugin works as expected. """ tab_type = CourseTabPluginManager.get_plugin("instructor") assert tab_type.title == 'Instructor' with pytest.raises(PluginError): CourseTabPluginManager.get_plugin("no_such_type")
def validate_tabs(cls, tabs): """ Check that the tabs set for the specified course is valid. If it isn't, raise InvalidTabsException with the complaint. Specific rules checked: - if no tabs specified, that's fine - if tabs specified, first two must have type 'courseware' and 'course_info', in that order. """ if tabs is None or len(tabs) == 0: return if len(tabs) < 2: raise InvalidTabsException( "Expected at least two tabs. tabs: '{0}'".format(tabs)) if tabs[0].get('type') != 'courseware': raise InvalidTabsException( "Expected first tab to have type 'courseware'. tabs: '{0}'". format(tabs)) if tabs[1].get('type') != 'course_info': raise InvalidTabsException( "Expected second tab to have type 'course_info'. tabs: '{0}'". format(tabs)) # the following tabs should appear only once # TODO: don't import openedx capabilities from common from openedx.core.lib.course_tabs import CourseTabPluginManager for tab_type in CourseTabPluginManager.get_tab_types(): if not tab_type.allow_multiple: cls._validate_num_tabs_of_type(tabs, tab_type.type, 1)
def test_get_tab_types(self, get_available_plugins): """ Verify that get_course_view_types sorts appropriately """ def create_mock_plugin(tab_type, priority): """ Create a mock plugin with the specified name and priority. """ mock_plugin = Mock() mock_plugin.type = tab_type mock_plugin.priority = priority return mock_plugin mock_plugins = { "Last": create_mock_plugin(tab_type="Last", priority=None), "Duplicate1": create_mock_plugin(tab_type="Duplicate", priority=None), "Duplicate2": create_mock_plugin(tab_type="Duplicate", priority=None), "First": create_mock_plugin(tab_type="First", priority=1), "Second": create_mock_plugin(tab_type="Second", priority=1), "Third": create_mock_plugin(tab_type="Third", priority=3), } get_available_plugins.return_value = mock_plugins self.assertEqual( [plugin.type for plugin in CourseTabPluginManager.get_tab_types()], ["First", "Second", "Third", "Duplicate", "Duplicate", "Last"])
def validate_tabs(cls, tabs): """ Check that the tabs set for the specified course is valid. If it isn't, raise InvalidTabsException with the complaint. Specific rules checked: - if no tabs specified, that's fine - if tabs specified, first two must have type 'courseware' and 'course_info', in that order. """ if tabs is None or len(tabs) == 0: return if len(tabs) < 2: raise InvalidTabsException("Expected at least two tabs. tabs: '{0}'".format(tabs)) if tabs[0].get('type') != 'course_info': raise InvalidTabsException( "Expected first tab to have type 'course_info'. tabs: '{0}'".format(tabs)) if tabs[1].get('type') != 'courseware': raise InvalidTabsException( "Expected second tab to have type 'courseware'. tabs: '{0}'".format(tabs)) # the following tabs should appear only once # TODO: don't import openedx capabilities from common from openedx.core.lib.course_tabs import CourseTabPluginManager for tab_type in CourseTabPluginManager.get_tab_types(): if not tab_type.allow_multiple: cls._validate_num_tabs_of_type(tabs, tab_type.type, 1)
def _get_dynamic_tabs(course, user): """ Returns the dynamic tab types for the current user. Note: dynamic tabs are those that are not persisted in the course, but are instead added dynamically based upon the user's role. """ dynamic_tabs = list() for tab_type in CourseTabPluginManager.get_tab_types(): if getattr(tab_type, "is_dynamic", False): tab = tab_type(dict()) if tab.is_enabled(course, user=user): dynamic_tabs.append(tab) dynamic_tabs.sort(key=lambda dynamic_tab: dynamic_tab.name) return dynamic_tabs
def test_get_tab_types(self, get_available_plugins): """ Verify that get_course_view_types sorts appropriately """ def create_mock_plugin(tab_type, priority): """ Create a mock plugin with the specified name and priority. """ mock_plugin = Mock() mock_plugin.type = tab_type mock_plugin.priority = priority return mock_plugin mock_plugins = { "Last": create_mock_plugin(tab_type="Last", priority=None), "Duplicate1": create_mock_plugin(tab_type="Duplicate", priority=None), "Duplicate2": create_mock_plugin(tab_type="Duplicate", priority=None), "First": create_mock_plugin(tab_type="First", priority=1), "Second": create_mock_plugin(tab_type="Second", priority=1), "Third": create_mock_plugin(tab_type="Third", priority=3), } get_available_plugins.return_value = mock_plugins self.assertEqual( [plugin.type for plugin in CourseTabPluginManager.get_tab_types()], ["First", "Second", "Third", "Duplicate", "Duplicate", "Last"] )