Esempio n. 1
0
    def test_get_subsection_grade_percentage_with_override(self):
        user = self.request.user
        subsection_key = self.sequence.location

        with mock_get_score(3, 3):
            # this update() call creates a persistent grade
            self.subsection_grade_factory.update(self.sequence)

            # there should only be one persistent grade
            persistent_grade = PersistentSubsectionGrade.objects.first()

            PersistentSubsectionGradeOverride.update_or_create_override(
                UserFactory(
                ),  # it doesn't matter to us who created the override
                persistent_grade,
                earned_graded_override=0,
                earned_all_override=0,
                possible_graded_override=3,
                feature=GradeOverrideFeatureEnum.gradebook,
            )

            # it's important that we stay in the mock_get_score() context here,
            # since get_subsection_grade_percentage() creates its own SubsectionGradeFactory,
            # which will in turn make calls to get_score().
            grade_percentage = gating_api.get_subsection_grade_percentage(
                subsection_key, user)
            assert 0 == grade_percentage
Esempio n. 2
0
    def test_get_subsection_grade_percentage_with_override(self):
        user = self.request.user
        subsection_key = self.sequence.location

        with mock_get_score(3, 3):
            # this update() call creates a persistent grade
            self.subsection_grade_factory.update(self.sequence)

            # there should only be one persistent grade
            persistent_grade = PersistentSubsectionGrade.objects.first()

            PersistentSubsectionGradeOverride.update_or_create_override(
                UserFactory(),  # it doesn't matter to us who created the override
                persistent_grade,
                earned_graded_override=0,
                earned_all_override=0,
                possible_graded_override=3,
                feature=PersistentSubsectionGradeOverrideHistory.GRADEBOOK,
            )

            # it's important that we stay in the mock_get_score() context here,
            # since get_subsection_grade_percentage() creates its own SubsectionGradeFactory,
            # which will in turn make calls to get_score().
            grade_percentage = gating_api.get_subsection_grade_percentage(subsection_key, user)
            assert 0 == grade_percentage
Esempio n. 3
0
    def _create_override(self, request_user, subsection_grade_model, **override_data):
        """
        Helper method to create a `PersistentSubsectionGradeOverride` object
        and send a `SUBSECTION_OVERRIDE_CHANGED` signal.
        """
        override = PersistentSubsectionGradeOverride.update_or_create_override(
            requesting_user=request_user,
            subsection_grade_model=subsection_grade_model,
            feature=grades_constants.GradeOverrideFeatureEnum.gradebook,
            **override_data
        )

        set_event_transaction_type(grades_events.SUBSECTION_GRADE_CALCULATED)
        create_new_event_transaction_id()

        recalculate_subsection_grade_v3.apply(
            kwargs=dict(
                user_id=subsection_grade_model.user_id,
                anonymous_user_id=None,
                course_id=text_type(subsection_grade_model.course_id),
                usage_id=text_type(subsection_grade_model.usage_key),
                only_if_higher=False,
                expected_modified_time=to_timestamp(override.modified),
                score_deleted=False,
                event_transaction_id=six.text_type(get_event_transaction_id()),
                event_transaction_type=six.text_type(get_event_transaction_type()),
                score_db_table=grades_constants.ScoreDatabaseTableEnum.overrides,
                force_update_subsections=True,
            )
        )
        # Emit events to let our tracking system to know we updated subsection grade
        grades_events.subsection_grade_calculated(subsection_grade_model)
        return override
Esempio n. 4
0
    def test_grade_override(self):
        """
        Creating a subsection grade override should NOT change the score values
        of the related PersistentSubsectionGrade.
        """
        grade = PersistentSubsectionGrade.update_or_create_grade(**self.params)
        override = PersistentSubsectionGradeOverride.update_or_create_override(
            requesting_user=self.user,
            subsection_grade_model=grade,
            earned_all_override=0.0,
            earned_graded_override=0.0,
            feature=PersistentSubsectionGradeOverrideHistory.GRADEBOOK,
        )

        grade = PersistentSubsectionGrade.update_or_create_grade(**self.params)
        self.assertEqual(self.params['earned_all'], grade.earned_all)
        self.assertEqual(self.params['earned_graded'], grade.earned_graded)

        # Any score values that aren't specified should use the values from grade as defaults
        self.assertEqual(0, override.earned_all_override)
        self.assertEqual(0, override.earned_graded_override)
        self.assertEqual(grade.possible_all, override.possible_all_override)
        self.assertEqual(grade.possible_graded,
                         override.possible_graded_override)

        # An override history record should be created
        self.assertEqual(
            1,
            PersistentSubsectionGradeOverrideHistory.objects.filter(
                override_id=override.id).count())
Esempio n. 5
0
    def _create_override(self, request_user, subsection_grade_model,
                         **override_data):
        """
        Helper method to create a `PersistentSubsectionGradeOverride` object
        and send a `SUBSECTION_OVERRIDE_CHANGED` signal.
        """
        override_data[
            'system'] = grades_constants.GradeOverrideFeatureEnum.gradebook
        override = PersistentSubsectionGradeOverride.update_or_create_override(
            requesting_user=request_user,
            subsection_grade_model=subsection_grade_model,
            feature=grades_constants.GradeOverrideFeatureEnum.gradebook,
            **override_data)

        set_event_transaction_type(grades_events.SUBSECTION_GRADE_CALCULATED)
        create_new_event_transaction_id()

        recalculate_subsection_grade_v3.apply(kwargs=dict(
            user_id=subsection_grade_model.user_id,
            anonymous_user_id=None,
            course_id=text_type(subsection_grade_model.course_id),
            usage_id=text_type(subsection_grade_model.usage_key),
            only_if_higher=False,
            expected_modified_time=to_timestamp(override.modified),
            score_deleted=False,
            event_transaction_id=six.text_type(get_event_transaction_id()),
            event_transaction_type=six.text_type(get_event_transaction_type()),
            score_db_table=grades_constants.ScoreDatabaseTableEnum.overrides,
            force_update_subsections=True,
        ))
        # Emit events to let our tracking system to know we updated subsection grade
        grades_events.subsection_grade_calculated(subsection_grade_model)
        return override
Esempio n. 6
0
    def test_grade_override(self):
        """
        Creating a subsection grade override should NOT change the score values
        of the related PersistentSubsectionGrade.
        """
        grade = PersistentSubsectionGrade.update_or_create_grade(**self.params)
        override = PersistentSubsectionGradeOverride.update_or_create_override(
            requesting_user=self.user,
            subsection_grade_model=grade,
            earned_all_override=0.0,
            earned_graded_override=0.0,
            feature=GradeOverrideFeatureEnum.gradebook,
        )

        grade = PersistentSubsectionGrade.update_or_create_grade(**self.params)
        self.assertEqual(self.params['earned_all'], grade.earned_all)
        self.assertEqual(self.params['earned_graded'], grade.earned_graded)
        history = override.get_history()
        self.assertEqual(1, len(list(history)))
        self.assertEqual('+', list(history)[0].history_type)
        # Any score values that aren't specified should use the values from grade as defaults
        self.assertEqual(0, override.earned_all_override)
        self.assertEqual(0, override.earned_graded_override)
        self.assertEqual(grade.possible_all, override.possible_all_override)
        self.assertEqual(grade.possible_graded, override.possible_graded_override)
