feat: Added enterprise uuid in event context for enterprise enrolment events

This commit is contained in:
RehanAziz
2021-07-08 10:58:24 +05:00
parent 36319bda48
commit e0efd9bbf2
10 changed files with 46 additions and 22 deletions

View File

@@ -1377,7 +1377,7 @@ class CourseEnrollment(models.Model):
from openedx.core.djangoapps.enrollments.permissions import ENROLL_IN_COURSE
return not user.has_perm(ENROLL_IN_COURSE, course)
def update_enrollment(self, mode=None, is_active=None, skip_refund=False):
def update_enrollment(self, mode=None, is_active=None, skip_refund=False, enterprise_uuid=None):
"""
Updates an enrollment for a user in a class. This includes options
like changing the mode, toggling is_active True/False, etc.
@@ -1413,7 +1413,7 @@ class CourseEnrollment(models.Model):
if activation_changed:
if self.is_active:
self.emit_event(EVENT_NAME_ENROLLMENT_ACTIVATED)
self.emit_event(EVENT_NAME_ENROLLMENT_ACTIVATED, enterprise_uuid=enterprise_uuid)
else:
UNENROLL_DONE.send(sender=None, course_enrollment=self, skip_refund=skip_refund)
self.emit_event(EVENT_NAME_ENROLLMENT_DEACTIVATED)
@@ -1457,7 +1457,7 @@ class CourseEnrollment(models.Model):
mode=mode, course_id=course_id,
cost=cost, currency=currency)
def emit_event(self, event_name):
def emit_event(self, event_name, enterprise_uuid=None):
"""
Emits an event to explicitly track course enrollment and unenrollment.
"""
@@ -1465,12 +1465,17 @@ class CourseEnrollment(models.Model):
try:
context = contexts.course_context_from_course_id(self.course_id)
if enterprise_uuid:
context["enterprise_uuid"] = enterprise_uuid
assert isinstance(self.course_id, CourseKey)
data = {
'user_id': self.user.id,
'course_id': str(self.course_id),
'mode': self.mode,
}
if enterprise_uuid and 'username' not in context:
data['username'] = self.user.username
segment_properties = {
'category': 'conversion',
'label': str(self.course_id),
@@ -1511,7 +1516,7 @@ class CourseEnrollment(models.Model):
)
@classmethod
def enroll(cls, user, course_key, mode=None, check_access=False, can_upgrade=False):
def enroll(cls, user, course_key, mode=None, check_access=False, can_upgrade=False, enterprise_uuid=None):
"""
Enroll a user in a course. This saves immediately.
@@ -1540,6 +1545,8 @@ class CourseEnrollment(models.Model):
while selecting a session. The default is set to False to avoid
breaking the orignal course enroll code.
enterprise_uuid (str): Add course enterprise uuid
Exceptions that can be raised: NonExistentCourseError,
EnrollmentClosedError, CourseFullError, AlreadyEnrolledError. All these
are subclasses of CourseEnrollmentException if you want to catch all of
@@ -1590,7 +1597,7 @@ class CourseEnrollment(models.Model):
# User is allowed to enroll if they've reached this point.
enrollment = cls.get_or_create_enrollment(user, course_key)
enrollment.update_enrollment(is_active=True, mode=mode)
enrollment.update_enrollment(is_active=True, mode=mode, enterprise_uuid=enterprise_uuid)
enrollment.send_signal(EnrollStatusChange.enroll)
return enrollment

View File

