Commit 84a2eeb8 by Calen Pennington

Merge pull request #6209 from edx/plat/fix-pure-system

Fix PureSystem so that runtime.publish() works for a pure XBlock.
parents 98878554 2faff29a
......@@ -609,6 +609,10 @@ class SplitTestDescriptor(SplitTestFields, SequenceDescriptor, StudioEditableDes
Called from Studio view.
"""
user_service = self.runtime.service(self, 'user')
if user_service is None:
return Response()
user_partition = self.get_selected_partition()
changed = False
......
......@@ -92,16 +92,36 @@ def get_test_system(course_id=SlashSeparatedCourseKey('org', 'course', 'run')):
where `my_render_func` is a function of the form my_render_func(template, context).
"""
user = Mock(is_staff=False)
user = Mock(name='get_test_system.user', is_staff=False)
descriptor_system = get_test_descriptor_system(),
def get_module(descriptor):
"""Mocks module_system get_module function"""
# pylint: disable=protected-access
# Unlike XBlock Runtimes or DescriptorSystems,
# each XModule is provided with a new ModuleSystem.
# Construct one for the new XModule.
module_system = get_test_system()
# Descriptors can all share a single DescriptorSystem.
# So, bind to the same one as the current descriptor.
module_system.descriptor_runtime = descriptor.runtime._descriptor_system
descriptor.bind_for_student(module_system, descriptor._field_data)
return descriptor
return TestModuleSystem(
static_url='/static',
track_function=Mock(),
get_module=Mock(),
track_function=Mock(name='get_test_system.track_function'),
get_module=get_module,
render_template=mock_render_template,
replace_urls=str,
user=user,
get_real_user=lambda(__): user,
filestore=Mock(),
filestore=Mock(name='get_test_system.filestore'),
debug=True,
hostname="edx.org",
xqueue={
......@@ -109,16 +129,16 @@ def get_test_system(course_id=SlashSeparatedCourseKey('org', 'course', 'run')):
'callback_url': '/',
'default_queuename': 'testqueue',
'waittime': 10,
'construct_callback': Mock(side_effect="/"),
'construct_callback': Mock(name='get_test_system.xqueue.construct_callback', side_effect="/"),
},
node_path=os.environ.get("NODE_PATH", "/usr/local/lib/node_modules"),
anonymous_student_id='student',
open_ended_grading_interface=open_ended_grading_interface,
course_id=course_id,
error_descriptor_class=ErrorDescriptor,
get_user_role=Mock(is_staff=False),
descriptor_runtime=get_test_descriptor_system(),
user_location=Mock(),
get_user_role=Mock(name='get_test_system.get_user_role', is_staff=False),
user_location=Mock(name='get_test_system.user_location'),
descriptor_runtime=descriptor_system,
)
......@@ -128,15 +148,17 @@ def get_test_descriptor_system():
"""
field_data = DictFieldData({})
return MakoDescriptorSystem(
load_item=Mock(),
resources_fs=Mock(),
error_tracker=Mock(),
descriptor_system = MakoDescriptorSystem(
load_item=Mock(name='get_test_descriptor_system.load_item'),
resources_fs=Mock(name='get_test_descriptor_system.resources_fs'),
error_tracker=Mock(name='get_test_descriptor_system.error_tracker'),
render_template=mock_render_template,
mixins=(InheritanceMixin, XModuleMixin),
field_data=field_data,
services={'field-data': field_data},
)
descriptor_system.get_asides = lambda block: []
return descriptor_system
def mock_render_template(*args, **kwargs):
......
......@@ -64,14 +64,14 @@ class ConditionalFactory(object):
error_msg='random error message'
)
else:
source_descriptor = Mock()
source_descriptor = Mock(name='source_descriptor')
source_descriptor.location = source_location
source_descriptor.runtime = descriptor_system
source_descriptor.render = lambda view, context=None: descriptor_system.render(source_descriptor, view, context)
# construct other descriptors:
child_descriptor = Mock()
child_descriptor = Mock(name='child_descriptor')
child_descriptor._xmodule.student_view.return_value.content = u'<p>This is a secret</p>'
child_descriptor.student_view = child_descriptor._xmodule.student_view
child_descriptor.displayable_items.return_value = [child_descriptor]
......@@ -85,6 +85,8 @@ class ConditionalFactory(object):
source_location: source_descriptor
}.get
system.descriptor_runtime = descriptor_system
# construct conditional module:
cond_location = Location("edX", "conditional_test", "test_run", "conditional", "SampleConditional", None)
field_data = DictFieldData({
......
......@@ -47,15 +47,7 @@ class SplitTestModuleTest(XModuleXmlImportTest, PartitionTestCase):
self.course_sequence = self.course.get_children()[0]
self.module_system = get_test_system()
def get_module(descriptor):
"""Mocks module_system get_module function"""
module_system = get_test_system()
module_system.get_module = get_module
descriptor.bind_for_student(module_system, descriptor._field_data) # pylint: disable=protected-access
return descriptor
self.module_system.get_module = get_module
self.module_system.descriptor_system = self.course.runtime
self.module_system.descriptor_runtime = self.course.runtime._descriptor_system # pylint: disable=protected-access
self.course.runtime.export_fs = MemoryFS()
self.partitions_service = StaticPartitionService(
......@@ -97,14 +89,12 @@ class SplitTestModuleLMSTest(SplitTestModuleTest):
self.module_system.render(self.split_test_module, STUDENT_VIEW).content
)
@ddt.data((0,), (1,))
@ddt.unpack
@ddt.data(0, 1)
def test_child_missing_tag_value(self, _user_tag):
# If user_tag has a missing value, we should still get back a valid child url
self.assertIn(self.split_test_module.child_descriptor.url_name, ['split_test_cond0', 'split_test_cond1'])
@ddt.data((100,), (200,), (300,), (400,), (500,), (600,), (700,), (800,), (900,), (1000,))
@ddt.unpack
@ddt.data(100, 200, 300, 400, 500, 600, 700, 800, 900, 1000)
def test_child_persist_new_tag_value_when_tag_missing(self, _user_tag):
# If a user_tag has a missing value, a group should be saved/persisted for that user.
# So, we check that we get the same url_name when we call on the url_name twice.
......
......@@ -27,15 +27,7 @@ class BaseVerticalModuleTest(XModuleXmlImportTest):
course_seq = self.course.get_children()[0]
self.module_system = get_test_system()
def get_module(descriptor):
"""Mocks module_system get_module function"""
module_system = get_test_system()
module_system.get_module = get_module
descriptor.bind_for_student(module_system, descriptor._field_data) # pylint: disable=protected-access
return descriptor
self.module_system.get_module = get_module
self.module_system.descriptor_system = self.course.runtime
self.module_system.descriptor_runtime = self.course.runtime._descriptor_system # pylint: disable=protected-access
self.course.runtime.export_fs = MemoryFS()
self.vertical = course_seq.get_children()[0]
......
......@@ -57,17 +57,7 @@ class BaseTestXmodule(ModuleStoreTestCase):
"""
Generate a new ModuleSystem that is minimally set up for testing
"""
runtime = get_test_system(course_id=self.course.id)
# When asked for a module out of a descriptor, just create a new xmodule runtime,
# and inject it into the descriptor
def get_module(descr):
descr.xmodule_runtime = self.new_module_runtime()
return descr
runtime.get_module = get_module
return runtime
return get_test_system(course_id=self.course.id)
def new_descriptor_runtime(self):
runtime = get_test_descriptor_system()
......
......@@ -39,7 +39,7 @@ from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import ItemFactory, CourseFactory, check_mongo_calls
from xmodule.x_module import XModuleDescriptor, STUDENT_VIEW
from xmodule.x_module import XModuleDescriptor, XModule, STUDENT_VIEW
TEST_DATA_DIR = settings.COMMON_TEST_DATA_ROOT
......@@ -51,6 +51,20 @@ class PureXBlock(XBlock):
pass
class EmptyXModule(XModule): # pylint: disable=abstract-method
"""
Empty XModule for testing with no dependencies.
"""
pass
class EmptyXModuleDescriptor(XModuleDescriptor): # pylint: disable=abstract-method
"""
Empty XModule for testing with no dependencies.
"""
module_class = EmptyXModule
@ddt.ddt
@override_settings(MODULESTORE=TEST_DATA_MOCK_MODULESTORE)
class ModuleRenderTestCase(ModuleStoreTestCase, LoginEnrollmentTestCase):
......@@ -1105,3 +1119,42 @@ class TestRebindModule(TestSubmittingProblems):
module = self.get_module_for_user(self.anon_user)
module.system.rebind_noauth_module_to_user(module, self.anon_user)
self.assertFalse(psycho_handler.called)
@ddt.ddt
@override_settings(MODULESTORE=TEST_DATA_MOCK_MODULESTORE)
class TestEventPublishing(ModuleStoreTestCase, LoginEnrollmentTestCase):
"""
Tests of event publishing for both XModules and XBlocks.
"""
def setUp(self):
"""
Set up the course and user context
"""
super(TestEventPublishing, self).setUp()
self.mock_user = UserFactory()
self.mock_user.id = 1
self.request_factory = RequestFactory()
@ddt.data('xblock', 'xmodule')
@XBlock.register_temp_plugin(PureXBlock, identifier='xblock')
@XBlock.register_temp_plugin(EmptyXModuleDescriptor, identifier='xmodule')
@patch.object(render, 'make_track_function')
def test_event_publishing(self, block_type, mock_track_function):
request = self.request_factory.get('')
request.user = self.mock_user
course = CourseFactory()
descriptor = ItemFactory(category=block_type, parent=course)
field_data_cache = FieldDataCache([course, descriptor], course.id, self.mock_user) # pylint: disable=no-member
block = render.get_module(self.mock_user, request, descriptor.location, field_data_cache)
event_type = 'event_type'
event = {'event': 'data'}
block.runtime.publish(block, event_type, event)
mock_track_function.assert_called_once_with(request)
mock_track_function.return_value.assert_called_once_with(event_type, event)
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