fix: hide gated content message for library content questions (learning MFE only) (#27277)

This commit is contained in:
Diane Kaplan
2021-04-14 14:11:21 -04:00
committed by GitHub
parent e78d2c5a83
commit 3152c14192
2 changed files with 58 additions and 8 deletions

View File

@@ -82,11 +82,14 @@ class BaseVerticalBlockTest(XModuleXmlImportTest):
Tests for the BaseVerticalBlock.
"""
test_html = 'Test HTML'
test_problem = 'Test Problem'
test_problem = 'Test_Problem'
test_html_nested = 'Nest Nested HTML'
test_problem_nested = 'Nest_Nested_Problem'
def setUp(self):
super().setUp()
# construct module
# construct module: course/sequence/vertical - problems
# \_ nested_vertical / problems
course = xml.CourseFactory.build()
sequence = xml.SequenceFactory.build(parent=course)
vertical = xml.VerticalFactory.build(parent=sequence)
@@ -95,6 +98,10 @@ class BaseVerticalBlockTest(XModuleXmlImportTest):
xml.HtmlFactory(parent=vertical, url_name='test-html', text=self.test_html)
xml.ProblemFactory(parent=vertical, url_name='test-problem', text=self.test_problem)
nested_vertical = xml.VerticalFactory.build(parent=vertical)
xml.HtmlFactory(parent=nested_vertical, url_name='test_html_nested', text=self.test_html_nested)
xml.ProblemFactory(parent=nested_vertical, url_name='test_problem_nested', text=self.test_problem_nested)
self.course = self.process_xml(course)
course_seq = self.course.get_children()[0]
self.module_system = get_test_system()
@@ -109,6 +116,10 @@ class BaseVerticalBlockTest(XModuleXmlImportTest):
self.problem_block = self.vertical.get_children()[1]
self.problem_block.has_score = True
self.problem_block.graded = True
self.extra_vertical_block = self.vertical.get_children()[2] # VerticalBlockWithMixins
self.nested_problem_block = self.extra_vertical_block.get_children()[1]
self.nested_problem_block.has_score = True
self.nested_problem_block.graded = True
self.username = "bilbo"
self.default_context = {"bookmarked": False, "username": self.username}
@@ -195,21 +206,42 @@ class VerticalBlockTestCase(BaseVerticalBlockTest):
assert "'completed': None" in html
assert "'past_due': False" in html
@ddt.data(True, False)
def test_render_access_denied_blocks(self, has_access_error):
@ddt.data((True, True), (True, False), (False, True), (False, False))
@ddt.unpack
def test_render_access_denied_blocks(self, node_has_access_error, child_has_access_error):
""" Tests access denied blocks are not rendered when hide_access_error_blocks is True """
self.module_system._services['bookmarks'] = Mock()
self.module_system._services['user'] = StubUserService()
self.vertical.due = datetime.now(pytz.UTC) + timedelta(days=-1)
self.problem_block.has_access_error = has_access_error
self.problem_block.has_access_error = node_has_access_error
self.nested_problem_block.has_access_error = child_has_access_error
context = {'username': self.username, 'hide_access_error_blocks': True}
html = self.module_system.render(self.vertical, STUDENT_VIEW, context).content
if has_access_error:
if node_has_access_error and child_has_access_error:
assert self.test_problem not in html
else:
assert self.test_problem_nested not in html
if node_has_access_error and not child_has_access_error:
assert self.test_problem not in html
assert self.test_problem_nested in html
if not node_has_access_error and child_has_access_error:
assert self.test_problem in html
assert self.test_problem_nested not in html
if not node_has_access_error and not child_has_access_error:
assert self.test_problem in html
assert self.test_problem_nested in html
@ddt.data(True, False)
def test_block_has_access_error(self, has_access_error):
""" Tests block_has_access_error gives the correct result for child node questions """
# Use special block from setup (vertical/nested_vertical/problem)
# has_access_error is set on problem an extra level down, so we have to recurse to pass
self.nested_problem_block.has_access_error = has_access_error
should_block = self.vertical.block_has_access_error(self.vertical)
assert should_block == has_access_error
@ddt.unpack
@ddt.data(

View File

@@ -82,7 +82,8 @@ class VerticalBlock(SequenceFields, XModuleFields, StudioEditableBlock, XmlParse
# pylint: disable=no-member
for child in child_blocks:
if context.get('hide_access_error_blocks') and getattr(child, 'has_access_error', False):
child_has_access_error = self.block_has_access_error(child)
if context.get('hide_access_error_blocks') and child_has_access_error:
continue
child_block_context = copy(child_context)
if child in list(child_blocks_to_complete_on_view):
@@ -130,6 +131,23 @@ class VerticalBlock(SequenceFields, XModuleFields, StudioEditableBlock, XmlParse
return fragment
def block_has_access_error(self, block):
"""
Returns whether has_access_error is True for the given block (itself or any child)
"""
# Check its access attribute (regular question will have it set)
has_access_error = getattr(block, 'has_access_error', False)
if has_access_error:
return True
# Check child nodes if they exist (e.g. randomized library question aka LibraryContentBlock)
for child in block.get_children():
has_access_error = getattr(child, 'has_access_error', False)
if has_access_error:
return True
has_access_error = self.block_has_access_error(child)
return has_access_error
def student_view(self, context):
"""
Renders the student view of the block in the LMS.