EDUCATOR-3668 | The CreateSubsectionGrade class should reflect possibly overridden values from the PersistentSubsectionGrade class.
This commit is contained in:
committed by
Alex Dusenbery
parent
19b7adae5c
commit
7b04832606
@@ -253,7 +253,29 @@ class CreateSubsectionGrade(NonZeroSubsectionGrade):
|
||||
Saves or updates the subsection grade in a persisted model.
|
||||
"""
|
||||
if self._should_persist_per_attempted(score_deleted, force_update_subsections):
|
||||
return PersistentSubsectionGrade.update_or_create_grade(**self._persisted_model_params(student))
|
||||
model = PersistentSubsectionGrade.update_or_create_grade(**self._persisted_model_params(student))
|
||||
self._update_aggregated_scores_from_model(model)
|
||||
return model
|
||||
|
||||
def _update_aggregated_scores_from_model(self, model):
|
||||
"""
|
||||
Updates this grade's `all_total` and `graded_total` attributes
|
||||
to reflect the values from the related persisted model.
|
||||
This is important, because PersistentSubsectionGradeOverrides
|
||||
are only taken into account when reading/writing at the persistence layer,
|
||||
so after we update a PersistentSubsectionGrade model (which could involve
|
||||
writing values that are overridden by the PersistentSubsectionGradeOverride model)
|
||||
we also need to update this grade object's attributes to reflect the
|
||||
now (possibly) overriden values.
|
||||
TODO: https://openedx.atlassian.net/browse/EDUCATOR-3835
|
||||
"""
|
||||
self.all_total.earned = model.earned_all
|
||||
self.all_total.possible = model.possible_all
|
||||
self.all_total.first_attempted = model.first_attempted
|
||||
|
||||
self.graded_total.earned = model.earned_graded
|
||||
self.graded_total.possible = model.possible_graded
|
||||
self.graded_total.first_attempted = model.first_attempted
|
||||
|
||||
@classmethod
|
||||
def bulk_create_models(cls, student, subsection_grades, course_key):
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
"""
|
||||
Tests for the SubsectionGradeFactory class.
|
||||
"""
|
||||
import ddt
|
||||
from courseware.tests.test_submitting_problems import ProblemSubmissionTestMixin
|
||||
from django.conf import settings
|
||||
from lms.djangoapps.grades.config.tests.utils import persistent_grades_feature_flags
|
||||
from mock import patch
|
||||
|
||||
from ..models import PersistentSubsectionGrade
|
||||
from ..models import PersistentSubsectionGrade, PersistentSubsectionGradeOverride
|
||||
from ..subsection_grade_factory import ZeroSubsectionGrade
|
||||
from .base import GradeTestBase
|
||||
from .utils import mock_get_score
|
||||
@@ -29,6 +32,10 @@ class TestSubsectionGradeFactory(ProblemSubmissionTestMixin, GradeTestBase):
|
||||
(grade.all_total.earned, grade.all_total.possible),
|
||||
(expected_earned, expected_possible),
|
||||
)
|
||||
self.assertEqual(
|
||||
(grade.graded_total.earned, grade.graded_total.possible),
|
||||
(expected_earned, expected_possible),
|
||||
)
|
||||
|
||||
def test_create_zero(self):
|
||||
"""
|
||||
@@ -100,3 +107,32 @@ class TestSubsectionGradeFactory(ProblemSubmissionTestMixin, GradeTestBase):
|
||||
):
|
||||
self.subsection_grade_factory.create(self.sequence)
|
||||
self.assertEqual(mock_read_saved_grade.called, feature_flag and course_setting)
|
||||
|
||||
def test_update_with_override(self):
|
||||
"""
|
||||
Tests that when a PersistentSubsectionGradeOverride exists, the update()
|
||||
method returns a CreateSubsectionGrade with scores that account
|
||||
for the override.
|
||||
"""
|
||||
# first, do an update to create a persistent grade
|
||||
with mock_get_score(2, 3):
|
||||
grade = self.subsection_grade_factory.update(self.sequence)
|
||||
self.assert_grade(grade, 2, 3)
|
||||
|
||||
# there should only be one persistent grade
|
||||
persistent_grade = PersistentSubsectionGrade.objects.first()
|
||||
self.assertEqual(2, persistent_grade.earned_graded)
|
||||
self.assertEqual(3, persistent_grade.possible_graded)
|
||||
|
||||
# Now create the override
|
||||
PersistentSubsectionGradeOverride.objects.create(
|
||||
grade=persistent_grade,
|
||||
earned_graded_override=0,
|
||||
earned_all_override=0,
|
||||
)
|
||||
|
||||
# Now, even if the problem scores interface gives us a 2/3,
|
||||
# the subsection grade returned should be 0/3 due to the override.
|
||||
with mock_get_score(2, 3):
|
||||
grade = self.subsection_grade_factory.update(self.sequence)
|
||||
self.assert_grade(grade, 0, 3)
|
||||
|
||||
Reference in New Issue
Block a user