diff --git a/openedx/core/djangoapps/discussions/docs/decisions/0003-configuration-rest-api.rst b/openedx/core/djangoapps/discussions/docs/decisions/0003-configuration-rest-api.rst index 5cb0b3fb67..c57c539a57 100644 --- a/openedx/core/djangoapps/discussions/docs/decisions/0003-configuration-rest-api.rst +++ b/openedx/core/djangoapps/discussions/docs/decisions/0003-configuration-rest-api.rst @@ -76,7 +76,7 @@ The payload is expected to be shaped like this (key names subject to change): 'active': configuration.provider_type or '', 'available': { provider: { - 'features': PROVIDER_FEATURE_MAP.get(provider) or [], + 'features': AVAILABLE_PROVIDER_MAP.get(provider).get('features') or [], } for provider in configuration.available_providers }, diff --git a/openedx/core/djangoapps/discussions/models.py b/openedx/core/djangoapps/discussions/models.py index 10e303a027..75ec49bf59 100644 --- a/openedx/core/djangoapps/discussions/models.py +++ b/openedx/core/djangoapps/discussions/models.py @@ -16,6 +16,7 @@ from model_utils.models import TimeStampedModel from opaque_keys.edx.django.models import LearningContextKeyField from opaque_keys.edx.keys import CourseKey from simple_history.models import HistoricalRecords +from collections import namedtuple from openedx.core.djangoapps.config_model_utils.models import StackedConfigurationModel from openedx.core.djangoapps.content.course_overviews.models import CourseOverview @@ -25,6 +26,9 @@ log = logging.getLogger(__name__) DEFAULT_PROVIDER_TYPE = 'legacy' +ProviderExternalLinks = namedtuple('ProviderExternalLinks', ['learn_more', 'configuration', 'general', 'accessibility', 'contact_email']) + + class Features(Enum): """ Features to be used/mapped in discussion providers @@ -55,85 +59,148 @@ class Features(Enum): WCAG_2_1 = 'wcag-2.1' WCAG_2_0_SUPPORT = 'wcag-2.0-support' -PROVIDER_FEATURE_MAP = { - 'legacy': [ - Features.DISCUSSION_PAGE.value, - Features.WCAG_2_1.value, - Features.AUTOMATIC_LEARNER_ENROLLMENT.value, - Features.WCAG_2_0_SUPPORT.value, - Features.INTERNATIONALIZATION_SUPPORT.value, - Features.ANONYMOUS_POSTING.value, - Features.REPORT_FLAG_CONTENT_TO_MODERATORS.value, - Features.QUESTION_DISCUSSION_SUPPORT.value, - Features.COMMUNITY_TA_SUPPORT.value, - Features.BLACKOUT_DISCUSSION_DATES.value, - Features.COURSE_COHORT_SUPPORT.value, - Features.RESEARCH_DATA_EVENTS.value, - ], - 'piazza': [ - Features.DISCUSSION_PAGE.value, - Features.LTI.value, - Features.WCAG_2_0_SUPPORT.value, - Features.ANONYMOUS_POSTING.value, - Features.REPORT_FLAG_CONTENT_TO_MODERATORS.value, - Features.QUESTION_DISCUSSION_SUPPORT.value, - Features.COMMUNITY_TA_SUPPORT.value, - Features.EMAIL_NOTIFICATIONS.value, - Features.BLACKOUT_DISCUSSION_DATES.value, - Features.DISCUSSION_CONTENT_PROMPTS.value, - Features.DIRECT_MESSAGES_FROM_INSTRUCTORS.value, - Features.USER_MENTIONS.value, - ], - 'edx-next': [ - Features.AUTOMATIC_LEARNER_ENROLLMENT.value, - Features.WCAG_2_0_SUPPORT.value, - Features.INTERNATIONALIZATION_SUPPORT.value, - Features.ANONYMOUS_POSTING.value, - Features.REPORT_FLAG_CONTENT_TO_MODERATORS.value, - Features.QUESTION_DISCUSSION_SUPPORT.value, - Features.COMMUNITY_TA_SUPPORT.value, - Features.EMAIL_NOTIFICATIONS.value, - Features.BLACKOUT_DISCUSSION_DATES.value, - Features.SIMPLIFIED_IN_CONTEXT_DISCUSSION.value, - Features.ADVANCED_IN_CONTEXT_DISCUSSION.value, - Features.COURSE_COHORT_SUPPORT.value, - Features.RESEARCH_DATA_EVENTS.value, - Features.DISCUSSION_CONTENT_PROMPTS.value, - Features.GRADED_DISCUSSIONS.value, - ], - 'yellowdig': [ - Features.WCAG_2_0_SUPPORT.value, - Features.ANONYMOUS_POSTING.value, - Features.REPORT_FLAG_CONTENT_TO_MODERATORS.value, - Features.QUESTION_DISCUSSION_SUPPORT.value, - Features.COMMUNITY_TA_SUPPORT.value, - Features.EMAIL_NOTIFICATIONS.value, - Features.RESEARCH_DATA_EVENTS.value, - Features.IN_PLATFORM_NOTIFICATIONS.value, - Features.GRADED_DISCUSSIONS.value, - Features.DIRECT_MESSAGES_FROM_INSTRUCTORS.value, - Features.USER_MENTIONS.value, - ], - 'inscribe': [ - Features.PRIMARY_DISCUSSION_APP_EXPERIENCE.value, - Features.LTI_BASIC_CONFIGURATION.value, - ], - 'discourse': [ - Features.PRIMARY_DISCUSSION_APP_EXPERIENCE.value, - Features.LTI_BASIC_CONFIGURATION.value, - Features.LTI_ADVANCED_SHARING_MODE.value, - ], - 'ed-discuss': [ - Features.PRIMARY_DISCUSSION_APP_EXPERIENCE.value, - Features.LTI_BASIC_CONFIGURATION.value, - Features.WCAG_2_0_SUPPORT.value, - Features.INTERNATIONALIZATION_SUPPORT.value, - Features.ANONYMOUS_POSTING.value, - Features.REPORT_FLAG_CONTENT_TO_MODERATORS.value, - Features.QUESTION_DISCUSSION_SUPPORT.value, - Features.COMMUNITY_TA_SUPPORT.value, - Features.EMAIL_NOTIFICATIONS.value, - ] +AVAILABLE_PROVIDER_MAP = { + 'legacy': { + 'features': [ + Features.DISCUSSION_PAGE.value, + Features.WCAG_2_1.value, + Features.AUTOMATIC_LEARNER_ENROLLMENT.value, + Features.WCAG_2_0_SUPPORT.value, + Features.INTERNATIONALIZATION_SUPPORT.value, + Features.ANONYMOUS_POSTING.value, + Features.REPORT_FLAG_CONTENT_TO_MODERATORS.value, + Features.QUESTION_DISCUSSION_SUPPORT.value, + Features.COMMUNITY_TA_SUPPORT.value, + Features.BLACKOUT_DISCUSSION_DATES.value, + Features.COURSE_COHORT_SUPPORT.value, + Features.RESEARCH_DATA_EVENTS.value, + ], + 'external_links': ProviderExternalLinks( + '', + '', + '', + '', + '', + )._asdict(), + }, + 'piazza': { + 'features': [ + Features.DISCUSSION_PAGE.value, + Features.LTI.value, + Features.WCAG_2_0_SUPPORT.value, + Features.ANONYMOUS_POSTING.value, + Features.REPORT_FLAG_CONTENT_TO_MODERATORS.value, + Features.QUESTION_DISCUSSION_SUPPORT.value, + Features.COMMUNITY_TA_SUPPORT.value, + Features.EMAIL_NOTIFICATIONS.value, + Features.BLACKOUT_DISCUSSION_DATES.value, + Features.DISCUSSION_CONTENT_PROMPTS.value, + Features.DIRECT_MESSAGES_FROM_INSTRUCTORS.value, + Features.USER_MENTIONS.value, + ], + 'external_links': ProviderExternalLinks( + 'https://piazza.com/product/overview', + 'https://support.piazza.com/support/solutions/articles/48001065447-configure-piazza-within-edx', + 'https://support.piazza.com/', + 'https://piazza.com/product/accessibility', + 'team@piazza.com', + )._asdict() + }, + 'edx-next': { + 'features': [ + Features.AUTOMATIC_LEARNER_ENROLLMENT.value, + Features.WCAG_2_0_SUPPORT.value, + Features.INTERNATIONALIZATION_SUPPORT.value, + Features.ANONYMOUS_POSTING.value, + Features.REPORT_FLAG_CONTENT_TO_MODERATORS.value, + Features.QUESTION_DISCUSSION_SUPPORT.value, + Features.COMMUNITY_TA_SUPPORT.value, + Features.EMAIL_NOTIFICATIONS.value, + Features.BLACKOUT_DISCUSSION_DATES.value, + Features.SIMPLIFIED_IN_CONTEXT_DISCUSSION.value, + Features.ADVANCED_IN_CONTEXT_DISCUSSION.value, + Features.COURSE_COHORT_SUPPORT.value, + Features.RESEARCH_DATA_EVENTS.value, + Features.DISCUSSION_CONTENT_PROMPTS.value, + Features.GRADED_DISCUSSIONS.value, + ], + 'external_links': ProviderExternalLinks( + '', + '', + '', + '', + '', + )._asdict(), + }, + 'yellowdig': { + 'features': [ + Features.WCAG_2_0_SUPPORT.value, + Features.ANONYMOUS_POSTING.value, + Features.REPORT_FLAG_CONTENT_TO_MODERATORS.value, + Features.QUESTION_DISCUSSION_SUPPORT.value, + Features.COMMUNITY_TA_SUPPORT.value, + Features.EMAIL_NOTIFICATIONS.value, + Features.RESEARCH_DATA_EVENTS.value, + Features.IN_PLATFORM_NOTIFICATIONS.value, + Features.GRADED_DISCUSSIONS.value, + Features.DIRECT_MESSAGES_FROM_INSTRUCTORS.value, + Features.USER_MENTIONS.value, + ], + 'external_links': ProviderExternalLinks( + 'https://www.youtube.com/watch?v=ZACief-qMwY', + '', + 'https://hubs.ly/H0J5Bn7', + '', + 'learnmore@yellowdig.com', + )._asdict(), + }, + 'inscribe': { + 'features': [ + Features.PRIMARY_DISCUSSION_APP_EXPERIENCE.value, + Features.LTI_BASIC_CONFIGURATION.value, + ], + 'external_links': ProviderExternalLinks( + '', + '', + 'https://www.inscribeapp.com/', + '', + '', + )._asdict(), + }, + 'discourse': { + 'features': [ + Features.PRIMARY_DISCUSSION_APP_EXPERIENCE.value, + Features.LTI_BASIC_CONFIGURATION.value, + Features.LTI_ADVANCED_SHARING_MODE.value, + ], + 'external_links': ProviderExternalLinks( + '', + '', + 'http://discourse.org/', + '', + '', + )._asdict(), + }, + 'ed-discuss': { + 'features': [ + Features.PRIMARY_DISCUSSION_APP_EXPERIENCE.value, + Features.LTI_BASIC_CONFIGURATION.value, + Features.WCAG_2_0_SUPPORT.value, + Features.INTERNATIONALIZATION_SUPPORT.value, + Features.ANONYMOUS_POSTING.value, + Features.REPORT_FLAG_CONTENT_TO_MODERATORS.value, + Features.QUESTION_DISCUSSION_SUPPORT.value, + Features.COMMUNITY_TA_SUPPORT.value, + Features.EMAIL_NOTIFICATIONS.value, + ], + 'external_links': ProviderExternalLinks( + '', + '', + 'https://edstem.org/us/', + '', + '', + )._asdict(), + } } @@ -295,7 +362,7 @@ class DiscussionsConfiguration(TimeStampedModel): """ Check if the provider supports some feature """ - features = PROVIDER_FEATURE_MAP.get(self.provider_type) or [] + features = AVAILABLE_PROVIDER_MAP.get(self.provider_type)['features'] or [] has_support = bool(feature in features) return has_support diff --git a/openedx/core/djangoapps/discussions/serializers.py b/openedx/core/djangoapps/discussions/serializers.py index b17c8a6db1..1649f11011 100644 --- a/openedx/core/djangoapps/discussions/serializers.py +++ b/openedx/core/djangoapps/discussions/serializers.py @@ -10,7 +10,7 @@ from openedx.core.djangoapps.django_comment_common.models import CourseDiscussio from openedx.core.lib.courses import get_course_by_id from xmodule.modulestore.django import modulestore -from .models import DEFAULT_PROVIDER_TYPE, PROVIDER_FEATURE_MAP, DiscussionsConfiguration, Features +from .models import DEFAULT_PROVIDER_TYPE, AVAILABLE_PROVIDER_MAP, DiscussionsConfiguration, Features class LtiSerializer(serializers.ModelSerializer): @@ -209,7 +209,7 @@ class DiscussionsConfigurationSerializer(serializers.ModelSerializer): 'plugin_configuration': plugin_configuration, 'providers': { 'active': provider_type or DEFAULT_PROVIDER_TYPE, - 'available': PROVIDER_FEATURE_MAP, + 'available': AVAILABLE_PROVIDER_MAP, }, }) return payload diff --git a/openedx/core/djangoapps/discussions/tests/test_views.py b/openedx/core/djangoapps/discussions/tests/test_views.py index 5e4157ff52..38e6732643 100644 --- a/openedx/core/djangoapps/discussions/tests/test_views.py +++ b/openedx/core/djangoapps/discussions/tests/test_views.py @@ -16,7 +16,7 @@ from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.tests.factories import CourseFactory -from ..models import PROVIDER_FEATURE_MAP +from ..models import AVAILABLE_PROVIDER_MAP DATA_LEGACY_COHORTS = { @@ -143,7 +143,7 @@ class DataTest(AuthorizedApiTest): assert response.status_code == self.expected_response_code assert not data['enabled'] assert data['provider_type'] == 'legacy' - assert data['providers']['available']['legacy'] == PROVIDER_FEATURE_MAP['legacy'] + assert data['providers']['available']['legacy'] == AVAILABLE_PROVIDER_MAP['legacy'] assert data['lti_configuration'] == {} assert data['plugin_configuration'] == { 'allow_anonymous': True, @@ -188,7 +188,7 @@ class DataTest(AuthorizedApiTest): data = self._setup_lti() assert data['enabled'] assert data['provider_type'] == 'piazza' - assert data['providers']['available']['piazza'] == PROVIDER_FEATURE_MAP['piazza'] + assert data['providers']['available']['piazza'] == AVAILABLE_PROVIDER_MAP['piazza'] assert data['lti_configuration'] == DATA_LTI_CONFIGURATION assert len(data['plugin_configuration']) == 0 assert len(data['lti_configuration']) > 0