Commit c5627b41 by Dave St.Germain

Merge pull request #3002 from edx/dcs/status-object

Convert CAPA inputtype statuses from strings to objects,
parents ce9e8d73 bf7aef1b
......@@ -62,7 +62,47 @@ log = logging.getLogger(__name__)
#########################################################################
registry = TagRegistry()
registry = TagRegistry() # pylint: disable=C0103
class Status(object):
"""
Problem status
attributes: classname, display_name
"""
css_classes = {
# status: css class
'unsubmitted': 'unanswered',
'incomplete': 'incorrect',
'queued': 'processing',
}
__slots__ = ('classname', '_status', 'display_name')
def __init__(self, status, gettext_func=unicode):
self.classname = self.css_classes.get(status, status)
_ = gettext_func
names = {
'correct': _('correct'),
'incorrect': _('incorrect'),
'incomplete': _('incomplete'),
'unanswered': _('unanswered'),
'unsubmitted': _('unanswered'),
'queued': _('processing'),
}
self.display_name = names.get(status, unicode(status))
self._status = status or ''
def __str__(self):
return self._status
def __unicode__(self):
return self._status.decode('utf8')
def __repr__(self):
return 'Status(%r)' % self._status
def __eq__(self, other):
return self._status == str(other)
class Attribute(object):
......@@ -261,9 +301,7 @@ class InputTypeBase(object):
context = {
'id': self.input_id,
'value': self.value,
'status': self.status,
'status_class': self.status_class,
'status_display': self.status_display,
'status': Status(self.status, self.capa_system.i18n.ugettext),
'msg': self.msg,
'STATIC_URL': self.capa_system.STATIC_URL,
}
......@@ -273,34 +311,6 @@ class InputTypeBase(object):
context.update(self._extra_context())
return context
@property
def status_class(self):
"""
Return the CSS class for the associated status.
"""
statuses = {
'unsubmitted': 'unanswered',
'incomplete': 'incorrect',
'queued': 'processing',
}
return statuses.get(self.status, self.status)
@property
def status_display(self):
"""
Return the human-readable and translated word for the associated status.
"""
_ = self.capa_system.i18n.ugettext
statuses = {
'correct': _('correct'),
'incorrect': _('incorrect'),
'incomplete': _('incomplete'),
'unanswered': _('unanswered'),
'unsubmitted': _('unanswered'),
'queued': _('queued'),
}
return statuses.get(self.status, self.status)
def _extra_context(self):
"""
Subclasses can override this to return extra context that should be passed to their templates for rendering.
......
......@@ -52,13 +52,7 @@
<input type="hidden" class="value" name="input_${id}" id="input_${id}" value="${value|h}" />
% endif
% if status == 'unsubmitted':
<span class="unanswered" style="display:inline-block;" id="status_${id}" aria-describedby="input_${id}"><span class="sr">Status: Unanswered</span></span>
% elif status == 'incomplete':
<span class="incorrect" id="status_${id}" aria-describedby="input_${id}"><span class="sr">Status: Incorrect</span></span>
% elif status == 'incorrect' and not has_options_value:
<span class="incorrect" id="status_${id}" aria-describedby="input_${id}"><span class="sr">Status: Incorrect</span></span>
% endif
<span class="status ${status.classname}" id="status_${id}" aria-describedby="input_${id}"><span class="sr">${status.display_name}</span></span>
<p id="answer_${id}" class="answer answer-annotation"></p>
</div>
......
<div id="chemicalequationinput_${id}" class="chemicalequationinput">
<div class="script_placeholder" data-src="${previewer}"/>
<div class="${status_class}" id="status_${id}">
<div class="${status.classname}" id="status_${id}">
<input type="text" name="input_${id}" id="input_${id}" aria-label="${label}" aria-describedby="answer_${id}" data-input-id="${id}" value="${value|h}"
% if size:
......@@ -11,7 +11,7 @@
<p class="status" aria-describedby="input_${id}">
${value|h} -
${status_display}
${status.display_name}
</p>
<div id="input_${id}_preview" class="equation"></div>
......
<form class="choicegroup capa_inputtype" id="inputtype_${id}">
<div class="indicator_container">
% if input_type == 'checkbox' or not value:
<span class="status ${status_class if show_correctness != 'never' else 'unanswered'}"
<span class="status ${status.classname if show_correctness != 'never' else 'unanswered'}"
id="status_${id}"
aria-describedby="inputtype_${id}">
<span class="sr">
......@@ -11,7 +11,7 @@
%endif
%endfor
-
${status_display}
${status.display_name}
</span>
</span>
% endif
......@@ -51,7 +51,7 @@
% if input_type == 'radio' and ( (isinstance(value, basestring) and (choice_id == value)) or (not isinstance(value, basestring) and choice_id in value) ):
% if status in ('correct', 'incorrect') and not show_correctness=='never':
<span class="sr status">${choice_description|h} - ${status_display}</span>
<span class="sr status">${choice_description|h} - ${status.display_name}</span>
% endif
% endif
</label>
......
......@@ -10,7 +10,7 @@
<div class="script_placeholder" data-src="/static/js/capa/choicetextinput.js"/>
<div class="indicator_container">
% if input_type == 'checkbox' or not element_checked:
<span class="status ${status_class}" id="status_${id}"></span>
<span class="status ${status.classname}" id="status_${id}"></span>
% endif
</div>
......
......@@ -17,10 +17,10 @@
<div class="grader-status" tabindex="-1">
<span id="status_${id}"
class="${status_class}"
class="${status.classname}"
aria-describedby="input_${id}"
>
<span class="status sr">${status_display}</span>
<span class="status sr">${status.display_name}</span>
</span>
% if status == 'queued':
<span style="display:none;" class="xqueue" id="${id}">${queue_len}</span>
......@@ -30,7 +30,7 @@
<div style="display:none;" name="${hidden}" inputid="input_${id}" />
% endif
<p class="debug">${status_display}</p>
<p class="debug">${status.display_name}</p>
</div>
<span id="answer_${id}"></span>
......
......@@ -9,29 +9,14 @@
<div class="script_placeholder" data-src="/static/js/sylvester.js"></div>
<div class="script_placeholder" data-src="/static/js/crystallography.js"></div>
% if status == 'unsubmitted':
<div class="unanswered" id="status_${id}">
% elif status == 'correct':
<div class="correct" id="status_${id}">
% elif status == 'incorrect':
<div class="incorrect" id="status_${id}">
% elif status == 'incomplete':
<div class="incorrect" id="status_${id}">
% endif
% if status in ['unsubmitted', 'correct', 'incorrect', 'incomplete']:
<div class="status ${status.classname}" id="status_${id}">
<input type="text" name="input_${id}" aria-describedby="answer_${id}" id="input_${id}" value="${value|h}" style="display:none;"/>
<p class="status" aria-describedby="input_${id}">
% if status == 'unsubmitted':
unanswered
% elif status == 'correct':
correct
% elif status == 'incorrect':
incorrect
% elif status == 'incomplete':
incomplete
% endif
${status.display_name}
</p>
<p id="answer_${id}" class="answer"></p>
......
......@@ -2,14 +2,8 @@
<div class="script_placeholder" data-src="/static/js/capa/protex/protex.nocache.js?raw"/>
<div class="script_placeholder" data-src="${applet_loader}"/>
% if status == 'unsubmitted':
<div class="unanswered" id="status_${id}">
% elif status == 'correct':
<div class="correct" id="status_${id}">
% elif status == 'incorrect':
<div class="incorrect" id="status_${id}">
% elif status == 'incomplete':
<div class="incomplete" id="status_${id}">
% if status in ['unsubmitted', 'correct', 'incorrect', 'incomplete']:
<div class="${status.classname}" id="status_${id}">
% endif
<div id="protex_container"></div>
......@@ -17,15 +11,7 @@
<input type="hidden" name="input_${id}" id="input_${id}" aria-describedby="answer_${id}" value="${value|h}"/>
<p class="status" aria-describedby="input_${id}">
% if status == 'unsubmitted':
unanswered
% elif status == 'correct':
correct
% elif status == 'incorrect':
incorrect
% elif status == 'incomplete':
incomplete
% endif
${status.display_name}
</p>
<p id="answer_${id}" class="answer"></p>
......
......@@ -8,14 +8,8 @@
<div class="script_placeholder" data-src="${STATIC_URL}js/capa/drag_and_drop.js"></div>
% if status == 'unsubmitted':
<div class="unanswered" id="status_${id}">
% elif status == 'correct':
<div class="correct" id="status_${id}">
% elif status == 'incorrect':
<div class="incorrect" id="status_${id}">
% elif status == 'incomplete':
<div class="incorrect" id="status_${id}">
% if status in ['unsubmitted', 'correct', 'incorrect', 'incomplete']:
<div class="${status.classname}" id="status_${id}">
% endif
......@@ -23,15 +17,7 @@
style="display:none;"/>
<p class="status" aria-describedby="input_${id}">
% if status == 'unsubmitted':
unanswered
% elif status == 'correct':
correct
% elif status == 'incorrect':
incorrect
% elif status == 'incomplete':
incomplete
% endif
${status.display_name}
</p>
<p id="answer_${id}" class="answer"></p>
......
......@@ -2,14 +2,8 @@
<div class="script_placeholder" data-src="/static/js/capa/genex/genex.nocache.js?raw"/>
<div class="script_placeholder" data-src="${applet_loader}"/>
% if status == 'unsubmitted':
<div class="unanswered" id="status_${id}">
% elif status == 'correct':
<div class="correct" id="status_${id}">
% elif status == 'incorrect':
<div class="incorrect" id="status_${id}">
% elif status == 'incomplete':
<div class="incomplete" id="status_${id}">
% if status in ['unsubmitted', 'correct', 'incorrect', 'incomplete']:
<div class="${status.classname}" id="status_${id}">
% endif
<div id="genex_container"></div>
......@@ -18,15 +12,7 @@
<input type="hidden" name="input_${id}" aria-describedby="answer_${id}" id="input_${id}" value="${value|h}"/>
<p class="status" aria-describedby="input_${id}">
% if status == 'unsubmitted':
unanswered
% elif status == 'correct':
correct
% elif status == 'incorrect':
incorrect
% elif status == 'incomplete':
incomplete
% endif
${status.display_name}
</p>
<p id="answer_${id}" class="answer"></p>
......
<section id="editamoleculeinput_${id}" class="editamoleculeinput">
<div class="script_placeholder" data-src="${applet_loader}"/>
% if status == 'unsubmitted':
<div class="unanswered" id="status_${id}">
% elif status == 'correct':
<div class="correct" id="status_${id}">
% elif status == 'incorrect':
<div class="incorrect" id="status_${id}">
% elif status == 'incomplete':
<div class="incorrect" id="status_${id}">
% endif
% if status in ['unsubmitted', 'correct', 'incorrect', 'incomplete']:
<div class="${status.classname}" id="status_${id}">
% endif
<div id="applet_${id}" class="applet" data-molfile-src="${file}" style="display:block;width:500px;height:400px">
</div>
......@@ -23,15 +17,7 @@
<p id="answer_${id}" class="answer"></p>
<p class="status" aria-describedby="input_${id}">
% if status == 'unsubmitted':
unanswered
% elif status == 'correct':
correct
% elif status == 'incorrect':
incorrect
% elif status == 'incomplete':
incomplete
% endif
${status.display_name}
</p>
<br/> <br/>
......
<section id="filesubmission_${id}" class="filesubmission">
<div class="grader-status file">
% if status == 'unsubmitted':
<span class="unanswered" style="display:inline-block;" id="status_${id}">Unanswered</span>
% elif status == 'correct':
<span class="correct" id="status_${id}">Correct</span>
% elif status == 'incorrect':
<span class="incorrect" id="status_${id}">Incorrect</span>
% elif status == 'queued':
<span class="processing" id="status_${id}">Queued</span>
<span style="display:none;" class="xqueue" id="${id}" >${queue_len}</span>
<span class="${status.classname}" id="status_${id}">${status.display_name}</span>
% if status == 'queued':
<span style="display:none;" class="xqueue" id="${id}">${queue_len}</span>
% endif
<p class="debug">${status}</p>
......
<% doinline = 'style="display:inline-block;vertical-align:top"' if inline else "" %>
<section id="formulaequationinput_${id}" class="inputtype formulaequationinput" ${doinline}>
<div class="${status_class}" id="status_${id}">
<div class="${status.classname}" id="status_${id}">
<input type="text" name="input_${id}" id="input_${id}"
data-input-id="${id}" value="${value|h}"
aria-label="${label}"
......@@ -20,7 +20,7 @@
% else:
${label}
%endif
</span> - ${status_display}
</span> - ${status.display_name}
</p>
<div id="input_${id}_preview" class="equation">
......
......@@ -39,38 +39,11 @@
(new ImageInput('${id}'));
</script>
% if status == 'unsubmitted':
<span
class="unanswered"
style="display: inline-block;"
class="status ${status.classname}"
id="status_${id}"
aria-describedby="input_${id}"
>
<span class="sr">Status: unanswered</span>
<span class="sr">${status.display_name}</span>
</span>
% elif status == 'correct':
<span
class="correct"
id="status_${id}"
aria-describedby="input_${id}"
>
<span class="sr">Status: correct</span>
</span>
% elif status == 'incorrect':
<span
class="incorrect"
id="status_${id}"
aria-describedby="input_${id}"
>
<span class="sr">Status: incorrect</span>
</span>
% elif status == 'incomplete':
<span
class="incorrect"
id="status_${id}"
aria-describedby="input_${id}"
>
<span class="sr">Status: incorrect</span>
</span>
% endif
</div>
......@@ -17,14 +17,8 @@
<div class="script_placeholder" data-src="${jschannel_loader}"/>
<div class="script_placeholder" data-src="${jsinput_loader}"/>
% if status == 'unsubmitted':
<div class="unanswered" id="status_${id}">
% elif status == 'correct':
<div class="correct" id="status_${id}">
% elif status == 'incorrect':
<div class="incorrect" id="status_${id}">
% elif status == 'incomplete':
<div class="incorrect" id="status_${id}">
% if status in ['unsubmitted', 'correct', 'incorrect', 'incomplete']:
<div class="${status.classname}" id="status_${id}">
% endif
<iframe name="iframe_${id}"
......@@ -44,15 +38,7 @@
<p id="answer_${id}" class="answer"></p>
<p class="status">
% if status == 'unsubmitted':
unanswered
% elif status == 'correct':
correct
% elif status == 'incorrect':
incorrect
% elif status == 'incomplete':
incomplete
% endif
${status.display_name}
</p>
<br/> <br/>
......
......@@ -18,23 +18,9 @@
<textarea style="display:none" id="input_${id}_fromjs" name="input_${id}_fromjs"></textarea>
% endif
% if status == 'unsubmitted':
<span class="unanswered" style="display:inline-block;" id="status_${id}" aria-describedby="input_${id}">
<span class="sr">Status: unanswered</span>
<span class="status ${status.classname}" id="status_${id}" aria-describedby="input_${id}">
<span class="sr">${status.display_name</span>
</span>
% elif status == 'correct':
<span class="correct" id="status_${id}" aria-describedby="input_${id}">
<span class="sr">Status: correct</span>
</span>
% elif status == 'incorrect':
<span class="incorrect" id="status_${id}" aria-describedby="input_${id}">
<span class="sr">Status: incorrect</span>
</span>
% elif status == 'incomplete':
<span class="incorrect" id="status_${id}" aria-describedby="input_${id}">
<span class="sr">Status: incorrect</span>
</span>
% endif
% if msg:
<br/>
<span class="debug">${msg|n}</span>
......
......@@ -18,10 +18,10 @@
<div class="grader-status" tabindex="-1">
<span id="status_${id}"
class="${status_class}"
class="${status.classname}"
aria-describedby="input_${id}"
>
<span class="status sr">${status_display}</span>
<span class="status sr">${status.display_name}</span>
</span>
% if status == 'queued':
<span style="display:none;" class="xqueue" id="${id}">${queue_len}</span>
......@@ -31,7 +31,7 @@
<div style="display:none;" name="${hidden}" inputid="input_${id}" />
% endif
<p class="debug">${status_display}</p>
<p class="debug">${status.display_name}</p>
</div>
<span id="answer_${id}"></span>
......
......@@ -13,10 +13,10 @@
</select>
<span id="answer_${id}"></span>
<span class="status ${status_class}"
<span class="status ${status.classname}"
id="status_${id}"
aria-describedby="input_${id}">
<span class="sr">${value|h} - ${status_display}</span>
<span class="sr">${value|h} - ${status.display_name}</span>
</span>
% if msg:
......
<span>
<div>
<div class="script_placeholder" data-src="${setup_script}"/>
<input type="hidden"
class="schematic"
......@@ -16,23 +16,7 @@
/>
<span id="answer_${id}"></span>
% if status == 'unsubmitted':
<span class="ui-icon ui-icon-bullet" style="display:inline-block;" id="status_${id}" aria-describedby="input_${id}">
<span class="sr">Status: unsubmitted</span>
<span class="status ${status.classname}" id="status_${id}" aria-describedby="input_${id}">
<span class="sr">${status.display_name}</span>
</span>
% elif status == 'correct':
<span class="ui-icon ui-icon-check" style="display:inline-block;" id="status_${id}" aria-describedby="input_${id}">
<span class="sr">Status: correct</span>
</span>
% elif status == 'incorrect':
<span class="ui-icon ui-icon-close" style="display:inline-block;" id="status_${id}" aria-describedby="input_${id}">
<span class="sr">Status: incorrect</span>
</span>
% elif status == 'incomplete':
<span class="ui-icon ui-icon-close" style="display:inline-block;" id="status_${id}" aria-describedby="input_${id}">
<span class="sr">Status: incomplete</span>
</span>
% endif
</span>
</div>
......@@ -8,7 +8,7 @@
% endif
% if status in ('unsubmitted', 'correct', 'incorrect', 'incomplete'):
<div class="${status_class} ${doinline}" id="status_${id}">
<div class="${status.classname} ${doinline}" id="status_${id}">
% endif
% if hidden:
<div style="display:none;" name="${hidden}" inputid="input_${id}" />
......@@ -38,7 +38,7 @@
${label}
%endif
-
${status_display}
${status.display_name}
</p>
<p id="answer_${id}" class="answer" aria-hidden="true"></p>
......
......@@ -11,14 +11,8 @@
<div class="script_placeholder" data-src="/static/js/vsepr/vsepr.js"></div>
% if status == 'unsubmitted':
<div class="unanswered" id="status_${id}">
% elif status == 'correct':
<div class="correct" id="status_${id}">
% elif status == 'incorrect':
<div class="incorrect" id="status_${id}">
% elif status == 'incomplete':
<div class="incorrect" id="status_${id}">
% if status in ['unsubmitted', 'correct', 'incorrect', 'incomplete']:
<div class="${status.classname}" id="status_${id}">
% endif
<input type="text" name="input_${id}" id="input_${id}" aria-describedby="answer_${id}" value="${value|h}"
......@@ -26,15 +20,7 @@
/>
<p class="status" aria-describedby="input_${id}">
% if status == 'unsubmitted':
unanswered
% elif status == 'correct':
correct
% elif status == 'incorrect':
incorrect
% elif status == 'incomplete':
incomplete
% endif
${status.display_name}
</p>
<p id="answer_${id}" class="answer"></p>
......
......@@ -7,6 +7,7 @@ import os.path
import fs.osfs
from capa.capa_problem import LoncapaProblem, LoncapaSystem
from capa.inputtypes import Status
from mock import Mock, MagicMock
import xml.sax.saxutils as saxutils
......@@ -47,6 +48,7 @@ def test_capa_system():
render_template=tst_render_template,
seed=0,
STATIC_URL='/dummy-static/',
STATUS_CLASS=Status,
xqueue={'interface': xqueue_interface, 'construct_callback': calledback_url, 'default_queuename': 'testqueue', 'waittime': 10},
)
return the_system
......
......@@ -153,9 +153,7 @@ class CapaHtmlRenderTest(unittest.TestCase):
# the solution
expected_textline_context = {
'STATIC_URL': '/dummy-static/',
'status': 'unsubmitted',
'status_class': 'unanswered',
'status_display': u'unanswered',
'status': the_system.STATUS_CLASS('unsubmitted'),
'label': '',
'value': '',
'preprocessor': None,
......
......@@ -4,7 +4,8 @@ class @HTMLModule
@el = $(@element)
JavascriptLoader.executeModuleScripts(@el)
Collapsible.setCollapsibles(@el)
MathJax.Hub.Queue ["Typeset", MathJax.Hub, @el[0]]
if MathJax?
MathJax.Hub.Queue ["Typeset", MathJax.Hub, @el[0]]
$: (selector) ->
$(selector, @el)
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