Commit 202e4823 by Diana Huang Committed by Andy Armstrong

Add new staff grading events.

parent 370b0d43
......@@ -266,6 +266,13 @@ class StaffAreaMixin(object):
submission_to_assess = staff_api.get_submission_to_assess(course_id, item_id, staff_id)
if submission_to_assess is not None:
# This is posting a tracking event to the runtime.
self.runtime.publish(self, 'openassessmentblock.get_submission_for_staff_grading', {
'type': 'full-grade',
'requesting_staff_id': staff_id,
'item_id': item_id,
'submission_returned_uuid': submission_to_assess['uuid']
})
submission = submission_api.get_submission_and_student(submission_to_assess['uuid'])
if submission:
anonymous_student_id = submission['student_item']['student_id']
......
......@@ -51,7 +51,8 @@ class StaffAssessmentMixin(object):
data['overall_feedback'],
create_rubric_dict(self.prompts, self.rubric_criteria_with_labels)
)
self.publish_assessment_event("openassessmentblock.staff_assess", assessment, type='full-grade')
assess_type = data.get('assess_type', 'regrade')
self.publish_assessment_event("openassessmentblock.staff_assess", assessment, type=assess_type)
workflow_api.update_from_assessments(assessment["submission_uuid"], None)
except StaffAssessmentRequestError:
......
......@@ -141,10 +141,17 @@ describe('OpenAssessment.StaffAreaView', function() {
};
var submitAssessment = function(staffArea, tab) {
spyOn(staffArea, 'callStaffAssess').and.callThrough();
var $submitButton = $('.action--submit', getAssessment(staffArea, tab));
$submitButton.click();
};
var verifyAssessType = function(staffArea, assessType) {
expect(staffArea.callStaffAssess).toHaveBeenCalledWith(
jasmine.any(String), jasmine.any(Object), jasmine.any(Object), jasmine.any(Function), jasmine.any(String), assessType
);
};
beforeEach(function() {
// Create a new stub server
server = new StubServer();
......@@ -470,6 +477,8 @@ describe('OpenAssessment.StaffAreaView', function() {
server.studentTemplate = 'oa_staff_graded_submission.html';
submitAssessment(staffArea, staffAreaTab);
verifyAssessType(staffArea, 'regrade');
// Verify that the student info is visible and shows the correct score
$gradeSection = $('.staff-info__student__grade', staffArea.element);
expect($('.ui-toggle-visibility', $gradeSection)).not.toHaveClass('is--collapsed');
......@@ -573,6 +582,7 @@ describe('OpenAssessment.StaffAreaView', function() {
fillAssessment($assessment);
server.staffGradeFormTemplate = 'oa_staff_grade_learners_assessment_2.html';
submitAssessment(staffArea, staffAreaTab);
verifyAssessType(staffArea, 'full-grade');
// Verify that the assessment form has been removed
expect($('.staff__grade__form', staffArea.element).html().trim()).toBe('');
......
......@@ -452,7 +452,7 @@
// the staff override itself.
view.loadStudentInfo({expanded_view: 'final-grade'});
};
this.callStaffAssess(submissionID, rubric, scope, successCallback, '.staff-override-error');
this.callStaffAssess(submissionID, rubric, scope, successCallback, '.staff-override-error', 'regrade');
},
/**
......@@ -475,7 +475,7 @@
view.baseView.scrollToTop(".openassessment__staff-area");
}
};
this.callStaffAssess(submissionID, rubric, scope, successCallback, '.staff-grade-error');
this.callStaffAssess(submissionID, rubric, scope, successCallback, '.staff-grade-error', 'full-grade');
},
/**
......@@ -487,13 +487,14 @@
* classes in different form).
* @param {function} successCallback A function to execute on success.
* @param {string} errorSelector a CSS class selector for displaying error messages.
* @param {string} assessType a string indicating whether this was a 'full-grade' or 'regrade'
*/
callStaffAssess: function(submissionID, rubric, scope, successCallback, errorSelector) {
callStaffAssess: function(submissionID, rubric, scope, successCallback, errorSelector, assessType) {
var view = this;
view.staffSubmitEnabled(scope, false);
this.server.staffAssess(
rubric.optionsSelected(), rubric.criterionFeedback(), rubric.overallFeedback(), submissionID
rubric.optionsSelected(), rubric.criterionFeedback(), rubric.overallFeedback(), submissionID, assessType
).done(successCallback).fail(function(errorMessage) {
scope.find(errorSelector).html(_.escape(errorMessage));
view.staffSubmitEnabled(scope, true);
......
......@@ -318,15 +318,17 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
* e.g. { clarity: "The essay was very clear." }
* @param {string} overallFeedback - A string with the staff member's overall feedback.
* @param {string} submissionID - The ID of the submission being assessed.
* @param {string} assessType a string indicating whether this was a 'full-grade' or 'regrade'
* @returns {promise} A promise which resolves with no arguments if successful,
* and which fails with an error message otherwise.
*/
staffAssess: function(optionsSelected, criterionFeedback, overallFeedback, submissionID) {
staffAssess: function(optionsSelected, criterionFeedback, overallFeedback, submissionID, assessType) {
return this.submitAssessment("staff_assess", {
options_selected: optionsSelected,
criterion_feedback: criterionFeedback,
overall_feedback: overallFeedback,
submission_uuid: submissionID
submission_uuid: submissionID,
assess_type: assessType
});
},
......
......@@ -53,7 +53,8 @@ STAFF_GOOD_ASSESSMENT = {
u'𝓒𝓸𝓷𝓬𝓲𝓼𝓮': u'Staff: ฝﻉɭɭ ɗѻกﻉ!',
u'Form': u'Staff: ƒαιя נσв'
},
'overall_feedback': u'Staff: good job!'
'overall_feedback': u'Staff: good job!',
'assess_type': 'full-grade'
}
# A sample bad staff assessment
......@@ -63,7 +64,8 @@ STAFF_BAD_ASSESSMENT = {
u'𝓒𝓸𝓷𝓬𝓲𝓼𝓮': u'Staff: ק๏๏г נσв',
u'Form': u'Staff: ק๏๏г נσв'
},
'overall_feedback': u'Staff: very poor'
'overall_feedback': u'Staff: very poor',
'assess_type': 'full-grade'
}
......
......@@ -163,6 +163,20 @@ class TestStaffAssessment(StaffAssessmentTestBase):
self.assert_assessment_event_published(xblock, 'openassessmentblock.staff_assess', assessment, type='full-grade')
@scenario('data/self_assessment_scenario.xml', user_id='Bob')
def test_staff_assess_handler_regrade(self, xblock):
student_item = xblock.get_student_item_dict()
# Create a submission for the student
submission = xblock.create_submission(student_item, self.SUBMISSION)
assessment_copy = copy.copy(STAFF_GOOD_ASSESSMENT)
assessment_copy['assess_type'] = 'regrade'
# Submit a staff-assessment
self.submit_staff_assessment(xblock, submission, assessment=assessment_copy)
assessment = staff_api.get_latest_staff_assessment(submission['uuid'])
self.assert_assessment_event_published(xblock, 'openassessmentblock.staff_assess', assessment, type='regrade')
@scenario('data/self_assessment_scenario.xml', user_id='Bob')
def test_permission_error(self, xblock):
# Create a submission for the student
student_item = xblock.get_student_item_dict()
......@@ -181,11 +195,14 @@ class TestStaffAssessment(StaffAssessmentTestBase):
STAFF_GOOD_ASSESSMENT['submission_uuid'] = submission['uuid']
for key in STAFF_GOOD_ASSESSMENT:
assessment_copy = copy.copy(STAFF_GOOD_ASSESSMENT)
del assessment_copy[key]
resp = self.request(xblock, 'staff_assess', json.dumps(assessment_copy), response_format='json')
self.assertFalse(resp['success'])
self.assertIn('msg', resp)
# We don't want to fail if the assess_type is not submitted to the
# backend, since it's only used for eventing right now.
if key != 'assess_type':
assessment_copy = copy.copy(STAFF_GOOD_ASSESSMENT)
del assessment_copy[key]
resp = self.request(xblock, 'staff_assess', json.dumps(assessment_copy), response_format='json')
self.assertFalse(resp['success'])
self.assertIn('msg', resp)
@scenario('data/self_assessment_scenario.xml', user_id='bob')
def test_assessment_error(self, xblock):
......
......@@ -675,12 +675,20 @@ class TestCourseStaff(XBlockHandlerTestCase):
bob_item = STUDENT_ITEM.copy()
bob_item["item_id"] = xblock.scope_ids.usage_id
# Create a submission for Bob, and corresponding workflow.
self._create_submission(bob_item, {'text': submission_text}, [])
submission = self._create_submission(bob_item, {'text': submission_text}, [])
resp = self.request(xblock, 'render_staff_grade_form', json.dumps({})).decode('utf-8')
self.assertNotIn(no_submissions_available, resp)
self.assertIn(submission_text, resp)
self.assert_event_published(xblock, 'openassessmentblock.get_submission_for_staff_grading', {
'type': 'full-grade',
'requesting_staff_id': 'Bob',
'item_id': bob_item['item_id'],
'submission_returned_uuid': submission['uuid']
})
def _verify_staff_assessment_context(self, context, required, ungraded=None, in_progress=None):
self.assertEquals(required, context['staff_assessment_required'])
if not required:
......
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