Commit fe21f475 by Gabe Mulley

Add module display name to module related server events

This information will likely be used frequently for analytics purposes, so we would like to denormalize here to avoid having to join with the modulestore later.

Fixes: AN-594
parent b0ae3a53
......@@ -22,6 +22,7 @@ from courseware.model_data import FieldDataCache, DjangoKeyValueStore
from lms.lib.xblock.field_data import LmsFieldData
from lms.lib.xblock.runtime import LmsModuleSystem, unquote_slashes
from edxmako.shortcuts import render_to_string
from eventtracking import tracker
from psychometrics.psychoanalyze import make_psychometrics_data_update_handler
from student.models import anonymous_id_for_user, user_by_anonymous_id
from xblock.core import XBlock
......@@ -571,6 +572,13 @@ def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, user):
)
raise Http404
tracking_context_name = 'module_callback_handler'
tracking_context = {
'module': {
'display_name': descriptor.display_name_with_default,
}
}
field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
course_id,
user,
......@@ -585,7 +593,8 @@ def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, user):
req = django_to_webob_request(request)
try:
resp = instance.handle(handler, req, suffix)
with tracker.get_tracker().context(tracking_context_name, tracking_context):
resp = instance.handle(handler, req, suffix)
except NoSuchHandlerError:
log.exception("XBlock %s attempted to access missing handler %r", instance, handler)
......
......@@ -698,3 +698,63 @@ class TestAnonymousStudentId(ModuleStoreTestCase, LoginEnrollmentTestCase):
'f82b5416c9f54b5ce33989511bb5ef2e',
self._get_anonymous_id('MITx/6.00x/2013_Spring', descriptor_class)
)
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
@patch('track.views.tracker')
class TestModuleTrackingContext(ModuleStoreTestCase):
"""
Ensure correct tracking information is included in events emitted during XBlock callback handling.
"""
def setUp(self):
self.user = UserFactory.create()
self.request = RequestFactory().get('/')
self.request.user = self.user
self.request.session = {}
self.course = CourseFactory.create()
self.problem_xml = OptionResponseXMLFactory().build_xml(
question_text='The correct answer is Correct',
num_inputs=2,
weight=2,
options=['Correct', 'Incorrect'],
correct_option='Correct'
)
def test_context_contains_display_name(self, mock_tracker):
problem_display_name = u'Option Response Problem'
actual_display_name = self.handle_callback_and_get_display_name_from_event(mock_tracker, problem_display_name)
self.assertEquals(problem_display_name, actual_display_name)
def handle_callback_and_get_display_name_from_event(self, mock_tracker, problem_display_name=None):
"""
Creates a fake module, invokes the callback and extracts the display name from the emitted problem_check event.
"""
descriptor_kwargs = {
'category': 'problem',
'data': self.problem_xml
}
if problem_display_name:
descriptor_kwargs['display_name'] = problem_display_name
descriptor = ItemFactory.create(**descriptor_kwargs)
render.handle_xblock_callback(
self.request,
self.course.id,
quote_slashes(str(descriptor.location)),
'xmodule_handler',
'problem_check',
)
self.assertEquals(len(mock_tracker.send.mock_calls), 1)
mock_call = mock_tracker.send.mock_calls[0]
event = mock_call[1][0]
self.assertEquals(event['event_type'], 'problem_check')
return event['context']['module']['display_name']
def test_missing_display_name(self, mock_tracker):
actual_display_name = self.handle_callback_and_get_display_name_from_event(mock_tracker)
self.assertTrue(actual_display_name.startswith('problem'))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment