def enter_grade(self, request, suffix=''):
        """
        """
        require(self.is_course_staff())
        user = get_user_by_username_or_email(request.params.get('user'))

        score = request.params.get('score')
        comment = request.params.get('comment')

        if not score:
            return Response(
                json_body={"error": "Enter a valid grade"},
                status_code=400,
            )

        try:
            score = int(score)
        except ValueError:
            return Response(
                json_body={"error": "Enter a valid grade"},
                status_code=400,
            )

        submission_id = self.get_submission_id(user)

        submission = submissions_api.create_submission(submission_id, {'comment': comment})

        submissions_api.set_score(submission['uuid'], score, self.max_score())

        self.get_or_create_student_module(user, score, comment)

        return Response(json_body={"success": "success"})
Example #2
0
    def set_staff_score(self, score, reason=None):
        """
        Set a staff score for the workflow.

        Allows for staff scores to be set on a submission, with annotations to provide an audit trail if needed.
        This method can be used for both required staff grading, and staff overrides.

        Args:
            score (dict): A dict containing 'points_earned', 'points_possible', and 'staff_id'.
            is_override (bool): Optionally True if staff is overriding a previous score.
            reason (string): An optional parameter specifying the reason for the staff grade. A default value
                will be used in the event that this parameter is not provided.

        """
        if reason is None:
            reason = "A staff member has defined the score for this submission"
        sub_dict = sub_api.get_submission_and_student(self.submission_uuid)
        sub_api.reset_score(
            sub_dict['student_item']['student_id'],
            self.course_id,
            self.item_id,
            emit_signal=False
        )
        sub_api.set_score(
            self.submission_uuid,
            score["points_earned"],
            score["points_possible"],
            annotation_creator=score["staff_id"],
            annotation_type=self.STAFF_ANNOTATION_TYPE,
            annotation_reason=reason
        )
Example #3
0
    def test_get_scores(self):
        student_item = copy.deepcopy(STUDENT_ITEM)
        student_item["course_id"] = "get_scores_course"

        student_item["item_id"] = "i4x://a/b/c/s1"
        s1 = api.create_submission(student_item, "Hello World")

        student_item["item_id"] = "i4x://a/b/c/s2"
        s2 = api.create_submission(student_item, "Hello World")

        student_item["item_id"] = "i4x://a/b/c/s3"
        s3 = api.create_submission(student_item, "Hello World")

        api.set_score(s1['uuid'], 3, 5)
        api.set_score(s1['uuid'], 4, 5)
        api.set_score(s1['uuid'], 2, 5)  # Should overwrite previous lines

        api.set_score(s2['uuid'], 0, 10)
        api.set_score(s3['uuid'], 4, 4)

        # Getting the scores for a user should never take more than one query
        with self.assertNumQueries(1):
            scores = api.get_scores(
                student_item["course_id"], student_item["student_id"]
            )
            self.assertEqual(
                scores,
                {
                    u"i4x://a/b/c/s1": (2, 5),
                    u"i4x://a/b/c/s2": (0, 10),
                    u"i4x://a/b/c/s3": (4, 4),
                }
            )
Example #4
0
    def test_get_scores(self):
        student_item = copy.deepcopy(STUDENT_ITEM)
        student_item["course_id"] = "get_scores_course"

        student_item["item_id"] = "i4x://a/b/c/s1"
        s1 = api.create_submission(student_item, "Hello World")

        student_item["item_id"] = "i4x://a/b/c/s2"
        s2 = api.create_submission(student_item, "Hello World")

        student_item["item_id"] = "i4x://a/b/c/s3"
        s3 = api.create_submission(student_item, "Hello World")

        api.set_score(s1['uuid'], 3, 5)
        api.set_score(s1['uuid'], 4, 5)
        api.set_score(s1['uuid'], 2, 5)  # Should overwrite previous lines

        api.set_score(s2['uuid'], 0, 10)
        api.set_score(s3['uuid'], 4, 4)

        # Getting the scores for a user should never take more than one query
        with self.assertNumQueries(1):
            scores = api.get_scores(student_item["course_id"],
                                    student_item["student_id"])
            self.assertEqual(
                scores, {
                    u"i4x://a/b/c/s1": (2, 5),
                    u"i4x://a/b/c/s2": (0, 10),
                    u"i4x://a/b/c/s3": (4, 4),
                })
Example #5
0
    def code_submit(self, data, suffix=''):
        """
        AJAX handler for Submit button
        """

        if (self.grader_id == ''):
            return {
                'error':
                'You can not submit the assignment as no grader_id is configured'
            }

        submission = sub_api.create_submission(self.student_item_key, data)

        submitted_code = data["submitted_code"]
        grading_result = java_code_grader.grade(self.grader_id, submitted_code)
        if grading_result.has_key("error"):
            sub_api.set_score(submission['uuid'], 0, self.max_points)
        else:
            sub_api.set_score(submission['uuid'], self.max_points,
                              self.max_points)

        new_score = sub_api.get_score(self.student_item_key)

        submit_result = {
            'points_earned': new_score['points_earned'],
            'points_possible': new_score['points_possible']
        }

        if grading_result.has_key("error"):
            submit_result["error"] = grading_result["error"]

        return submit_result
Example #6
0
    def enter_grade(self, request, suffix=''):
        # pylint: disable=unused-argument
        """
        Persist a score for a student given by staff.
        """
        require(self.is_course_staff())
        module = StudentModule.objects.get(pk=request.params['module_id'])
        state = json.loads(module.state)
        score = int(request.params['grade'])
        if self.is_instructor():
            uuid = request.params['submission_id']
            submissions_api.set_score(uuid, score, self.max_score())
        else:
            state['staff_score'] = score
        state['comment'] = request.params.get('comment', '')
        module.state = json.dumps(state)
        module.save()
        log.info(
            "enter_grade for course:%s module:%s student:%s",
            module.course_id,
            module.module_state_key,
            module.student.username
        )

        return Response(json_body=self.staff_grading_data())
