Merge pull request #25012 from open-craft/farhaan/bb-2961-ora-button-support
[BB-2961] [BD-05] [TNL-7577] Added open response button to the component tray
This commit is contained in:
@@ -41,7 +41,7 @@ __all__ = [
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# NOTE: This list is disjoint from ADVANCED_COMPONENT_TYPES
|
||||
COMPONENT_TYPES = ['discussion', 'html', 'problem', 'video']
|
||||
COMPONENT_TYPES = ['discussion', 'html', 'openassessment', 'problem', 'video']
|
||||
|
||||
ADVANCED_COMPONENT_TYPES = sorted(set(name for name, class_ in XBlock.load_classes()) - set(COMPONENT_TYPES))
|
||||
|
||||
@@ -260,7 +260,8 @@ def get_component_templates(courselike, library=False):
|
||||
'discussion': _("Discussion"),
|
||||
'html': _("HTML"),
|
||||
'problem': _("Problem"),
|
||||
'video': _("Video")
|
||||
'video': _("Video"),
|
||||
'openassessment': _("Open Response")
|
||||
}
|
||||
|
||||
component_templates = []
|
||||
@@ -269,9 +270,11 @@ def get_component_templates(courselike, library=False):
|
||||
# by the components in the order listed in COMPONENT_TYPES.
|
||||
component_types = COMPONENT_TYPES[:]
|
||||
|
||||
# Libraries do not support discussions
|
||||
# Libraries do not support discussions and openassessment
|
||||
component_not_supported_by_library = ['discussion', 'openassessment']
|
||||
if library:
|
||||
component_types = [component for component in component_types if component != 'discussion']
|
||||
component_types = [component for component in component_types
|
||||
if component not in set(component_not_supported_by_library)]
|
||||
|
||||
component_types = _filter_disabled_blocks(component_types)
|
||||
|
||||
@@ -288,9 +291,14 @@ def get_component_templates(courselike, library=False):
|
||||
# add the default template with localized display name
|
||||
# TODO: Once mixins are defined per-application, rather than per-runtime,
|
||||
# this should use a cms mixed-in class. (cpennington)
|
||||
template_id = None
|
||||
display_name = xblock_type_display_name(category, _('Blank')) # this is the Blank Advanced problem
|
||||
# The first template that is given should be Blank Assessment Template
|
||||
if category == 'openassessment':
|
||||
display_name = _("Blank Open Response Assessment")
|
||||
template_id = "blank-assessment"
|
||||
templates_for_category.append(
|
||||
create_template_dict(display_name, category, support_level_without_template, None, 'advanced')
|
||||
create_template_dict(display_name, category, support_level_without_template, template_id, 'advanced')
|
||||
)
|
||||
categories.add(category)
|
||||
|
||||
|
||||
@@ -2256,9 +2256,11 @@ class TestComponentTemplates(CourseTestCase):
|
||||
XBlockStudioConfiguration.objects.create(name='discussion', enabled=True, support_level="ps")
|
||||
XBlockStudioConfiguration.objects.create(name='problem', enabled=True, support_level="us")
|
||||
XBlockStudioConfiguration.objects.create(name='video', enabled=True, support_level="us")
|
||||
# XBlock masquerading as a problem
|
||||
# ORA Block has it's own category.
|
||||
XBlockStudioConfiguration.objects.create(name='openassessment', enabled=True, support_level="us")
|
||||
# XBlock masquerading as a problem
|
||||
XBlockStudioConfiguration.objects.create(name='drag-and-drop-v2', enabled=True, support_level="fs")
|
||||
XBlockStudioConfiguration.objects.create(name='staffgradedxblock', enabled=True, support_level="us")
|
||||
|
||||
self.templates = get_component_templates(self.course)
|
||||
|
||||
@@ -2266,9 +2268,22 @@ class TestComponentTemplates(CourseTestCase):
|
||||
"""
|
||||
Returns the templates for the specified type, or None if none is found.
|
||||
"""
|
||||
template_dict = next((template for template in self.templates if template.get('type') == template_type), None)
|
||||
template_dict = self._get_template_dict_of_type(template_type)
|
||||
return template_dict.get('templates') if template_dict else None
|
||||
|
||||
def get_display_name_of_type(self, template_type):
|
||||
"""
|
||||
Returns the display name for the specified type, or None if none found.
|
||||
"""
|
||||
template_dict = self._get_template_dict_of_type(template_type)
|
||||
return template_dict.get('display_name') if template_dict else None
|
||||
|
||||
def _get_template_dict_of_type(self, template_type):
|
||||
"""
|
||||
Returns a dictionary of values for a category type.
|
||||
"""
|
||||
return next((template for template in self.templates if template.get('type') == template_type), None)
|
||||
|
||||
def get_template(self, templates, display_name):
|
||||
"""
|
||||
Returns the template which has the specified display name.
|
||||
@@ -2281,6 +2296,10 @@ class TestComponentTemplates(CourseTestCase):
|
||||
"""
|
||||
self._verify_basic_component("discussion", "Discussion")
|
||||
self._verify_basic_component("video", "Video")
|
||||
self._verify_basic_component("openassessment", "Blank Open Response Assessment", True, 6)
|
||||
self._verify_basic_component_display_name("discussion", "Discussion")
|
||||
self._verify_basic_component_display_name("video", "Video")
|
||||
self._verify_basic_component_display_name("openassessment", "Open Response")
|
||||
self.assertGreater(len(self.get_templates_of_type('html')), 0)
|
||||
self.assertGreater(len(self.get_templates_of_type('problem')), 0)
|
||||
self.assertIsNone(self.get_templates_of_type('advanced'))
|
||||
@@ -2338,13 +2357,13 @@ class TestComponentTemplates(CourseTestCase):
|
||||
|
||||
# Verify that non-advanced components are not added twice
|
||||
self.course.advanced_modules.append('video')
|
||||
self.course.advanced_modules.append('openassessment')
|
||||
self.course.advanced_modules.append('drag-and-drop-v2')
|
||||
self.templates = get_component_templates(self.course)
|
||||
advanced_templates = self.get_templates_of_type('advanced')
|
||||
self.assertEqual(len(advanced_templates), 1)
|
||||
only_template = advanced_templates[0]
|
||||
self.assertNotEqual(only_template.get('category'), 'video')
|
||||
self.assertNotEqual(only_template.get('category'), 'openassessment')
|
||||
self.assertNotEqual(only_template.get('category'), 'drag-and-drop-v2')
|
||||
|
||||
# Now fully disable word_cloud through XBlockConfiguration
|
||||
XBlockConfiguration.objects.create(name='word_cloud', enabled=False)
|
||||
@@ -2415,12 +2434,14 @@ class TestComponentTemplates(CourseTestCase):
|
||||
problem_templates = self.get_templates_of_type('problem')
|
||||
return self.get_template(problem_templates, label)
|
||||
|
||||
def verify_openassessment_present(support_level):
|
||||
""" Helper method to verify that openassessment template is present """
|
||||
openassessment = get_xblock_problem('Open Response Assessment')
|
||||
self.assertIsNotNone(openassessment)
|
||||
self.assertEqual(openassessment.get('category'), 'openassessment')
|
||||
self.assertEqual(openassessment.get('support_level'), support_level)
|
||||
def verify_staffgradedxblock_present(support_level):
|
||||
"""
|
||||
Helper method to verify that staffgradedxblock template is present
|
||||
"""
|
||||
sgp = get_xblock_problem('Staff Graded Points')
|
||||
self.assertIsNotNone(sgp)
|
||||
self.assertEqual(sgp.get('category'), 'staffgradedxblock')
|
||||
self.assertEqual(sgp.get('support_level'), support_level)
|
||||
|
||||
def verify_dndv2_present(support_level):
|
||||
"""
|
||||
@@ -2431,24 +2452,24 @@ class TestComponentTemplates(CourseTestCase):
|
||||
self.assertEqual(dndv2.get('category'), 'drag-and-drop-v2')
|
||||
self.assertEqual(dndv2.get('support_level'), support_level)
|
||||
|
||||
verify_openassessment_present(True)
|
||||
verify_dndv2_present(True)
|
||||
verify_staffgradedxblock_present(True)
|
||||
|
||||
# Now enable XBlockStudioConfigurationFlag. The openassessment block is marked
|
||||
# Now enable XBlockStudioConfigurationFlag. The staffgradedxblock block is marked
|
||||
# unsupported, so will no longer show up, but DnDv2 will continue to appear.
|
||||
XBlockStudioConfigurationFlag.objects.create(enabled=True)
|
||||
self.assertIsNone(get_xblock_problem('Peer Assessment'))
|
||||
self.assertIsNone(get_xblock_problem('Staff Graded Points'))
|
||||
self.assertIsNotNone(get_xblock_problem('Drag and Drop'))
|
||||
|
||||
# Now allow unsupported components.
|
||||
self.course.allow_unsupported_xblocks = True
|
||||
verify_openassessment_present('us')
|
||||
verify_staffgradedxblock_present('us')
|
||||
verify_dndv2_present('fs')
|
||||
|
||||
# Now disable the blocks completely through XBlockConfiguration
|
||||
XBlockConfiguration.objects.create(name='openassessment', enabled=False)
|
||||
XBlockConfiguration.objects.create(name='staffgradedxblock', enabled=False)
|
||||
XBlockConfiguration.objects.create(name='drag-and-drop-v2', enabled=False)
|
||||
self.assertIsNone(get_xblock_problem('Peer Assessment'))
|
||||
self.assertIsNone(get_xblock_problem('Staff Graded Points'))
|
||||
self.assertIsNone(get_xblock_problem('Drag and Drop'))
|
||||
|
||||
def _verify_advanced_xblocks(self, expected_xblocks, expected_support_levels):
|
||||
@@ -2464,15 +2485,22 @@ class TestComponentTemplates(CourseTestCase):
|
||||
template_support_levels = [template['support_level'] for template in templates[0]['templates']]
|
||||
self.assertEqual(template_support_levels, expected_support_levels)
|
||||
|
||||
def _verify_basic_component(self, component_type, display_name, support_level=True):
|
||||
def _verify_basic_component(self, component_type, display_name, support_level=True, no_of_templates=1):
|
||||
"""
|
||||
Verify the display name and support level of basic components (that have no boilerplates).
|
||||
"""
|
||||
templates = self.get_templates_of_type(component_type)
|
||||
self.assertEqual(1, len(templates))
|
||||
self.assertEqual(no_of_templates, len(templates))
|
||||
self.assertEqual(display_name, templates[0]['display_name'])
|
||||
self.assertEqual(support_level, templates[0]['support_level'])
|
||||
|
||||
def _verify_basic_component_display_name(self, component_type, display_name):
|
||||
"""
|
||||
Verify the display name of basic components.
|
||||
"""
|
||||
component_display_name = self.get_display_name_of_type(component_type)
|
||||
self.assertEqual(display_name, component_display_name)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestXBlockInfo(ItemTest):
|
||||
|
||||
@@ -337,6 +337,7 @@ class UnitTestLibraries(CourseTestCase):
|
||||
self.assertIn('problem', templates)
|
||||
self.assertNotIn('discussion', templates)
|
||||
self.assertNotIn('advanced', templates)
|
||||
self.assertNotIn('openassessment', templates)
|
||||
|
||||
def test_advanced_problem_types(self):
|
||||
"""
|
||||
|
||||
@@ -1707,10 +1707,6 @@ DEFAULT_COURSE_LANGUAGE = "en"
|
||||
# None to omit.
|
||||
#
|
||||
ADVANCED_PROBLEM_TYPES = [
|
||||
{
|
||||
'component': 'openassessment',
|
||||
'boilerplate_name': None,
|
||||
},
|
||||
{
|
||||
'component': 'drag-and-drop-v2',
|
||||
'boilerplate_name': None
|
||||
|
||||
BIN
cms/static/images/large-openassessment-icon.png
Normal file
BIN
cms/static/images/large-openassessment-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 738 B |
@@ -45,3 +45,10 @@
|
||||
height: ($baseline*3);
|
||||
background: url('#{$static-path}/images/large-video-icon.png') center no-repeat;
|
||||
}
|
||||
|
||||
.large-openassessment-icon {
|
||||
display: inline-block;
|
||||
width: ($baseline*3);
|
||||
height: ($baseline*3);
|
||||
background: url('#{$static-path}/images/large-openassessment-icon.png') center no-repeat;
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: ($baseline*5);
|
||||
width: ($baseline*6.25);
|
||||
height: ($baseline*5);
|
||||
margin-bottom: ($baseline/2);
|
||||
box-shadow: 0 1px 1px $shadow, 0 1px 0 rgba(255, 255, 255, 0.4) inset;
|
||||
|
||||
@@ -163,7 +163,7 @@ nodeenv==1.5.0 # via -r requirements/edx/base.in
|
||||
numpy==1.18.5 # via -c requirements/edx/../constraints.txt, chem, openedx-calc, scipy
|
||||
oauthlib==3.0.1 # via -c requirements/edx/../constraints.txt, -r requirements/edx/base.in, django-oauth-toolkit, lti-consumer-xblock, requests-oauthlib, social-auth-core
|
||||
openedx-calc==1.0.9 # via -r requirements/edx/base.in
|
||||
ora2==2.12.1 # via -c requirements/edx/../constraints.txt, -r requirements/edx/base.in
|
||||
ora2==2.13.3 # via -r requirements/edx/base.in
|
||||
packaging==20.7 # via bleach, drf-yasg
|
||||
path.py==12.5.0 # via edx-enterprise, edx-i18n-tools, ora2, staff-graded-xblock, xmodule
|
||||
path==13.1.0 # via -c requirements/edx/../constraints.txt, -r requirements/edx/paver.txt, path.py
|
||||
|
||||
@@ -196,7 +196,7 @@ nodeenv==1.5.0 # via -r requirements/edx/testing.txt
|
||||
numpy==1.18.5 # via -c requirements/edx/../constraints.txt, -r requirements/edx/testing.txt, chem, openedx-calc, scipy
|
||||
oauthlib==3.0.1 # via -c requirements/edx/../constraints.txt, -r requirements/edx/testing.txt, django-oauth-toolkit, lti-consumer-xblock, requests-oauthlib, social-auth-core
|
||||
openedx-calc==1.0.9 # via -r requirements/edx/testing.txt
|
||||
ora2==2.12.1 # via -c requirements/edx/../constraints.txt, -r requirements/edx/testing.txt
|
||||
ora2==2.13.3 # via -r requirements/edx/testing.txt
|
||||
packaging==20.7 # via -r requirements/edx/testing.txt, bleach, drf-yasg, pytest, sphinx, tox
|
||||
path.py==12.5.0 # via -r requirements/edx/testing.txt, edx-enterprise, edx-i18n-tools, ora2, staff-graded-xblock, xmodule
|
||||
path==13.1.0 # via -c requirements/edx/../constraints.txt, -r requirements/edx/testing.txt, path.py
|
||||
|
||||
@@ -188,7 +188,7 @@ nodeenv==1.5.0 # via -r requirements/edx/base.txt
|
||||
numpy==1.18.5 # via -c requirements/edx/../constraints.txt, -r requirements/edx/base.txt, chem, openedx-calc, scipy
|
||||
oauthlib==3.0.1 # via -c requirements/edx/../constraints.txt, -r requirements/edx/base.txt, django-oauth-toolkit, lti-consumer-xblock, requests-oauthlib, social-auth-core
|
||||
openedx-calc==1.0.9 # via -r requirements/edx/base.txt
|
||||
ora2==2.12.1 # via -c requirements/edx/../constraints.txt, -r requirements/edx/base.txt
|
||||
ora2==2.13.3 # via -r requirements/edx/base.txt
|
||||
packaging==20.7 # via -r requirements/edx/base.txt, bleach, drf-yasg, pytest, tox
|
||||
path.py==12.5.0 # via -r requirements/edx/base.txt, edx-enterprise, edx-i18n-tools, ora2, staff-graded-xblock, xmodule
|
||||
path==13.1.0 # via -c requirements/edx/../constraints.txt, -r requirements/edx/base.txt, path.py
|
||||
|
||||
Reference in New Issue
Block a user