fix: [AA-1076] add override info to progress API (#29585)
* fix: [AA-1076] add override info to progress API - Indicate if a grade has been overridden in the progress tab.
This commit is contained in:
@@ -27,6 +27,7 @@ class SubsectionScoresSerializer(ReadOnlySerializer):
|
||||
block_key = serializers.SerializerMethodField()
|
||||
display_name = serializers.CharField()
|
||||
has_graded_assignment = serializers.BooleanField(source='graded')
|
||||
override = serializers.SerializerMethodField()
|
||||
learner_has_access = serializers.SerializerMethodField()
|
||||
num_points_earned = serializers.FloatField(source='graded_total.earned')
|
||||
num_points_possible = serializers.FloatField(source='graded_total.possible')
|
||||
@@ -36,6 +37,16 @@ class SubsectionScoresSerializer(ReadOnlySerializer):
|
||||
show_grades = serializers.SerializerMethodField()
|
||||
url = serializers.SerializerMethodField()
|
||||
|
||||
def get_override(self, subsection):
|
||||
"""Proctoring or grading score override"""
|
||||
if subsection.override is None:
|
||||
return None
|
||||
else:
|
||||
return {
|
||||
"system": subsection.override.system,
|
||||
"reason": subsection.override.override_reason,
|
||||
}
|
||||
|
||||
def get_block_key(self, subsection):
|
||||
return str(subsection.location)
|
||||
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
Tests for Progress Tab API in the Course Home API
|
||||
"""
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
import dateutil
|
||||
import ddt
|
||||
from datetime import datetime, timedelta # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from django.conf import settings
|
||||
|
||||
from pytz import UTC
|
||||
from unittest.mock import patch # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from django.urls import reverse
|
||||
@@ -17,6 +19,12 @@ from common.djangoapps.student.tests.factories import UserFactory
|
||||
from lms.djangoapps.course_home_api.tests.utils import BaseCourseHomeTests
|
||||
from lms.djangoapps.course_home_api.models import DisableProgressPageStackedConfig
|
||||
from lms.djangoapps.course_home_api.toggles import COURSE_HOME_MICROFRONTEND_PROGRESS_TAB
|
||||
from lms.djangoapps.grades.config.tests.utils import persistent_grades_feature_flags
|
||||
from lms.djangoapps.grades.constants import GradeOverrideFeatureEnum
|
||||
from lms.djangoapps.grades.models import (
|
||||
PersistentSubsectionGrade,
|
||||
PersistentSubsectionGradeOverride
|
||||
)
|
||||
from lms.djangoapps.verify_student.models import ManualVerification
|
||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
||||
from openedx.core.djangoapps.course_date_signals.utils import MIN_DURATION
|
||||
@@ -184,6 +192,50 @@ class ProgressTabTestViews(BaseCourseHomeTests):
|
||||
assert not gated_score['learner_has_access']
|
||||
assert ungated_score['learner_has_access']
|
||||
|
||||
@override_waffle_flag(COURSE_HOME_MICROFRONTEND_PROGRESS_TAB, active=True)
|
||||
@patch.dict(settings.FEATURES, {'ASSUME_ZERO_GRADE_IF_ABSENT_FOR_ALL_TESTS': False})
|
||||
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"
|
||||
override = 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
|
||||
|
||||
@override_waffle_flag(COURSE_HOME_MICROFRONTEND_PROGRESS_TAB, active=True)
|
||||
def test_view_other_students_progress_page(self):
|
||||
# Test the ability to view progress pages of other students by changing the url
|
||||
|
||||
@@ -102,6 +102,9 @@ class ProgressTabView(RetrieveAPIView):
|
||||
learner_has_access: (bool) whether the learner has access to the subsection (could be FBE gated)
|
||||
num_points_earned: (int) the amount of points the user has earned for the given subsection
|
||||
num_points_possible: (int) the total amount of points possible for the given subsection
|
||||
override: Optional object if grade has been overridden by proctor or grading change
|
||||
system: (str) either GRADING or PROCTORING
|
||||
reason: (str) a comment on the grading override
|
||||
percent_graded: (float) the percentage of total points the user has received a grade for in a given
|
||||
subsection
|
||||
problem_scores: List of objects that represent individual problem scores with the following fields:
|
||||
|
||||
Reference in New Issue
Block a user