Commit 9320fc55 by Braden MacDonald Committed by Zia Fazal

Add module key and library source info to problem events

parent 932fb626
......@@ -803,6 +803,7 @@ def _get_module_by_usage_id(request, course_id, usage_id):
try:
descriptor = modulestore().get_item(usage_key)
descriptor_orig_usage_key, descriptor_orig_version = modulestore().get_block_original_usage(usage_key)
except ItemNotFoundError:
log.warn(
"Invalid location for course id {course_id}: {usage_key}".format(
......@@ -824,7 +825,7 @@ def _get_module_by_usage_id(request, course_id, usage_id):
log.debug("No module %s for user %s -- access denied?", usage_key, user)
raise Http404
return instance
return instance, descriptor_orig_usage_key, descriptor_orig_version
def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, user):
......@@ -846,7 +847,7 @@ def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, user):
if error_msg:
return HttpResponse(json.dumps({'success': error_msg}))
instance = _get_module_by_usage_id(request, course_id, usage_id)
instance, descriptor_orig_usage_key, descriptor_orig_version = _get_module_by_usage_id(request, course_id, usage_id)
tracking_context_name = 'module_callback_handler'
tracking_context = {
......@@ -854,6 +855,10 @@ def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, user):
'display_name': instance.display_name_with_default,
}
}
# For blocks that are inherited from a content library, we add some additional metadata:
if descriptor_orig_usage_key is not None:
tracking_context['module']['original_usage_key'] = unicode(descriptor_orig_usage_key)
tracking_context['module']['original_usage_version'] = unicode(descriptor_orig_version)
req = django_to_webob_request(request)
try:
......@@ -905,7 +910,7 @@ def xblock_view(request, course_id, usage_id, view_name):
if not request.user.is_authenticated():
raise PermissionDenied
instance = _get_module_by_usage_id(request, course_id, usage_id)
instance, _, __ = _get_module_by_usage_id(request, course_id, usage_id)
try:
fragment = instance.render(view_name, context=request.GET)
......
......@@ -5,6 +5,7 @@ Test for lms courseware app, module render unit
from functools import partial
import json
from bson import ObjectId
import ddt
from django.http import Http404, HttpResponse
from django.core.urlresolvers import reverse
......@@ -13,6 +14,7 @@ from django.test.client import RequestFactory
from django.test.utils import override_settings
from django.contrib.auth.models import AnonymousUser
from mock import MagicMock, patch, Mock
from opaque_keys.edx.keys import UsageKey
from opaque_keys.edx.locations import SlashSeparatedCourseKey
from xblock.field_data import FieldData
from xblock.runtime import Runtime
......@@ -1002,12 +1004,13 @@ class TestModuleTrackingContext(ModuleStoreTestCase):
def test_context_contains_display_name(self, mock_tracker):
mock_tracker.reset_mock()
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)
module_info = self.handle_callback_and_get_module_info_from_event(mock_tracker, problem_display_name)
self.assertEquals(problem_display_name, module_info['display_name'])
def handle_callback_and_get_display_name_from_event(self, mock_tracker, problem_display_name=None):
def handle_callback_and_get_module_info_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.
Creates a fake module, invokes the callback and extracts the 'module'
metadata from the emitted problem_check event.
"""
descriptor_kwargs = {
'category': 'problem',
......@@ -1035,9 +1038,24 @@ class TestModuleTrackingContext(ModuleStoreTestCase):
self.fail('Event type "problem_check" not found in call list.')
def test_missing_display_name(self, mock_tracker):
actual_display_name = self.handle_callback_and_get_display_name_from_event(mock_tracker)
actual_display_name = self.handle_callback_and_get_module_info_from_event(mock_tracker)['display_name']
self.assertTrue(actual_display_name.startswith('problem'))
def test_library_source_information(self, mock_tracker):
"""
Check that XBlocks that are inherited from a library include the
information about their library block source in events.
We patch the modulestore to avoid having to create a library.
"""
original_usage_key = UsageKey.from_string(u'block-v1:A+B+C+type@problem+block@abcd1234')
original_usage_version = ObjectId()
with patch('xmodule.modulestore.mixed.MixedModuleStore.get_block_original_usage', lambda _, key: (original_usage_key, original_usage_version)):
module_info = self.handle_callback_and_get_module_info_from_event(mock_tracker)
self.assertIn('original_usage_key', module_info)
self.assertEqual(module_info['original_usage_key'], unicode(original_usage_key))
self.assertIn('original_usage_version', module_info)
self.assertEqual(module_info['original_usage_version'], unicode(original_usage_version))
class TestXmoduleRuntimeEvent(TestSubmittingProblems):
"""
......
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