feat: add 'external course updates' experiment flag

When this flag is enabled, users will be 50/50 bucketed into an
experiment where users get course highlights and nudges from an
external service (like sailthru or braze) rather than from
edx-platform via ACE.

AA-661
This commit is contained in:
Michael Terry
2021-02-23 14:34:38 -05:00
parent e792242b5f
commit 9570c1c72b
11 changed files with 266 additions and 30 deletions

View File

@@ -1467,6 +1467,7 @@ class CourseEnrollment(models.Model):
"""
Emits an event to explicitly track course enrollment and unenrollment.
"""
from openedx.core.djangoapps.schedules.config import set_up_external_updates_for_enrollment
try:
context = contexts.course_context_from_course_id(self.course_id)
@@ -1486,11 +1487,14 @@ class CourseEnrollment(models.Model):
}
if event_name == EVENT_NAME_ENROLLMENT_ACTIVATED:
segment_properties['email'] = self.user.email
# This next property is for an experiment, see method's comments for more information
segment_properties['external_course_updates'] = set_up_external_updates_for_enrollment(self.user,
self.course_id)
with tracker.get_tracker().context(event_name, context):
tracker.emit(event_name, data)
segment.track(self.user_id, event_name, segment_properties)
except: # pylint: disable=bare-except
except Exception: # pylint: disable=broad-except
if event_name and self.course_id:
log.exception(
u'Unable to emit event %s for user %s and course %s',

View File

@@ -10,7 +10,7 @@ from django.db import IntegrityError
from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver
from lms.djangoapps.courseware.toggles import courseware_mfe_first_section_celebration_is_active
from lms.djangoapps.courseware.toggles import courseware_mfe_progress_milestones_are_active
from common.djangoapps.student.helpers import EMAIL_EXISTS_MSG_FMT, USERNAME_EXISTS_MSG_FMT, AccountValidationError
from common.djangoapps.student.models import CourseEnrollment, CourseEnrollmentCelebration, is_email_retired, is_username_retired # lint-amnesty, pylint: disable=line-too-long
@@ -59,7 +59,7 @@ def create_course_enrollment_celebration(sender, instance, created, **kwargs):
# The UI for celebrations is only supported on the MFE right now, so don't turn on
# celebrations unless this enrollment's course is MFE-enabled and has milestones enabled.
if not courseware_mfe_first_section_celebration_is_active(instance.course_id):
if not courseware_mfe_progress_milestones_are_active(instance.course_id):
return
try:

View File

@@ -154,6 +154,18 @@ class EnrollmentTest(UrlResetMixin, SharedModuleStoreTestCase):
# Expect that we're no longer enrolled
assert not CourseEnrollment.is_enrolled(self.user, self.course.id)
@ddt.data(-1, 0, 1)
def test_external_course_updates_signal(self, value):
"""Confirm that we send the external updates experiment bucket with the activation signal"""
with patch('openedx.core.djangoapps.schedules.config.set_up_external_updates_for_enrollment',
return_value=value):
with patch('common.djangoapps.student.models.segment') as mock_segment:
CourseEnrollment.enroll(self.user, self.course.id)
assert mock_segment.track.call_count == 1
assert mock_segment.track.call_args[0][1] == 'edx.course.enrollment.activated'
assert mock_segment.track.call_args[0][2]['external_course_updates'] == value
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_EMAIL_OPT_IN': True})
@patch('openedx.core.djangoapps.user_api.preferences.api.update_email_opt_in')
@ddt.data(

View File

@@ -3,7 +3,6 @@
from edx_toggles.toggles.testutils import override_waffle_flag
from lms.djangoapps.courseware.toggles import (
COURSEWARE_MICROFRONTEND_PROGRESS_MILESTONES,
COURSEWARE_MICROFRONTEND_PROGRESS_MILESTONES_FIRST_SECTION_CELEBRATION,
REDIRECT_TO_COURSEWARE_MICROFRONTEND
)
from common.djangoapps.student.models import CourseEnrollmentCelebration
@@ -17,7 +16,6 @@ class ReceiversTest(SharedModuleStoreTestCase):
"""
@override_waffle_flag(REDIRECT_TO_COURSEWARE_MICROFRONTEND, active=True)
@override_waffle_flag(COURSEWARE_MICROFRONTEND_PROGRESS_MILESTONES, active=True)
@override_waffle_flag(COURSEWARE_MICROFRONTEND_PROGRESS_MILESTONES_FIRST_SECTION_CELEBRATION, active=True)
def test_celebration_created(self):
""" Test that we make celebration objects when enrollments are created """
assert CourseEnrollmentCelebration.objects.count() == 0