feat: adding unenrollments to event bus (#33085)
* feat: adding unenrollments to event bus * fix: quality fixes * fix: tweaks to pass tests * fix: more tweaks for testing --------- Co-authored-by: John Nagro <jnagro@edx.org>
This commit is contained in:
@@ -303,11 +303,13 @@ CREDENTIALS_PUBLIC_SERVICE_URL = 'http://localhost:18150'
|
||||
# in the LMS and CMS.
|
||||
# .. toggle_tickets: 'https://github.com/openedx/edx-platform/pull/31813'
|
||||
FEATURES['ENABLE_SEND_XBLOCK_EVENTS_OVER_BUS'] = True
|
||||
FEATURES['ENABLE_SEND_ENROLLMENT_EVENTS_OVER_BUS'] = True
|
||||
EVENT_BUS_PRODUCER = 'edx_event_bus_redis.create_producer'
|
||||
EVENT_BUS_REDIS_CONNECTION_URL = 'redis://:password@edx.devstack.redis:6379/'
|
||||
EVENT_BUS_TOPIC_PREFIX = 'dev'
|
||||
EVENT_BUS_CONSUMER = 'edx_event_bus_redis.RedisEventConsumer'
|
||||
EVENT_BUS_XBLOCK_LIFECYCLE_TOPIC = 'course-authoring-xblock-lifecycle'
|
||||
EVENT_BUS_ENROLLMENT_LIFECYCLE_TOPIC = 'course-authoring-enrollment-lifecycle'
|
||||
|
||||
################# New settings must go ABOVE this line #################
|
||||
########################################################################
|
||||
|
||||
25
common/djangoapps/student/handlers.py
Normal file
25
common/djangoapps/student/handlers.py
Normal file
@@ -0,0 +1,25 @@
|
||||
"""
|
||||
Handlers for student
|
||||
"""
|
||||
from django.conf import settings
|
||||
from django.dispatch import receiver
|
||||
|
||||
from openedx_events.event_bus import get_producer
|
||||
from openedx_events.learning.signals import (
|
||||
COURSE_UNENROLLMENT_COMPLETED,
|
||||
)
|
||||
|
||||
|
||||
@receiver(COURSE_UNENROLLMENT_COMPLETED)
|
||||
def course_unenrollment_receiver(sender, signal, **kwargs):
|
||||
"""
|
||||
Removes user notification preference when user un-enrolls from the course
|
||||
"""
|
||||
if settings.FEATURES.get("ENABLE_SEND_ENROLLMENT_EVENTS_OVER_BUS"):
|
||||
get_producer().send(
|
||||
signal=COURSE_UNENROLLMENT_COMPLETED,
|
||||
topic=getattr(settings, "EVENT_BUS_ENROLLMENT_LIFECYCLE_TOPIC", "course-unenrollment-lifecycle"),
|
||||
event_key_field='enrollment.course.course_key',
|
||||
event_data={'enrollment': kwargs.get('enrollment')},
|
||||
event_metadata=kwargs.get('metadata')
|
||||
)
|
||||
67
common/djangoapps/student/tests/test_handlers.py
Normal file
67
common/djangoapps/student/tests/test_handlers.py
Normal file
@@ -0,0 +1,67 @@
|
||||
"""
|
||||
Unit tests for event bus tests for course unenrollments
|
||||
"""
|
||||
|
||||
import unittest
|
||||
from datetime import datetime, timezone
|
||||
from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from django.test.utils import override_settings
|
||||
from common.djangoapps.student.handlers import course_unenrollment_receiver
|
||||
from common.djangoapps.student.tests.factories import (
|
||||
UserFactory,
|
||||
CourseEnrollmentFactory,
|
||||
)
|
||||
|
||||
from openedx_events.data import EventsMetadata
|
||||
from openedx_events.learning.signals import COURSE_UNENROLLMENT_COMPLETED
|
||||
from pytest import mark
|
||||
|
||||
|
||||
@mark.django_db
|
||||
class UnenrollmentEventBusTests(unittest.TestCase):
|
||||
"""
|
||||
Tests for unenrollment events that interact with the event bus.
|
||||
"""
|
||||
@override_settings(ENABLE_SEND_ENROLLMENT_EVENTS_OVER_BUS=False)
|
||||
@mock.patch('common.djangoapps.student.handlers.get_producer', autospec=True)
|
||||
def test_event_disabled(self, mock_producer):
|
||||
"""
|
||||
Test to verify that we do not push `CERTIFICATE_CREATED` events to the event bus if the
|
||||
`SEND_CERTIFICATE_CREATED_SIGNAL` setting is disabled.
|
||||
"""
|
||||
course_unenrollment_receiver(None, None)
|
||||
mock_producer.assert_not_called()
|
||||
|
||||
@override_settings(FEATURES={'ENABLE_SEND_ENROLLMENT_EVENTS_OVER_BUS': True})
|
||||
@mock.patch('common.djangoapps.student.handlers.get_producer', autospec=True)
|
||||
def test_event_enabled(self, mock_producer):
|
||||
"""
|
||||
Test to verify that we push `COURSE_UNENROLLMENT_COMPLETED` events to the event bus.
|
||||
"""
|
||||
user = UserFactory()
|
||||
enrollment = CourseEnrollmentFactory(user=user)
|
||||
|
||||
event_metadata = EventsMetadata(
|
||||
event_type=COURSE_UNENROLLMENT_COMPLETED.event_type,
|
||||
id=uuid4(),
|
||||
minorversion=0,
|
||||
source='openedx/lms/web',
|
||||
sourcehost='lms.test',
|
||||
time=datetime.now(timezone.utc)
|
||||
)
|
||||
|
||||
event_kwargs = {
|
||||
'enrollment': enrollment,
|
||||
'metadata': event_metadata
|
||||
}
|
||||
course_unenrollment_receiver(None, COURSE_UNENROLLMENT_COMPLETED, **event_kwargs)
|
||||
|
||||
# verify that the data sent to the event bus matches what we expect
|
||||
print(mock_producer.return_value)
|
||||
print(mock_producer.return_value.send.call_args)
|
||||
data = mock_producer.return_value.send.call_args.kwargs
|
||||
assert data['event_data']['enrollment'] == enrollment
|
||||
assert data['topic'] == 'course-unenrollment-lifecycle'
|
||||
assert data['event_key_field'] == 'enrollment.course.course_key'
|
||||
@@ -46,7 +46,7 @@ def on_user_course_unenrollment(enrollment, **kwargs):
|
||||
preference = CourseNotificationPreference.objects.get(user__id=user_id, course_id=course_key)
|
||||
preference.delete()
|
||||
except ObjectDoesNotExist:
|
||||
log.info(f'Notification Preference doesnot exist for {enrollment.user.pii.username} in {course_key}')
|
||||
log.info(f'Notification Preference does not exist for {enrollment.user.pii.username} in {course_key}')
|
||||
|
||||
|
||||
@receiver(USER_NOTIFICATION_REQUESTED)
|
||||
|
||||
Reference in New Issue
Block a user