Commit 0ba747ef by Joe Blaylock

Merge pull request #30 from edx/jrbl/xblock_submit_return_type

Jrbl/xblock submit return type
parents 21daed03 9861f268
/* START CSS for OpenAssessmentBlock */ /* START CSS for OpenAssessmentBlock */
.openassessment_block .openassessment_question { .openassessment_block .openassessment_prompt {
font-weight: bold; font-weight: bold;
} }
...@@ -26,17 +26,17 @@ ...@@ -26,17 +26,17 @@
.openassessment_response_status_block .clickhere { .openassessment_response_status_block .clickhere {
font-size: small; font-size: small;
font-color: black; color: black;
font-weight: normal; font-weight: normal;
text-align: center; text-align: center;
} }
.openassessment_response_status_block .success { .openassessment_response_status_block .success {
font-color: green; color: green;
} }
.openassessment_response_status_block .failure { .openassessment_response_status_block .failure {
font-color: red; color: red;
} }
.clickhere_span { .clickhere_span {
......
<!-- START OpenAssessmentBlock HTML -->
<div class="openassessment_block" id="openassessment_block_${xblock_trace[0]}">
<p class="openassessment_prompt"
id="openassessment_rubric_instructions_${xblock_trace[0]}">${rubric_instructions}</p>
% for criterion in rubric_criteria:
<div>
<p class="openassessment_prompt">${criterion["instructions"]}</p>
% for value in sorted([k for k in criterion.keys() if k != 'name' and k != 'instructions']):
<input type="radio" value="${value}">${criterion[value]}</input>
% endfor
</div>
% endfor
<input type="button"
class="openassessment_submit" id="openassessment_submit_${xblock_trace[0]}" value="Submit" />
</div>
<div class="openassessment_response_status_block" id=openassessment_response_status_block_${xblock_trace[0]}">
This message should be invisible; please upgrade your browser.
</div>
<!-- END OpenAssessmentBlock HTML -->
<!-- START OpenAssessmentBlock HTML --> <!-- START OpenAssessmentBlock HTML -->
<div class="openassessment_block" id="openassessment_block_${xblock_trace[0]}"> <div class="openassessment_block" id="openassessment_block_${xblock_trace[0]}">
<p class="openassessment_question" id="openassessment_question_${xblock_trace[0]}">${question}</p> <p class="openassessment_prompt" id="openassessment_question_${xblock_trace[0]}">${question}</p>
<textarea class="openassessment_submission" id="openassessment_submission_${xblock_trace[0]}">Compose your response here</textarea> <textarea class="openassessment_submission" id="openassessment_submission_${xblock_trace[0]}">Compose your response here</textarea>
<input type="button" class="openassessment_submit" id="openassessment_submit_${xblock_trace[0]}" value="Submit" /> <input type="button" class="openassessment_submit" id="openassessment_submit_${xblock_trace[0]}" value="Submit" />
</div> </div>
<div class="openassessment_response_status_block" id=openassessment_response_status_block_${xblock_trace[0]}"> <div class="openassessment_response_status_block" id=openassessment_response_status_block_${xblock_trace[0]}">
This message should be invisible; consider upgrading your browser. This message should be invisible; please upgrade your browser.
</div> </div>
<!-- END OpenAssessmentBlock HTML --> <!-- END OpenAssessmentBlock HTML -->
/* START Javascript for OpenassessmentComposeXBlock. */
function OpenAssessmentBlock(runtime, element) {
var handlerUrl = runtime.handlerUrl(element, 'assess');
var success_msg = '<p class="success">Thanks for your feedback!</p>';
var failure_msg = '<p class="failure">An error occurred with your feedback</p>';
var click_msg = '<p class="clickhere">(click here to dismiss this message)</p>';
/* Sample Debug Console: http://localhost:8000/submissions/Joe_Bloggs/TestCourse/u_3 */
function displayStatus(result) {
status = result[0]
error_msg = result[1]
if (status) {
$('.openassessment_response_status_block', element).html(success_msg.concat(click_msg));
} else {
$('.openassessment_response_status_block', element).html(failure_msg.concat(error_msg).concat(click_msg));
}
$('.openassessment_response_status_block', element).css('display', 'block');
}
$('.openassessment_response_status_block', element).click(function(eventObject) {
$('.openassessment_response_status_block', element).css('display', 'none');
});
$('.openassessment_submit', element).click(function(eventObject) {
$.ajax({
type: "POST",
url: handlerUrl,
/* data: JSON.stringify({"submission": $('.openassessment_submission', element).val()}), */
data: JSON.stringify({"assessment": "I'm not sure how to stringify a form"}),
success: displayStatus
});
});
$(function ($) {
/* Here's where you'd do things on page load. */
$(element).css('background-color', 'LightBlue')
});
}
/* END Javascript for OpenassessmentComposeXBlock. */
/* START Javascript for OpenassessmentComposeXBlock. */ /* START Javascript for OpenassessmentComposeXBlock. */
function OpenAssessmentBlock(runtime, element) { function OpenAssessmentBlock(runtime, element) {
/* Sample Debug Console: http://localhost:8000/submissions/Joe_Bloggs/TestCourse/u_3 */ var handlerUrl = runtime.handlerUrl(element, 'submit');
var success_msg = '<p class="failure">Your submission has been received, thank you!</p>'; var success_msg = '<p class="success">Your submission has been received, thank you!</p>';
var failure_msg = '<p class="success">An error occurred with your submission</p>'; var failure_msg = '<p class="failure">An error occurred with your submission</p>';
var click_msg = '<p class="clickhere">(click here to dismiss this message)</p>'; var click_msg = '<p class="clickhere">(click here to dismiss this message)</p>';
/* Sample Debug Console: http://localhost:8000/submissions/Joe_Bloggs/TestCourse/u_3 */
function itWorked(result) { function displayStatus(result) {
if (itWorked) { status = result[0]
$('.openassessment_response_status_block', element).html(success_msg.concat(click_msg)); error_msg = result[2]
if (status) {
$('.openassessment_response_status_block', element).html(success_msg.concat(click_msg));
} else { } else {
$('.openassessment_response_status_block', element).html(failure_msg.concat(click_msg)); $('.openassessment_response_status_block', element).html(failure_msg.concat(error_msg).concat(click_msg));
} }
$('.openassessment_response_status_block', element).css('display', 'block'); $('.openassessment_response_status_block', element).css('display', 'block');
} }
...@@ -18,13 +21,12 @@ function OpenAssessmentBlock(runtime, element) { ...@@ -18,13 +21,12 @@ function OpenAssessmentBlock(runtime, element) {
$('.openassessment_response_status_block', element).css('display', 'none'); $('.openassessment_response_status_block', element).css('display', 'none');
}); });
var handlerUrl = runtime.handlerUrl(element, 'submit');
$('.openassessment_submit', element).click(function(eventObject) { $('.openassessment_submit', element).click(function(eventObject) {
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: handlerUrl, url: handlerUrl,
data: JSON.stringify({"submission": $('.openassessment_submission', element).val()}), data: JSON.stringify({"submission": $('.openassessment_submission', element).val()}),
success: itWorked success: displayStatus
}); });
}); });
......
...@@ -10,7 +10,7 @@ from mock import patch ...@@ -10,7 +10,7 @@ from mock import patch
from workbench.runtime import WorkbenchRuntime from workbench.runtime import WorkbenchRuntime
from submissions import api from submissions import api
from submissions.api import SubmissionInternalError from submissions.api import SubmissionRequestError, SubmissionInternalError
class TestOpenAssessment(TestCase): class TestOpenAssessment(TestCase):
...@@ -28,6 +28,7 @@ class TestOpenAssessment(TestCase): ...@@ -28,6 +28,7 @@ class TestOpenAssessment(TestCase):
/> />
""", self.runtime.id_generator) """, self.runtime.id_generator)
self.assessment = self.runtime.get_block(assessment_id) self.assessment = self.runtime.get_block(assessment_id)
self.default_json_submission = json.dumps({"submission": "This is my answer to this test question!"})
def make_request(self, body): def make_request(self, body):
"""Mock request method.""" """Mock request method."""
...@@ -35,49 +36,44 @@ class TestOpenAssessment(TestCase): ...@@ -35,49 +36,44 @@ class TestOpenAssessment(TestCase):
request.body = body request.body = body
return request return request
def text_of_response(self, response):
"""Return the text of response."""
return "".join(response.app_iter)
def test_submit_submission(self): def test_submit_submission(self):
""" """XBlock accepts response, returns true on success."""
Verify we can submit an answer to the XBlock and get the expected return
value.
"""
json_data = json.dumps(
{"submission": "This is my answer to this test question!"}
)
resp = self.runtime.handle( resp = self.runtime.handle(
self.assessment, 'submit', self.assessment, 'submit',
self.make_request(json_data) self.make_request(self.default_json_submission)
) )
result = self.text_of_response(resp) result = json.loads(resp.body)
self.assertEqual("true", result) self.assertTrue(result[0])
@patch.object(api, 'create_submission') @patch.object(api, 'create_submission')
def test_submission_failure(self, mock_submit): def test_submission_general_failure(self, mock_submit):
""" """Internal errors return some code for submission failure."""
Nothing from the front end currently causes an exception. However the
backend could have an internal error that will bubble up. This will
mock an internal error and ensure the front end returns the proper
value.
"""
mock_submit.side_effect = SubmissionInternalError("Cat on fire.") mock_submit.side_effect = SubmissionInternalError("Cat on fire.")
json_data = json.dumps( resp = self.runtime.handle(
{"submission": "This is my answer to this test question!"} self.assessment, 'submit',
self.make_request(self.default_json_submission)
) )
result = json.loads(resp.body)
self.assertFalse(result[0])
self.assertEqual(result[1], "EUNKNOWN")
self.assertEqual(result[2], self.assessment.submit_errors["EUNKNOWN"])
@patch.object(api, 'create_submission')
def test_submission_API_failure(self, mock_submit):
"""API usage errors return code and meaningful message."""
mock_submit.side_effect = SubmissionRequestError("Cat on fire.")
resp = self.runtime.handle( resp = self.runtime.handle(
self.assessment, 'submit', self.assessment, 'submit',
self.make_request(json_data) self.make_request(self.default_json_submission)
) )
result = self.text_of_response(resp) result = json.loads(resp.body)
self.assertEquals("false", result) self.assertFalse(result[0])
self.assertEqual(result[1], "EBADFORM")
self.assertEqual(result[2], "Cat on fire.")
def test_load_student_view(self): def test_load_student_view(self):
""" """OA XBlock returns some HTML to the user.
View basic test for verifying we're returned some HTML about the View basic test for verifying we're returned some HTML about the
Open Assessment XBlock. We don't want to match too heavily against the Open Assessment XBlock. We don't want to match too heavily against the
contents. contents.
......
...@@ -8,3 +8,4 @@ django-extensions==1.3.3 ...@@ -8,3 +8,4 @@ django-extensions==1.3.3
djangorestframework==2.3.5 djangorestframework==2.3.5
Mako==0.9.1 Mako==0.9.1
pytz==2013.9 pytz==2013.9
django-pdb==0.3.2
...@@ -107,6 +107,7 @@ MIDDLEWARE_CLASSES = ( ...@@ -107,6 +107,7 @@ MIDDLEWARE_CLASSES = (
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
# Uncomment the next line for simple clickjacking protection: # Uncomment the next line for simple clickjacking protection:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware', # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django_pdb.middleware.PdbMiddleware', # Needed to enable shell-on-crash behavior
) )
ROOT_URLCONF = 'urls' ROOT_URLCONF = 'urls'
...@@ -130,6 +131,7 @@ INSTALLED_APPS = ( ...@@ -130,6 +131,7 @@ INSTALLED_APPS = (
# Third party # Third party
'django_extensions', 'django_extensions',
'django_pdb', # Allows post-mortem debugging on exceptions
# XBlock # XBlock
'workbench', 'workbench',
......
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