Example #7
0
    def set_staff_score(self, score, reason=None):
        """
        Set a staff score for the workflow.

        Allows for staff scores to be set on a submission, with annotations to provide an audit trail if needed.
        This method can be used for both required staff grading, and staff overrides.

        Args:
            score (dict): A dict containing 'points_earned', 'points_possible', and 'staff_id'.
            is_override (bool): Optionally True if staff is overriding a previous score.
            reason (string): An optional parameter specifying the reason for the staff grade. A default value
                will be used in the event that this parameter is not provided.

        """
        if reason is None:
            reason = "A staff member has defined the score for this submission"
        sub_dict = sub_api.get_submission_and_student(self.submission_uuid)
        sub_api.reset_score(
            sub_dict['student_item']['student_id'],
            self.course_id,
            self.item_id,
            emit_signal=False
        )
        sub_api.set_score(
            self.submission_uuid,
            score["points_earned"],
            score["points_possible"],
            annotation_creator=score["staff_id"],
            annotation_type=self.STAFF_ANNOTATION_TYPE,
            annotation_reason=reason
        )
    def test_delete_student_state_resets_scores(self):
        problem_location = self.course.id.make_usage_key('dummy', 'module')

        # Create a student module for the user
        StudentModule.objects.create(
            student=self.student,
            course_id=self.course.id,
            module_state_key=problem_location,
            state=json.dumps({})
        )

        # Create a submission and score for the student using the submissions API
        student_item = {
            'student_id': anonymous_id_for_user(self.student, self.course.id),
            'course_id': self.course.id.to_deprecated_string(),
            'item_id': problem_location.to_deprecated_string(),
            'item_type': 'openassessment'
        }
        submission = sub_api.create_submission(student_item, 'test answer')
        sub_api.set_score(submission['uuid'], 1, 2)

        # Delete student state using the instructor dash
        url = reverse('instructor_dashboard_legacy', kwargs={'course_id': self.course.id.to_deprecated_string()})
        response = self.client.post(url, {
            'action': 'Delete student state for module',
            'unique_student_identifier': self.student.email,
            'problem_for_student': problem_location.to_deprecated_string(),
        })

        self.assertEqual(response.status_code, 200)

        # Verify that the student's scores have been reset in the submissions API
        score = sub_api.get_score(student_item)
        self.assertIs(score, None)
Example #9
0
    def test_delete_submission_scores(self):
        user = UserFactory()
        problem_location = self.course_key.make_usage_key('dummy', 'module')

        # Create a student module for the user
        StudentModule.objects.create(student=user,
                                     course_id=self.course_key,
                                     module_state_key=problem_location,
                                     state=json.dumps({}))

        # Create a submission and score for the student using the submissions API
        student_item = {
            'student_id': anonymous_id_for_user(user, self.course_key),
            'course_id': self.course_key.to_deprecated_string(),
            'item_id': problem_location.to_deprecated_string(),
            'item_type': 'openassessment'
        }
        submission = sub_api.create_submission(student_item, 'test answer')
        sub_api.set_score(submission['uuid'], 1, 2)

        # Delete student state using the instructor dash
        reset_student_attempts(self.course_key,
                               user,
                               problem_location,
                               delete_module=True)

        # Verify that the student's scores have been reset in the submissions API
        score = sub_api.get_score(student_item)
        self.assertIs(score, None)
Example #10
0
    def test_delete_submission_scores(self):
        user = UserFactory()
        course_id = 'ora2/1/1'
        item_id = 'i4x://ora2/1/openassessment/b3dce2586c9c4876b73e7f390e42ef8f'

        # Create a student module for the user
        StudentModule.objects.create(
            student=user, course_id=course_id, module_state_key=item_id, state=json.dumps({})
        )

        # Create a submission and score for the student using the submissions API
        student_item = {
            'student_id': anonymous_id_for_user(user, course_id),
            'course_id': course_id,
            'item_id': item_id,
            'item_type': 'openassessment'
        }
        submission = sub_api.create_submission(student_item, 'test answer')
        sub_api.set_score(submission['uuid'], 1, 2)

        # Delete student state using the instructor dash
        reset_student_attempts(course_id, user, item_id, delete_module=True)

        # Verify that the student's scores have been reset in the submissions API
        score = sub_api.get_score(student_item)
        self.assertIs(score, None)
    def test_reset_different_student_item(self, changed):
        # Create a submissions for two students
        submission = sub_api.create_submission(self.STUDENT_ITEM, "test answer")
        sub_api.set_score(submission["uuid"], 1, 2)

        other_student = copy.copy(self.STUDENT_ITEM)
        other_student.update(changed)
        submission = sub_api.create_submission(other_student, "other test answer")
        sub_api.set_score(submission["uuid"], 3, 4)

        # Reset the score for the first student
        sub_api.reset_score(
            self.STUDENT_ITEM["student_id"], self.STUDENT_ITEM["course_id"], self.STUDENT_ITEM["item_id"]
        )

        # The first student's scores should be reset
        self.assertIs(sub_api.get_score(self.STUDENT_ITEM), None)
        scores = sub_api.get_scores(self.STUDENT_ITEM["course_id"], self.STUDENT_ITEM["student_id"])
        self.assertNotIn(self.STUDENT_ITEM["item_id"], scores)

        # But the second student should still have a score
        score = sub_api.get_score(other_student)
        self.assertEqual(score["points_earned"], 3)
        self.assertEqual(score["points_possible"], 4)
        scores = sub_api.get_scores(other_student["course_id"], other_student["student_id"])
        self.assertIn(other_student["item_id"], scores)
    def test_delete_student_state_resets_scores(self):
        item_id = 'i4x://MITx/999/openassessment/b3dce2586c9c4876b73e7f390e42ef8f'

        # Create a student module for the user
        StudentModule.objects.create(
            student=self.student, course_id=self.course.id, module_state_key=item_id, state=json.dumps({})
        )

        # Create a submission and score for the student using the submissions API
        student_item = {
            'student_id': anonymous_id_for_user(self.student, self.course.id),
            'course_id': self.course.id,
            'item_id': item_id,
            'item_type': 'openassessment'
        }
        submission = sub_api.create_submission(student_item, 'test answer')
        sub_api.set_score(submission['uuid'], 1, 2)

        # Delete student state using the instructor dash
        url = reverse('instructor_dashboard_legacy', kwargs={'course_id': self.course.id})
        response = self.client.post(url, {
            'action': 'Delete student state for module',
            'unique_student_identifier': self.student.email,
            'problem_for_student': 'openassessment/b3dce2586c9c4876b73e7f390e42ef8f',
        })

        self.assertEqual(response.status_code, 200)

        # Verify that the student's scores have been reset in the submissions API
        score = sub_api.get_score(student_item)
        self.assertIs(score, None)