Esempio n. 7
0
    def test_grade_override(self):
        """
        Creating a subsection grade override should NOT change the score values
        of the related PersistentSubsectionGrade.
        """
        grade = PersistentSubsectionGrade.update_or_create_grade(**self.params)
        override = PersistentSubsectionGradeOverride.update_or_create_override(
            requesting_user=self.user,
            subsection_grade_model=grade,
            earned_all_override=0.0,
            earned_graded_override=0.0,
            feature=GradeOverrideFeatureEnum.gradebook,
        )

        grade = PersistentSubsectionGrade.update_or_create_grade(**self.params)
        assert self.params['earned_all'] == grade.earned_all
        assert self.params['earned_graded'] == grade.earned_graded
        history = override.get_history()
        assert 1 == len(list(history))
        assert '+' == list(history)[0].history_type
        # Any score values that aren't specified should use the values from grade as defaults
        assert 0 == override.earned_all_override
        assert 0 == override.earned_graded_override
        assert grade.possible_all == override.possible_all_override
        assert grade.possible_graded == override.possible_graded_override
Esempio n. 8
0
def update_or_create_override(grade, **kwargs):
    """
    Update or creates a subsection override.
    """
    kwargs['subsection_grade_model'] = grade
    return _PersistentSubsectionGradeOverride.update_or_create_override(
        **kwargs)
Esempio n. 9
0
    def test_grade_override(self):
        """
        Creating a subsection grade override should NOT change the score values
        of the related PersistentSubsectionGrade.
        """
        grade = PersistentSubsectionGrade.update_or_create_grade(**self.params)
        override = PersistentSubsectionGradeOverride.update_or_create_override(
            requesting_user=self.user,
            subsection_grade_model=grade,
            earned_all_override=0.0,
            earned_graded_override=0.0,
            feature=PersistentSubsectionGradeOverrideHistory.GRADEBOOK,
        )

        grade = PersistentSubsectionGrade.update_or_create_grade(**self.params)
        self.assertEqual(self.params['earned_all'], grade.earned_all)
        self.assertEqual(self.params['earned_graded'], grade.earned_graded)

        # Any score values that aren't specified should use the values from grade as defaults
        self.assertEqual(0, override.earned_all_override)
        self.assertEqual(0, override.earned_graded_override)
        self.assertEqual(grade.possible_all, override.possible_all_override)
        self.assertEqual(grade.possible_graded, override.possible_graded_override)

        # An override history record should be created
        self.assertEqual(1, PersistentSubsectionGradeOverrideHistory.objects.filter(override_id=override.id).count())
Esempio n. 10
0
    def test_override_is_visible(self):
        with persistent_grades_feature_flags(global_flag=True):
            chapter = ItemFactory(parent=self.course, category='chapter')
            subsection = ItemFactory.create(parent=chapter,
                                            category="sequential",
                                            display_name="Subsection")

            CourseEnrollment.enroll(self.user, self.course.id)

            params = {
                "user_id": self.user.id,
                "usage_key": subsection.location,
                "course_version": self.course.course_version,
                "subtree_edited_timestamp": "2016-08-01 18:53:24.354741Z",
                "earned_all": 6.0,
                "possible_all": 12.0,
                "earned_graded": 6.0,
                "possible_graded": 8.0,
                "visible_blocks": [],
                "first_attempted": datetime.now(),
            }

            created_grade = PersistentSubsectionGrade.update_or_create_grade(
                **params)
            proctoring_failure_comment = "Failed Test Proctoring"
            PersistentSubsectionGradeOverride.update_or_create_override(
                requesting_user=self.staff_user,
                subsection_grade_model=created_grade,
                earned_all_override=0.0,
                earned_graded_override=0.0,
                system=GradeOverrideFeatureEnum.proctoring,
                feature=GradeOverrideFeatureEnum.proctoring,
                comment=proctoring_failure_comment)

            response = self.client.get(self.url)
            assert response.status_code == 200

            sections = response.data['section_scores']
            overridden_subsection = sections[1]['subsections'][0]
            override_entry = overridden_subsection["override"]

            assert override_entry[
                'system'] == GradeOverrideFeatureEnum.proctoring
            assert override_entry['reason'] == proctoring_failure_comment