Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion lms/djangoapps/grades/signals/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from django.dispatch import receiver
from opaque_keys.edx.keys import LearningContextKey
from openedx_events.learning.signals import EXAM_ATTEMPT_VERIFIED
from openedx_events.learning.signals import EXAM_ATTEMPT_REJECTED, EXAM_ATTEMPT_VERIFIED
from submissions.models import score_reset, score_set
from xblock.scorable import ScorableXBlockMixin, Score

Expand Down Expand Up @@ -322,3 +322,28 @@ def exam_attempt_verified_event_handler(sender, signal, **kwargs): # pylint: di

if should_override_grade_on_rejected_exam(course_key):
undo_override_subsection_grade(user_data.id, course_key, usage_key, GradeOverrideFeatureEnum.proctoring)


@receiver(EXAM_ATTEMPT_REJECTED)
def exam_attempt_rejected_event_handler(sender, signal, **kwargs): # pylint: disable=unused-argument
"""
Consume `EXAM_ATTEMPT_REJECTED` events from the event bus. This will trigger a subsection override.
"""
from ..api import override_subsection_grade

event_data = kwargs.get('exam_attempt')
override_grade_value = 0.0
user_data = event_data.student_user
course_key = event_data.course_key
usage_key = event_data.usage_key

override_subsection_grade(
user_data.id,
course_key,
usage_key,
earned_all=override_grade_value,
earned_graded=override_grade_value,
Comment thread
varshamenon4 marked this conversation as resolved.
Outdated
feature=GradeOverrideFeatureEnum.proctoring,
overrider=None,
comment=None,
)
34 changes: 32 additions & 2 deletions lms/djangoapps/grades/tests/test_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@
from opaque_keys.edx.keys import CourseKey, UsageKey
from openedx_events.data import EventsMetadata
from openedx_events.learning.data import ExamAttemptData, UserData, UserPersonalData
from openedx_events.learning.signals import EXAM_ATTEMPT_VERIFIED
from openedx_events.learning.signals import EXAM_ATTEMPT_REJECTED, EXAM_ATTEMPT_VERIFIED

from common.djangoapps.student.tests.factories import UserFactory
from lms.djangoapps.grades.signals.handlers import exam_attempt_verified_event_handler
from lms.djangoapps.grades.signals.handlers import (
exam_attempt_rejected_event_handler,
exam_attempt_verified_event_handler
)
from ..constants import GradeOverrideFeatureEnum


Expand Down Expand Up @@ -101,3 +104,30 @@ def test_exam_attempt_verified_event_handler(self, override_enabled, mock_undo_o
)
else:
mock_undo_override.assert_not_called()

@mock.patch('lms.djangoapps.grades.api.override_subsection_grade')
def test_exam_attempt_rejected_event_handler(self, mock_override):
exam_event_data = self._get_exam_event_data(self.student_user,
self.course_key,
self.usage_key,
exam_type='proctored')
event_metadata = self._get_exam_event_metadata(EXAM_ATTEMPT_REJECTED)

event_kwargs = {
'exam_attempt': exam_event_data,
'metadata': event_metadata
}
exam_attempt_rejected_event_handler(None, EXAM_ATTEMPT_REJECTED, ** event_kwargs)

override_grade_value = 0.0

mock_override.assert_called_once_with(
self.student_user.id,
self.course_key,
self.usage_key,
earned_all=override_grade_value,
earned_graded=override_grade_value,
feature=GradeOverrideFeatureEnum.proctoring,
overrider=None,
comment=None,
)