Attribute grade overrides from proctoring to the final reviewer

More generally, makes it so we don't ever pull in the user to whom
we're attributing overrides from the request, but always use the one
passed in via method parameters

Also pass through comments, if they're provided via this method

JIRA:EDUCATOR-4641
This commit is contained in:
Matt Hughes
2019-09-27 10:31:35 -04:00
committed by Matt Hughes
parent 6f3e1e7e3d
commit 6085852c99
6 changed files with 41 additions and 14 deletions

View File

@@ -679,6 +679,7 @@ class PersistentSubsectionGradeOverride(models.Model):
# model in the grades app, which will fail.
if 'grades' in apps.app_configs:
history = HistoricalRecords()
_history_user = None
def __str__(self):
return u', '.join([
@@ -734,15 +735,18 @@ class PersistentSubsectionGradeOverride(models.Model):
log.info(u'Creating override for user ***{}*** for PersistentSubsectionGrade'
u'***{}*** with override data ***{}*** and derived grade_defaults ***{}***.'
.format(requesting_user, subsection_grade_model, override_data, grade_defaults))
override, _ = PersistentSubsectionGradeOverride.objects.update_or_create(
grade=subsection_grade_model,
defaults=grade_defaults,
)
override_history_entry = override.history.first()
if not override_history_entry.history_user and requesting_user:
override_history_entry.history_user = requesting_user
override_history_entry.save()
try:
override = PersistentSubsectionGradeOverride.objects.get(grade=subsection_grade_model)
for key, value in six.iteritems(grade_defaults):
setattr(override, key, value)
except PersistentSubsectionGradeOverride.DoesNotExist:
override = PersistentSubsectionGradeOverride(grade=subsection_grade_model, **grade_defaults)
if requesting_user:
# setting this on a non-field attribute which simple
# history reads from to determine which user to attach to
# the history row
override._history_user = requesting_user # pylint: disable=protected-access
override.save()
return override

View File

@@ -1813,6 +1813,27 @@ class SubsectionGradeViewTest(GradebookViewTestBase):
assert expected_data == resp.data
def test_comment_appears(self):
"""
Test that comments passed (e.g. from proctoring) appear in the history rows
"""
proctoring_failure_fake_comment = "Failed Test Proctoring"
self.login_course_staff()
override = PersistentSubsectionGradeOverride.update_or_create_override(
requesting_user=self.global_staff,
subsection_grade_model=self.grade,
earned_all_override=0.0,
earned_graded_override=0.0,
feature=GradeOverrideFeatureEnum.proctoring,
comment=proctoring_failure_fake_comment
)
resp = self.client.get(
self.get_url(subsection_id=self.usage_key)
)
assert resp.data['history'][0]['override_reason'] == proctoring_failure_fake_comment
@ddt.data(
'login_staff',
)

View File

@@ -29,7 +29,7 @@ class GradesService(object):
def override_subsection_grade(
self, user_id, course_key_or_id, usage_key_or_id, earned_all=None, earned_graded=None,
feature=api.constants.GradeOverrideFeatureEnum.proctoring
feature=api.constants.GradeOverrideFeatureEnum.proctoring, overrider=None, comment=None
):
"""
Creates a PersistentSubsectionGradeOverride corresponding to the given
@@ -46,7 +46,9 @@ class GradesService(object):
usage_key_or_id,
earned_all=earned_all,
earned_graded=earned_graded,
feature=feature)
feature=feature,
overrider=overrider,
comment=comment)
def undo_override_subsection_grade(self, user_id, course_key_or_id, usage_key_or_id,
feature=api.constants.GradeOverrideFeatureEnum.proctoring):

View File

@@ -113,7 +113,7 @@ edx-oauth2-provider==1.3.1
edx-opaque-keys[django]==2.0.0
edx-organizations==2.1.0
edx-proctoring-proctortrack==1.0.5
edx-proctoring==2.0.9
edx-proctoring==2.1.0
edx-rbac==1.0.3 # via edx-enterprise
edx-rest-api-client==1.9.2
edx-search==1.2.2

View File

@@ -137,7 +137,7 @@ edx-oauth2-provider==1.3.1
edx-opaque-keys[django]==2.0.0
edx-organizations==2.1.0
edx-proctoring-proctortrack==1.0.5
edx-proctoring==2.0.9
edx-proctoring==2.1.0
edx-rbac==1.0.3
edx-rest-api-client==1.9.2
edx-search==1.2.2

View File

@@ -133,7 +133,7 @@ edx-oauth2-provider==1.3.1
edx-opaque-keys[django]==2.0.0
edx-organizations==2.1.0
edx-proctoring-proctortrack==1.0.5
edx-proctoring==2.0.9
edx-proctoring==2.1.0
edx-rbac==1.0.3
edx-rest-api-client==1.9.2
edx-search==1.2.2