Commit 9a6b5086 by Se Won Jang Committed by Stephen Sanchez

Allow Mathjax(Latex) in Student responses

Currently, Latex rendering is only supported for question prompts in ORA2. This
commit introduces Latex rendering in ORA2 student response, peer assessment
view, self assessment view, grade view, and staff-info view. The reason that
this Latex rendering code is inserted directly into ORA2 is that edx-platform,
does not know when to start Latex rendering for ORA2 views that come in via
AJAX.

This commit introduces "Preview in Latex" feature which allows students to see
their response rendered in MathJax before submission.

Conflicts:
	openassessment/xblock/static/js/openassessment-lms.min.js
	openassessment/xblock/static/js/openassessment-studio.min.js
parent c0923489
...@@ -109,6 +109,16 @@ ...@@ -109,6 +109,16 @@
</div> </div>
<p class="setting-help">{% trans "Specify whether students can submit an image file along with their text response." %}</p> <p class="setting-help">{% trans "Specify whether students can submit an image file along with their text response." %}</p>
</li> </li>
<li id="openassessment_submission_latex_wrapper" class="field comp-setting-entry">
<div class="wrapper-comp-setting">
<label for="openassessment_submission_latex_editor" class="setting-label">{% trans "Allow Latex Responses"%}</label>
<select id="openassessment_submission_latex_editor" class="input setting-input" name="latex submission">
<option value="0">{% trans "False"%}</option>
<option value="1" {% if allow_latex %} selected="true" {% endif %}>{% trans "True"%}</option>
</select>
</div>
<p class="setting-help">{% trans "Specify whether students can write Latex formatted strings"%}</p>
</li>
<li id="openassessment_leaderboard_wrapper" class="field comp-setting-entry"> <li id="openassessment_leaderboard_wrapper" class="field comp-setting-entry">
<div class="wrapper-comp-setting"> <div class="wrapper-comp-setting">
<label for="openassessment_leaderboard_editor" class="setting-label">{% trans "Top Responses" %}</label> <label for="openassessment_leaderboard_editor" class="setting-label">{% trans "Top Responses" %}</label>
......
{% load i18n %} {% load i18n %}
{% spaceless %} {% spaceless %}
<li id="openassessment__grade" class="openassessment__steps__step step--grade is--complete has--grade"> <li id="openassessment__grade" class="openassessment__steps__step step--grade is--complete has--grade {% if allow_latex %}allow--latex{% endif %}">
<header class="step__header ui-toggle-visibility__control"> <header class="step__header ui-toggle-visibility__control">
<h2 class="step__title"> <h2 class="step__title">
<span class="wrapper--copy"> <span class="wrapper--copy">
......
{% load i18n %} {% load i18n %}
{% spaceless %} {% spaceless %}
<li id="openassessment__leaderboard" class="openassessment__steps__step step--leaderboard is--complete"> <li id="openassessment__leaderboard" class="openassessment__steps__step step--leaderboard is--complete {% if allow_latex %} allow--latex{% endif %}">
<header class="step__header"> <header class="step__header">
<h2 class="step__title"> <h2 class="step__title">
<span class="wrapper--copy"> <span class="wrapper--copy">
......
{% load tz %} {% load tz %}
{% load i18n %} {% load i18n %}
{% block list_item %} {% block list_item %}
<li id="openassessment__peer-assessment" class="openassessment__steps__step step--peer-assessment ui-toggle-visibility"> <li id="openassessment__peer-assessment" class="openassessment__steps__step step--peer-assessment ui-toggle-visibility {% if allow_latex %} allow--latex {%endif%}">
{% endblock %} {% endblock %}
{% spaceless %} {% spaceless %}
......
...@@ -103,6 +103,24 @@ ...@@ -103,6 +103,24 @@
</h3> </h3>
</div> </div>
</li> </li>
{% if allow_latex %}
<li class="list--actions__item">
<button type="submit" id="submission__preview" class="action action--save submission__save is--disabled">{% trans "Preview in Latex"%}</button>
<div id="response__preview_explanation" class="response__submission__status">
<h3 class="response__submission__status__title">
{% trans "Click to preview your submission in Latex"%}
</h3>
</div>
</li>
<li id = "submission__preview__item" class="list--actions__item">
<article class="submission__answer__display">
<h3 class="submission__answer__display__title">Preview Response</h3>
<div class="submission__answer__display__content">
<p id="preview_content"></p>
</div>
</article>
</li>
{% endif %}
</ul> </ul>
</div> </div>
</form> </form>
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
{% load i18n %} {% load i18n %}
{% block list_item %} {% block list_item %}
<li id="openassessment__response" class="openassessment__steps__step step--response is--complete ui-toggle-visibility is--collapsed"> <li id="openassessment__response" class="openassessment__steps__step step--response is--complete ui-toggle-visibility is--collapsed {% if allow_latex %}allow--latex{%endif%}">
{% endblock %} {% endblock %}
{% block title %} {% block title %}
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
{% load i18n %} {% load i18n %}
{% block list_item %} {% block list_item %}
<li id="openassessment__response" class="openassessment__steps__step step--response is--complete ui-toggle-visibility is--collapsed"> <li id="openassessment__response" class="openassessment__steps__step step--response is--complete ui-toggle-visibility is--collapsed {% if allow_latex %}allow--latex{%endif%}">
{% endblock %} {% endblock %}
{% block title %} {% block title %}
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
{% load tz %} {% load tz %}
{% spaceless %} {% spaceless %}
{% block list_item %} {% block list_item %}
<li id="openassessment__self-assessment" class="openassessment__steps__step step--self-assessment ui-toggle-visibility"> <li id="openassessment__self-assessment" class="openassessment__steps__step step--self-assessment ui-toggle-visibility {% if allow_latex %}allow--latex{%endif%}">
{% endblock %} {% endblock %}
<header class="step__header ui-toggle-visibility__control"> <header class="step__header ui-toggle-visibility__control">
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
{% load tz %} {% load tz %}
{% spaceless %} {% spaceless %}
{% block list_item %} {% block list_item %}
<li id="openassessment__student-training" class="openassessment__steps__step step--student-training ui-toggle-visibility"> <li id="openassessment__student-training" class="openassessment__steps__step step--student-training ui-toggle-visibility {% if allow_latex %}allow--latex{%endif%}">
{% endblock %} {% endblock %}
<header class="step__header ui-toggle-visibility__control"> <header class="step__header ui-toggle-visibility__control">
......
...@@ -137,6 +137,7 @@ class GradeMixin(object): ...@@ -137,6 +137,7 @@ class GradeMixin(object):
'rubric_criteria': self._rubric_criteria_grade_context(peer_assessments, self_assessment), 'rubric_criteria': self._rubric_criteria_grade_context(peer_assessments, self_assessment),
'has_submitted_feedback': has_submitted_feedback, 'has_submitted_feedback': has_submitted_feedback,
'allow_file_upload': self.allow_file_upload, 'allow_file_upload': self.allow_file_upload,
'allow_latex': self.allow_latex,
'file_url': self.get_download_url_from_submission(student_submission) 'file_url': self.get_download_url_from_submission(student_submission)
} }
......
...@@ -80,7 +80,9 @@ class LeaderboardMixin(object): ...@@ -80,7 +80,9 @@ class LeaderboardMixin(object):
else: else:
score['content'] = "" score['content'] = ""
context = { 'topscores': scores } context = { 'topscores': scores,
'allow_latex': self.allow_latex,
}
return ('openassessmentblock/leaderboard/oa_leaderboard_show.html', context) return ('openassessmentblock/leaderboard/oa_leaderboard_show.html', context)
def render_leaderboard_incomplete(self): def render_leaderboard_incomplete(self):
......
...@@ -122,6 +122,12 @@ class OpenAssessmentBlock( ...@@ -122,6 +122,12 @@ class OpenAssessmentBlock(
help="File upload allowed with submission." help="File upload allowed with submission."
) )
allow_latex = Boolean(
default=False,
scope=Scope.settings,
help="Latex rendering allowed with submission."
)
title = String( title = String(
default="", default="",
scope=Scope.content, scope=Scope.content,
...@@ -399,6 +405,7 @@ class OpenAssessmentBlock( ...@@ -399,6 +405,7 @@ class OpenAssessmentBlock(
block.title = config['title'] block.title = config['title']
block.prompt = config['prompt'] block.prompt = config['prompt']
block.allow_file_upload = config['allow_file_upload'] block.allow_file_upload = config['allow_file_upload']
block.allow_latex = config['allow_latex']
block.leaderboard_show = config['leaderboard_show'] block.leaderboard_show = config['leaderboard_show']
return block return block
......
...@@ -156,7 +156,8 @@ class PeerAssessmentMixin(object): ...@@ -156,7 +156,8 @@ class PeerAssessmentMixin(object):
context_dict = { context_dict = {
"rubric_criteria": self.rubric_criteria_with_labels, "rubric_criteria": self.rubric_criteria_with_labels,
"estimated_time": "20 minutes" # TODO: Need to configure this. "estimated_time": "20 minutes", # TODO: Need to configure this.
"allow_latex": self.allow_latex,
} }
if self.rubric_feedback_prompt is not None: if self.rubric_feedback_prompt is not None:
......
...@@ -73,6 +73,7 @@ EDITOR_UPDATE_SCHEMA = Schema({ ...@@ -73,6 +73,7 @@ EDITOR_UPDATE_SCHEMA = Schema({
Required('submission_start'): Any(datetime_validator, None), Required('submission_start'): Any(datetime_validator, None),
Required('submission_due'): Any(datetime_validator, None), Required('submission_due'): Any(datetime_validator, None),
Required('allow_file_upload'): bool, Required('allow_file_upload'): bool,
Required('allow_latex'): bool,
Required('leaderboard_show'): int, Required('leaderboard_show'): int,
Required('assessments'): [ Required('assessments'): [
Schema({ Schema({
......
...@@ -51,7 +51,7 @@ class SelfAssessmentMixin(object): ...@@ -51,7 +51,7 @@ class SelfAssessmentMixin(object):
SubmissionError: Error occurred while retrieving the current submission. SubmissionError: Error occurred while retrieving the current submission.
SelfAssessmentRequestError: Error occurred while checking if we had a self-assessment. SelfAssessmentRequestError: Error occurred while checking if we had a self-assessment.
""" """
context = {} context = {'allow_latex': self.allow_latex}
path = 'openassessmentblock/self/oa_self_unavailable.html' path = 'openassessmentblock/self/oa_self_unavailable.html'
problem_closed, reason, start_date, due_date = self.is_closed(step="self-assessment") problem_closed, reason, start_date, due_date = self.is_closed(step="self-assessment")
......
...@@ -137,6 +137,9 @@ class StaffInfoMixin(object): ...@@ -137,6 +137,9 @@ class StaffInfoMixin(object):
# Include release/due dates for each step in the problem # Include release/due dates for each step in the problem
context['step_dates'] = list() context['step_dates'] = list()
# Include Latex setting
context['allow_latex'] = self.allow_latex
steps = ['submission'] + self.assessment_steps steps = ['submission'] + self.assessment_steps
for step in steps: for step in steps:
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -243,6 +243,7 @@ describe("OpenAssessment.Server", function() { ...@@ -243,6 +243,7 @@ describe("OpenAssessment.Server", function() {
assessments: ASSESSMENTS, assessments: ASSESSMENTS,
editorAssessmentsOrder: EDITOR_ASSESSMENTS_ORDER, editorAssessmentsOrder: EDITOR_ASSESSMENTS_ORDER,
imageSubmissionEnabled: true, imageSubmissionEnabled: true,
latexEnabled: false,
leaderboardNum: 15 leaderboardNum: 15
}); });
expect($.ajax).toHaveBeenCalledWith({ expect($.ajax).toHaveBeenCalledWith({
...@@ -258,6 +259,7 @@ describe("OpenAssessment.Server", function() { ...@@ -258,6 +259,7 @@ describe("OpenAssessment.Server", function() {
assessments: ASSESSMENTS, assessments: ASSESSMENTS,
editor_assessments_order: EDITOR_ASSESSMENTS_ORDER, editor_assessments_order: EDITOR_ASSESSMENTS_ORDER,
allow_file_upload: true, allow_file_upload: true,
latexEnabled: false,
leaderboard_show: 15 leaderboard_show: 15
}) })
}); });
......
...@@ -52,6 +52,9 @@ OpenAssessment.PeerView.prototype = { ...@@ -52,6 +52,9 @@ OpenAssessment.PeerView.prototype = {
// Load the HTML and install event handlers // Load the HTML and install event handlers
$('#openassessment__peer-assessment', view.element).replaceWith(html); $('#openassessment__peer-assessment', view.element).replaceWith(html);
view.installHandlers(true); view.installHandlers(true);
if (MathJax != undefined && MathJax != null) {
MathJax.Hub.Typeset($('#openassessment__peer-assessment', view.element)[0]);
}
} }
).fail(function(errMsg) { ).fail(function(errMsg) {
view.baseView.showLoadError('peer-assessment'); view.baseView.showLoadError('peer-assessment');
......
...@@ -69,6 +69,8 @@ OpenAssessment.ResponseView.prototype = { ...@@ -69,6 +69,8 @@ OpenAssessment.ResponseView.prototype = {
var handlePrepareUpload = function(eventData) { view.prepareUpload(eventData.target.files); }; var handlePrepareUpload = function(eventData) { view.prepareUpload(eventData.target.files); };
sel.find('input[type=file]').on('change', handlePrepareUpload); sel.find('input[type=file]').on('change', handlePrepareUpload);
// keep the preview as display none at first
sel.find('#submission__preview__item').hide();
// Install a click handler for submission // Install a click handler for submission
sel.find('#step--response__submit').click( sel.find('#step--response__submit').click(
...@@ -88,6 +90,23 @@ OpenAssessment.ResponseView.prototype = { ...@@ -88,6 +90,23 @@ OpenAssessment.ResponseView.prototype = {
} }
); );
// Install click handler for the preview button
sel.find('#submission__preview').click(
function(eventObject) {
eventObject.preventDefault();
// extract typed-in response and replace newline with br
var preview_text = sel.find('#submission__answer__value').val();
var preview_container = sel.find('#preview_content');
preview_container.html(preview_text.replace(/\r\n|\r|\n/g,"<br />"));
// Render in mathjax
sel.find('#submission__preview__item').show();
if (MathJax !== undefined && MathJax !== null) {
MathJax.Hub.Queue(['Typeset', MathJax.Hub, preview_container[0]]);
}
}
);
// Install a click handler for the save button // Install a click handler for the save button
sel.find('#file__upload').click( sel.find('#file__upload').click(
function(eventObject) { function(eventObject) {
...@@ -174,6 +193,19 @@ OpenAssessment.ResponseView.prototype = { ...@@ -174,6 +193,19 @@ OpenAssessment.ResponseView.prototype = {
}, },
/** /**
Enable/disable the preview button.
Works exactly the same way as saveEnabled method.
**/
previewEnabled: function(enabled) {
var sel = $('#submission__preview', this.element);
if (typeof enabled === 'undefined') {
return !sel.hasClass('is--disabled');
} else {
sel.toggleClass('is--disabled', !enabled);
}
},
/**
Set the save status message. Set the save status message.
Retrieve the save status message. Retrieve the save status message.
...@@ -289,6 +321,7 @@ OpenAssessment.ResponseView.prototype = { ...@@ -289,6 +321,7 @@ OpenAssessment.ResponseView.prototype = {
// only if the response has changed // only if the response has changed
if (this.responseChanged()) { if (this.responseChanged()) {
this.saveEnabled(isBlank); this.saveEnabled(isBlank);
this.previewEnabled(isBlank);
this.saveStatus(gettext('This response has not been saved.')); this.saveStatus(gettext('This response has not been saved.'));
this.unsavedWarningEnabled(true); this.unsavedWarningEnabled(true);
} }
......
...@@ -55,6 +55,7 @@ if (typeof OpenAssessment.Server == "undefined" || !OpenAssessment.Server) { ...@@ -55,6 +55,7 @@ if (typeof OpenAssessment.Server == "undefined" || !OpenAssessment.Server) {
) )
**/ **/
render: function(component) { render: function(component) {
var that = this;
var url = this.url('render_' + component); var url = this.url('render_' + component);
return $.Deferred(function(defer) { return $.Deferred(function(defer) {
$.ajax({ $.ajax({
...@@ -63,6 +64,9 @@ if (typeof OpenAssessment.Server == "undefined" || !OpenAssessment.Server) { ...@@ -63,6 +64,9 @@ if (typeof OpenAssessment.Server == "undefined" || !OpenAssessment.Server) {
dataType: "html" dataType: "html"
}).done(function(data) { }).done(function(data) {
defer.resolveWith(this, [data]); defer.resolveWith(this, [data]);
if (window.MathJax) {
that.renderLatex();
}
}).fail(function(data) { }).fail(function(data) {
defer.rejectWith(this, [gettext('This section could not be loaded.')]); defer.rejectWith(this, [gettext('This section could not be loaded.')]);
}); });
...@@ -70,6 +74,21 @@ if (typeof OpenAssessment.Server == "undefined" || !OpenAssessment.Server) { ...@@ -70,6 +74,21 @@ if (typeof OpenAssessment.Server == "undefined" || !OpenAssessment.Server) {
}, },
/** /**
Render Latex for all new DOM elements with class 'allow--latex'.
Once rendered, remove the class so that a single element does
not get rendered multiple times.
**/
renderLatex: function() {
var i, latex_elems = $('.allow--latex');
if (latex_elems && latex_elems.length !== 0) {
for (i = 0; i < latex_elems.length; i++) {
MathJax.Hub.Queue(['Typeset', MathJax.Hub, latex_elems[i]]);
}
}
latex_elems.removeClass('allow--latex');
},
/**
Render the Peer Assessment Section after a complete workflow, in order to Render the Peer Assessment Section after a complete workflow, in order to
continue grading peers. continue grading peers.
...@@ -419,6 +438,7 @@ if (typeof OpenAssessment.Server == "undefined" || !OpenAssessment.Server) { ...@@ -419,6 +438,7 @@ if (typeof OpenAssessment.Server == "undefined" || !OpenAssessment.Server) {
criteria (list of object literals): The rubric criteria. criteria (list of object literals): The rubric criteria.
assessments (list of object literals): The assessments the student will be evaluated on. assessments (list of object literals): The assessments the student will be evaluated on.
imageSubmissionEnabled (boolean): TRUE if image attachments are allowed. imageSubmissionEnabled (boolean): TRUE if image attachments are allowed.
latexEnabled: TRUE if latex rendering is enabled.
leaderboardNum (int): The number of scores to show in the leaderboard. leaderboardNum (int): The number of scores to show in the leaderboard.
Returns: Returns:
...@@ -439,6 +459,7 @@ if (typeof OpenAssessment.Server == "undefined" || !OpenAssessment.Server) { ...@@ -439,6 +459,7 @@ if (typeof OpenAssessment.Server == "undefined" || !OpenAssessment.Server) {
assessments: kwargs.assessments, assessments: kwargs.assessments,
editor_assessments_order: kwargs.editorAssessmentsOrder, editor_assessments_order: kwargs.editorAssessmentsOrder,
allow_file_upload: kwargs.imageSubmissionEnabled, allow_file_upload: kwargs.imageSubmissionEnabled,
allow_latex: kwargs.latexEnabled,
leaderboard_show: kwargs.leaderboardNum leaderboard_show: kwargs.leaderboardNum
}); });
return $.Deferred(function(defer) { return $.Deferred(function(defer) {
......
...@@ -194,6 +194,7 @@ OpenAssessment.StudioView.prototype = { ...@@ -194,6 +194,7 @@ OpenAssessment.StudioView.prototype = {
submissionDue: view.settingsView.submissionDue(), submissionDue: view.settingsView.submissionDue(),
assessments: view.settingsView.assessmentsDescription(), assessments: view.settingsView.assessmentsDescription(),
imageSubmissionEnabled: view.settingsView.imageSubmissionEnabled(), imageSubmissionEnabled: view.settingsView.imageSubmissionEnabled(),
latexEnabled: view.settingsView.latexEnabled(),
leaderboardNum: view.settingsView.leaderboardNum(), leaderboardNum: view.settingsView.leaderboardNum(),
editorAssessmentsOrder: view.settingsView.editorAssessmentsOrder() editorAssessmentsOrder: view.settingsView.editorAssessmentsOrder()
}).done( }).done(
......
...@@ -141,6 +141,25 @@ OpenAssessment.EditSettingsView.prototype = { ...@@ -141,6 +141,25 @@ OpenAssessment.EditSettingsView.prototype = {
}, },
/** /**
Enable / disable latex rendering.
Args:
isEnabled(boolean, optional): if provided enable/disable latex rendering
Returns:
boolean
**/
latexEnabled: function(isEnabled) {
var sel = $('#openassessment_submission_latex_editor', this.settingsElement);
if (isEnabled !== undefined) {
if (isEnabled) {
sel.val(1);
} else {
sel.val(0)
}
}
return (sel.val() == 1);
},
/**
Get or set the number of scores to show in the leaderboard. Get or set the number of scores to show in the leaderboard.
If set to 0, the leaderboard will not be shown. If set to 0, the leaderboard will not be shown.
......
...@@ -102,6 +102,7 @@ ...@@ -102,6 +102,7 @@
li { li {
margin-bottom: 0 !important; margin-bottom: 0 !important;
margin-top: 5px !important;
} }
button, .button, .action { button, .button, .action {
......
...@@ -541,6 +541,7 @@ ...@@ -541,6 +541,7 @@
display: block; display: block;
text-align: center; text-align: center;
margin-bottom: ($baseline-v/2); margin-bottom: ($baseline-v/2);
min-width: 215px;
@include media($bp-ds) { @include media($bp-ds) {
display: inline-block; display: inline-block;
......
...@@ -72,6 +72,9 @@ class StudentTrainingMixin(object): ...@@ -72,6 +72,9 @@ class StudentTrainingMixin(object):
context = {} context = {}
template = 'openassessmentblock/student_training/student_training_unavailable.html' template = 'openassessmentblock/student_training/student_training_unavailable.html'
# add allow_latex field to the context
context['allow_latex'] = self.allow_latex
if not workflow_status: if not workflow_status:
return template, context return template, context
......
...@@ -121,6 +121,7 @@ class StudioMixin(object): ...@@ -121,6 +121,7 @@ class StudioMixin(object):
'feedbackprompt': self.rubric_feedback_prompt, 'feedbackprompt': self.rubric_feedback_prompt,
'feedback_default_text': feedback_default_text, 'feedback_default_text': feedback_default_text,
'allow_file_upload': self.allow_file_upload, 'allow_file_upload': self.allow_file_upload,
'allow_latex': self.allow_latex,
'leaderboard_show': self.leaderboard_show, 'leaderboard_show': self.leaderboard_show,
'editor_assessments_order': [ 'editor_assessments_order': [
make_django_template_key(asmnt) make_django_template_key(asmnt)
...@@ -213,6 +214,7 @@ class StudioMixin(object): ...@@ -213,6 +214,7 @@ class StudioMixin(object):
self.submission_start = data['submission_start'] self.submission_start = data['submission_start']
self.submission_due = data['submission_due'] self.submission_due = data['submission_due']
self.allow_file_upload = bool(data['allow_file_upload']) self.allow_file_upload = bool(data['allow_file_upload'])
self.allow_latex = bool(data['allow_latex'])
self.leaderboard_show = data['leaderboard_show'] self.leaderboard_show = data['leaderboard_show']
return {'success': True, 'msg': self._(u'Successfully updated OpenAssessment XBlock')} return {'success': True, 'msg': self._(u'Successfully updated OpenAssessment XBlock')}
......
...@@ -337,6 +337,7 @@ class SubmissionMixin(object): ...@@ -337,6 +337,7 @@ class SubmissionMixin(object):
context["submission_due"] = due_date context["submission_due"] = due_date
context['allow_file_upload'] = self.allow_file_upload context['allow_file_upload'] = self.allow_file_upload
context['allow_latex'] = self.allow_latex
context['has_peer'] = 'peer-assessment' in self.assessment_steps context['has_peer'] = 'peer-assessment' in self.assessment_steps
context['has_self'] = 'self-assessment' in self.assessment_steps context['has_self'] = 'self-assessment' in self.assessment_steps
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"assessments": [ "assessments": [
{ {
...@@ -29,6 +30,7 @@ ...@@ -29,6 +30,7 @@
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"criteria": [ "criteria": [
{ {
...@@ -78,6 +80,7 @@ ...@@ -78,6 +80,7 @@
"no_feedback_prompt": { "no_feedback_prompt": {
"prompt": "Test prompt", "prompt": "Test prompt",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"criteria": [ "criteria": [
{ {
...@@ -129,6 +132,7 @@ ...@@ -129,6 +132,7 @@
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompt": "Test Prompt",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"criteria": [ "criteria": [
{ {
...@@ -179,6 +183,7 @@ ...@@ -179,6 +183,7 @@
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompt": "Test Prompt",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"criteria": [ "criteria": [
{ {
...@@ -231,6 +236,7 @@ ...@@ -231,6 +236,7 @@
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompt": "Test Prompt",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"criteria": [ "criteria": [
{ {
...@@ -283,6 +289,7 @@ ...@@ -283,6 +289,7 @@
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompt": "Test Prompt",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"criteria": [ "criteria": [
{ {
...@@ -327,6 +334,7 @@ ...@@ -327,6 +334,7 @@
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompt": "Test Prompt",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"criteria": [ "criteria": [
{ {
...@@ -370,6 +378,7 @@ ...@@ -370,6 +378,7 @@
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "prompty", "prompt": "prompty",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"criteria": [ "criteria": [
[] []
...@@ -392,6 +401,7 @@ ...@@ -392,6 +401,7 @@
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompt": "Test Prompt",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"criteria": [ "criteria": [
{ {
...@@ -435,6 +445,7 @@ ...@@ -435,6 +445,7 @@
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompt": "Test Prompt",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"criteria": [ "criteria": [
{ {
...@@ -464,6 +475,7 @@ ...@@ -464,6 +475,7 @@
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompt": "Test Prompt",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"criteria": [ "criteria": [
{ {
...@@ -502,6 +514,7 @@ ...@@ -502,6 +514,7 @@
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompt": "Test Prompt",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"criteria": [ "criteria": [
{ {
...@@ -545,6 +558,7 @@ ...@@ -545,6 +558,7 @@
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompt": "Test Prompt",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"criteria": [ "criteria": [
{ {
...@@ -587,6 +601,7 @@ ...@@ -587,6 +601,7 @@
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompt": "Test Prompt",
"allow_file_upload": 6, "allow_file_upload": 6,
"allow_latex": false,
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -628,6 +643,7 @@ ...@@ -628,6 +643,7 @@
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"prompt": "Test Prompt", "prompt": "Test Prompt",
"allow_file_upload": null, "allow_file_upload": null,
"allow_latex": false,
"criteria": [ "criteria": [
{ {
"order_num": 0, "order_num": 0,
...@@ -699,6 +715,7 @@ ...@@ -699,6 +715,7 @@
"submission_start": "4014-02-10T09:46", "submission_start": "4014-02-10T09:46",
"title": "My new title.", "title": "My new title.",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"assessments": [ "assessments": [
{ {
...@@ -755,6 +772,7 @@ ...@@ -755,6 +772,7 @@
"submission_start": "4014-02-10T09:46", "submission_start": "4014-02-10T09:46",
"title": "My new title.", "title": "My new title.",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"assessments": [ "assessments": [
{ {
...@@ -809,6 +827,7 @@ ...@@ -809,6 +827,7 @@
"submission_start": "4014-02-10T09:46", "submission_start": "4014-02-10T09:46",
"title": "My new title.", "title": "My new title.",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"assessments": [ "assessments": [
{ {
...@@ -866,6 +885,7 @@ ...@@ -866,6 +885,7 @@
"submission_start": "4014-02-10T09:46", "submission_start": "4014-02-10T09:46",
"title": "My new title.", "title": "My new title.",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"assessments": [ "assessments": [
{ {
...@@ -923,6 +943,7 @@ ...@@ -923,6 +943,7 @@
"submission_start": "4014-02-10T09:46", "submission_start": "4014-02-10T09:46",
"title": "My new title.", "title": "My new title.",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"assessments": [ "assessments": [
{ {
...@@ -974,6 +995,7 @@ ...@@ -974,6 +995,7 @@
"submission_start": "4014-02-10T09:46", "submission_start": "4014-02-10T09:46",
"title": "My new title.", "title": "My new title.",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"assessments": [ "assessments": [
{ {
...@@ -1032,6 +1054,7 @@ ...@@ -1032,6 +1054,7 @@
"submission_start": "4014-02-10T09:46", "submission_start": "4014-02-10T09:46",
"title": "My new title.", "title": "My new title.",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"assessments": [ "assessments": [
{ {
...@@ -1082,6 +1105,7 @@ ...@@ -1082,6 +1105,7 @@
"submission_start": "4014-02-10T09:46", "submission_start": "4014-02-10T09:46",
"title": "My new title.", "title": "My new title.",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"assessments": [ "assessments": [
{ {
...@@ -1133,6 +1157,7 @@ ...@@ -1133,6 +1157,7 @@
"submission_start": "4014-02-10T09:46", "submission_start": "4014-02-10T09:46",
"title": "My new title.", "title": "My new title.",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"assessments": [ "assessments": [
{ {
...@@ -1160,6 +1185,7 @@ ...@@ -1160,6 +1185,7 @@
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"criteria": [ "criteria": [
{ {
...@@ -1210,6 +1236,7 @@ ...@@ -1210,6 +1236,7 @@
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"criteria": [ "criteria": [
{ {
...@@ -1260,6 +1287,7 @@ ...@@ -1260,6 +1287,7 @@
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"criteria": [ "criteria": [
{ {
...@@ -1333,6 +1361,7 @@ ...@@ -1333,6 +1361,7 @@
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"feedback_default_text": "Feedback default text", "feedback_default_text": "Feedback default text",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"criteria": [ "criteria": [
{ {
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
"submission_start": "4014-02-10T09:46", "submission_start": "4014-02-10T09:46",
"title": "My new title.", "title": "My new title.",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"assessments": [ "assessments": [
{ {
...@@ -83,6 +84,7 @@ ...@@ -83,6 +84,7 @@
"submission_start": "4014-02-10T09:46", "submission_start": "4014-02-10T09:46",
"title": "ɯʎ uǝʍ ʇıʇןǝ", "title": "ɯʎ uǝʍ ʇıʇןǝ",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"assessments": [ "assessments": [
{ {
...@@ -134,6 +136,7 @@ ...@@ -134,6 +136,7 @@
"submission_start": "4014-02-10T09:46", "submission_start": "4014-02-10T09:46",
"title": "My new title.", "title": "My new title.",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"assessments": [ "assessments": [
{ {
...@@ -196,6 +199,7 @@ ...@@ -196,6 +199,7 @@
"submission_due": "4014-02-27T09:46", "submission_due": "4014-02-27T09:46",
"submission_start": "4014-02-10T09:46", "submission_start": "4014-02-10T09:46",
"allow_file_upload": false, "allow_file_upload": false,
"allow_latex": false,
"leaderboard_show": 0, "leaderboard_show": 0,
"title": "My new title.", "title": "My new title.",
"assessments": [ "assessments": [
......
...@@ -23,6 +23,7 @@ class StudioViewTest(XBlockHandlerTestCase): ...@@ -23,6 +23,7 @@ class StudioViewTest(XBlockHandlerTestCase):
"submission_start": "4014-02-10T09:46", "submission_start": "4014-02-10T09:46",
"submission_due": "4014-02-27T09:46", "submission_due": "4014-02-27T09:46",
"allow_file_upload": False, "allow_file_upload": False,
"allow_latex": False,
"leaderboard_show": 4, "leaderboard_show": 4,
"assessments": [{"name": "self-assessment"}], "assessments": [{"name": "self-assessment"}],
"editor_assessments_order": [ "editor_assessments_order": [
......
...@@ -108,6 +108,7 @@ class TestSerializeContent(TestCase): ...@@ -108,6 +108,7 @@ class TestSerializeContent(TestCase):
self.oa_block.rubric_criteria = data.get('criteria', copy.deepcopy(self.BASIC_CRITERIA)) self.oa_block.rubric_criteria = data.get('criteria', copy.deepcopy(self.BASIC_CRITERIA))
self.oa_block.rubric_assessments = data.get('assessments', copy.deepcopy(self.BASIC_ASSESSMENTS)) self.oa_block.rubric_assessments = data.get('assessments', copy.deepcopy(self.BASIC_ASSESSMENTS))
self.oa_block.allow_file_upload = data.get('allow_file_upload') self.oa_block.allow_file_upload = data.get('allow_file_upload')
self.oa_block.allow_latex = data.get('allow_latex')
self.oa_block.leaderboard_show = data.get('leaderboard_show', 0) self.oa_block.leaderboard_show = data.get('leaderboard_show', 0)
@ddt.file_data('data/serialize.json') @ddt.file_data('data/serialize.json')
...@@ -408,6 +409,7 @@ class TestParseFromXml(TestCase): ...@@ -408,6 +409,7 @@ class TestParseFromXml(TestCase):
'criteria', 'criteria',
'assessments', 'assessments',
'allow_file_upload', 'allow_file_upload',
'allow_latex',
'leaderboard_show' 'leaderboard_show'
] ]
for field_name in expected_fields: for field_name in expected_fields:
......
...@@ -624,6 +624,9 @@ def serialize_content_to_xml(oa_block, root): ...@@ -624,6 +624,9 @@ def serialize_content_to_xml(oa_block, root):
if oa_block.allow_file_upload is not None: if oa_block.allow_file_upload is not None:
root.set('allow_file_upload', unicode(oa_block.allow_file_upload)) root.set('allow_file_upload', unicode(oa_block.allow_file_upload))
if oa_block.allow_latex is not None:
root.set('allow_latex', unicode(oa_block.allow_latex))
# Open assessment displayed title # Open assessment displayed title
title = etree.SubElement(root, 'title') title = etree.SubElement(root, 'title')
title.text = unicode(oa_block.title) title.text = unicode(oa_block.title)
...@@ -746,6 +749,10 @@ def parse_from_xml(root): ...@@ -746,6 +749,10 @@ def parse_from_xml(root):
if 'allow_file_upload' in root.attrib: if 'allow_file_upload' in root.attrib:
allow_file_upload = _parse_boolean(unicode(root.attrib['allow_file_upload'])) allow_file_upload = _parse_boolean(unicode(root.attrib['allow_file_upload']))
allow_latex = False
if 'allow_latex' in root.attrib:
allow_latex = _parse_boolean(unicode(root.attrib['allow_latex']))
# Retrieve the title # Retrieve the title
title_el = root.find('title') title_el = root.find('title')
if title_el is None: if title_el is None:
...@@ -785,6 +792,7 @@ def parse_from_xml(root): ...@@ -785,6 +792,7 @@ def parse_from_xml(root):
'submission_start': submission_start, 'submission_start': submission_start,
'submission_due': submission_due, 'submission_due': submission_due,
'allow_file_upload': allow_file_upload, 'allow_file_upload': allow_file_upload,
'allow_latex': allow_latex,
'leaderboard_show': leaderboard_show 'leaderboard_show': leaderboard_show
} }
......
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