Example #13
0
    def test_delete_submission_scores(self):
        user = UserFactory()
        problem_location = self.course_key.make_usage_key('dummy', 'module')

        # Create a student module for the user
        StudentModule.objects.create(
            student=user,
            course_id=self.course_key,
            module_state_key=problem_location,
            state=json.dumps({})
        )

        # Create a submission and score for the student using the submissions API
        student_item = {
            'student_id': anonymous_id_for_user(user, self.course_key),
            'course_id': self.course_key.to_deprecated_string(),
            'item_id': problem_location.to_deprecated_string(),
            'item_type': 'openassessment'
        }
        submission = sub_api.create_submission(student_item, 'test answer')
        sub_api.set_score(submission['uuid'], 1, 2)

        # Delete student state using the instructor dash
        reset_student_attempts(
            self.course_key, user, problem_location,
            delete_module=True
        )

        # Verify that the student's scores have been reset in the submissions API
        score = sub_api.get_score(student_item)
        self.assertIs(score, None)
Example #14
0
File: api.py Project: ctpad/edx-tim
def _check_if_finished_and_create_score(student_item,
                                        submission,
                                        required_evaluations_for_student,
                                        required_evaluations_for_submission):
    """Basic function for checking if a student is finished with peer workflow.

    Checks if the student is finished with the peer evaluation workflow. If the
    student already has a final grade calculated, there is no need to proceed.
    If they do not have a grade, the student has a final grade calculated.

    """
    if Score.objects.filter(student_item=student_item):
        return

    finished_evaluating = has_finished_required_evaluating(
        student_item.student_id,
        required_evaluations_for_student
    )
    evaluations = PeerEvaluation.objects.filter(submission=submission)
    submission_finished = evaluations.count() >= required_evaluations_for_submission
    scores = []
    for evaluation in evaluations:
        scores.append(evaluation.points_earned)
    if finished_evaluating and submission_finished:
        submission_api.set_score(
            StudentItemSerializer(student_item).data,
            SubmissionSerializer(submission).data,
            _calculate_final_score(scores),
            evaluations[0].points_possible
        )
Example #15
0
    def make_student(self, block, name, **state):
        answer = {}
        for key in ("sha1", "mimetype", "filename"):
            if key in state:
                answer[key] = state.pop(key)
        score = state.pop("score", None)

        user = User(username=name)
        user.save()
        profile = UserProfile(user=user, name=name)
        profile.save()
        module = StudentModule(
            module_state_key=block.location, student=user, course_id=self.course_id, state=json.dumps(state)
        )
        module.save()

        anonymous_id = anonymous_id_for_user(user, self.course_id)
        item = StudentItem(student_id=anonymous_id, course_id=self.course_id, item_id=block.block_id, item_type="sga")
        item.save()

        if answer:
            student_id = block.student_submission_id(anonymous_id)
            submission = submissions_api.create_submission(student_id, answer)
            if score is not None:
                submissions_api.set_score(submission["uuid"], score, block.max_score())
        else:
            submission = None

        self.addCleanup(item.delete)
        self.addCleanup(profile.delete)
        self.addCleanup(module.delete)
        self.addCleanup(user.delete)

        return {"module": module, "item": item, "submission": submission}
Example #16
0
    def test_delete_submission_scores(self, _lti_mock):
        user = UserFactory()
        problem_location = self.course_key.make_usage_key("dummy", "module")

        # Create a student module for the user
        StudentModule.objects.create(
            student=user, course_id=self.course_key, module_state_key=problem_location, state=json.dumps({})
        )

        # Create a submission and score for the student using the submissions API
        student_item = {
            "student_id": anonymous_id_for_user(user, self.course_key),
            "course_id": self.course_key.to_deprecated_string(),
            "item_id": problem_location.to_deprecated_string(),
            "item_type": "openassessment",
        }
        submission = sub_api.create_submission(student_item, "test answer")
        sub_api.set_score(submission["uuid"], 1, 2)

        # Delete student state using the instructor dash
        reset_student_attempts(self.course_key, user, problem_location, requesting_user=user, delete_module=True)

        # Verify that the student's scores have been reset in the submissions API
        score = sub_api.get_score(student_item)
        self.assertIs(score, None)
    def test_delete_student_state_resets_scores(self):
        item_id = 'i4x://MITx/999/openassessment/b3dce2586c9c4876b73e7f390e42ef8f'

        # Create a student module for the user
        StudentModule.objects.create(
            student=self.student, course_id=self.course.id, module_state_key=item_id, state=json.dumps({})
        )

        # Create a submission and score for the student using the submissions API
        student_item = {
            'student_id': anonymous_id_for_user(self.student, self.course.id),
            'course_id': self.course.id,
            'item_id': item_id,
            'item_type': 'openassessment'
        }
        submission = sub_api.create_submission(student_item, 'test answer')
        sub_api.set_score(submission['uuid'], 1, 2)

        # Delete student state using the instructor dash
        url = reverse('instructor_dashboard', kwargs={'course_id': self.course.id})
        response = self.client.post(url, {
            'action': 'Delete student state for module',
            'unique_student_identifier': self.student.email,
            'problem_for_student': 'openassessment/b3dce2586c9c4876b73e7f390e42ef8f',
        })

        self.assertEqual(response.status_code, 200)

        # Verify that the student's scores have been reset in the submissions API
        score = sub_api.get_score(student_item)
        self.assertIs(score, None)
Example #18
0
 def setUp(self):
     """ Create a submission and score. """
     super().setUp()
     self.submission = sub_api.create_submission(self.STUDENT_ITEM,
                                                 "test answer")
     sub_api.set_score(self.submission['uuid'], self.SCORE["points_earned"],
                       self.SCORE["points_possible"])
Example #19
0
    def set_score(self, score):
        """
        Set a score for the workflow.

        Scores are persisted via the Submissions API, separate from the Workflow
        Data. Score is associated with the same submission_uuid as this workflow

        Args:
            score (dict): A dict containing 'points_earned' and
                'points_possible'.

        """
        sub_api.set_score(self.submission_uuid, score["points_earned"],
                          score["points_possible"])

        # This should be replaced by using the event tracking API, but
        # that's not quite ready yet. So we're making this temp hack.
        emit_event({
            "context": {
                "course_id": self.course_id
            },
            "event": {
                "submission_uuid": self.submission_uuid,
                "points_earned": score["points_earned"],
                "points_possible": score["points_possible"],
            },
            "event_source": "server",
            "event_type": "openassessment.workflow.score",
            "time": datetime.utcnow(),
        })
    def test_submissions_api_overrides_scores(self):
        """
        Check that answering incorrectly is graded properly.
        """
        self.basic_setup()
        self.submit_question_answer('p1', {'2_1': 'Correct'})
        self.submit_question_answer('p2', {'2_1': 'Correct'})
        self.submit_question_answer('p3', {'2_1': 'Incorrect'})
        self.check_grade_percent(0.67)
        self.assertEqual(self.get_course_grade().letter_grade, 'B')

        # But now, set the score with the submissions API and watch
        # as it overrides the score read from StudentModule and our
        # student gets an A instead.
        self._stop_signal_patch()
        student_item = {
            'student_id': anonymous_id_for_user(self.student_user, self.course.id),
            'course_id': unicode(self.course.id),
            'item_id': unicode(self.problem_location('p3')),
            'item_type': 'problem'
        }
        submission = submissions_api.create_submission(student_item, 'any answer')
        submissions_api.set_score(submission['uuid'], 1, 1)
        self.check_grade_percent(1.0)
        self.assertEqual(self.get_course_grade().letter_grade, 'A')