@@ -68,7 +68,8 @@ def context_dict_for_learning_context(context_key):
{
'context_id': 'course-v1:org+course+run',
'course_id': 'course-v1:org+course+run',
'org_id': 'org'
'org_id': 'org',
'enterprise_uuid': 'enterprise_customer_uuid'
}
Example 2::
@@ -76,7 +77,8 @@ def context_dict_for_learning_context(context_key):
{
'context_id': 'lib:edX:a-content-library',
'course_id': '',
'org_id': 'edX'
'org_id': 'edX',
'enterprise_uuid': '1a0fbcbe-49e5-42f1-8e83-4cddfa592f22'
}
"""
@@ -84,6 +86,7 @@ def context_dict_for_learning_context(context_key):
'context_id': str(context_key) if context_key else '',
'course_id': '',
'org_id': '',
'enterprise_uuid': '',
}
if context_key is not None:
assert isinstance(context_key, LearningContextKey)
@@ -91,4 +94,6 @@ def context_dict_for_learning_context(context_key):
context_dict['course_id'] = str(context_key)
if hasattr(context_key, 'org'):
context_dict['org_id'] = context_key.org
if hasattr(context_key, 'enterprise_uuid'):
context_dict['enterprise_uuid'] = context_key.enterprise_uuid
return context_dict

View File

@@ -28,13 +28,13 @@ class TestContexts(TestCase): # lint-amnesty, pylint: disable=missing-class-doc
def assert_parses_course_id_from_url(self, format_string, course_id):
assert contexts.course_context_from_url(format_string.format(course_id=course_id)) ==\
{'course_id': course_id, 'org_id': self.ORG_ID}
{'course_id': course_id, 'org_id': self.ORG_ID, 'enterprise_uuid': ''}
def test_no_course_id_in_url(self):
self.assert_empty_context_for_url('http://foo.bar.com/dashboard')
def assert_empty_context_for_url(self, url):
assert contexts.course_context_from_url(url) == {'course_id': '', 'org_id': ''}
assert contexts.course_context_from_url(url) == {'course_id': '', 'org_id': '', 'enterprise_uuid': ''}
@ddt.data('', '/', '/?', '?format=json')
def test_malformed_course_id(self, postfix):

View File

@@ -74,9 +74,11 @@ class TrackMiddlewareTestCase(TestCase):
def test_default_request_context(self):
context = self.get_context_for_path('/courses/')
assert context == {'accept_language': '', 'referer': '', 'user_id': '', 'session': '', 'username': '',
'ip': '127.0.0.1', 'host': 'testserver', 'agent': '', 'path': '/courses/', 'org_id': '',
'course_id': '', 'client_id': None}
assert context == {
'accept_language': '', 'referer': '', 'user_id': '', 'session': '', 'username': '', 'ip': '127.0.0.1',
'host': 'testserver', 'agent': '', 'path': '/courses/', 'org_id': '', 'course_id': '', 'client_id': None,
'enterprise_uuid': ''
}
def test_no_forward_for_header_ip_context(self):
request = self.request_factory.get('/courses/')

View File

@@ -238,6 +238,7 @@ class TestTrackViews(EventTrackingTestCase): # lint-amnesty, pylint: disable=mi
'referer': '',
'client_id': None,
'course_id': 'foo/bar/baz',
'enterprise_uuid': '',
'path': self.path_with_course,
'page': None
}
@@ -279,6 +280,7 @@ class TestTrackViews(EventTrackingTestCase): # lint-amnesty, pylint: disable=mi
'referer': '',
'client_id': '1033501218.1368477899',
'course_id': 'foo/bar/baz',
'enterprise_uuid': '',
'path': self.path_with_course,
'page': None
}

View File

@@ -174,7 +174,11 @@ class GradesEventIntegrationTest(ProblemSubmissionTestMixin, SharedModuleStoreTe
# make sure the tracker's context is updated with course info
for args in events_tracker.get_tracker().context.call_args_list:
assert args[0][1] == {'course_id': str(self.course.id), 'org_id': str(self.course.org)}
assert args[0][1] == {
'course_id': str(self.course.id),
'enterprise_uuid': '',
'org_id': str(self.course.org)
}
event_transaction_id = events_tracker.emit.mock_calls[0][1][1]['event_transaction_id']
events_tracker.emit.assert_has_calls(

View File

@@ -146,7 +146,7 @@ def get_enrollment(username, course_id):
return _data_api().get_course_enrollment(username, course_id)
def add_enrollment(username, course_id, mode=None, is_active=True, enrollment_attributes=None):
def add_enrollment(username, course_id, mode=None, is_active=True, enrollment_attributes=None, enterprise_uuid=None):
"""Enrolls a user in a course.
Enrolls a user in a course. If the mode is not specified, this will default to `CourseMode.DEFAULT_MODE_SLUG`.
@@ -159,6 +159,7 @@ def add_enrollment(username, course_id, mode=None, is_active=True, enrollment_at
is_active (boolean): Optional argument for making the new enrollment inactive. If not specified, is_active
defaults to True.
enrollment_attributes (list): Attributes to be set the enrollment.
enterprise_uuid (str): Add course enterprise uuid
Returns:
A serializable dictionary of the new course enrollment.
@@ -197,7 +198,7 @@ def add_enrollment(username, course_id, mode=None, is_active=True, enrollment_at
if mode is None:
mode = _default_course_mode(course_id)
validate_course_mode(course_id, mode, is_active=is_active)
enrollment = _data_api().create_course_enrollment(username, course_id, mode, is_active)
enrollment = _data_api().create_course_enrollment(username, course_id, mode, is_active, enterprise_uuid)
if enrollment_attributes is not None:
set_enrollment_attributes(username, course_id, enrollment_attributes)

View File

@@ -115,7 +115,7 @@ def get_user_enrollments(course_key):
).order_by('created')
def create_course_enrollment(username, course_id, mode, is_active):
def create_course_enrollment(username, course_id, mode, is_active, enterprise_uuid=None):
"""Create a new course enrollment for the given user.
Creates a new course enrollment for the specified user username.
@@ -125,6 +125,7 @@ def create_course_enrollment(username, course_id, mode, is_active):
course_id (str): The course to create the course enrollment for.
mode (str): (Optional) The mode for the new enrollment.
is_active (boolean): (Optional) Determines if the enrollment is active.
enterprise_uuid (str): Add course enterprise uuid
Returns:
A serializable dictionary representing the new course enrollment.
@@ -146,7 +147,7 @@ def create_course_enrollment(username, course_id, mode, is_active):
raise UserNotFoundError(msg) # lint-amnesty, pylint: disable=raise-missing-from
try:
enrollment = CourseEnrollment.enroll(user, course_key, check_access=True)
enrollment = CourseEnrollment.enroll(user, course_key, check_access=True, enterprise_uuid=enterprise_uuid)
return _update_enrollment(enrollment, is_active=is_active, mode=mode)
except NonExistentCourseError as err:
raise CourseNotFoundError(str(err)) # lint-amnesty, pylint: disable=raise-missing-from

View File

@@ -36,9 +36,9 @@ def get_course_enrollment(student_id, course_id):
return _get_fake_enrollment(student_id, course_id)
def create_course_enrollment(student_id, course_id, mode='honor', is_active=True):
def create_course_enrollment(student_id, course_id, mode='honor', is_active=True, enterprise_uuid=None):
"""Stubbed out Enrollment creation request. """
return add_enrollment(student_id, course_id, mode=mode, is_active=is_active)
return add_enrollment(student_id, course_id, mode=mode, is_active=is_active, enterprise_uuid=enterprise_uuid)
def update_course_enrollment(student_id, course_id, mode=None, is_active=None):
@@ -74,14 +74,15 @@ def _get_fake_course_info(course_id, include_expired=False):
return course
def add_enrollment(student_id, course_id, is_active=True, mode='honor'):
def add_enrollment(student_id, course_id, is_active=True, mode='honor', enterprise_uuid=None):
"""Append an enrollment to the enrollments array."""
enrollment = {
"created": datetime.datetime.now(),
"mode": mode,
"is_active": is_active,
"course": _get_fake_course_info(course_id),
"student": student_id
"student": student_id,
"enterprise_uuid": enterprise_uuid
}
_ENROLLMENTS.append(enrollment)
return enrollment

View File

@@ -800,7 +800,8 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
str(course_id),
mode=mode,
is_active=is_active,
enrollment_attributes=enrollment_attributes
enrollment_attributes=enrollment_attributes,
enterprise_uuid=request.data.get('enterprise_uuid')
)
cohort_name = request.data.get('cohort')