diff --git a/cms/djangoapps/contentstore/views/item.py b/cms/djangoapps/contentstore/views/item.py index b79c7355ec..d9ff2a1c56 100644 --- a/cms/djangoapps/contentstore/views/item.py +++ b/cms/djangoapps/contentstore/views/item.py @@ -1308,7 +1308,7 @@ def create_xblock_info(xblock, data=None, metadata=None, include_ancestor_info=F xblock_info.update({ 'is_proctored_exam': xblock.is_proctored_exam, - 'was_ever_special_exam': _was_xblock_ever_special_exam( + 'was_ever_proctored_exam': _was_xblock_ever_proctored_exam( course, xblock ), 'online_proctoring_rules': rules_url, @@ -1364,13 +1364,14 @@ def create_xblock_info(xblock, data=None, metadata=None, include_ancestor_info=F return xblock_info -def _was_xblock_ever_special_exam(course, xblock): +def _was_xblock_ever_proctored_exam(course, xblock): """ - Determine whether this XBlock is or was ever configured as a special exam. + Determine whether this XBlock is or was ever configured as a proctored exam. - If this block is *not* currently a special exam, the best way for us to tell - whether it was was *ever* configured as a special exam is by checking whether - edx-proctoring has an exam record associated with the block's ID. + If this block is *not* currently a proctored exam, the best way for us to tell + whether it was was *ever* configured as a proctored exam is by checking whether + edx-proctoring has an exam record associated with the block's ID, + and the exam record is proctored. If an exception is not raised, then we know that such a record exists, indicating that this *was* once a special exam. @@ -1380,14 +1381,13 @@ def _was_xblock_ever_special_exam(course, xblock): Returns: bool """ - if xblock.is_time_limited: + if xblock.is_proctored_enabled: return True try: - get_exam_by_content_id(course.id, xblock.location) + exam = get_exam_by_content_id(course.id, xblock.location) + return 'is_proctored' in exam and exam['is_proctored'] except ProctoredExamNotFoundException: return False - else: - return True def add_container_page_publishing_info(xblock, xblock_info): diff --git a/cms/djangoapps/contentstore/views/tests/test_item.py b/cms/djangoapps/contentstore/views/tests/test_item.py index 8ce3da5e46..31e55b2256 100644 --- a/cms/djangoapps/contentstore/views/tests/test_item.py +++ b/cms/djangoapps/contentstore/views/tests/test_item.py @@ -2843,6 +2843,7 @@ class TestXBlockInfo(ItemTest): @patch.dict('django.conf.settings.FEATURES', {'ENABLE_SPECIAL_EXAMS': True}) +@ddt.ddt class TestSpecialExamXBlockInfo(ItemTest): """ Unit tests for XBlock outline handling, specific to special exam XBlocks. @@ -2854,7 +2855,7 @@ class TestSpecialExamXBlockInfo(ItemTest): item_module, 'does_backend_support_onboarding', return_value=True ) patch_get_exam_by_content_id_success = patch.object( - item_module, 'get_exam_by_content_id' + item_module, 'get_exam_by_content_id', return_value={'is_proctored': True} ) patch_get_exam_by_content_id_not_found = patch.object( item_module, 'get_exam_by_content_id', side_effect=ProctoredExamNotFoundException @@ -2908,7 +2909,7 @@ class TestSpecialExamXBlockInfo(ItemTest): ) # exam proctoring should be enabled and time limited. assert xblock_info['is_proctored_exam'] is True - assert xblock_info['was_ever_special_exam'] is True + assert xblock_info['was_ever_proctored_exam'] is True assert xblock_info['is_time_limited'] is True assert xblock_info['default_time_limit_minutes'] == 100 assert xblock_info['proctoring_exam_configuration_link'] == 'test_url' @@ -2920,8 +2921,15 @@ class TestSpecialExamXBlockInfo(ItemTest): @patch_get_exam_configuration_dashboard_url @patch_does_backend_support_onboarding @patch_get_exam_by_content_id_success - def test_xblock_was_ever_special_exam( + @ddt.data( + (True, True), + (False, False), + ) + @ddt.unpack + def test_xblock_was_ever_proctored_exam( self, + is_proctored, + expected_value, mock_get_exam_by_content_id, _mock_does_backend_support_onboarding_patch, _mock_get_exam_configuration_dashboard_url, @@ -2935,13 +2943,14 @@ class TestSpecialExamXBlockInfo(ItemTest): is_time_limited=False, is_onboarding_exam=False, ) + mock_get_exam_by_content_id.return_value = {'is_proctored': is_proctored} sequential = modulestore().get_item(sequential.location) xblock_info = create_xblock_info( sequential, include_child_info=True, include_children_predicate=ALWAYS, ) - assert xblock_info['was_ever_special_exam'] is True + assert xblock_info['was_ever_proctored_exam'] is expected_value assert mock_get_exam_by_content_id.call_count == 1 @patch_get_exam_configuration_dashboard_url @@ -2968,7 +2977,7 @@ class TestSpecialExamXBlockInfo(ItemTest): include_child_info=True, include_children_predicate=ALWAYS, ) - assert xblock_info['was_ever_special_exam'] is False + assert xblock_info['was_ever_proctored_exam'] is False assert mock_get_exam_by_content_id.call_count == 1 diff --git a/cms/static/js/views/modals/course_outline_modals.js b/cms/static/js/views/modals/course_outline_modals.js index 9503338d04..79e18e4517 100644 --- a/cms/static/js/views/modals/course_outline_modals.js +++ b/cms/static/js/views/modals/course_outline_modals.js @@ -325,8 +325,8 @@ define(['jquery', 'backbone', 'underscore', 'gettext', 'js/views/baseview', isTimedExam: isTimeLimited && !( isProctoredExam || isPracticeExam || isOnboardingExam ), - specialExamLockedIn: ( - xblockInfo.get('released_to_students') && xblockInfo.get('was_ever_special_exam') + proctoredExamLockedIn: ( + xblockInfo.get('released_to_students') && xblockInfo.get('was_ever_proctored_exam') ) }, this.getContext())); diff --git a/cms/templates/js/timed-examination-preference-editor.underscore b/cms/templates/js/timed-examination-preference-editor.underscore index 9507011dbc..5cf037debf 100644 --- a/cms/templates/js/timed-examination-preference-editor.underscore +++ b/cms/templates/js/timed-examination-preference-editor.underscore @@ -2,19 +2,19 @@