Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: emit event for rejected exam attempt #181

Merged
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
14 changes: 13 additions & 1 deletion edx_exams/apps/core/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@
ExamIllegalStatusTransition
)
from edx_exams.apps.core.models import Exam, ExamAttempt
from edx_exams.apps.core.signals.signals import emit_exam_attempt_submitted_event, emit_exam_attempt_verified_event
from edx_exams.apps.core.signals.signals import (
emit_exam_attempt_rejected_event,
emit_exam_attempt_submitted_event,
emit_exam_attempt_verified_event
)
from edx_exams.apps.core.statuses import ExamAttemptStatus

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -115,6 +119,14 @@ def update_attempt_status(attempt_id, to_status):
attempt_obj.exam.exam_type
)

if to_status == ExamAttemptStatus.rejected:
emit_exam_attempt_rejected_event(
attempt_obj.user,
course_key,
usage_key,
attempt_obj.exam.exam_type
)

attempt_obj.status = to_status
attempt_obj.save()

Expand Down
16 changes: 15 additions & 1 deletion edx_exams/apps/core/signals/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""
from django.dispatch import receiver
from openedx_events.event_bus import get_producer
from openedx_events.learning.signals import EXAM_ATTEMPT_SUBMITTED, EXAM_ATTEMPT_VERIFIED
from openedx_events.learning.signals import EXAM_ATTEMPT_REJECTED, EXAM_ATTEMPT_SUBMITTED, EXAM_ATTEMPT_VERIFIED


@receiver(EXAM_ATTEMPT_SUBMITTED)
Expand Down Expand Up @@ -32,3 +32,17 @@
event_data={'exam_attempt': kwargs['exam_attempt']},
event_metadata=kwargs['metadata'],
)


@receiver(EXAM_ATTEMPT_REJECTED)
def listen_for_exam_attempt_rejected(sender, signal, **kwargs): # pylint: disable=unused-argument
"""
Publish EXAM_ATTEMPT_REJECTED signal onto the event bus
"""
get_producer().send(

Check warning on line 42 in edx_exams/apps/core/signals/handlers.py

View check run for this annotation

Codecov / codecov/patch

edx_exams/apps/core/signals/handlers.py#L42

Added line #L42 was not covered by tests
signal=EXAM_ATTEMPT_REJECTED,
topic='exam-attempt-rejected',
event_key_field='exam_attempt.course_key',
event_data={'exam_attempt': kwargs['exam_attempt']},
event_metadata=kwargs['metadata'],
)
30 changes: 27 additions & 3 deletions edx_exams/apps/core/signals/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""

from openedx_events.learning.data import ExamAttemptData, UserData, UserPersonalData
from openedx_events.learning.signals import EXAM_ATTEMPT_SUBMITTED, EXAM_ATTEMPT_VERIFIED
from openedx_events.learning.signals import EXAM_ATTEMPT_REJECTED, EXAM_ATTEMPT_SUBMITTED, EXAM_ATTEMPT_VERIFIED


def emit_exam_attempt_submitted_event(user, course_key, usage_key, exam_type):
Expand Down Expand Up @@ -36,14 +36,13 @@ def emit_exam_attempt_verified_event(user, course_key, usage_key, exam_type):
"""
Emit the EXAM_ATTEMPT_VERIFIED Open edX event.
"""
name = user.full_name or ''
user_data = UserData(
id=user.id,
is_active=user.is_active,
pii=UserPersonalData(
username=user.username,
email=user.email,
name=name
name=user.full_name
)
)

Expand All @@ -56,3 +55,28 @@ def emit_exam_attempt_verified_event(user, course_key, usage_key, exam_type):
exam_type=exam_type
)
)


def emit_exam_attempt_rejected_event(user, course_key, usage_key, exam_type):
"""
Emit the EXAM_ATTEMPT_REJECTED Open edX event.
"""
user_data = UserData(
id=user.id,
is_active=user.is_active,
pii=UserPersonalData(
username=user.username,
email=user.email,
name=user.full_name
)
)

# .. event_implemented_name: EXAM_ATTEMPT_REJECTED
EXAM_ATTEMPT_REJECTED.send_event(
exam_attempt=ExamAttemptData(
student_user=user_data,
course_key=course_key,
usage_key=usage_key,
exam_type=exam_type
)
)
28 changes: 28 additions & 0 deletions edx_exams/apps/core/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,34 @@ def test_verified_attempt_event_emitted(self, mock_event_send):
)
mock_event_send.assert_called_with(exam_attempt=expected_data)

@patch('edx_exams.apps.core.signals.signals.EXAM_ATTEMPT_REJECTED.send_event')
def test_reject_attempt_event_emitted(self, mock_event_send):
"""
Test that when an exam is rejected, the EXAM_ATTEMPT_REJECTED Open edX event is emitted.
"""
update_attempt_status(self.exam_attempt.id, ExamAttemptStatus.rejected)
self.assertEqual(mock_event_send.call_count, 1)

user_data = UserData(
id=self.user.id,
is_active=self.user.is_active,
pii=UserPersonalData(
username=self.user.username,
email=self.user.email,
name=self.user.full_name
)
)
course_key = CourseKey.from_string(self.exam.course_id)
usage_key = UsageKey.from_string(self.exam.content_id)

expected_data = ExamAttemptData(
student_user=user_data,
course_key=course_key,
usage_key=usage_key,
exam_type=self.exam.exam_type,
)
mock_event_send.assert_called_with(exam_attempt=expected_data)

def test_illegal_start(self):
"""
Test that an already started exam cannot be started
Expand Down
Loading