feat: Added enterprise uuid in event context for enterprise enrolment events
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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/')
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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')
|
||||
|
||||
Reference in New Issue
Block a user