Commit 07241aa1 by E. Kolpakov

Addressed review notes:

* Added tests for `problem_types` CapaDescriptor property
* Improved indentation in tests
* Improved validation messages
parent f2f363c8
...@@ -441,7 +441,7 @@ class JavascriptResponse(LoncapaResponse): ...@@ -441,7 +441,7 @@ class JavascriptResponse(LoncapaResponse):
Javascript using Node.js. Javascript using Node.js.
""" """
human_name = _('Javascript Input') human_name = _('JavaScript Input')
tags = ['javascriptresponse'] tags = ['javascriptresponse']
max_inputfields = 1 max_inputfields = 1
allowed_inputfields = ['javascriptinput'] allowed_inputfields = ['javascriptinput']
......
...@@ -6,6 +6,7 @@ from bson.objectid import ObjectId, InvalidId ...@@ -6,6 +6,7 @@ from bson.objectid import ObjectId, InvalidId
from collections import namedtuple from collections import namedtuple
from copy import copy from copy import copy
from capa.responsetypes import registry from capa.responsetypes import registry
from gettext import ngettext
from .mako_module import MakoModuleDescriptor from .mako_module import MakoModuleDescriptor
from opaque_keys import InvalidKeyError from opaque_keys import InvalidKeyError
...@@ -359,7 +360,8 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe ...@@ -359,7 +360,8 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe
# TODO: change this to action_runtime_event='...' once the unit page supports that feature. # TODO: change this to action_runtime_event='...' once the unit page supports that feature.
# See https://openedx.atlassian.net/browse/TNL-993 # See https://openedx.atlassian.net/browse/TNL-993
action_class='library-update-btn', action_class='library-update-btn',
action_label=_(u"↻ Update now") # Translators: ↻ is an UTF icon symbol, no need translating it.
action_label=_(u"↻ Update now.")
) )
) )
return False return False
...@@ -369,7 +371,7 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe ...@@ -369,7 +371,7 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe
StudioValidationMessage.ERROR, StudioValidationMessage.ERROR,
_(u'Library is invalid, corrupt, or has been deleted.'), _(u'Library is invalid, corrupt, or has been deleted.'),
action_class='edit-button', action_class='edit-button',
action_label=_(u"Edit Library List") action_label=_(u"Edit Library List.")
) )
) )
return False return False
...@@ -395,7 +397,7 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe ...@@ -395,7 +397,7 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe
StudioValidationMessage.NOT_CONFIGURED, StudioValidationMessage.NOT_CONFIGURED,
_(u"A library has not yet been selected."), _(u"A library has not yet been selected."),
action_class='edit-button', action_class='edit-button',
action_label=_(u"Select a Library") action_label=_(u"Select a Library.")
) )
) )
return validation return validation
...@@ -418,7 +420,7 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe ...@@ -418,7 +420,7 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe
StudioValidationMessage.WARNING, StudioValidationMessage.WARNING,
_(u'There are no matching problem types in the specified libraries.'), _(u'There are no matching problem types in the specified libraries.'),
action_class='edit-button', action_class='edit-button',
action_label=_(u"Select another problem type") action_label=_(u"Select another problem type.")
) )
) )
...@@ -427,11 +429,20 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe ...@@ -427,11 +429,20 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe
validation, validation,
StudioValidationMessage( StudioValidationMessage(
StudioValidationMessage.WARNING, StudioValidationMessage.WARNING,
_(u'The specified libraries are configured to fetch {count} problems, ' (
u'but there are only {actual} matching problems.') ngettext(
.format(actual=matching_children_count, count=self.max_count), u'The specified libraries are configured to fetch {count} problem, ',
u'The specified libraries are configured to fetch {count} problems, ',
self.max_count
) +
ngettext(
u'but there are only {actual} matching problem.',
u'but there are only {actual} matching problems.',
matching_children_count
)
).format(count=self.max_count, actual=matching_children_count),
action_class='edit-button', action_class='edit-button',
action_label=_(u"Edit configuration") action_label=_(u"Edit the library configuration.")
) )
) )
......
...@@ -19,10 +19,11 @@ from webob.multidict import MultiDict ...@@ -19,10 +19,11 @@ from webob.multidict import MultiDict
import xmodule import xmodule
from xmodule.tests import DATA_DIR from xmodule.tests import DATA_DIR
from capa import responsetypes
from capa.responsetypes import (StudentInputError, LoncapaProblemError, from capa.responsetypes import (StudentInputError, LoncapaProblemError,
ResponseError) ResponseError)
from capa.xqueue_interface import XQueueInterface from capa.xqueue_interface import XQueueInterface
from xmodule.capa_module import CapaModule, ComplexEncoder from xmodule.capa_module import CapaModule, CapaDescriptor, ComplexEncoder
from opaque_keys.edx.locations import Location from opaque_keys.edx.locations import Location
from xblock.field_data import DictFieldData from xblock.field_data import DictFieldData
from xblock.fields import ScopeIds from xblock.fields import ScopeIds
...@@ -1660,6 +1661,62 @@ class CapaModuleTest(unittest.TestCase): ...@@ -1660,6 +1661,62 @@ class CapaModuleTest(unittest.TestCase):
('answerpool', ['choice_1', 'choice_3', 'choice_2', 'choice_0'])) ('answerpool', ['choice_1', 'choice_3', 'choice_2', 'choice_0']))
self.assertEquals(event_info['success'], 'incorrect') self.assertEquals(event_info['success'], 'incorrect')
@ddt.ddt
class CapaDescriptorTest(unittest.TestCase):
def _create_descriptor(self, xml):
""" Creates a CapaDescriptor to run test against """
descriptor = CapaDescriptor(get_test_system(), scope_ids=1)
descriptor.data = xml
return descriptor
@ddt.data(*responsetypes.registry.registered_tags())
def test_all_response_types(self, response_tag):
""" Tests that every registered response tag is correctly returned """
xml = "<problem><{response_tag}></{response_tag}></problem>".format(response_tag=response_tag)
descriptor = self._create_descriptor(xml)
self.assertEquals(descriptor.problem_types, {response_tag})
def test_response_types_ignores_non_response_tags(self):
xml = textwrap.dedent("""
<problem>
<p>Label</p>
<div>Some comment</div>
<multiplechoiceresponse>
<choicegroup type="MultipleChoice" answer-pool="4">
<choice correct="false">Apple</choice>
<choice correct="false">Banana</choice>
<choice correct="false">Chocolate</choice>
<choice correct ="true">Donut</choice>
</choicegroup>
</multiplechoiceresponse>
</problem>
""")
descriptor = self._create_descriptor(xml)
self.assertEquals(descriptor.problem_types, {"multiplechoiceresponse"})
def test_response_types_multiple_tags(self):
xml = textwrap.dedent("""
<problem>
<p>Label</p>
<div>Some comment</div>
<multiplechoiceresponse>
<choicegroup type="MultipleChoice" answer-pool="1">
<choice correct ="true">Donut</choice>
</choicegroup>
</multiplechoiceresponse>
<multiplechoiceresponse>
<choicegroup type="MultipleChoice" answer-pool="1">
<choice correct ="true">Buggy</choice>
</choicegroup>
</multiplechoiceresponse>
<optionresponse>
<optioninput label="Option" options="('1','2')" correct="2"></optioninput>
</optionresponse>
</problem>
""")
descriptor = self._create_descriptor(xml)
self.assertEquals(descriptor.problem_types, {"multiplechoiceresponse", "optionresponse"})
class ComplexEncoderTest(unittest.TestCase): class ComplexEncoderTest(unittest.TestCase):
def test_default(self): def test_default(self):
...@@ -1690,18 +1747,10 @@ class TestProblemCheckTracking(unittest.TestCase): ...@@ -1690,18 +1747,10 @@ class TestProblemCheckTracking(unittest.TestCase):
<p>Which piece of furniture is built for sitting?</p> <p>Which piece of furniture is built for sitting?</p>
<multiplechoiceresponse> <multiplechoiceresponse>
<choicegroup type="MultipleChoice"> <choicegroup type="MultipleChoice">
<choice correct="false"> <choice correct="false"><text>a table</text></choice>
<text>a table</text> <choice correct="false"><text>a desk</text></choice>
</choice> <choice correct="true"><text>a chair</text></choice>
<choice correct="false"> <choice correct="false"><text>a bookshelf</text></choice>
<text>a desk</text>
</choice>
<choice correct="true">
<text>a chair</text>
</choice>
<choice correct="false">
<text>a bookshelf</text>
</choice>
</choicegroup> </choicegroup>
</multiplechoiceresponse> </multiplechoiceresponse>
<p>Which of the following are musical instruments?</p> <p>Which of the following are musical instruments?</p>
......
...@@ -293,7 +293,7 @@ class StudioLibraryContainerCapaFilterTest(LibraryContentTestBase): ...@@ -293,7 +293,7 @@ class StudioLibraryContainerCapaFilterTest(LibraryContentTestBase):
# Choice group test # Choice group test
children_headers = self._set_library_content_settings(count=2, capa_type="Dropdown") children_headers = self._set_library_content_settings(count=2, capa_type="Dropdown")
self.assertEqual(len(children_headers), 2) self.assertEqual(len(children_headers), 2)
self.assertLessEqual( self.assertEqual(
children_headers, children_headers,
set([header.upper() for header in ["Problem Select 1", "Problem Select 2"]]) set([header.upper() for header in ["Problem Select 1", "Problem Select 2"]])
) )
......
""" """
Acceptance tests for Library Content in LMS Acceptance tests for Library Content in LMS
""" """
import textwrap
import ddt import ddt
from .base_studio_test import StudioLibraryTest from .base_studio_test import StudioLibraryTest
from ...fixtures.course import CourseFixture from ...fixtures.course import CourseFixture
...@@ -45,11 +46,13 @@ class StudioLibraryContainerTest(StudioLibraryTest, UniqueCourseTest): ...@@ -45,11 +46,13 @@ class StudioLibraryContainerTest(StudioLibraryTest, UniqueCourseTest):
XBlockFixtureDesc( XBlockFixtureDesc(
"problem", "Dropdown", "problem", "Dropdown",
data=""" data=textwrap.dedent("""
<problem> <problem>
<p>Dropdown</p> <p>Dropdown</p>
<optionresponse><optioninput label="Dropdown" options="('1', '2')" correct="'2'"></optioninput></optionresponse> <optionresponse><optioninput label="Dropdown" options="('1', '2')" correct="'2'"></optioninput></optionresponse>
</problem>""") </problem>
""")
)
) )
def populate_course_fixture(self, course_fixture): def populate_course_fixture(self, course_fixture):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment