From 8ba74429b166074fcf448a12843f560eea6d5782 Mon Sep 17 00:00:00 2001 From: cewing Date: Wed, 18 Mar 2015 23:56:01 -0700 Subject: [PATCH] MIT: CCX. Fixes for API changes that affect the binding of descriptors to student context. fix for making sure all descriptor fields are always available for course descriptors despite module_class tricks add required fields to cache data for tests use a different strategy to mock up the get_children method --- common/lib/xmodule/xmodule/course_module.py | 10 ++++++- lms/djangoapps/ccx/tests/test_views.py | 32 +++++++++------------ lms/djangoapps/courseware/module_render.py | 2 +- lms/djangoapps/instructor/tests/test_api.py | 1 - 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/common/lib/xmodule/xmodule/course_module.py b/common/lib/xmodule/xmodule/course_module.py index 0628743910..2bca5d3405 100644 --- a/common/lib/xmodule/xmodule/course_module.py +++ b/common/lib/xmodule/xmodule/course_module.py @@ -835,8 +835,16 @@ class CourseFields(object): ) +class CourseModule(CourseFields, SequenceModule): + """ + The CourseDescriptor needs its module_class to be a SequenceModule, but some code that + expects a CourseDescriptor to have all its fields can fail if it gets a SequenceModule instead. + This class is to make sure that all the fields are present in all cases. + """ + + class CourseDescriptor(CourseFields, SequenceDescriptor): - module_class = SequenceModule + module_class = CourseModule def __init__(self, *args, **kwargs): """ diff --git a/lms/djangoapps/ccx/tests/test_views.py b/lms/djangoapps/ccx/tests/test_views.py index a86c681d36..46a7d28dbb 100644 --- a/lms/djangoapps/ccx/tests/test_views.py +++ b/lms/djangoapps/ccx/tests/test_views.py @@ -21,6 +21,7 @@ from student.tests.factories import ( # pylint: disable=import-error UserFactory, ) +from xmodule.x_module import XModuleMixin from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import ( CourseFactory, @@ -418,8 +419,20 @@ class TestCoachDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase): ) +original_get_children = XModuleMixin.get_children +def patched_get_children(self, usage_key_filter=None): # pylint: disable=missing-docstring + def iter_children(): # pylint: disable=missing-docstring + print self.__dict__ + for child in original_get_children(self, usage_key_filter=usage_key_filter): + child._field_data_cache = {} # pylint: disable=protected-access + if not child.visible_to_staff_only: + yield child + return list(iter_children()) + + @override_settings(FIELD_OVERRIDE_PROVIDERS=( 'ccx.overrides.CustomCoursesForEdxOverrideProvider',)) +@patch('xmodule.x_module.XModuleMixin.get_children', patched_get_children, spec=True) class TestCCXGrades(ModuleStoreTestCase, LoginEnrollmentTestCase): """ Tests for Custom Courses views. @@ -479,8 +492,7 @@ class TestCCXGrades(ModuleStoreTestCase, LoginEnrollmentTestCase): for block in iter_blocks(course): block._field_data = OverrideFieldData.wrap( # pylint: disable=protected-access coach, block._field_data) # pylint: disable=protected-access - block._field_data_cache = {} # pylint: disable=protected-access - visible_children(block) + block._field_data_cache = {'tabs':[],'discussion_topics':[]} # pylint: disable=protected-access def cleanup_provider_classes(): """ @@ -759,19 +771,3 @@ def iter_blocks(course): for descendant in visit(child): # wish they'd backport yield from yield descendant return visit(course) - - -def visible_children(block): - """ - Return only visible children - """ - block_get_children = block.get_children - - def get_children(): # pylint: disable=missing-docstring - def iter_children(): # pylint: disable=missing-docstring - for child in block_get_children(): - child._field_data_cache = {} # pylint: disable=protected-access - if not child.visible_to_staff_only: - yield child - return list(iter_children()) - block.get_children = get_children diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index 7c1eeacff5..f7ac22e950 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -691,7 +691,7 @@ def get_module_for_descriptor_internal(user, descriptor, field_data_cache, cours ) authored_data = OverrideFieldData.wrap(user, descriptor._field_data) # pylint: disable=protected-access - descriptor.bind_for_student(system, LmsFieldData(authored_data, field_data), user.id) + descriptor.bind_for_student(system, LmsFieldData(authored_data, student_data), user.id) descriptor.scope_ids = descriptor.scope_ids._replace(user_id=user.id) # pylint: disable=protected-access # Do not check access when it's a noauth request. diff --git a/lms/djangoapps/instructor/tests/test_api.py b/lms/djangoapps/instructor/tests/test_api.py index d9a399e0bf..22333c0d15 100644 --- a/lms/djangoapps/instructor/tests/test_api.py +++ b/lms/djangoapps/instructor/tests/test_api.py @@ -3134,7 +3134,6 @@ def get_extended_due(course, unit, user): return None -@override_settings(MODULESTORE=TEST_DATA_MOCK_MODULESTORE) class TestDueDateExtensions(ModuleStoreTestCase, LoginEnrollmentTestCase): """ Test data dumps for reporting.