Example #21
0
    def test_reset_then_add_score(self):
        # Create a submission for the student and score it
        submission = sub_api.create_submission(self.STUDENT_ITEM,
                                               'test answer')
        sub_api.set_score(submission['uuid'], 1, 2)

        # Reset scores
        sub_api.reset_score(
            self.STUDENT_ITEM['student_id'],
            self.STUDENT_ITEM['course_id'],
            self.STUDENT_ITEM['item_id'],
        )

        # Score the student again
        sub_api.set_score(submission['uuid'], 3, 4)

        # Expect that the new score is available
        score = sub_api.get_score(self.STUDENT_ITEM)
        self.assertEqual(score['points_earned'], 3)
        self.assertEqual(score['points_possible'], 4)

        scores = sub_api.get_scores(self.STUDENT_ITEM['course_id'],
                                    self.STUDENT_ITEM['student_id'])
        self.assertIn(self.STUDENT_ITEM['item_id'], scores)
        self.assertEqual(scores[self.STUDENT_ITEM['item_id']], (3, 4))
    def test_delete_student_state_resets_scores(self):
        problem_location = self.course.id.make_usage_key('dummy', 'module')

        # Create a student module for the user
        StudentModule.objects.create(student=self.student,
                                     course_id=self.course.id,
                                     module_state_key=problem_location,
                                     state=json.dumps({}))

        # Create a submission and score for the student using the submissions API
        student_item = {
            'student_id': anonymous_id_for_user(self.student, self.course.id),
            'course_id': self.course.id.to_deprecated_string(),
            'item_id': problem_location.to_deprecated_string(),
            'item_type': 'openassessment'
        }
        submission = sub_api.create_submission(student_item, 'test answer')
        sub_api.set_score(submission['uuid'], 1, 2)

        # Delete student state using the instructor dash
        url = reverse(
            'instructor_dashboard_legacy',
            kwargs={'course_id': self.course.id.to_deprecated_string()})
        response = self.client.post(
            url, {
                'action': 'Delete student state for module',
                'unique_student_identifier': self.student.email,
                'problem_for_student': problem_location.to_deprecated_string(),
            })

        self.assertEqual(response.status_code, 200)

        # Verify that the student's scores have been reset in the submissions API
        score = sub_api.get_score(student_item)
        self.assertIs(score, None)
Example #23
0
    def test_reset_different_student_item(self, changed):
        # Create a submissions for two students
        submission = sub_api.create_submission(self.STUDENT_ITEM,
                                               'test answer')
        sub_api.set_score(submission['uuid'], 1, 2)

        other_student = copy.copy(self.STUDENT_ITEM)
        other_student.update(changed)
        submission = sub_api.create_submission(other_student,
                                               'other test answer')
        sub_api.set_score(submission['uuid'], 3, 4)

        # Reset the score for the first student
        sub_api.reset_score(
            self.STUDENT_ITEM['student_id'],
            self.STUDENT_ITEM['course_id'],
            self.STUDENT_ITEM['item_id'],
        )

        # The first student's scores should be reset
        self.assertIs(sub_api.get_score(self.STUDENT_ITEM), None)
        scores = sub_api.get_scores(self.STUDENT_ITEM['course_id'],
                                    self.STUDENT_ITEM['student_id'])
        self.assertNotIn(self.STUDENT_ITEM['item_id'], scores)

        # But the second student should still have a score
        score = sub_api.get_score(other_student)
        self.assertEqual(score['points_earned'], 3)
        self.assertEqual(score['points_possible'], 4)
        scores = sub_api.get_scores(other_student['course_id'],
                                    other_student['student_id'])
        self.assertIn(other_student['item_id'], scores)
Example #24
0
    def set_score(self, score):
        """
        Set a score for the workflow.

        Scores are persisted via the Submissions API, separate from the Workflow
        Data. Score is associated with the same submission_uuid as this workflow

        Args:
            score (dict): A dict containing 'points_earned' and
                'points_possible'.

        """
        sub_api.set_score(
            self.submission_uuid,
            score["points_earned"],
            score["points_possible"]
        )

        # This should be replaced by using the event tracking API, but
        # that's not quite ready yet. So we're making this temp hack.
        emit_event({
            "context": {
                "course_id": self.course_id
            },
            "event": {
                "submission_uuid": self.submission_uuid,
                "points_earned": score["points_earned"],
                "points_possible": score["points_possible"],
            },
            "event_source": "server",
            "event_type": "openassessment.workflow.score",
            "time": datetime.utcnow(),
        })
Example #25
0
    def score_update(self, submission_result):

        parent = super(ScilabXBlock, self)
        if hasattr(parent, 'score_update'):
            parent.score_update(submission_result)

        submission_uid, validation_key = submission_result.lms_key.split('+')

        # TODO: Validate submission
        # submission = submissions_api.get_submission(submission_uid)

        submissions_api.set_score(submission_uid,
                                  int(100 * submission_result.score),
                                  100,
                                  annotation_reason=submission_result.msg,
                                  annotation_creator='xblock_scilab',
                                  annotation_type='check')

        self.points = submission_result.score
        self.runtime.publish(
            self, 'grade', {
                'value': submission_result.score * self.max_score(),
                'max_value': self.max_score()
            })

        annotation = ifmo_submissions_api.get_annotation(
            self.student_submission_dict())
        self.message = None
        try:
            message = (json.loads(annotation.get('reason'))['message']).strip()
            if message:
                self.message = u"<b>Результат последней проверки:</b> %s" % message
        except (ValueError, KeyError):
            pass
