diff --git a/cms/djangoapps/contentstore/views/item.py b/cms/djangoapps/contentstore/views/item.py index df77bc47a0..f40188b806 100644 --- a/cms/djangoapps/contentstore/views/item.py +++ b/cms/djangoapps/contentstore/views/item.py @@ -70,7 +70,7 @@ from xmodule.modulestore.django import modulestore from xmodule.modulestore.draft_and_published import DIRECT_ONLY_CATEGORIES from xmodule.modulestore.exceptions import InvalidLocationError, ItemNotFoundError from xmodule.modulestore.inheritance import own_metadata -from xmodule.services import ConfigurationService, SettingsService +from xmodule.services import ConfigurationService, SettingsService, TeamsConfigurationService from xmodule.tabs import CourseTabList from xmodule.x_module import AUTHOR_VIEW, PREVIEW_VIEWS, STUDENT_VIEW, STUDIO_VIEW from edx_proctoring.api import get_exam_configuration_dashboard_url, does_backend_support_onboarding @@ -292,6 +292,8 @@ class StudioEditModuleRuntime(object): return SettingsService() if service_name == "lti-configuration": return ConfigurationService(CourseEditLTIFieldsEnabledFlag) + if service_name == "teams_configuration": + return TeamsConfigurationService() return None diff --git a/common/lib/xmodule/xmodule/services.py b/common/lib/xmodule/xmodule/services.py index 95cea2a423..baeea84f46 100644 --- a/common/lib/xmodule/xmodule/services.py +++ b/common/lib/xmodule/xmodule/services.py @@ -7,6 +7,7 @@ import inspect from config_models.models import ConfigurationModel from django.conf import settings +from xmodule.modulestore.django import modulestore class SettingsService(object): @@ -95,3 +96,26 @@ class ConfigurationService(object): ) self.configuration = configuration_model + + +class TeamsConfigurationService(object): + """ + An XBlock service that returns the teams_configuration object for a course. + """ + def __init__(self): + self._course = None + + def get_course(self, course_id): + """ + Return the course instance associated with this TeamsConfigurationService. + This default implementation looks up the course from the modulestore. + """ + return modulestore().get_course(course_id) + + def get_teams_configuration(self, course_id): + """ + Returns the team configuration for a given course.id + """ + if not self._course: + self._course = self.get_course(course_id) + return self._course.teams_configuration diff --git a/common/lib/xmodule/xmodule/tests/test_services.py b/common/lib/xmodule/xmodule/tests/test_services.py index 44362ce6e5..10dcabafbf 100644 --- a/common/lib/xmodule/xmodule/tests/test_services.py +++ b/common/lib/xmodule/xmodule/tests/test_services.py @@ -4,16 +4,20 @@ Tests for SettingsService from __future__ import absolute_import -from unittest import TestCase +import unittest +from django.test import TestCase import ddt import mock + from config_models.models import ConfigurationModel from django.conf import settings from django.test.utils import override_settings from xblock.runtime import Mixologist -from xmodule.services import ConfigurationService, SettingsService +from opaque_keys.edx.locator import CourseLocator +from xmodule.services import ConfigurationService, SettingsService, TeamsConfigurationService +from openedx.core.lib.teams_config import TeamsConfig class _DummyBlock(object): @@ -37,7 +41,7 @@ class DummyUnexpected(object): @ddt.ddt -class TestSettingsService(TestCase): +class TestSettingsService(unittest.TestCase): """ Test SettingsService """ xblock_setting_key1 = 'dummy_block' @@ -96,7 +100,7 @@ class TestSettingsService(TestCase): self.assertEqual(self.settings_service.get_settings_bucket(block), [1, 2, 3]) -class TestConfigurationService(TestCase): +class TestConfigurationService(unittest.TestCase): """ Tests for ConfigurationService """ @@ -115,3 +119,43 @@ class TestConfigurationService(TestCase): """ config_service = ConfigurationService(DummyConfig) self.assertEqual(config_service.configuration, DummyConfig) + + +class MockConfigurationService(TeamsConfigurationService): + """ + Mock ConfigurationService for testing. + """ + def __init__(self, course, **kwargs): + super(MockConfigurationService, self).__init__() + self._course = course + + def get_course(self, course_id): + return self._course + + +class ConfigurationServiceBaseClass(TestCase): + """ + Base test class for testing the ConfigurationService. + """ + + def setUp(self): + super(ConfigurationServiceBaseClass, self).setUp() + + self.teams_config = TeamsConfig( + {'max_size': 2, 'topics': [{'id': 'topic', 'name': 'Topic', 'description': 'A Topic'}]} + ) + self.course = mock.Mock( + id=CourseLocator('org_0', 'course_0', 'run_0'), + teams_configuration=self.teams_config + ) + self.configuration_service = MockConfigurationService(self.course) + + +class TestTeamsConfigurationService(ConfigurationServiceBaseClass): + """ + Test operations of the teams configuration service + """ + + def test_get_teamsconfiguration(self): + teams_config = self.configuration_service.get_teams_configuration(self.course.id) + self.assertEqual(teams_config, self.teams_config)