Addressed notes from reviewers about Library content filters.
This commit is contained in:
committed by
E. Kolpakov
parent
6ac258850f
commit
332d2b0368
@@ -58,6 +58,8 @@ registry = TagRegistry()
|
||||
CorrectMap = correctmap.CorrectMap # pylint: disable=invalid-name
|
||||
CORRECTMAP_PY = None
|
||||
|
||||
# Make '_' a no-op so we can scrape strings
|
||||
_ = lambda text: text
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Exceptions
|
||||
@@ -439,6 +441,7 @@ class JavascriptResponse(LoncapaResponse):
|
||||
Javascript using Node.js.
|
||||
"""
|
||||
|
||||
human_name = _('Javascript Input')
|
||||
tags = ['javascriptresponse']
|
||||
max_inputfields = 1
|
||||
allowed_inputfields = ['javascriptinput']
|
||||
@@ -684,6 +687,7 @@ class ChoiceResponse(LoncapaResponse):
|
||||
|
||||
"""
|
||||
|
||||
human_name = _('Checkboxes')
|
||||
tags = ['choiceresponse']
|
||||
max_inputfields = 1
|
||||
allowed_inputfields = ['checkboxgroup', 'radiogroup']
|
||||
@@ -754,6 +758,7 @@ class MultipleChoiceResponse(LoncapaResponse):
|
||||
"""
|
||||
# TODO: handle direction and randomize
|
||||
|
||||
human_name = _('Multiple Choice')
|
||||
tags = ['multiplechoiceresponse']
|
||||
max_inputfields = 1
|
||||
allowed_inputfields = ['choicegroup']
|
||||
@@ -1042,6 +1047,7 @@ class MultipleChoiceResponse(LoncapaResponse):
|
||||
@registry.register
|
||||
class TrueFalseResponse(MultipleChoiceResponse):
|
||||
|
||||
human_name = _('True/False Choice')
|
||||
tags = ['truefalseresponse']
|
||||
|
||||
def mc_setup_response(self):
|
||||
@@ -1073,6 +1079,7 @@ class OptionResponse(LoncapaResponse):
|
||||
TODO: handle direction and randomize
|
||||
"""
|
||||
|
||||
human_name = _('Dropdown')
|
||||
tags = ['optionresponse']
|
||||
hint_tag = 'optionhint'
|
||||
allowed_inputfields = ['optioninput']
|
||||
@@ -1108,6 +1115,7 @@ class NumericalResponse(LoncapaResponse):
|
||||
to a number (e.g. `4+5/2^2`), and accepts with a tolerance.
|
||||
"""
|
||||
|
||||
human_name = _('Numerical Input')
|
||||
tags = ['numericalresponse']
|
||||
hint_tag = 'numericalhint'
|
||||
allowed_inputfields = ['textline', 'formulaequationinput']
|
||||
@@ -1308,6 +1316,7 @@ class StringResponse(LoncapaResponse):
|
||||
</hintgroup>
|
||||
</stringresponse>
|
||||
"""
|
||||
human_name = _('Text Input')
|
||||
tags = ['stringresponse']
|
||||
hint_tag = 'stringhint'
|
||||
allowed_inputfields = ['textline']
|
||||
@@ -1426,6 +1435,7 @@ class CustomResponse(LoncapaResponse):
|
||||
or in a <script>...</script>
|
||||
"""
|
||||
|
||||
human_name = _('Custom Evaluated Script')
|
||||
tags = ['customresponse']
|
||||
|
||||
allowed_inputfields = ['textline', 'textbox', 'crystallography',
|
||||
@@ -1800,6 +1810,7 @@ class SymbolicResponse(CustomResponse):
|
||||
Symbolic math response checking, using symmath library.
|
||||
"""
|
||||
|
||||
human_name = _('Symbolic Math Input')
|
||||
tags = ['symbolicresponse']
|
||||
max_inputfields = 1
|
||||
|
||||
@@ -1868,6 +1879,7 @@ class CodeResponse(LoncapaResponse):
|
||||
|
||||
"""
|
||||
|
||||
human_name = _('Code Input')
|
||||
tags = ['coderesponse']
|
||||
allowed_inputfields = ['textbox', 'filesubmission', 'matlabinput']
|
||||
max_inputfields = 1
|
||||
@@ -2145,6 +2157,7 @@ class ExternalResponse(LoncapaResponse):
|
||||
|
||||
"""
|
||||
|
||||
human_name = _('External Grader')
|
||||
tags = ['externalresponse']
|
||||
allowed_inputfields = ['textline', 'textbox']
|
||||
awdmap = {
|
||||
@@ -2302,6 +2315,7 @@ class FormulaResponse(LoncapaResponse):
|
||||
Checking of symbolic math response using numerical sampling.
|
||||
"""
|
||||
|
||||
human_name = _('Math Expression Input')
|
||||
tags = ['formularesponse']
|
||||
hint_tag = 'formulahint'
|
||||
allowed_inputfields = ['textline', 'formulaequationinput']
|
||||
@@ -2514,6 +2528,7 @@ class SchematicResponse(LoncapaResponse):
|
||||
"""
|
||||
Circuit schematic response type.
|
||||
"""
|
||||
human_name = _('Circuit Schematic Builder')
|
||||
tags = ['schematicresponse']
|
||||
allowed_inputfields = ['schematic']
|
||||
|
||||
@@ -2592,6 +2607,7 @@ class ImageResponse(LoncapaResponse):
|
||||
True, if click is inside any region or rectangle. Otherwise False.
|
||||
"""
|
||||
|
||||
human_name = _('Image Mapped Input')
|
||||
tags = ['imageresponse']
|
||||
allowed_inputfields = ['imageinput']
|
||||
|
||||
@@ -2710,6 +2726,7 @@ class AnnotationResponse(LoncapaResponse):
|
||||
The response contains both a comment (student commentary) and an option (student tag).
|
||||
Only the tag is currently graded. Answers may be incorrect, partially correct, or correct.
|
||||
"""
|
||||
human_name = _('Annotation Input')
|
||||
tags = ['annotationresponse']
|
||||
allowed_inputfields = ['annotationinput']
|
||||
max_inputfields = 1
|
||||
@@ -2834,6 +2851,7 @@ class ChoiceTextResponse(LoncapaResponse):
|
||||
ChoiceResponse.
|
||||
"""
|
||||
|
||||
human_name = _('Checkboxes With Text Input')
|
||||
tags = ['choicetextresponse']
|
||||
max_inputfields = 1
|
||||
allowed_inputfields = ['choicetextgroup',
|
||||
|
||||
@@ -5,6 +5,7 @@ LibraryContent: The XBlock used to include blocks from a library in a course.
|
||||
from bson.objectid import ObjectId, InvalidId
|
||||
from collections import namedtuple
|
||||
from copy import copy
|
||||
from capa.responsetypes import registry
|
||||
|
||||
from .mako_module import MakoModuleDescriptor
|
||||
from opaque_keys import InvalidKeyError
|
||||
@@ -33,34 +34,18 @@ def enum(**enums):
|
||||
return type('Enum', (), enums)
|
||||
|
||||
|
||||
def _get_human_name(problem_class):
|
||||
"""
|
||||
Get the human-friendly name for a problem type.
|
||||
"""
|
||||
return getattr(problem_class, 'human_name', problem_class.__name__)
|
||||
|
||||
|
||||
def _get_capa_types():
|
||||
"""
|
||||
Gets capa types tags and labels
|
||||
"""
|
||||
capa_types = {
|
||||
# basic tab
|
||||
'choiceresponse': _('Checkboxes'),
|
||||
'optionresponse': _('Dropdown'),
|
||||
'multiplechoiceresponse': _('Multiple Choice'),
|
||||
'truefalseresponse': _('True/False Choice'),
|
||||
'numericalresponse': _('Numerical Input'),
|
||||
'stringresponse': _('Text Input'),
|
||||
|
||||
# advanced tab
|
||||
'schematicresponse': _('Circuit Schematic Builder'),
|
||||
'customresponse': _('Custom Evaluated Script'),
|
||||
'imageresponse': _('Image Mapped Input'),
|
||||
'formularesponse': _('Math Expression Input'),
|
||||
'jsmeresponse': _('Molecular Structure'),
|
||||
|
||||
# not in "Add Component" menu
|
||||
'javascriptresponse': _('Javascript Input'),
|
||||
'symbolicresponse': _('Symbolic Math Input'),
|
||||
'coderesponse': _('Code Input'),
|
||||
'externalresponse': _('External Grader'),
|
||||
'annotationresponse': _('Annotation Input'),
|
||||
'choicetextresponse': _('Checkboxes With Text Input'),
|
||||
}
|
||||
capa_types = {tag: _get_human_name(registry.get_class_for_tag(tag)) for tag in registry.registered_tags()}
|
||||
|
||||
return [{'value': ANY_CAPA_TYPE_VALUE, 'display_name': _('Any Type')}] + sorted([
|
||||
{'value': capa_type, 'display_name': caption}
|
||||
@@ -429,9 +414,9 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe
|
||||
validation,
|
||||
StudioValidationMessage(
|
||||
StudioValidationMessage.WARNING,
|
||||
_(u'There are no content matching configured filters in the selected libraries.'),
|
||||
_(u'There are no matching problem types in the specified libraries.'),
|
||||
action_class='edit-button',
|
||||
action_label=_(u"Edit Problem Type Filter")
|
||||
action_label=_(u"Select another problem type")
|
||||
)
|
||||
)
|
||||
|
||||
@@ -440,10 +425,11 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe
|
||||
validation,
|
||||
StudioValidationMessage(
|
||||
StudioValidationMessage.WARNING,
|
||||
_(u'Configured to fetch {count} blocks, library and filter settings yield only {actual} blocks.')
|
||||
_(u'The specified libraries are configured to fetch {count} problems, '
|
||||
u'but there are only {actual} matching problems.')
|
||||
.format(actual=matching_children_count, count=self.max_count),
|
||||
action_class='edit-button',
|
||||
action_label=_(u"Edit block configuration")
|
||||
action_label=_(u"Edit configuration")
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -28,7 +28,10 @@ class LibraryContentTestBase(UniqueCourseTest):
|
||||
STAFF_EMAIL = "staff101@example.com"
|
||||
|
||||
def populate_library_fixture(self, library_fixture):
|
||||
pass
|
||||
"""
|
||||
To be overwritten by subclassed tests. Used to install a library to
|
||||
run tests on.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
@@ -207,7 +210,7 @@ class StudioLibraryContainerCapaFilterTest(LibraryContentTestBase):
|
||||
|
||||
def _get_problem_select_text(self, name, items, correct):
|
||||
""" Generates Select Option CAPA problem XML """
|
||||
items_text = ",".join(map(lambda item: "'{0}'".format(item), items))
|
||||
items_text = ",".join(["'{0}'".format(item) for item in items])
|
||||
|
||||
return """<problem>
|
||||
<p>{name}</p>
|
||||
@@ -281,7 +284,7 @@ class StudioLibraryContainerCapaFilterTest(LibraryContentTestBase):
|
||||
self.assertEqual(len(children_headers), 1)
|
||||
self.assertLessEqual(
|
||||
children_headers,
|
||||
set(map(lambda header: header.upper(), ["Problem Choice Group 1", "Problem Choice Group 2"]))
|
||||
set([header.upper() for header in ["Problem Choice Group 1", "Problem Choice Group 2"]])
|
||||
)
|
||||
|
||||
# Choice group test
|
||||
@@ -289,7 +292,7 @@ class StudioLibraryContainerCapaFilterTest(LibraryContentTestBase):
|
||||
self.assertEqual(len(children_headers), 2)
|
||||
self.assertLessEqual(
|
||||
children_headers,
|
||||
set(map(lambda header: header.upper(), ["Problem Select 1", "Problem Select 2"]))
|
||||
set([header.upper() for header in ["Problem Select 1", "Problem Select 2"]])
|
||||
)
|
||||
|
||||
# Missing problem type test
|
||||
|
||||
@@ -189,8 +189,7 @@ class StudioLibraryContainerTest(StudioLibraryTest, UniqueCourseTest):
|
||||
When I set Problem Type selector so that there are matching content
|
||||
Then I can see that warning messages are not shown
|
||||
"""
|
||||
expected_text = 'There are no content matching configured filters in the selected libraries. ' \
|
||||
'Edit Problem Type Filter'
|
||||
expected_text = 'There are no matching problem types in the specified libraries. Select another problem type'
|
||||
|
||||
library_container = self._get_library_xblock_wrapper(self.unit_page.xblocks[0])
|
||||
|
||||
@@ -223,7 +222,8 @@ class StudioLibraryContainerTest(StudioLibraryTest, UniqueCourseTest):
|
||||
And I set Problem Type selector so "Any"
|
||||
Then I can see that "No matching content" warning is shown
|
||||
"""
|
||||
expected_tpl = "Configured to fetch {count} blocks, library and filter settings yield only {actual} blocks."
|
||||
expected_tpl = "The specified libraries are configured to fetch {count} problems, " \
|
||||
"but there are only {actual} matching problems."
|
||||
|
||||
library_container = self._get_library_xblock_wrapper(self.unit_page.xblocks[0])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user