Example #26
0
    def _create_submissions_and_scores(
            self, xblock, submissions_and_scores,
            submission_key=None, points_possible=10
    ):
        """
        Create submissions and scores that should be displayed by the leaderboard.

        Args:
            xblock (OpenAssessmentBlock)
            submisions_and_scores (list): List of `(submission, score)` tuples, where
                `submission` is the essay text (string) and `score` is the integer
                number of points earned.

        Keyword Args:
            points_possible (int): The total number of points possible for this problem
            submission_key (string): The key to use in the submission dict.  If None, use
                the submission value itself instead of embedding it in a dictionary.
        """
        for num, (submission, points_earned) in enumerate(submissions_and_scores):
            # Assign a unique student ID
            # These aren't displayed by the leaderboard, so we can set them
            # to anything without affecting the test.
            student_item = xblock.get_student_item_dict()
            # adding rand number to the student_id to make it unique.
            student_item['student_id'] = u'student {num} {num2}'.format(num=num, num2=randint(2, 1000))
            if submission_key is not None:
                answer = {submission_key: submission}
            else:
                answer = submission

            # Create a submission
            sub = sub_api.create_submission(student_item, answer)

            # Create a score for the submission
            sub_api.set_score(sub['uuid'], points_earned, points_possible)
Example #27
0
    def enter_grade(self, request, suffix=''):
        # pylint: disable=unused-argument
        """
        Persist a score for a student given by staff.
        """
        require(self.is_course_staff())
        score = request.params.get('grade', None)
        module = self.get_student_module(request.params['module_id'])
        if not score:
            return Response(json_body=self.validate_score_message(
                module.course_id, module.student.username))

        state = json.loads(module.state)
        try:
            score = int(score)
        except ValueError:
            return Response(json_body=self.validate_score_message(
                module.course_id, module.student.username))

        if self.is_instructor():
            uuid = request.params['submission_id']
            submissions_api.set_score(uuid, score, self.max_score())
        else:
            state['staff_score'] = score
        state['comment'] = request.params.get('comment', '')
        module.state = json.dumps(state)
        module.save()
        log.info("enter_grade for course:%s module:%s student:%s",
                 module.course_id, module.module_state_key,
                 module.student.username)

        return Response(json_body=self.staff_grading_data())
Example #28
0
    def _create_submissions_and_scores(
        self, xblock, submissions_and_scores,
        submission_key="text", points_possible=10
    ):
        """
        Create submissions and scores that should be displayed by the leaderboard.

        Args:
            xblock (OpenAssessmentBlock)
            submisions_and_scores (list): List of `(submission, score)` tuples, where
                `submission` is the essay text (string) and `score` is the integer
                number of points earned.

        Keyword Args:
            points_possible (int): The total number of points possible for this problem
            submission_key (string): The key to use in the submission dict.  If None, use
                the submission value itself instead of embedding it in a dictionary.
        """
        for num, (submission, points_earned) in enumerate(submissions_and_scores):
            # Assign a unique student ID
            # These aren't displayed by the leaderboard, so we can set them
            # to anything without affecting the test.
            student_item = xblock.get_student_item_dict()
            # adding rand number to the student_id to make it unique.
            student_item['student_id'] = "student {num} {num2}".format(num=num, num2=randint(2, 1000))
            if submission_key is not None:
                answer = {submission_key: submission}
            else:
                answer = submission

            # Create a submission
            sub = sub_api.create_submission(student_item, answer)

            # Create a score for the submission
            sub_api.set_score(sub['uuid'], points_earned, points_possible)
    def test_submissions_api_overrides_scores(self):
        """
        Check that answering incorrectly is graded properly.
        """
        self.basic_setup()
        self.submit_question_answer('p1', {'2_1': 'Correct'})
        self.submit_question_answer('p2', {'2_1': 'Correct'})
        self.submit_question_answer('p3', {'2_1': 'Incorrect'})
        self.check_grade_percent(0.67)
        self.assertEqual(self.get_course_grade().letter_grade, 'B')

        # But now, set the score with the submissions API and watch
        # as it overrides the score read from StudentModule and our
        # student gets an A instead.
        self._stop_signal_patch()
        student_item = {
            'student_id': anonymous_id_for_user(self.student_user,
                                                self.course.id),
            'course_id': unicode(self.course.id),
            'item_id': unicode(self.problem_location('p3')),
            'item_type': 'problem'
        }
        submission = submissions_api.create_submission(student_item,
                                                       'any answer')
        submissions_api.set_score(submission['uuid'], 1, 1)
        self.check_grade_percent(1.0)
        self.assertEqual(self.get_course_grade().letter_grade, 'A')
Example #30
0
    def test_create_score(self):
        submission = api.create_submission(STUDENT_ITEM, ANSWER_ONE)
        student_item = self._get_student_item(STUDENT_ITEM)
        self._assert_submission(submission, ANSWER_ONE, student_item.pk, 1)

        api.set_score(submission["uuid"], 11, 12)
        score = api.get_latest_score_for_submission(submission["uuid"])
        self._assert_score(score, 11, 12)
Example #31
0
    def test_create_score(self):
        submission = api.create_submission(STUDENT_ITEM, ANSWER_ONE)
        student_item = self._get_student_item(STUDENT_ITEM)
        self._assert_submission(submission, ANSWER_ONE, student_item.pk, 1)

        api.set_score(submission["uuid"], 11, 12)
        score = api.get_latest_score_for_submission(submission["uuid"])
        self._assert_score(score, 11, 12)
Example #32
0
    def test_create_score(self):
        submission = api.create_submission(STUDENT_ITEM, ANSWER_ONE)
        student_item = self._get_student_item(STUDENT_ITEM)
        self._assert_submission(submission, ANSWER_ONE, student_item.pk, 1)

        api.set_score(submission["uuid"], 11, 12)
        score = api.get_latest_score_for_submission(submission["uuid"])
        self._assert_score(score, 11, 12)
        self.assertFalse(ScoreAnnotation.objects.all().exists())
Example #33
0
    def make_student(self, block, name, make_state=True, **state):
        """
        Create a student along with submission state.
        """
        answer = {}
        module = None
        for key in ('sha1', 'mimetype', 'filename', 'finalized'):
            if key in state:
                answer[key] = state.pop(key)
        score = state.pop('score', None)

        with transaction.atomic():
            user = User(username=name)
            user.save()
            profile = UserProfile(user=user, name=name)
            profile.save()
            if make_state:
                module = StudentModule(
                    module_state_key=block.location,
                    student=user,
                    course_id=self.course_id,
                    state=json.dumps(state))
                module.save()

            anonymous_id = anonymous_id_for_user(user, self.course_id)
            item = StudentItem(
                student_id=anonymous_id,
                course_id=self.course_id,
                item_id=block.block_id,
                item_type='sga')
            item.save()

            if answer:
                student_id = block.get_student_item_dict(anonymous_id)
                submission = submissions_api.create_submission(student_id, answer)
                if score is not None:
                    submissions_api.set_score(
                        submission['uuid'], score, block.max_score())
            else:
                submission = None

            self.addCleanup(item.delete)
            self.addCleanup(profile.delete)
            self.addCleanup(user.delete)

            if make_state:
                self.addCleanup(module.delete)
                return {
                    'module': module,
                    'item': item,
                    'submission': submission
                }

            return {
                'item': item,
                'submission': submission
            }
