From 91fcad813d10de48361fbfcd5eccd98701b8ff92 Mon Sep 17 00:00:00 2001 From: SaadYousaf Date: Tue, 5 Oct 2021 13:40:10 +0500 Subject: [PATCH] fix: update discussion features with support level added to API response --- openedx/core/djangoapps/discussions/models.py | 234 +++++++++--------- .../djangoapps/discussions/serializers.py | 9 +- .../discussions/tests/test_views.py | 8 +- 3 files changed, 129 insertions(+), 122 deletions(-) diff --git a/openedx/core/djangoapps/discussions/models.py b/openedx/core/djangoapps/discussions/models.py index 38e7394607..efdd616148 100644 --- a/openedx/core/djangoapps/discussions/models.py +++ b/openedx/core/djangoapps/discussions/models.py @@ -33,40 +33,43 @@ ProviderExternalLinks = namedtuple( ['learn_more', 'configuration', 'general', 'accessibility', 'contact_email'] ) +ProviderFeature = namedtuple('ProviderFeature', ['id', 'feature_support_type']) + class Features(Enum): """ Features to be used/mapped in discussion providers """ - ANONYMOUS_POSTING = 'anonymous-posting' - # Todo: https://openedx.atlassian.net/browse/TNL-8546 - # This will be added back in once we add LTI v1.3 support for discussion - # configuration in the future. https://openedx.atlassian.net/browse/TNL-8365 - # AUTOMATIC_LEARNER_ENROLLMENT = 'automatic-learner-enrollment' + # Basic Supported Features + PRIMARY_DISCUSSION_APP_EXPERIENCE = ProviderFeature('primary-discussion-app-experience', 'basic') + LTI_BASIC_CONFIGURATION = ProviderFeature('lti-basic-configuration', 'basic') + # DISCUSSION_PAGE = ProviderFeature('discussion-page', 'basic') - BLACKOUT_DISCUSSION_DATES = 'blackout-discussion-dates' - COMMUNITY_TA_SUPPORT = 'community-ta-support' - COURSE_COHORT_SUPPORT = 'course-cohort-support' - DISCUSSION_PAGE = 'discussion-page' - INTERNATIONALIZATION_SUPPORT = 'internationalization-support' - PRIMARY_DISCUSSION_APP_EXPERIENCE = 'primary-discussion-app-experience' - QUESTION_DISCUSSION_SUPPORT = 'question-discussion-support' - REPORT_FLAG_CONTENT_TO_MODERATORS = 'report/flag-content-to-moderators' - RESEARCH_DATA_EVENTS = 'research-data-events' - WCAG_2_0_SUPPORT = 'wcag-2.0-support' - WCAG_2_1 = 'wcag-2.1' - ADVANCED_IN_CONTEXT_DISCUSSION = 'advanced-in-context-discussion' - DIRECT_MESSAGES_FROM_INSTRUCTORS = 'direct-messages-from-instructors' - DISCUSSION_CONTENT_PROMPTS = 'discussion-content-prompts' - EMAIL_NOTIFICATIONS = 'email-notifications' - EMBEDDED_COURSE_SECTIONS = 'embedded-course-sections' - GRADED_DISCUSSIONS = 'graded-discussions' - IN_PLATFORM_NOTIFICATIONS = 'in-platform-notifications' - LTI_ADVANCED_SHARING_MODE = 'lti-advanced-sharing-mode' - LTI_BASIC_CONFIGURATION = 'lti-basic-configuration' - SIMPLIFIED_IN_CONTEXT_DISCUSSION = 'simplified-in-context-discussion' - USER_MENTIONS = 'user-mentions' + # Partially Supported Features + QUESTION_DISCUSSION_SUPPORT = ProviderFeature('question-discussion-support', 'partial') + COMMUNITY_TA_SUPPORT = ProviderFeature('community-ta-support', 'partial') + REPORT_FLAG_CONTENT_TO_MODERATORS = ProviderFeature('report/flag-content-to-moderators', 'partial') + LTI_ADVANCED_SHARING_MODE = ProviderFeature('lti-advanced-sharing-mode', 'partial') + AUTOMATIC_LEARNER_ENROLLMENT = ProviderFeature('automatic-learner-enrollment', 'partial') + ANONYMOUS_POSTING = ProviderFeature('anonymous-posting', 'partial') + INTERNATIONALIZATION_SUPPORT = ProviderFeature('internationalization-support', 'partial') + EMAIL_NOTIFICATIONS = ProviderFeature('email-notifications', 'partial') + WCAG_2_0_SUPPORT = ProviderFeature('wcag-2.0-support', 'partial') + BLACKOUT_DISCUSSION_DATES = ProviderFeature('blackout-discussion-dates', 'partial') + # WCAG_2_1 = ProviderFeature('wcag-2.1', 'partial') + # EMBEDDED_COURSE_SECTIONS = ProviderFeature('embedded-course-sections', 'basic') + + # Fully Supported Features + COURSE_COHORT_SUPPORT = ProviderFeature('course-cohort-support', 'full') + RESEARCH_DATA_EVENTS = ProviderFeature('research-data-events', 'full') + + # Commonly Requested Features + IN_PLATFORM_NOTIFICATIONS = ProviderFeature('in-platform-notifications', 'common') + DISCUSSION_CONTENT_PROMPTS = ProviderFeature('discussion-content-prompts', 'common') + GRADED_DISCUSSIONS = ProviderFeature('graded-discussions', 'common') + DIRECT_MESSAGES_FROM_INSTRUCTORS = ProviderFeature('direct-messages-from-instructors', 'common') + USER_MENTIONS = ProviderFeature('user-mentions', 'common') def pii_sharing_required_message(provider_name): @@ -91,18 +94,18 @@ def pii_sharing_required_message(provider_name): AVAILABLE_PROVIDER_MAP = { 'legacy': { 'features': [ - Features.ANONYMOUS_POSTING.value, - Features.BLACKOUT_DISCUSSION_DATES.value, - Features.COMMUNITY_TA_SUPPORT.value, - Features.COURSE_COHORT_SUPPORT.value, - Features.DISCUSSION_PAGE.value, - Features.INTERNATIONALIZATION_SUPPORT.value, - Features.PRIMARY_DISCUSSION_APP_EXPERIENCE.value, - Features.QUESTION_DISCUSSION_SUPPORT.value, - Features.RESEARCH_DATA_EVENTS.value, - Features.REPORT_FLAG_CONTENT_TO_MODERATORS.value, - Features.WCAG_2_0_SUPPORT.value, - Features.WCAG_2_1.value, + Features.LTI_BASIC_CONFIGURATION.value.id, + Features.PRIMARY_DISCUSSION_APP_EXPERIENCE.value.id, + Features.QUESTION_DISCUSSION_SUPPORT.value.id, + Features.COMMUNITY_TA_SUPPORT.value.id, + Features.REPORT_FLAG_CONTENT_TO_MODERATORS.value.id, + Features.AUTOMATIC_LEARNER_ENROLLMENT.value.id, + Features.ANONYMOUS_POSTING.value.id, + Features.INTERNATIONALIZATION_SUPPORT.value.id, + Features.WCAG_2_0_SUPPORT.value.id, + Features.BLACKOUT_DISCUSSION_DATES.value.id, + Features.COURSE_COHORT_SUPPORT.value.id, + Features.RESEARCH_DATA_EVENTS.value.id, ], 'external_links': ProviderExternalLinks( learn_more='', @@ -114,20 +117,71 @@ AVAILABLE_PROVIDER_MAP = { 'messages': [], 'has_full_support': True }, + 'ed-discuss': { + 'features': [ + Features.PRIMARY_DISCUSSION_APP_EXPERIENCE.value.id, + Features.LTI_BASIC_CONFIGURATION.value.id, + Features.QUESTION_DISCUSSION_SUPPORT.value.id, + Features.REPORT_FLAG_CONTENT_TO_MODERATORS.value.id, + Features.LTI_ADVANCED_SHARING_MODE.value.id, + Features.AUTOMATIC_LEARNER_ENROLLMENT.value.id, + Features.ANONYMOUS_POSTING.value.id, + Features.INTERNATIONALIZATION_SUPPORT.value.id, + Features.EMAIL_NOTIFICATIONS.value.id, + Features.WCAG_2_0_SUPPORT.value.id, + Features.BLACKOUT_DISCUSSION_DATES.value.id, + Features.IN_PLATFORM_NOTIFICATIONS.value.id, + Features.USER_MENTIONS.value.id, + ], + 'external_links': ProviderExternalLinks( + learn_more='', + configuration='', + general='https://edstem.org/us/', + accessibility='', + contact_email='', + )._asdict(), + 'messages': [], + 'has_full_support': False + }, + 'inscribe': { + 'features': [ + Features.PRIMARY_DISCUSSION_APP_EXPERIENCE.value.id, + Features.LTI_BASIC_CONFIGURATION.value.id, + Features.QUESTION_DISCUSSION_SUPPORT.value.id, + Features.COMMUNITY_TA_SUPPORT.value.id, + Features.REPORT_FLAG_CONTENT_TO_MODERATORS.value.id, + Features.LTI_ADVANCED_SHARING_MODE.value.id, + Features.AUTOMATIC_LEARNER_ENROLLMENT.value.id, + Features.ANONYMOUS_POSTING.value.id, + Features.INTERNATIONALIZATION_SUPPORT.value.id, + Features.EMAIL_NOTIFICATIONS.value.id, + Features.WCAG_2_0_SUPPORT.value.id, + Features.RESEARCH_DATA_EVENTS.value.id, + Features.IN_PLATFORM_NOTIFICATIONS.value.id, + Features.DISCUSSION_CONTENT_PROMPTS.value.id, + ], + 'external_links': ProviderExternalLinks( + learn_more='', + configuration='', + general='https://www.inscribeapp.com/', + accessibility='', + contact_email='', + )._asdict(), + 'messages': [pii_sharing_required_message('InScribe')], + 'has_full_support': False + }, 'piazza': { 'features': [ - Features.ANONYMOUS_POSTING.value, - Features.BLACKOUT_DISCUSSION_DATES.value, - Features.COMMUNITY_TA_SUPPORT.value, - Features.DIRECT_MESSAGES_FROM_INSTRUCTORS.value, - Features.DISCUSSION_CONTENT_PROMPTS.value, - Features.DISCUSSION_PAGE.value, - Features.EMAIL_NOTIFICATIONS.value, - Features.LTI_BASIC_CONFIGURATION.value, - Features.QUESTION_DISCUSSION_SUPPORT.value, - Features.REPORT_FLAG_CONTENT_TO_MODERATORS.value, - Features.USER_MENTIONS.value, - Features.WCAG_2_0_SUPPORT.value, + Features.PRIMARY_DISCUSSION_APP_EXPERIENCE.value.id, + Features.LTI_BASIC_CONFIGURATION.value.id, + Features.QUESTION_DISCUSSION_SUPPORT.value.id, + Features.COMMUNITY_TA_SUPPORT.value.id, + Features.REPORT_FLAG_CONTENT_TO_MODERATORS.value.id, + Features.LTI_ADVANCED_SHARING_MODE.value.id, + Features.ANONYMOUS_POSTING.value.id, + Features.EMAIL_NOTIFICATIONS.value.id, + Features.WCAG_2_0_SUPPORT.value.id, + Features.BLACKOUT_DISCUSSION_DATES.value.id, ], 'external_links': ProviderExternalLinks( learn_more='https://piazza.com/product/overview', @@ -141,19 +195,18 @@ AVAILABLE_PROVIDER_MAP = { }, 'yellowdig': { 'features': [ - Features.ANONYMOUS_POSTING.value, - Features.COMMUNITY_TA_SUPPORT.value, - Features.DIRECT_MESSAGES_FROM_INSTRUCTORS.value, - Features.EMAIL_NOTIFICATIONS.value, - Features.GRADED_DISCUSSIONS.value, - Features.IN_PLATFORM_NOTIFICATIONS.value, - Features.LTI_BASIC_CONFIGURATION.value, - Features.PRIMARY_DISCUSSION_APP_EXPERIENCE.value, - Features.QUESTION_DISCUSSION_SUPPORT.value, - Features.REPORT_FLAG_CONTENT_TO_MODERATORS.value, - Features.RESEARCH_DATA_EVENTS.value, - Features.USER_MENTIONS.value, - Features.WCAG_2_0_SUPPORT.value, + Features.PRIMARY_DISCUSSION_APP_EXPERIENCE.value.id, + Features.LTI_BASIC_CONFIGURATION.value.id, + Features.QUESTION_DISCUSSION_SUPPORT.value.id, + Features.COMMUNITY_TA_SUPPORT.value.id, + Features.REPORT_FLAG_CONTENT_TO_MODERATORS.value.id, + Features.EMAIL_NOTIFICATIONS.value.id, + Features.WCAG_2_0_SUPPORT.value.id, + Features.RESEARCH_DATA_EVENTS.value.id, + Features.IN_PLATFORM_NOTIFICATIONS.value.id, + Features.GRADED_DISCUSSIONS.value.id, + Features.DIRECT_MESSAGES_FROM_INSTRUCTORS.value.id, + Features.USER_MENTIONS.value.id, ], 'external_links': ProviderExternalLinks( learn_more='https://www.youtube.com/watch?v=ZACief-qMwY', @@ -166,59 +219,6 @@ AVAILABLE_PROVIDER_MAP = { 'has_full_support': False, 'admin_only_config': True, }, - 'inscribe': { - 'features': [ - Features.PRIMARY_DISCUSSION_APP_EXPERIENCE.value, - Features.LTI_BASIC_CONFIGURATION.value, - ], - 'external_links': ProviderExternalLinks( - learn_more='', - configuration='', - general='https://www.inscribeapp.com/', - accessibility='', - contact_email='', - )._asdict(), - 'messages': [pii_sharing_required_message('InScribe')], - 'has_full_support': False - }, - 'discourse': { - 'features': [ - Features.LTI_ADVANCED_SHARING_MODE.value, - Features.LTI_BASIC_CONFIGURATION.value, - Features.PRIMARY_DISCUSSION_APP_EXPERIENCE.value, - ], - 'external_links': ProviderExternalLinks( - learn_more='', - configuration='', - general='http://discourse.org/', - accessibility='', - contact_email='', - )._asdict(), - 'messages': [pii_sharing_required_message('Discourse')], - 'has_full_support': False - }, - 'ed-discuss': { - 'features': [ - Features.ANONYMOUS_POSTING.value, - Features.COMMUNITY_TA_SUPPORT.value, - Features.EMAIL_NOTIFICATIONS.value, - Features.INTERNATIONALIZATION_SUPPORT.value, - Features.LTI_BASIC_CONFIGURATION.value, - Features.PRIMARY_DISCUSSION_APP_EXPERIENCE.value, - Features.QUESTION_DISCUSSION_SUPPORT.value, - Features.REPORT_FLAG_CONTENT_TO_MODERATORS.value, - Features.WCAG_2_0_SUPPORT.value, - ], - 'external_links': ProviderExternalLinks( - learn_more='', - configuration='', - general='https://edstem.org/us/', - accessibility='', - contact_email='', - )._asdict(), - 'messages': [], - 'has_full_support': False - } } diff --git a/openedx/core/djangoapps/discussions/serializers.py b/openedx/core/djangoapps/discussions/serializers.py index dd0751c7f4..cd9c350077 100644 --- a/openedx/core/djangoapps/discussions/serializers.py +++ b/openedx/core/djangoapps/discussions/serializers.py @@ -203,7 +203,7 @@ class DiscussionsConfigurationSerializer(serializers.ModelSerializer): course_key = instance.context_key payload = super().to_representation(instance) lti_configuration_data = {} - supports_lti = instance.supports(Features.LTI_BASIC_CONFIGURATION.value) + supports_lti = instance.supports(Features.LTI_BASIC_CONFIGURATION.value.id) if supports_lti: lti_configuration = LtiSerializer(instance.lti_configuration, context={ 'pii_sharing_allowed': get_lti_pii_sharing_state_for_course(course_key), @@ -219,7 +219,10 @@ class DiscussionsConfigurationSerializer(serializers.ModelSerializer): ) if legacy_settings.is_valid(raise_exception=True): plugin_configuration = legacy_settings.data - features_list = [feature.value for feature in Features] + features_list = [ + {'id': feature.value.id, 'feature_support_type': feature.value.feature_support_type} + for feature in Features + ] payload.update({ 'features': features_list, 'lti_configuration': lti_configuration_data, @@ -256,7 +259,7 @@ class DiscussionsConfigurationSerializer(serializers.ModelSerializer): Update LtiConfiguration """ lti_configuration_data = validated_data.get('lti_configuration') - supports_lti = instance.supports(Features.LTI_BASIC_CONFIGURATION.value) + supports_lti = instance.supports(Features.LTI_BASIC_CONFIGURATION.value.id) if not supports_lti: instance.lti_configuration = None elif lti_configuration_data: diff --git a/openedx/core/djangoapps/discussions/tests/test_views.py b/openedx/core/djangoapps/discussions/tests/test_views.py index 12d0813590..f6c6805461 100644 --- a/openedx/core/djangoapps/discussions/tests/test_views.py +++ b/openedx/core/djangoapps/discussions/tests/test_views.py @@ -150,7 +150,12 @@ class DataTest(AuthorizedApiTest): name for name, spec in data['providers']['available'].items() if "messages" not in spec ], "Found available providers without messages field" - assert data['lti_configuration'] == {} + assert data['lti_configuration'] == { + 'lti_1p1_client_key': '', + 'lti_1p1_client_secret': '', + 'lti_1p1_launch_url': '', + 'version': None + } assert data['plugin_configuration'] == { 'allow_anonymous': True, 'allow_anonymous_to_peers': False, @@ -480,7 +485,6 @@ class DataTest(AuthorizedApiTest): assert data['enabled'] assert data['provider_type'] == 'legacy' assert not data['plugin_configuration']['allow_anonymous'] - assert not data['lti_configuration'] @ddt.data(*[ user_type.name for user_type in CourseUserType