diff --git a/common/djangoapps/xmodule_modifiers.py b/common/djangoapps/xmodule_modifiers.py index 654482fab6d30edae72ffce5d5a8718e48c7fb9e..537a7592c2feb9f177e66297b28afddef78f44e4 100644 --- a/common/djangoapps/xmodule_modifiers.py +++ b/common/djangoapps/xmodule_modifiers.py @@ -126,8 +126,12 @@ def replace_static_urls(data_dir, block, view, frag, context, course_id=None, st def grade_histogram(module_id): - ''' Print out a histogram of grades on a given problem. - Part of staff member debug info. + ''' + Print out a histogram of grades on a given problem in staff member debug info. + + Warning: If a student has just looked at an xmodule and not attempted + it, their grade is None. Since there will always be at least one such student + this function almost always returns []. ''' from django.db import connection cursor = connection.cursor() @@ -161,7 +165,7 @@ def add_staff_debug_info(user, block, view, frag, context): # pylint: disable=u return frag block_id = block.id - if block.has_score: + if block.has_score and settings.FEATURES.get('DISPLAY_HISTOGRAMS_TO_STAFF'): histogram = grade_histogram(block_id) render_histogram = len(histogram) > 0 else: diff --git a/lms/djangoapps/courseware/tests/test_module_render.py b/lms/djangoapps/courseware/tests/test_module_render.py index 0f942b4d3fab8c91ad3912a4e2a006dbc9995821..0dd527ed2b69096b75ec4b29bf48f91b0e15d09a 100644 --- a/lms/djangoapps/courseware/tests/test_module_render.py +++ b/lms/djangoapps/courseware/tests/test_module_render.py @@ -564,6 +564,65 @@ class TestStaffDebugInfo(ModuleStoreTestCase): result_fragment = module.render('student_view') self.assertIn('Staff Debug', result_fragment.content) + @patch.dict('django.conf.settings.FEATURES', {'DISPLAY_HISTOGRAMS_TO_STAFF': False}) + def test_histogram_disabled(self): + module = render.get_module( + self.user, + self.request, + self.location, + self.field_data_cache, + self.course.id, + ) + result_fragment = module.render('student_view') + self.assertNotIn('histrogram', result_fragment.content) + + def test_histogram_enabled_for_unscored_xmodules(self): + """Histograms should not display for xmodules which are not scored.""" + + html_descriptor = ItemFactory.create( + category='html', + data='Here are some course details.' + ) + field_data_cache = FieldDataCache.cache_for_descriptor_descendents( + self.course.id, + self.user, + self.descriptor + ) + with patch('xmodule_modifiers.grade_histogram') as mock_grade_histogram: + mock_grade_histogram.return_value = [] + module = render.get_module( + self.user, + self.request, + html_descriptor.location, + field_data_cache, + self.course.id, + ) + module.render('student_view') + self.assertFalse(mock_grade_histogram.called) + + def test_histogram_enabled_for_scored_xmodules(self): + """Histograms should display for xmodules which are scored.""" + + StudentModuleFactory.create( + course_id=self.course.id, + module_state_key=self.location, + student=UserFactory(), + grade=1, + max_grade=1, + state="{}", + ) + with patch('xmodule_modifiers.grade_histogram') as mock_grade_histogram: + mock_grade_histogram.return_value = [] + module = render.get_module( + self.user, + self.request, + self.location, + self.field_data_cache, + self.course.id, + ) + module.render('student_view') + self.assertTrue(mock_grade_histogram.called) + PER_COURSE_ANONYMIZED_DESCRIPTORS = (LTIDescriptor, ) diff --git a/lms/envs/common.py b/lms/envs/common.py index d3724c68b2b904e795c181b9d2a15004cb2ba5f3..e528c884e86989fdc152bf590313d933f099077d 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -57,6 +57,7 @@ FEATURES = { 'USE_DJANGO_PIPELINE': True, 'DISPLAY_DEBUG_INFO_TO_STAFF': True, + 'DISPLAY_HISTOGRAMS_TO_STAFF': False, # For large courses this slows down courseware access for staff. 'REROUTE_ACTIVATION_EMAIL': False, # nonempty string = address for all activation emails 'DEBUG_LEVEL': 0, # 0 = lowest level, least verbose, 255 = max level, most verbose