Merge pull request #28698 from edx/mikix/hide-after-due-mfe

feat: notify MFE when a sequence is hidden-after-due
This commit is contained in:
Michael Terry
2021-09-10 09:12:57 -04:00
committed by GitHub
4 changed files with 76 additions and 19 deletions

View File

@@ -366,23 +366,37 @@ class SequenceBlock(
return json.dumps(self._get_completion(data))
raise NotFoundError('Unexpected dispatch type')
def get_metadata(self, view=STUDENT_VIEW):
def get_metadata(self, view=STUDENT_VIEW, context=None):
"""Returns a dict of some common block properties"""
context = {'exclude_units': True}
context = context or {}
context['exclude_units'] = True
prereq_met = True
prereq_meta_info = {}
banner_text = None
display_items = self.get_display_items()
course = self._get_course()
is_hidden_after_due = False
if self._required_prereq():
if self.runtime.user_is_staff:
banner_text = _('This subsection is unlocked for learners when they meet the prerequisite requirements.') # lint-amnesty, pylint: disable=line-too-long
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 view == STUDENT_VIEW and not self._can_user_view_content(course):
if context.get('specific_masquerade', False):
# Still show the content, but flag to the staff user that the learner wouldn't be able to see it
banner_text = self._hidden_content_banner_text(course)
else:
is_hidden_after_due = True
meta = self._get_render_metadata(context, display_items, prereq_met, prereq_meta_info, banner_text, view)
meta['display_name'] = self.display_name_with_default
meta['format'] = getattr(self, 'format', '')
meta['is_hidden_after_due'] = is_hidden_after_due
return meta
@classmethod
@@ -434,7 +448,10 @@ class SequenceBlock(
self, self.course_id
)
def student_view(self, context): # lint-amnesty, pylint: disable=missing-function-docstring
def student_view(self, context):
"""
Renders the normal student view of the block in the LMS.
"""
_ = self.runtime.service(self, "i18n").ugettext
context = context or {}
self._capture_basic_metrics()
@@ -443,7 +460,9 @@ class SequenceBlock(
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.') # lint-amnesty, pylint: disable=line-too-long
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)
@@ -496,6 +515,16 @@ class SequenceBlock(
banner_text = _("This exam is hidden from the learner.")
return banner_text, special_exam_html
def _hidden_content_banner_text(self, course):
"""
Chooses a banner message to show for hidden content
"""
_ = self.runtime.service(self, 'i18n').gettext
if course.self_paced:
return _('Because the course has ended, this assignment is hidden from the learner.')
else:
return _('Because the due date has passed, this assignment is hidden from the learner.')
def _hidden_content_student_view(self, context):
"""
Checks whether the content of this sequential is hidden from the
@@ -505,10 +534,7 @@ class SequenceBlock(
_ = self.runtime.service(self, "i18n").ugettext
course = self._get_course()
if not self._can_user_view_content(course):
if course.self_paced:
banner_text = _("Because the course has ended, this assignment is hidden from the learner.")
else:
banner_text = _("Because the due date has passed, this assignment is hidden from the learner.")
banner_text = self._hidden_content_banner_text(course)
hidden_content_html = self.system.render_template(
'hidden_content.html',
@@ -535,7 +561,9 @@ class SequenceBlock(
# 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 _get_render_metadata(self, context, display_items, prereq_met, prereq_meta_info, banner_text=None, view=STUDENT_VIEW, fragment=None): # lint-amnesty, pylint: disable=line-too-long, missing-function-docstring
def _get_render_metadata(self, context, display_items, prereq_met, prereq_meta_info, banner_text=None,
view=STUDENT_VIEW, fragment=None):
"""Returns a dictionary of sequence metadata, used by render methods and for the courseware API"""
if prereq_met and not self._is_gate_fulfilled():
_ = self.runtime.service(self, "i18n").ugettext
banner_text = _(

View File

@@ -110,6 +110,11 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
module_system.descriptor_runtime = block._runtime # pylint: disable=protected-access
block.xmodule_runtime = module_system
# The render operation will ask modulestore for the current course to get some data. As these tests were
# originally not written to be compatible with a real modulestore, we've mocked out the relevant return values.
module_system.modulestore = Mock()
module_system.modulestore.get_course.return_value = self.course
def _get_rendered_view(self,
sequence,
requested_child=None,
@@ -124,12 +129,8 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
if extra_context:
context.update(extra_context)
# The render operation will ask modulestore for the current course to get some data. As these tests were
# originally not written to be compatible with a real modulestore, we've mocked out the relevant return values.
with patch.object(SequenceBlock, '_get_course') as mock_course:
self.course.self_paced = self_paced
mock_course.return_value = self.course
return sequence.xmodule_runtime.render(sequence, view, context).content
self.course.self_paced = self_paced
return sequence.xmodule_runtime.render(sequence, view, context).content
def _assert_view_at_position(self, rendered_html, expected_position):
"""