Example #34
0
    def test_create_score(self):
        submission = api.create_submission(STUDENT_ITEM, ANSWER_ONE)
        student_item = self._get_student_item(STUDENT_ITEM)
        self._assert_submission(submission, ANSWER_ONE, student_item.pk, 1)

        api.set_score(submission["uuid"], 11, 12)
        score = api.get_latest_score_for_submission(submission["uuid"])
        self._assert_score(score, 11, 12)
        self.assertFalse(ScoreAnnotation.objects.all().exists())
Example #35
0
    def make_student(self, block, name, make_state=True, **state):
        """
        Create a student along with submission state.
        """
        answer = {}
        module = None
        for key in ('sha1', 'mimetype', 'filename', 'finalized'):
            if key in state:
                answer[key] = state.pop(key)
        score = state.pop('score', None)

        with transaction.atomic():
            user = User(username=name, email='{}@example.com'.format(name))
            user.save()
            profile = UserProfile(user=user, name=name)
            profile.save()
            if make_state:
                module = StudentModule(
                    module_state_key=block.location,
                    student=user,
                    course_id=self.course_id,
                    state=json.dumps(state))
                module.save()

            anonymous_id = anonymous_id_for_user(user, self.course_id)
            item = StudentItem(
                student_id=anonymous_id,
                course_id=self.course_id,
                item_id=block.block_id,
                item_type='sga')
            item.save()

            if answer:
                student_id = block.get_student_item_dict(anonymous_id)
                submission = submissions_api.create_submission(student_id, answer)
                if score is not None:
                    submissions_api.set_score(
                        submission['uuid'], score, block.max_score())
            else:
                submission = None

            self.addCleanup(item.delete)
            self.addCleanup(profile.delete)
            self.addCleanup(user.delete)

            if make_state:
                self.addCleanup(module.delete)
                return {
                    'module': module,
                    'item': item,
                    'submission': submission
                }

            return {
                'item': item,
                'submission': submission
            }
Example #36
0
    def test_get_score_for_submission_hidden_score(self):
        # Create a "hidden" score for the submission
        # (by convention, a score with points possible set to 0)
        submission = api.create_submission(STUDENT_ITEM, ANSWER_ONE)
        api.set_score(submission["uuid"], 0, 0)

        # Expect that the retrieved score is None
        score = api.get_latest_score_for_submission(submission['uuid'])
        self.assertIs(score, None)
Example #37
0
    def test_get_score_for_submission_hidden_score(self):
        # Create a "hidden" score for the submission
        # (by convention, a score with points possible set to 0)
        submission = api.create_submission(STUDENT_ITEM, ANSWER_ONE)
        api.set_score(submission["uuid"], 0, 0)

        # Expect that the retrieved score is None
        score = api.get_latest_score_for_submission(submission['uuid'])
        self.assertIs(score, None)
    def student_submit(self, data, suffix=''):
        """
        AJAX handler for Submit button
        """

        submitted_expression_values = json.loads(
            data['submitted_expression_values'])
        self.deserialize_data_from_context(data)

        # prepare "expressions" data for formula_service.evaluate_submission(variables, expressions)
        formula_service_expressions = {}
        for expression_name, expression in self.expressions.iteritems(
        ):  # expressions is unicode???
            formula_service_expressions[expression_name] = [
                expression, submitted_expression_values[expression_name]
            ]

        # prepare "variables" data for formula_service.evaluate_submission(variables, expressions)
        formula_service_variables = {}  # TODO cache the following loop
        for var_name, var_value in self.generated_variables.iteritems():
            formula_service_variables[var_name] = [
                self.variables[var_name], var_value
            ]

        # ask cexprtk to verify the submission
        evaluation_result = formula_service.evaluate_submission(
            formula_service_variables, formula_service_expressions)
        points_earned = self.max_points
        for expr_name, point in evaluation_result.iteritems():
            if (point == 0):
                points_earned = 0
                break

        # save the submission
        submission_data = {
            'generated_question': data['saved_generated_question'],
            'expression_values': data['submitted_expression_values'],
            'variable_values': data['serialized_generated_variables']
        }
        submission = sub_api.create_submission(self.student_item_key,
                                               submission_data)
        sub_api.set_score(submission['uuid'], points_earned, self.max_points)

        submit_result = {}
        submit_result['point_string'] = self.point_string

        # disable the "Submit" button once the submission attempts reach max_attemps value
        self.attempt_number = submission['attempt_number']
        submit_result['attempt_number'] = self.attempt_number_string
        if (self.attempt_number >= self.max_attempts):
            submit_result['submit_disabled'] = 'disabled'
        else:
            submit_result['submit_disabled'] = ''

        return submit_result
    def test_database_error(self, create_mock):
        # Create a submission for the student and score it
        submission = sub_api.create_submission(self.STUDENT_ITEM, "test answer")
        sub_api.set_score(submission["uuid"], 1, 2)

        # Simulate a database error when creating the reset score
        create_mock.side_effect = DatabaseError("Test error")
        with self.assertRaises(sub_api.SubmissionInternalError):
            sub_api.reset_score(
                self.STUDENT_ITEM["student_id"], self.STUDENT_ITEM["course_id"], self.STUDENT_ITEM["item_id"]
            )
Example #40
0
    def test_get_scores(self):
        student_item = copy.deepcopy(STUDENT_ITEM)
        student_item["course_id"] = "get_scores_course"

        student_item["item_id"] = "i4x://a/b/c/s1"
        s1 = api.create_submission(student_item, "Hello World")

        student_item["item_id"] = "i4x://a/b/c/s2"
        s2 = api.create_submission(student_item, "Hello World")

        student_item["item_id"] = "i4x://a/b/c/s3"
        s3 = api.create_submission(student_item, "Hello World")

        api.set_score(s1['uuid'], 3, 5)
        api.set_score(s1['uuid'], 4, 5)
        api.set_score(s1['uuid'], 2, 5)  # Should overwrite previous lines

        api.set_score(s2['uuid'], 0, 10)
        api.set_score(s3['uuid'], 4, 4)

        # Getting the scores for a user should never take more than one query
        with self.assertNumQueries(1):
            scores = api.get_scores(
                student_item["course_id"], student_item["student_id"]
            )
        self.assertEqual(
            scores,
            {
                'i4x://a/b/c/s1': {
                    'created_at': now(),
                    'points_earned': 2,
                    'points_possible': 5,
                    'student_item': 1,
                    'submission': 1,
                    'submission_uuid': s1['uuid'],
                },
                'i4x://a/b/c/s2': {
                    'created_at': now(),
                    'points_earned': 0,
                    'points_possible': 10,
                    'student_item': 2,
                    'submission': 2,
                    'submission_uuid': s2['uuid'],
                },
                'i4x://a/b/c/s3': {
                    'created_at': now(),
                    'points_earned': 4,
                    'points_possible': 4,
                    'student_item': 3,
                    'submission': 3,
                    'submission_uuid': s3['uuid'],
                },
            }
        )
