Skip to content
Snippets Groups Projects
Commit 99e6cab2 authored by Renzo Lucioni's avatar Renzo Lucioni
Browse files

Merge pull request #10253 from edx/renzo/studio-entity-plugins

Groundwork for Studio extensibility
parents 2e6880f6 32460a99
No related merge requests found
"""Studio tab plugin manager and API."""
import abc
from openedx.core.lib.api.plugins import PluginManager
class StudioTabPluginManager(PluginManager):
"""Manager for all available Studio tabs.
Examples of Studio tabs include Courses, Libraries, and Programs. All Studio
tabs should implement `StudioTab`.
"""
NAMESPACE = 'openedx.studio_tab'
@classmethod
def get_enabled_tabs(cls):
"""Returns a list of enabled Studio tabs."""
tabs = cls.get_available_plugins()
enabled_tabs = [tab for tab in tabs.viewvalues() if tab.is_enabled()]
return enabled_tabs
class StudioTab(object):
"""Abstract class used to represent Studio tabs.
Examples of Studio tabs include Courses, Libraries, and Programs.
"""
__metaclass__ = abc.ABCMeta
@abc.abstractproperty
def tab_text(self):
"""Text to display in a tab used to navigate to a list of instances of this tab.
Should be internationalized using `ugettext_noop()` since the user won't be available in this context.
"""
pass
@abc.abstractproperty
def button_text(self):
"""Text to display in a button used to create a new instance of this tab.
Should be internationalized using `ugettext_noop()` since the user won't be available in this context.
"""
pass
@abc.abstractproperty
def view_name(self):
"""Name of the view used to render this tab.
Used within templates in conjuction with Django's `reverse()` to generate a URL for this tab.
"""
pass
@abc.abstractmethod
def is_enabled(cls, user=None): # pylint: disable=no-self-argument,unused-argument
"""Indicates whether this tab should be enabled.
This is a class method; override with @classmethod.
Keyword Arguments:
user (User): The user signed in to Studio.
"""
pass
"""Tests for the Studio tab plugin API."""
from django.test import TestCase
import mock
from cms.lib.studio_tabs import StudioTabPluginManager
from openedx.core.lib.api.plugins import PluginError
class TestStudioTabPluginApi(TestCase):
"""Unit tests for the Studio tab plugin API."""
@mock.patch('cms.lib.studio_tabs.StudioTabPluginManager.get_available_plugins')
def test_get_enabled_tabs(self, get_available_plugins):
"""Verify that only enabled tabs are retrieved."""
enabled_tab = self._mock_tab(is_enabled=True)
mock_tabs = {
'disabled_tab': self._mock_tab(),
'enabled_tab': enabled_tab,
}
get_available_plugins.return_value = mock_tabs
self.assertEqual(StudioTabPluginManager.get_enabled_tabs(), [enabled_tab])
def test_get_invalid_plugin(self):
"""Verify that get_plugin fails when an invalid plugin is requested."""
with self.assertRaises(PluginError):
StudioTabPluginManager.get_plugin('invalid_tab')
def _mock_tab(self, is_enabled=False):
"""Generate a mock tab."""
tab = mock.Mock()
tab.is_enabled = mock.Mock(return_value=is_enabled)
return tab
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment