From b3b3ef98b244d7ccded375b79e1b42efd550ce43 Mon Sep 17 00:00:00 2001 From: brianhw Date: Tue, 19 Oct 2021 16:40:30 -0400 Subject: [PATCH] feat: add courserun_key property to GA event transformer. (#28761) The GA transformer adds the context.course_id property of a tracking log event to the event transmitted automatically to Segment in the "label" property, so GA can use it. This adds it also to the "courserun_key" property, so that regular users of Segment events can also query it in a more consistently-named property. However, it does so only if it is a valid CourseKey. For DENG-997. Add CourseKey parsing. --- common/djangoapps/track/shim.py | 12 +++++++++ common/djangoapps/track/tests/test_shim.py | 29 ++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/common/djangoapps/track/shim.py b/common/djangoapps/track/shim.py index ec4e6a71d0..dd3ae78d00 100644 --- a/common/djangoapps/track/shim.py +++ b/common/djangoapps/track/shim.py @@ -3,6 +3,9 @@ import json +from opaque_keys import InvalidKeyError +from opaque_keys.edx.keys import CourseKey + from .transformers import EventTransformerRegistry CONTEXT_FIELDS_TO_INCLUDE = [ @@ -85,6 +88,15 @@ class GoogleAnalyticsProcessor: copied_event = event.copy() if course_id is not None: copied_event['label'] = course_id + # The value stored as course_id is not always a courserun_key. + # It may, for example, be a library instead. So we parse it first to be sure. + # We add a str() call to the input so that sentinel values don't cause + # CourseKey to spit up with a different error. + try: + courserun_key = CourseKey.from_string(str(course_id)) + copied_event['courserun_key'] = str(courserun_key) + except InvalidKeyError: + pass copied_event['nonInteraction'] = 1 diff --git a/common/djangoapps/track/tests/test_shim.py b/common/djangoapps/track/tests/test_shim.py index dbd0cd28cc..6e08a5fd3e 100644 --- a/common/djangoapps/track/tests/test_shim.py +++ b/common/djangoapps/track/tests/test_shim.py @@ -8,11 +8,13 @@ import ddt from django.test.utils import override_settings from openedx.core.lib.tests.assertions.events import assert_events_equal +from opaque_keys.edx.locator import CourseLocator from .. import transformers from ..shim import PrefixedEventProcessor from . import FROZEN_TIME, EventTrackingTestCase + LEGACY_SHIM_PROCESSOR = [ { 'ENGINE': 'common.djangoapps.track.shim.LegacyFieldMappingProcessor' @@ -156,6 +158,33 @@ class GoogleAnalyticsProcessorTestCase(EventTrackingTestCase): } assert_events_equal(expected_event, emitted_event) + def test_valid_course_id(self): + """ Test that a courserun_key is added if course_id is a valid course key. """ + data = {sentinel.key: sentinel.value} + courserun_key = str(CourseLocator(org='testx', course='test_course', run='test_run')) + + context = { + 'path': sentinel.path, + 'user_id': sentinel.user_id, + 'client_id': sentinel.client_id, + 'course_id': courserun_key, + } + with self.tracker.context('test', context): + self.tracker.emit(sentinel.name, data) + + emitted_event = self.get_event() + + expected_event = { + 'context': context, + 'data': data, + 'label': courserun_key, + 'courserun_key': courserun_key, + 'name': sentinel.name, + 'nonInteraction': 1, + 'timestamp': FROZEN_TIME, + } + assert_events_equal(expected_event, emitted_event) + @override_settings( EVENT_TRACKING_BACKENDS={