Example #41
0
    def test_get_scores(self):
        student_item = copy.deepcopy(STUDENT_ITEM)
        student_item["course_id"] = "get_scores_course"

        student_item["item_id"] = "i4x://a/b/c/s1"
        s1 = api.create_submission(student_item, "Hello World")

        student_item["item_id"] = "i4x://a/b/c/s2"
        s2 = api.create_submission(student_item, "Hello World")

        student_item["item_id"] = "i4x://a/b/c/s3"
        s3 = api.create_submission(student_item, "Hello World")

        api.set_score(s1['uuid'], 3, 5)
        api.set_score(s1['uuid'], 4, 5)
        api.set_score(s1['uuid'], 2, 5)  # Should overwrite previous lines

        api.set_score(s2['uuid'], 0, 10)
        api.set_score(s3['uuid'], 4, 4)

        # Getting the scores for a user should never take more than one query
        with self.assertNumQueries(1):
            scores = api.get_scores(
                student_item["course_id"], student_item["student_id"]
            )
        self.assertEqual(
            scores,
            {
                u'i4x://a/b/c/s1': {
                    'created_at': now(),
                    'points_earned': 2,
                    'points_possible': 5,
                    'student_item': 1,
                    'submission': 1,
                    'submission_uuid': s1['uuid'],
                },
                u'i4x://a/b/c/s2': {
                    'created_at': now(),
                    'points_earned': 0,
                    'points_possible': 10,
                    'student_item': 2,
                    'submission': 2,
                    'submission_uuid': s2['uuid'],
                },
                u'i4x://a/b/c/s3': {
                    'created_at': now(),
                    'points_earned': 4,
                    'points_possible': 4,
                    'student_item': 3,
                    'submission': 3,
                    'submission_uuid': s3['uuid'],
                },
            }
        )
Example #42
0
    def test_set_score_signal(self, send_mock):
        submission = api.create_submission(STUDENT_ITEM, ANSWER_ONE)
        api.set_score(submission['uuid'], 11, 12)

        # Verify that the send method was properly called
        send_mock.assert_called_with(
            sender=None,
            points_possible=12,
            points_earned=11,
            anonymous_user_id=STUDENT_ITEM['student_id'],
            course_id=STUDENT_ITEM['course_id'],
            item_id=STUDENT_ITEM['item_id'])
    def test_override_with_one_score(self):
        # Create a submission for the student and score it
        submission = sub_api.create_submission(self.STUDENT_ITEM, 'test answer')
        sub_api.set_score(submission['uuid'], 1, 10)

        sub_api.score_override(
            self.STUDENT_ITEM,
            5,
            10,
        )

        self.assertEqual(sub_api.get_score(self.STUDENT_ITEM)['points_earned'], 5)
        self.assertEqual(sub_api.get_score(self.STUDENT_ITEM)['points_possible'], 10)
Example #44
0
    def test_set_score_signal(self, send_mock):
        submission = api.create_submission(STUDENT_ITEM, ANSWER_ONE)
        api.set_score(submission['uuid'], 11, 12)

        # Verify that the send method was properly called
        send_mock.assert_called_with(
            sender=None,
            points_possible=12,
            points_earned=11,
            anonymous_user_id=STUDENT_ITEM['student_id'],
            course_id=STUDENT_ITEM['course_id'],
            item_id=STUDENT_ITEM['item_id']
        )
Example #45
0
    def set_score(self, score):
        """
        Set a score for the workflow.

        Scores are persisted via the Submissions API, separate from the Workflow
        Data. Score is associated with the same submission_uuid as this workflow

        Args:
            score (dict): A dict containing 'points_earned' and
                'points_possible'.

        """
        sub_api.set_score(self.submission_uuid, score["points_earned"], score["points_possible"])
    def test_reset_then_get_score_for_submission(self):
        # Create a submission for the student and score it
        submission = sub_api.create_submission(self.STUDENT_ITEM, "test answer")
        sub_api.set_score(submission["uuid"], 1, 2)

        # Reset scores
        sub_api.reset_score(
            self.STUDENT_ITEM["student_id"], self.STUDENT_ITEM["course_id"], self.STUDENT_ITEM["item_id"]
        )

        # If we're retrieving the score for a particular submission,
        # instead of a student item, then we should STILL get a score.
        self.assertIsNot(sub_api.get_latest_score_for_submission(submission["uuid"]), None)
Example #47
0
    def score_update(self, submission_result):

        parent = super(ImageMagickXBlock, self)
        if hasattr(parent, 'score_update'):
            parent.score_update(submission_result)

        submission_uid, validation_key = submission_result.lms_key.split('+')

        # TODO: Validate submission
        # submission = submissions_api.get_submission(submission_uid)

        submissions_api.set_score(submission_uid,
                                  int(100 * submission_result.score),
                                  100,
                                  annotation_reason=submission_result.msg
                                  or "undefined",
                                  annotation_creator=self.submission_type,
                                  annotation_type='check')

        self.points = submission_result.score
        self.runtime.publish(
            self, 'grade', {
                'value': submission_result.score * self.max_score(),
                'max_value': self.max_score()
            })

        self.latest_check = None
        try:
            annotation = ifmo_submissions_api.get_annotation(
                self.student_submission_dict())
            message_dict = json.loads(annotation.get('reason'))

            # edx-submission prevents datetime to be converted to str, do it manually
            # TODO: Create own serializer for Score model
            score = annotation.get("score")
            score["created_at"] = str(score["created_at"])

            self.latest_check = {
                "score":
                score,
                "report_file":
                message_dict.get('report_file', ''),
                "report_storage":
                REPORT_STORAGE,
                "message":
                message_dict.get(
                    'err_output',
                    'Произошла неизвестная ошибка при сравнении изображений.'),
            }
        except (ValueError, KeyError):
            pass
Example #48
0
 def enter_grade(self, request, suffix=''):
     require(self.is_course_staff())
     module = StudentModule.objects.get(pk=request.params['module_id'])
     state = json.loads(module.state)
     score = int(request.params['grade'])
     if self.is_instructor():
         uuid = request.params['submission_id']
         submissions_api.set_score(uuid, score, self.max_score())
     else:
         state['staff_score'] = score
     state['comment'] = request.params.get('comment', '')
     module.state = json.dumps(state)
     module.save()
     return Response(json_body=self.staff_grading_data())
