EDUCATOR-2303 allow learners to see gated banner before starting proctored or timed exam
This commit is contained in:
@@ -241,13 +241,23 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule):
|
||||
context = context or {}
|
||||
self._capture_basic_metrics()
|
||||
banner_text = None
|
||||
special_html_view = self._hidden_content_student_view(context) or self._special_exam_student_view()
|
||||
if special_html_view:
|
||||
masquerading_as_specific_student = context.get('specific_masquerade', False)
|
||||
banner_text, special_html = special_html_view
|
||||
if special_html and not masquerading_as_specific_student:
|
||||
return Fragment(special_html)
|
||||
return self._student_view(context, banner_text)
|
||||
prereq_met = True
|
||||
prereq_meta_info = {}
|
||||
|
||||
if self._required_prereq():
|
||||
if self.runtime.user_is_staff:
|
||||
banner_text = _('This subsection is unlocked for learners when they meet the prerequisite requirements.')
|
||||
else:
|
||||
# check if prerequisite has been met
|
||||
prereq_met, prereq_meta_info = self._compute_is_prereq_met(True)
|
||||
if prereq_met:
|
||||
special_html_view = self._hidden_content_student_view(context) or self._special_exam_student_view()
|
||||
if special_html_view:
|
||||
masquerading_as_specific_student = context.get('specific_masquerade', False)
|
||||
banner_text, special_html = special_html_view
|
||||
if special_html and not masquerading_as_specific_student:
|
||||
return Fragment(special_html)
|
||||
return self._student_view(context, prereq_met, prereq_meta_info, banner_text)
|
||||
|
||||
def _special_exam_student_view(self):
|
||||
"""
|
||||
@@ -299,7 +309,7 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule):
|
||||
# NOTE (CCB): We default to true to maintain the behavior in place prior to allowing anonymous access access.
|
||||
return context.get('user_authenticated', True)
|
||||
|
||||
def _student_view(self, context, banner_text=None):
|
||||
def _student_view(self, context, prereq_met, prereq_meta_info, banner_text=None):
|
||||
"""
|
||||
Returns the rendered student view of the content of this
|
||||
sequential. If banner_text is given, it is added to the
|
||||
@@ -307,15 +317,7 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule):
|
||||
"""
|
||||
display_items = self.get_display_items()
|
||||
self._update_position(context, len(display_items))
|
||||
prereq_met = True
|
||||
prereq_meta_info = {}
|
||||
|
||||
if self._required_prereq():
|
||||
if self.runtime.user_is_staff:
|
||||
banner_text = _('This subsection is unlocked for learners when they meet the prerequisite requirements.')
|
||||
else:
|
||||
# check if prerequisite has been met
|
||||
prereq_met, prereq_meta_info = self._compute_is_prereq_met(True)
|
||||
if prereq_met and not self._is_gate_fulfilled():
|
||||
banner_text = _('This section is a prerequisite. You must complete this section in order to unlock additional content.')
|
||||
|
||||
|
||||
@@ -325,6 +325,14 @@ class CoursewarePage(CoursePage, CompletionOnViewMixin):
|
||||
bookmarks_page = BookmarksPage(self.browser, self.course_id)
|
||||
bookmarks_page.visit()
|
||||
|
||||
def is_gating_banner_visible(self):
|
||||
"""
|
||||
Check if the gated banner for locked content is visible.
|
||||
"""
|
||||
return self.q(css='.problem-header').is_present() \
|
||||
and self.q(css='.btn-brand').text[0] == u'Go To Prerequisite Section' \
|
||||
and self.q(css='.problem-header').text[0] == u'Content Locked'
|
||||
|
||||
|
||||
class CoursewareSequentialTabPage(CoursePage):
|
||||
"""
|
||||
|
||||
@@ -60,7 +60,7 @@ class GatingTest(UniqueCourseTest):
|
||||
self.course_info['display_name']
|
||||
)
|
||||
course_fixture.add_advanced_settings({
|
||||
"enable_subsection_gating": {"value": "true"}
|
||||
"enable_subsection_gating": {"value": "true"}, 'enable_proctored_exams': {"value": "true"}
|
||||
})
|
||||
|
||||
course_fixture.add_children(
|
||||
@@ -70,7 +70,11 @@ class GatingTest(UniqueCourseTest):
|
||||
),
|
||||
XBlockFixtureDesc('sequential', 'Test Subsection 2').add_children(
|
||||
XBlockFixtureDesc('problem', 'Test Problem 2')
|
||||
)
|
||||
),
|
||||
XBlockFixtureDesc('sequential', 'Test Subsection 3').add_children(
|
||||
XBlockFixtureDesc('problem', 'Test Problem 3')
|
||||
),
|
||||
|
||||
)
|
||||
).install()
|
||||
|
||||
@@ -95,16 +99,16 @@ class GatingTest(UniqueCourseTest):
|
||||
self.studio_course_outline.select_advanced_tab(desired_item='gated_content')
|
||||
self.studio_course_outline.make_gating_prerequisite()
|
||||
|
||||
def _setup_gated_subsection(self):
|
||||
def _setup_gated_subsection(self, subsection_index=1):
|
||||
"""
|
||||
Gate the second subsection on the first subsection
|
||||
Gate the given indexed subsection on the first subsection
|
||||
"""
|
||||
# Login as staff
|
||||
self._auto_auth(self.STAFF_USERNAME, self.STAFF_EMAIL, True)
|
||||
|
||||
# Gate the second subsection based on the score achieved in the first subsection
|
||||
self.studio_course_outline.visit()
|
||||
self.studio_course_outline.open_subsection_settings_dialog(1)
|
||||
self.studio_course_outline.open_subsection_settings_dialog(subsection_index)
|
||||
self.studio_course_outline.select_advanced_tab(desired_item='gated_content')
|
||||
self.studio_course_outline.add_prerequisite_to_subsection("80", "")
|
||||
|
||||
@@ -164,13 +168,13 @@ class GatingTest(UniqueCourseTest):
|
||||
self._auto_auth(self.STUDENT_USERNAME, self.STUDENT_EMAIL, False)
|
||||
|
||||
self.course_home_page.visit()
|
||||
self.assertEqual(self.course_home_page.outline.num_subsections, 2)
|
||||
self.assertEqual(self.course_home_page.outline.num_subsections, 3)
|
||||
|
||||
# Fulfill prerequisite and verify that gated subsection is shown
|
||||
self.courseware_page.visit()
|
||||
self._fulfill_prerequisite()
|
||||
self.course_home_page.visit()
|
||||
self.assertEqual(self.course_home_page.outline.num_subsections, 2)
|
||||
self.assertEqual(self.course_home_page.outline.num_subsections, 3)
|
||||
|
||||
def test_gated_subsection_in_lms_for_staff(self):
|
||||
"""
|
||||
@@ -190,7 +194,7 @@ class GatingTest(UniqueCourseTest):
|
||||
|
||||
self.course_home_page.visit()
|
||||
self.assertEqual(self.course_home_page.preview.staff_view_mode, 'Staff')
|
||||
self.assertEqual(self.course_home_page.outline.num_subsections, 2)
|
||||
self.assertEqual(self.course_home_page.outline.num_subsections, 3)
|
||||
|
||||
# Click on gated section and check for banner
|
||||
self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 2')
|
||||
@@ -204,8 +208,68 @@ class GatingTest(UniqueCourseTest):
|
||||
self.course_home_page.visit()
|
||||
self.course_home_page.preview.set_staff_view_mode('Learner')
|
||||
self.course_home_page.wait_for_page()
|
||||
self.assertEqual(self.course_home_page.outline.num_subsections, 2)
|
||||
self.assertEqual(self.course_home_page.outline.num_subsections, 3)
|
||||
self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 1')
|
||||
self.courseware_page.wait_for_page()
|
||||
# banner displayed informing section is a prereq
|
||||
self.assertTrue(self.courseware_page.has_banner())
|
||||
|
||||
def test_gated_banner_before_special_exam(self):
|
||||
"""
|
||||
When a subsection with a prereq is a special
|
||||
exam, show the gating banner before starting
|
||||
the special exam.
|
||||
|
||||
Setup the course with a subsection having pre-req
|
||||
Subsection with pre-req is a special exam
|
||||
Go the LMS course outline page
|
||||
Click the special exam subsection
|
||||
The gated banner asking for completing
|
||||
prereqs should be visible
|
||||
Go to the required subsection
|
||||
Fulfill the requirements
|
||||
Visit the special exam subsection again
|
||||
The gated banner is not visible anymore
|
||||
and user can start the special exam
|
||||
"""
|
||||
|
||||
self._setup_prereq()
|
||||
|
||||
# Gating subsection 1 and making it a timed exam
|
||||
self._setup_gated_subsection()
|
||||
self.studio_course_outline.open_subsection_settings_dialog(1)
|
||||
self.studio_course_outline.select_advanced_tab()
|
||||
self.studio_course_outline.make_exam_timed()
|
||||
|
||||
# Gating subsection 2 and making it a proctored exam
|
||||
self._setup_gated_subsection(2)
|
||||
self.studio_course_outline.open_subsection_settings_dialog(2)
|
||||
self.studio_course_outline.select_advanced_tab()
|
||||
self.studio_course_outline.make_exam_proctored()
|
||||
|
||||
self._auto_auth(self.STUDENT_USERNAME, self.STUDENT_EMAIL, False)
|
||||
self.course_home_page.visit()
|
||||
|
||||
# Test gating banner before starting timed exam
|
||||
self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 2')
|
||||
self.assertTrue(self.courseware_page.is_gating_banner_visible())
|
||||
|
||||
# Test gating banner before proctored exams
|
||||
self.course_home_page.visit()
|
||||
self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 3')
|
||||
self.assertTrue(self.courseware_page.is_gating_banner_visible())
|
||||
|
||||
# Fulfill requirements
|
||||
self.course_home_page.visit()
|
||||
self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 1')
|
||||
self._fulfill_prerequisite()
|
||||
|
||||
# Banner is not visible anymore on timed exam sub-section
|
||||
self.course_home_page.visit()
|
||||
self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 2')
|
||||
self.assertFalse(self.courseware_page.is_gating_banner_visible())
|
||||
|
||||
# Banner is not visible on proctored exam subsection
|
||||
self.course_home_page.visit()
|
||||
self.course_home_page.outline.go_to_section('Test Section 1', 'Test Subsection 3')
|
||||
self.assertFalse(self.courseware_page.is_gating_banner_visible())
|
||||
|
||||
Reference in New Issue
Block a user