def test_no_peer_assessment_error_handled(self, mock_get_workflow, mock_get_staff_score): """ Tests to verify that, given a problem that requires the peer step and a submission associated with a workflow that has no assessments, an overriding staff score will push the workflow into the done state and not crash when there are no assessments in the "completed" peer step. """ mock_get_workflow.raises = PeerWorkflow.DoesNotExist mock_get_staff_score.return_value = { "points_earned": 10, "points_possible": 10, "contributing_assessments": 123, "staff_id": "staff 1", } _, submission = self._create_workflow_with_status( "user 1", "test/1/1", "peer-problem", "peer", steps=["peer"] ) workflow_api.update_from_assessments( submission["uuid"], { "peer": { "must_grade": 5, "must_be_graded_by": 3 } }, override_submitter_requirements=True )
def test_unable_to_load_api(self): submission = sub_api.create_submission({ "student_id": "test student", "course_id": "test course", "item_id": "test item", "item_type": "openassessment", }, "test answer") with self.assertRaises(AssessmentWorkflowInternalError): workflow_api.create_workflow(submission['uuid'], ['self']) with self.assertRaises(AssessmentWorkflowInternalError): workflow_api.update_from_assessments(submission['uuid'], {})
def _create_dummy_submission(self, student_item): """ Create a dummy submission for a student. Args: student_item (dict): Serialized StudentItem model. Returns: str: submission UUID """ answer = {'text': " ".join(loremipsum.get_paragraphs(5))} submission = sub_api.create_submission(student_item, answer) workflow_api.create_workflow(submission['uuid'], STEPS) workflow_api.update_from_assessments( submission['uuid'], {'peer': {'must_grade': 1, 'must_be_graded_by': 1}} ) return submission['uuid']
def staff_assess(self, data, suffix=''): """ Create a staff assessment from a staff submission. """ if 'submission_uuid' not in data: return { 'success': False, 'msg': self._(u"The submission ID of the submission being assessed was not found.") } try: assessment = staff_api.create_assessment( data['submission_uuid'], self.get_student_item_dict()["student_id"], data['options_selected'], clean_criterion_feedback(self.rubric_criteria, data['criterion_feedback']), data['overall_feedback'], create_rubric_dict(self.prompts, self.rubric_criteria_with_labels) ) 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) student_item = sub_api.get_submission_and_student(data['submission_uuid']).get('student_item', None) if student_item: student_id = student_item.get('student_id', None) if student_id: student_email = self.get_user_email(student_id) send_notification_for_assessment.delay(student_email, 'staff', "{0}".format(self.course_id), "{0}".format(self.scope_ids.usage_id)) except StaffAssessmentRequestError: logger.warning( u"An error occurred while submitting a staff assessment " u"for the submission {}".format(data['submission_uuid']), exc_info=True ) msg = self._(u"Your staff assessment could not be submitted.") return {'success': False, 'msg': msg} except StaffAssessmentInternalError: logger.exception( u"An error occurred while submitting a staff assessment " u"for the submission {}".format(data['submission_uuid']), ) msg = self._(u"Your staff assessment could not be submitted.") return {'success': False, 'msg': msg} else: return {'success': True, 'msg': u""}
def update_workflow_status(self, submission_uuid=None): """ Update the status of a workflow. For example, change the status from peer-assessment to self-assessment. Creates a score if the student has completed all requirements. Keyword Arguments: submission_uuid (str): The submission associated with the workflow to update. Defaults to the submission created by the current student. Returns: None Raises: AssessmentWorkflowError """ if submission_uuid is None: submission_uuid = self.submission_uuid if submission_uuid: requirements = self.workflow_requirements() workflow_api.update_from_assessments(submission_uuid, requirements)
def test_preexisting_workflow(self): """ Verifies that even if a workflow does not go through start_workflow, it won't blow up. update_from_assessments() will go through _get_steps(), and add a staff step to the workflow even if it was created without one initially. """ submission = sub_api.create_submission({ "student_id": "test student", "course_id": "test course", "item_id": "test item", "item_type": "openassessment", }, "test answer") # Create the model object directly, bypassing start_workflow() workflow = AssessmentWorkflow.objects.create( submission_uuid=submission["uuid"], status=AssessmentWorkflow.STATUS.waiting, course_id="test course", item_id="test item" ) # This call will throw exceptions if the workflow is in an invalid state workflow_api.update_from_assessments(submission["uuid"], {})
def test_preexisting_workflow(self): """ Verifies that even if a workflow does not go through start_workflow, it won't blow up. update_from_assessments() will go through _get_steps(), and add a staff step to the workflow even if it was created without one initially. """ submission = sub_api.create_submission( { "student_id": "test student", "course_id": "test course", "item_id": "test item", "item_type": "openassessment", }, "test answer") # Create the model object directly, bypassing start_workflow() workflow = AssessmentWorkflow.objects.create( submission_uuid=submission["uuid"], status=AssessmentWorkflow.STATUS.waiting, course_id="test course", item_id="test item") # This call will throw exceptions if the workflow is in an invalid state workflow_api.update_from_assessments(submission["uuid"], {})
def test_update_peer_workflow(self): submission = sub_api.create_submission(ITEM_1, ANSWER_1) workflow = workflow_api.create_workflow(submission["uuid"], ["training", "peer"]) StudentTrainingWorkflow.create_workflow( submission_uuid=submission["uuid"]) requirements = { "training": { "num_required": 2 }, "peer": { "must_grade": 5, "must_be_graded_by": 3 } } workflow_keys = set(workflow.keys()) self.assertEqual( workflow_keys, { 'submission_uuid', 'status', 'created', 'modified', 'score', 'assessment_score_priority' }) self.assertEqual(workflow["submission_uuid"], submission["uuid"]) self.assertEqual(workflow["status"], "training") peer_workflows = list( PeerWorkflow.objects.filter(submission_uuid=submission["uuid"])) self.assertFalse(peer_workflows) workflow_from_get = workflow_api.get_workflow_for_submission( submission["uuid"], requirements) del workflow_from_get['status_details'] self.assertEqual(workflow, workflow_from_get) requirements["training"]["num_required"] = 0 workflow = workflow_api.update_from_assessments( submission["uuid"], requirements) # New step is Peer, and a Workflow has been created. self.assertEqual(workflow["status"], "peer") peer_workflow = PeerWorkflow.objects.get( submission_uuid=submission["uuid"]) self.assertIsNotNone(peer_workflow)
def test_update_peer_workflow(self): submission = sub_api.create_submission(ITEM_1, "Shoot Hot Rod") workflow = workflow_api.create_workflow(submission["uuid"], ["training", "peer"], ON_INIT_PARAMS) StudentTrainingWorkflow.create_workflow(submission_uuid=submission["uuid"]) requirements = { "training": { "num_required": 2 }, "peer": { "must_grade": 5, "must_be_graded_by": 3 } } workflow_keys = set(workflow.keys()) self.assertEqual( workflow_keys, { 'override_score', 'submission_uuid', 'uuid', 'status', 'created', 'modified', 'score' } ) self.assertEqual(workflow["submission_uuid"], submission["uuid"]) self.assertEqual(workflow["status"], "training") peer_workflows = list(PeerWorkflow.objects.filter(submission_uuid=submission["uuid"])) self.assertFalse(peer_workflows) workflow_from_get = workflow_api.get_workflow_for_submission( submission["uuid"], requirements ) del workflow_from_get['status_details'] self.assertEqual(workflow, workflow_from_get) requirements["training"]["num_required"] = 0 workflow = workflow_api.update_from_assessments(submission["uuid"], requirements) # New step is Peer, and a Workflow has been created. self.assertEqual(workflow["status"], "peer") peer_workflow = PeerWorkflow.objects.get(submission_uuid=submission["uuid"]) self.assertIsNotNone(peer_workflow)
def test_unexpected_exception_wrapped(self, data, mock_create): mock_create.side_effect = Exception("Kaboom!") submission = sub_api.create_submission(ITEM_1, "Ultra Magnus fumble") workflow_api.update_from_assessments(submission["uuid"], data["steps"])
def test_unexpected_exception_wrapped(self, data, mock_create): with raises(workflow_api.AssessmentWorkflowInternalError): mock_create.side_effect = Exception("Kaboom!") submission = sub_api.create_submission(ITEM_1, ANSWER_2) workflow_api.update_from_assessments(submission["uuid"], data["steps"])