Example #49
0
    def test_database_error(self, create_mock):
        # Create a submission for the student and score it
        submission = sub_api.create_submission(self.STUDENT_ITEM,
                                               'test answer')
        sub_api.set_score(submission['uuid'], 1, 2)

        # Simulate a database error when creating the reset score
        create_mock.side_effect = DatabaseError("Test error")
        with self.assertRaises(sub_api.SubmissionInternalError):
            sub_api.reset_score(
                self.STUDENT_ITEM['student_id'],
                self.STUDENT_ITEM['course_id'],
                self.STUDENT_ITEM['item_id'],
            )
Example #50
0
    def set_score(self, score):
        """
        Set a score for the workflow.

        Scores are persisted via the Submissions API, separate from the Workflow
        Data. Score is associated with the same submission_uuid as this workflow

        Args:
            score (dict): A dict containing 'points_earned' and
                'points_possible'.

        """
        sub_api.set_score(self.submission_uuid, score["points_earned"],
                          score["points_possible"])
Example #51
0
    def setUp(self):
        super(TestOraAggregateDataIntegration, self).setUp()
        # Create submissions and assessments
        self.submission = self._create_submission(STUDENT_ITEM)
        self.scorer_submission = self._create_submission(SCORER_ITEM)
        self.earned_points = 1
        self.possible_points = 2
        peer_api.get_submission_to_assess(self.scorer_submission['uuid'], 1)
        self.assessment = self._create_assessment(self.scorer_submission['uuid'])

        sub_api.set_score(self.submission['uuid'], self.earned_points, self.possible_points)
        self.score = sub_api.get_score(STUDENT_ITEM)
        peer_api.get_score(self.submission['uuid'], {'must_be_graded_by': 1, 'must_grade': 0})
        self._create_assessment_feedback(self.submission['uuid'])
    def test_reset_with_one_score(self):
        # Create a submission for the student and score it
        submission = sub_api.create_submission(self.STUDENT_ITEM, "test answer")
        sub_api.set_score(submission["uuid"], 1, 2)

        # Reset scores
        sub_api.reset_score(
            self.STUDENT_ITEM["student_id"], self.STUDENT_ITEM["course_id"], self.STUDENT_ITEM["item_id"]
        )

        # Expect that no scores are available for the student
        self.assertIs(sub_api.get_score(self.STUDENT_ITEM), None)
        scores = sub_api.get_scores(self.STUDENT_ITEM["course_id"], self.STUDENT_ITEM["student_id"])
        self.assertEqual(len(scores), 0)
Example #53
0
    def enter_grade(self, request, suffix=''):
        require(self.is_course_staff())
        module = StudentModule.objects.get(pk=request.params['module_id'])
        state = json.loads(module.state)
        score = int(request.params['grade'])
        if self.is_instructor():
            uuid = request.params['submission_id']
            submissions_api.set_score(uuid, score, self.max_score())
        else:
            state['staff_score'] = score
        state['comment'] = request.params.get('comment', '')
        module.state = json.dumps(state)
        module.save()

        return Response(json_body=self.staff_grading_data())
Example #54
0
    def setUp(self):
        super(TestOraAggregateDataIntegration, self).setUp()
        self.maxDiff = None  # pylint: disable=invalid-name
        # Create submissions and assessments
        self.submission = self._create_submission(STUDENT_ITEM)
        self.scorer_submission = self._create_submission(SCORER_ITEM)
        self.earned_points = 1
        self.possible_points = 2
        peer_api.get_submission_to_assess(self.scorer_submission['uuid'], 1)
        self.assessment = self._create_assessment(self.scorer_submission['uuid'])
        self.assertEqual(self.assessment['parts'][0]['criterion']['label'], "criterion_1")

        sub_api.set_score(self.submission['uuid'], self.earned_points, self.possible_points)
        self.score = sub_api.get_score(STUDENT_ITEM)
        peer_api.get_score(self.submission['uuid'], {'must_be_graded_by': 1, 'must_grade': 0})
        self._create_assessment_feedback(self.submission['uuid'])
    def test_override_with_one_score(self):
        # Create a submission for the student and score it
        submission = sub_api.create_submission(self.STUDENT_ITEM,
                                               'test answer')
        sub_api.set_score(submission['uuid'], 1, 10)

        sub_api.score_override(
            self.STUDENT_ITEM,
            5,
            10,
        )

        self.assertEqual(
            sub_api.get_score(self.STUDENT_ITEM)['points_earned'], 5)
        self.assertEqual(
            sub_api.get_score(self.STUDENT_ITEM)['points_possible'], 10)
 def setUp(self):
     """ Create a submission and score. """
     self.submission = sub_api.create_submission(self.STUDENT_ITEM, "test answer")
     self.score = sub_api.set_score(
         self.submission['uuid'],
         self.SCORE["points_earned"],
         self.SCORE["points_possible"]
     )
Example #57
0
    def test_reset_with_multiple_scores(self):
        # Create a submission for the student and score it
        submission = sub_api.create_submission(self.STUDENT_ITEM, 'test answer')
        sub_api.set_score(submission['uuid'], 1, 2)
        sub_api.set_score(submission['uuid'], 2, 2)

        # Reset scores
        sub_api.reset_score(
            self.STUDENT_ITEM['student_id'],
            self.STUDENT_ITEM['course_id'],
            self.STUDENT_ITEM['item_id'],
        )

        # Expect that no scores are available for the student
        self.assertIs(sub_api.get_score(self.STUDENT_ITEM), None)
        scores = sub_api.get_scores(self.STUDENT_ITEM['course_id'], self.STUDENT_ITEM['student_id'])
        self.assertEqual(len(scores), 0)
    def test_override_doesnt_overwrite_submission_score(self):
        # Create a submission for the student and score it
        submission = sub_api.create_submission(self.STUDENT_ITEM, 'test answer')
        sub_api.set_score(submission['uuid'], 1, 10)

        sub_api.score_override(
            self.STUDENT_ITEM,
            8,
            10,
        )

        submission_score = sub_api.get_latest_score_for_submission(submission['uuid'])
        self.assertEqual(submission_score['points_earned'], 1)
        self.assertEqual(submission_score['points_possible'], 10)

        override_score = sub_api.get_score_override(self.STUDENT_ITEM)
        self.assertEqual(override_score['points_earned'], 8)
        self.assertEqual(override_score['points_possible'], 10)