Commit cff20069 by Braden MacDonald

Clean up the submit handlers

parent f7a0d156
...@@ -26,7 +26,7 @@ import json ...@@ -26,7 +26,7 @@ import json
from collections import namedtuple from collections import namedtuple
from xblock.core import XBlock from xblock.core import XBlock
from xblock.exceptions import NoSuchViewError from xblock.exceptions import NoSuchViewError, JsonHandlerError
from xblock.fields import Boolean, Scope, String, Integer, Float, List from xblock.fields import Boolean, Scope, String, Integer, Float, List
from xblock.fragment import Fragment from xblock.fragment import Fragment
from xblock.validation import ValidationMessage from xblock.validation import ValidationMessage
...@@ -468,6 +468,14 @@ class MentoringBlock(XBlock, StepParentMixin, StudioEditableXBlockMixin, StudioC ...@@ -468,6 +468,14 @@ class MentoringBlock(XBlock, StepParentMixin, StudioEditableXBlockMixin, StudioC
@XBlock.json_handler @XBlock.json_handler
def submit(self, submissions, suffix=''): def submit(self, submissions, suffix=''):
log.info(u'Received submissions: {}'.format(submissions)) log.info(u'Received submissions: {}'.format(submissions))
# server-side check that the user is allowed to submit:
if self.max_attempts_reached:
raise JsonHandlerError(403, "Maximum number of attempts already reached.")
elif self.has_missing_dependency:
raise JsonHandlerError(
403,
"You need to complete all previous steps before being able to complete the current one."
)
# This has now been attempted: # This has now been attempted:
self.attempted = True self.attempted = True
...@@ -476,6 +484,7 @@ class MentoringBlock(XBlock, StepParentMixin, StudioEditableXBlockMixin, StudioC ...@@ -476,6 +484,7 @@ class MentoringBlock(XBlock, StepParentMixin, StudioEditableXBlockMixin, StudioC
return self.handle_assessment_submit(submissions, suffix) return self.handle_assessment_submit(submissions, suffix)
submit_results = [] submit_results = []
previously_completed = self.completed
completed = True completed = True
for child_id in self.steps: for child_id in self.steps:
child = self.runtime.get_block(child_id) child = self.runtime.get_block(child_id)
...@@ -486,37 +495,30 @@ class MentoringBlock(XBlock, StepParentMixin, StudioEditableXBlockMixin, StudioC ...@@ -486,37 +495,30 @@ class MentoringBlock(XBlock, StepParentMixin, StudioEditableXBlockMixin, StudioC
child.save() child.save()
completed = completed and (child_result['status'] == 'correct') completed = completed and (child_result['status'] == 'correct')
# Once it has been completed once, keep completion even if user changes values if completed and self.next_step == self.url_name:
if self.completed:
completed = True
# server-side check to not set completion if the max_attempts is reached
if self.max_attempts_reached:
completed = False
if self.has_missing_dependency:
completed = False
message = 'You need to complete all previous steps before being able to complete the current one.'
elif completed and self.next_step == self.url_name:
self.next_step = self.followed_by self.next_step = self.followed_by
# Once it was completed, lock score # Update the score and attempts, unless the user had already achieved a perfect score ("completed"):
if not self.completed: if not previously_completed:
# save user score and results # Update the results
while self.student_results: while self.student_results:
self.student_results.pop() self.student_results.pop()
for result in submit_results: for result in submit_results:
self.student_results.append(result) self.student_results.append(result)
# Save the user's latest score
self.runtime.publish(self, 'grade', { self.runtime.publish(self, 'grade', {
'value': self.score.raw, 'value': self.score.raw,
'max_value': 1, 'max_value': 1,
}) })
if not self.completed and self.max_attempts > 0: # Mark this as having used an attempt:
self.num_attempts += 1 if self.max_attempts > 0:
self.num_attempts += 1
self.completed = completed is True # Save the completion status.
# Once it has been completed once, keep completion even if user changes values
self.completed = bool(completed) or previously_completed
message = self.get_message(completed) message = self.get_message(completed)
raw_score = self.score.raw raw_score = self.score.raw
...@@ -570,14 +572,13 @@ class MentoringBlock(XBlock, StepParentMixin, StudioEditableXBlockMixin, StudioC ...@@ -570,14 +572,13 @@ class MentoringBlock(XBlock, StepParentMixin, StudioEditableXBlockMixin, StudioC
if current_child == steps[-1]: if current_child == steps[-1]:
log.info(u'Last assessment step submitted: {}'.format(submissions)) log.info(u'Last assessment step submitted: {}'.format(submissions))
if not self.max_attempts_reached: self.runtime.publish(self, 'grade', {
self.runtime.publish(self, 'grade', { 'value': score.raw,
'value': score.raw, 'max_value': 1,
'max_value': 1, 'score_type': 'proficiency',
'score_type': 'proficiency', })
}) event_data['final_grade'] = score.raw
event_data['final_grade'] = score.raw assessment_message = self.assessment_message
assessment_message = self.assessment_message
self.num_attempts += 1 self.num_attempts += 1
self.completed = True self.completed = True
......
...@@ -32,6 +32,24 @@ function MentoringStandardView(runtime, element, mentoring) { ...@@ -32,6 +32,24 @@ function MentoringStandardView(runtime, element, mentoring) {
submitDOM.attr('disabled', 'disabled'); submitDOM.attr('disabled', 'disabled');
} }
function handleSubmitError(jqXHR, textStatus, errorThrown) {
if (textStatus == "error") {
var errMsg = errorThrown;
// Check if there's a more specific JSON error message:
if (jqXHR.responseText) {
// Is there a more specific error message we can show?
try {
errMsg = JSON.parse(jqXHR.responseText).error;
} catch (error) { errMsg = jqXHR.responseText.substr(0, 300); }
}
mentoring.setContent(messagesDOM, errMsg);
messagesDOM.show();
submitDOM.attr('disabled', 'disabled');
}
}
function calculate_results(handler_name) { function calculate_results(handler_name) {
var data = {}; var data = {};
var children = mentoring.children; var children = mentoring.children;
...@@ -45,7 +63,7 @@ function MentoringStandardView(runtime, element, mentoring) { ...@@ -45,7 +63,7 @@ function MentoringStandardView(runtime, element, mentoring) {
if (submitXHR) { if (submitXHR) {
submitXHR.abort(); submitXHR.abort();
} }
submitXHR = $.post(handlerUrl, JSON.stringify(data)).success(handleSubmitResults); submitXHR = $.post(handlerUrl, JSON.stringify(data)).success(handleSubmitResults).error(handleSubmitError);
} }
function submit() { function submit() {
......
...@@ -68,6 +68,7 @@ class MentoringProgressionTest(MentoringBaseTest): ...@@ -68,6 +68,7 @@ class MentoringProgressionTest(MentoringBaseTest):
answer = mentoring.find_element_by_css_selector('textarea') answer = mentoring.find_element_by_css_selector('textarea')
answer.send_keys('This is the answer') answer.send_keys('This is the answer')
submit = mentoring.find_element_by_css_selector('.submit input.input-main') submit = mentoring.find_element_by_css_selector('.submit input.input-main')
self.assertTrue(submit.is_displayed() and submit.is_enabled())
submit.click() submit.click()
self.wait_until_disabled(submit) self.wait_until_disabled(submit)
...@@ -90,6 +91,7 @@ class MentoringProgressionTest(MentoringBaseTest): ...@@ -90,6 +91,7 @@ class MentoringProgressionTest(MentoringBaseTest):
answer = mentoring.find_element_by_css_selector('textarea') answer = mentoring.find_element_by_css_selector('textarea')
answer.send_keys('This is the answer') answer.send_keys('This is the answer')
submit = mentoring.find_element_by_css_selector('.submit input.input-main') submit = mentoring.find_element_by_css_selector('.submit input.input-main')
self.assertTrue(submit.is_displayed() and submit.is_enabled())
submit.click() submit.click()
self.wait_until_disabled(submit) self.wait_until_disabled(submit)
self.assert_warning_is_hidden(mentoring) self.assert_warning_is_hidden(mentoring)
...@@ -106,7 +108,11 @@ class MentoringProgressionTest(MentoringBaseTest): ...@@ -106,7 +108,11 @@ class MentoringProgressionTest(MentoringBaseTest):
# Complete step 2 - no more warnings anywhere # Complete step 2 - no more warnings anywhere
submit = mentoring.find_element_by_css_selector('.submit input.input-main') submit = mentoring.find_element_by_css_selector('.submit input.input-main')
submit.click() # Already filled the textarea in previous step answer = mentoring.find_element_by_css_selector('textarea')
self.assertEqual(answer.text, "") # Earlier attempt to submit did not save
answer.send_keys('This is the answer')
self.assertTrue(submit.is_displayed() and submit.is_enabled())
submit.click()
self.wait_until_disabled(submit) self.wait_until_disabled(submit)
messages = mentoring.find_element_by_css_selector('.messages') messages = mentoring.find_element_by_css_selector('.messages')
......
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