Commit a584f06b by Victor Shnayder

Add support for varying max_score.

parent d0e2b85e
...@@ -34,9 +34,10 @@ class MockStaffGradingService(object): ...@@ -34,9 +34,10 @@ class MockStaffGradingService(object):
return json.dumps({'success': True, return json.dumps({'success': True,
'submission_id': self.cnt, 'submission_id': self.cnt,
'submission': 'Test submission {cnt}'.format(cnt=self.cnt), 'submission': 'Test submission {cnt}'.format(cnt=self.cnt),
'max_score': 2 + self.cnt % 3,
'rubric': 'A rubric'}) 'rubric': 'A rubric'})
def save_grade(self, course_id, submission_id, score, feedback): def save_grade(self, course_id, grader_id, submission_id, score, feedback):
return self.get_next(course_id) return self.get_next(course_id)
...@@ -62,16 +63,23 @@ class StaffGradingService(object): ...@@ -62,16 +63,23 @@ class StaffGradingService(object):
return r.text return r.text
def save_grade(self, course_id, submission_id, score, feedback): def save_grade(self, course_id, grader_id, submission_id, score, feedback):
""" """
Save a grade. Save a score and feedback for a submission.
TODO: what is data? Returns json dict with keys
'success': bool
'error': error msg, if something went wrong.
Returns json, or raises GradingServiceError if there's a problem. Raises GradingServiceError if there's a problem connecting.
""" """
try: try:
r = self.session.get(self.url + 'save_grade') data = {'course_id': course_id,
'submission_id': submission_id,
'score': score,
'feedback': feedback,
'grader_id': grader}
r = self.session.post(self.url + 'save_grade')
except requests.exceptions.ConnectionError as err: except requests.exceptions.ConnectionError as err:
# reraise as promised GradingServiceError, but preserve stacktrace. # reraise as promised GradingServiceError, but preserve stacktrace.
raise GradingServiceError, str(err), sys.exc_info()[2] raise GradingServiceError, str(err), sys.exc_info()[2]
...@@ -163,7 +171,11 @@ def save_grade(request, course_id): ...@@ -163,7 +171,11 @@ def save_grade(request, course_id):
p = request.POST p = request.POST
try: try:
result_json = _service.save_grade(course_id, p['submission_id'], p['score'], p['feedback']) result_json = _service.save_grade(course_id,
request.user.id,
p['submission_id'],
p['score'],
p['feedback'])
except GradingServiceError: except GradingServiceError:
log.exception("Error saving grade") log.exception("Error saving grade")
return _err_response('Could not connect to grading service') return _err_response('Could not connect to grading service')
......
...@@ -112,15 +112,9 @@ class TestInstructorDashboardForumAdmin(ct.PageLoader): ...@@ -112,15 +112,9 @@ class TestInstructorDashboardForumAdmin(ct.PageLoader):
xmodule.modulestore.django._MODULESTORES = {} xmodule.modulestore.django._MODULESTORES = {}
courses = modulestore().get_courses() courses = modulestore().get_courses()
<<<<<<< HEAD
self.full = modulestore().get_course("edX/full/6.002_Spring_2012")
self.toy = modulestore().get_course("edX/toy/2012_Fall")
=======
self.course_id = "edX/toy/2012_Fall" self.course_id = "edX/toy/2012_Fall"
self.toy = modulestore().get_course(self.course_id) self.toy = modulestore().get_course(self.course_id)
>>>>>>> Refactor testing code, hook up frontend.
# Create two accounts # Create two accounts
self.student = 'view@test.com' self.student = 'view@test.com'
...@@ -236,9 +230,6 @@ class TestStaffGradingService(ct.PageLoader): ...@@ -236,9 +230,6 @@ class TestStaffGradingService(ct.PageLoader):
access control and error handling logic -- all the actual work is on the access control and error handling logic -- all the actual work is on the
backend. backend.
''' '''
def setUp(self): def setUp(self):
xmodule.modulestore.django._MODULESTORES = {} xmodule.modulestore.django._MODULESTORES = {}
...@@ -265,8 +256,6 @@ class TestStaffGradingService(ct.PageLoader): ...@@ -265,8 +256,6 @@ class TestStaffGradingService(ct.PageLoader):
self.check_for_get_code(404, url) self.check_for_get_code(404, url)
self.check_for_post_code(404, url) self.check_for_post_code(404, url)
<<<<<<< HEAD
=======
@patch.object(staff_grading_service, '_service', _mock_service) @patch.object(staff_grading_service, '_service', _mock_service)
def test_get_next(self): def test_get_next(self):
...@@ -286,11 +275,12 @@ class TestStaffGradingService(ct.PageLoader): ...@@ -286,11 +275,12 @@ class TestStaffGradingService(ct.PageLoader):
url = reverse('staff_grading_save_grade', kwargs={'course_id': self.course_id}) url = reverse('staff_grading_save_grade', kwargs={'course_id': self.course_id})
data = {'score': '12', 'feedback': 'great!', 'submission_id': '123'} data = {'score': '12',
'feedback': 'great!',
'submission_id': '123'}
r = self.check_for_post_code(200, url, data) r = self.check_for_post_code(200, url, data)
d = json.loads(r.content) d = json.loads(r.content)
self.assertTrue(d['success'], str(d)) self.assertTrue(d['success'], str(d))
self.assertEquals(d['submission_id'], _mock_service.cnt) self.assertEquals(d['submission_id'], _mock_service.cnt)
>>>>>>> Refactor testing code, hook up frontend.
...@@ -18,21 +18,19 @@ class StaffGradingBackend ...@@ -18,21 +18,19 @@ class StaffGradingBackend
mock: (cmd, data) -> mock: (cmd, data) ->
# Return a mock response to cmd and data # Return a mock response to cmd and data
@mock_cnt++
if cmd == 'get_next' if cmd == 'get_next'
@mock_cnt++
response = response =
success: true success: true
submission: 'submission! ' + @mock_cnt submission: 'submission! ' + @mock_cnt
rubric: 'A rubric! ' + @mock_cnt rubric: 'A rubric! ' + @mock_cnt
submission_id: @mock_cnt submission_id: @mock_cnt
max_score: 2 + @mock_cnt % 3
else if cmd == 'save_grade' else if cmd == 'save_grade'
console.log("eval: #{data.score} pts, Feedback: #{data.feedback}") console.log("eval: #{data.score} pts, Feedback: #{data.feedback}")
response = response =
success: true @mock('get_next', {})
submission: 'another submission! ' + @mock_cnt
rubric: 'A rubric!' + @mock_cnt
submission_id: @mock_cnt
else else
response = response =
success: false success: false
...@@ -72,6 +70,7 @@ class StaffGrading ...@@ -72,6 +70,7 @@ class StaffGrading
@submission_wrapper = $('.submission-wrapper') @submission_wrapper = $('.submission-wrapper')
@rubric_wrapper = $('.rubric-wrapper') @rubric_wrapper = $('.rubric-wrapper')
@feedback_area = $('.feedback-area') @feedback_area = $('.feedback-area')
@score_selection_container = $('.score-selection-container')
@submit_button = $('.submit-button') @submit_button = $('.submit-button')
# model state # model state
...@@ -81,15 +80,12 @@ class StaffGrading ...@@ -81,15 +80,12 @@ class StaffGrading
@rubric = '' @rubric = ''
@error_msg = '' @error_msg = ''
@message = '' @message = ''
@max_score = 0
@score = null @score = null
# action handlers # action handlers
@submit_button.click @submit @submit_button.click @submit
# TODO: hook up an event to the input changing, which updates
# @score (instead of the individual hacks)
$('#correct-radio').click @graded_callback
$('#incorrect-radio').click @graded_callback
# render intial state # render intial state
@render_view() @render_view()
...@@ -98,6 +94,24 @@ class StaffGrading ...@@ -98,6 +94,24 @@ class StaffGrading
@get_next_submission() @get_next_submission()
setup_score_selection: =>
# first, get rid of all the old inputs, if any.
@score_selection_container.html('')
# Now create new labels and inputs for each possible score.
for score in [1..@max_score]
id = 'score-' + score
label = """<label for="#{id}">#{score}</label>"""
input = """
<input type="radio" name="score-selection" id="#{id}" value="#{score}"/>
"""
@score_selection_container.append(label + input)
# And now hook up an event handler again
$("input[name='score-selection']").change @graded_callback
set_button_text: (text) => set_button_text: (text) =>
@submit_button.attr('value', text) @submit_button.attr('value', text)
...@@ -113,7 +127,7 @@ class StaffGrading ...@@ -113,7 +127,7 @@ class StaffGrading
if response.success if response.success
if response.submission if response.submission
@data_loaded(response.submission, response.rubric, response.submission_id) @data_loaded(response.submission, response.rubric, response.submission_id, response.max_score)
else else
@no_more(response.message) @no_more(response.message)
else else
...@@ -136,11 +150,12 @@ class StaffGrading ...@@ -136,11 +150,12 @@ class StaffGrading
@error_msg = msg @error_msg = msg
@state = state_error @state = state_error
data_loaded: (submission, rubric, submission_id) -> data_loaded: (submission, rubric, submission_id, max_score) ->
@submission = submission @submission = submission
@rubric = rubric @rubric = rubric
@submission_id = submission_id @submission_id = submission_id
@feedback_area.val('') @feedback_area.val('')
@max_score = max_score
@score = null @score = null
@state = state_grading @state = state_grading
...@@ -149,6 +164,8 @@ class StaffGrading ...@@ -149,6 +164,8 @@ class StaffGrading
@rubric = null @rubric = null
@submission_id = null @submission_id = null
@message = message @message = message
@score = null
@max_score = 0
@state = state_no_data @state = state_no_data
render_view: () -> render_view: () ->
...@@ -157,6 +174,9 @@ class StaffGrading ...@@ -157,6 +174,9 @@ class StaffGrading
show_submit_button = true show_submit_button = true
@message_container.html(@message) @message_container.html(@message)
if @backend.mock_backend
@message_container.append("<p>NOTE: Mocking backend.</p>")
@error_container.html(@error_msg) @error_container.html(@error_msg)
if @state == state_error if @state == state_error
...@@ -170,10 +190,8 @@ class StaffGrading ...@@ -170,10 +190,8 @@ class StaffGrading
# no submit button until user picks grade. # no submit button until user picks grade.
show_submit_button = false show_submit_button = false
# TODO: clean up with proper input-related logic @setup_score_selection()
$('#correct-radio')[0].checked = false
$('#incorrect-radio')[0].checked = false
else if @state == state_graded else if @state == state_graded
show_grading_elements = true show_grading_elements = true
@set_button_text('Submit') @set_button_text('Submit')
...@@ -204,7 +222,7 @@ class StaffGrading ...@@ -204,7 +222,7 @@ class StaffGrading
# for now, just create an instance and load it... # for now, just create an instance and load it...
mock_backend = false mock_backend = true
ajax_url = $('.staff-grading').data('ajax_url') ajax_url = $('.staff-grading').data('ajax_url')
backend = new StaffGradingBackend(ajax_url, mock_backend) backend = new StaffGradingBackend(ajax_url, mock_backend)
......
...@@ -30,11 +30,7 @@ ...@@ -30,11 +30,7 @@
<div class="evaluation"> <div class="evaluation">
<textarea name="feedback" placeholder="Feedback for student..." <textarea name="feedback" placeholder="Feedback for student..."
class="feedback-area" cols="70" rows="10"></textarea> class="feedback-area" cols="70" rows="10"></textarea>
<p> <p class="score-selection-container">
<label for="correct-radio">Correct</label>
<input type="radio" name="score-selection" id="correct-radio" value="1">
<label for="incorrect-radio">Incorrect</label>
<input type="radio" name="score-selection" id="incorrect-radio" value="0">
</p> </p>
</div> </div>
......
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