Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions docs/guides/hooks/filters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ well as the trigger location in this same repository.
- org.openedx.learning.dashboard.render.started.v1
- `2022-06-14 <https://github.com/eduNEXT/edx-platform/blob/master/common/djangoapps/student/views/dashboard.py#L878>`_

* - `VerticalChildRenderStarted <https://github.com/openedx/openedx-filters/blob/main/openedx_filters/learning/filters.py#L427>`_
- org.openedx.learning.veritical_child_block.render.started.v1
- `2022-08-18 <https://github.com/openedx/edx-platform/blob/master/xmodule/vertical_block.py#L122>`_
* - `VerticalBlockChildRenderStarted <https://github.com/openedx/openedx-filters/blob/main/openedx_filters/learning/filters.py#L427>`_
- org.openedx.learning.veritical_block_child.render.started.v1
- `2022-08-18 <https://github.com/openedx/edx-platform/blob/master/xmodule/vertical_block.py#L170>`_

* - `VerticalBlockRenderCompleted <https://github.com/openedx/openedx-filters/blob/main/openedx_filters/learning/filters.py#L476>`_
- org.openedx.learning.veritical_block.render.completed.v1
- `2022-02-18 <https://github.com/openedx/edx-platform/blob/master/xmodule/vertical_block.py#L121>`_
2 changes: 1 addition & 1 deletion requirements/edx/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ openedx-events==5.0.0
# via
# -r requirements/edx/base.in
# edx-event-bus-kafka
openedx-filters==1.0.0
openedx-filters==1.1.0
# via
# -r requirements/edx/base.in
# lti-consumer-xblock
Expand Down
2 changes: 1 addition & 1 deletion requirements/edx/development.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1009,7 +1009,7 @@ openedx-events==5.0.0
# via
# -r requirements/edx/testing.txt
# edx-event-bus-kafka
openedx-filters==1.0.0
openedx-filters==1.1.0
# via
# -r requirements/edx/testing.txt
# lti-consumer-xblock
Expand Down
2 changes: 1 addition & 1 deletion requirements/edx/testing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -959,7 +959,7 @@ openedx-events==5.0.0
# via
# -r requirements/edx/base.txt
# edx-event-bus-kafka
openedx-filters==1.0.0
openedx-filters==1.1.0
# via
# -r requirements/edx/base.txt
# lti-consumer-xblock
Expand Down
148 changes: 148 additions & 0 deletions xmodule/tests/test_vertical.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
import ddt
from fs.memoryfs import MemoryFS
from django.contrib.auth.models import AnonymousUser
from django.test import override_settings
from openedx_filters import PipelineStep
from openedx_filters.learning.filters import VerticalBlockChildRenderStarted, VerticalBlockRenderCompleted

from . import get_test_system
from .helpers import StubUserService
Expand Down Expand Up @@ -78,6 +81,62 @@ def vertical_is_complete(self, item):
return self._completion_value == 1 if self._enabled else None


class TestVerticalBlockChildRenderStep(PipelineStep):
"""
Utility class for testing filters on vertical block children
"""
filter_content = "Altered Content"

def run_filter(self, block, context): # lint-amnesty, pylint: disable=arguments-differ
"""Pipeline step that changes child content"""
if type(block).__name__ == "HtmlBlockWithMixins":
block.get_html = lambda: TestVerticalBlockChildRenderStep.filter_content
return {"block": block, "context": context}


class TestPreventVerticalBlockChildRender(PipelineStep):
"""
Utility class to test vertical block children are skipped in rendering.
"""

def run_filter(self, block, context): # lint-amnesty, pylint: disable=arguments-differ
"""Pipeline step that raises exceptions during child block rendering"""
if type(block).__name__ == "HtmlBlockWithMixins":
raise VerticalBlockChildRenderStarted.PreventChildBlockRender(
"Skip block test exception"
)


class TestVerticalBlockRenderCompletedStep(PipelineStep):
"""
Utility class for testing filters on vertical block render completion
"""
filter_content = "Extra content added"

def run_filter(self, block, fragment, context, view): # lint-amnesty, pylint: disable=arguments-differ
"""Pipeline step that alters the output of the fragment"""
fragment.content += TestVerticalBlockRenderCompletedStep.filter_content
return {
"block": block,
"fragment": fragment,
"context": context,
"view": view
}


class TestPreventVerticalBlockRenderStep(PipelineStep):
"""
Utility class for testing VerticalBlock render can be stopped.
"""
filter_content = "<div class=\"alert alert-danger\">Assignments are not available for Audit students.<div>"

def run_filter(self, block, fragment, context, view): # lint-amnesty, pylint: disable=arguments-differ
"""Pipeline step that raises an exception"""
raise VerticalBlockRenderCompleted.PreventVerticalBlockRender(
TestPreventVerticalBlockRenderStep.filter_content
)


class BaseVerticalBlockTest(XModuleXmlImportTest):
"""
Tests for the BaseVerticalBlock.
Expand Down Expand Up @@ -289,3 +348,92 @@ def test_render_studio_view(self):
html = self.module_system.render(self.vertical, AUTHOR_VIEW, context).content
assert self.test_html in html
assert self.test_problem in html

@override_settings(
OPEN_EDX_FILTERS_CONFIG={
"org.openedx.learning.vertical_block_child.render.started.v1": {
"pipeline": [
"xmodule.tests.test_vertical.TestVerticalBlockChildRenderStep"
],
"fail_silently": False,
},
},
)
def test_vertical_block_child_render_started_filter_execution(self):
"""
Test the VerticalBlockChildRenderStarted filter's effects on student view.
"""
self.module_system._services['bookmarks'] = Mock()
self.module_system._services['user'] = StubUserService(user=Mock())
self.module_system._services['completion'] = StubCompletionService(enabled=True, completion_value=0)

html = self.module_system.render(self.vertical, STUDENT_VIEW, self.default_context).content

assert TestVerticalBlockChildRenderStep.filter_content in html

@override_settings(
OPEN_EDX_FILTERS_CONFIG={
"org.openedx.learning.vertical_block_child.render.started.v1": {
"pipeline": [
"xmodule.tests.test_vertical.TestPreventVerticalBlockChildRender"
],
"fail_silently": False,
},
},
)
def test_vertical_block_child_render_is_skipped_on_filter_exception(self):
"""
Test VerticalBlockChildRenderStarted filter can be used to skip child blocks.
"""
self.module_system._services['bookmarks'] = Mock()
self.module_system._services['user'] = StubUserService(user=Mock())
self.module_system._services['completion'] = StubCompletionService(enabled=True, completion_value=0)

html = self.module_system.render(self.vertical, STUDENT_VIEW, self.default_context).content

assert self.test_html not in html
assert self.test_html_nested not in html

@override_settings(
OPEN_EDX_FILTERS_CONFIG={
"org.openedx.learning.vertical_block.render.completed.v1": {
"pipeline": [
"xmodule.tests.test_vertical.TestVerticalBlockRenderCompletedStep"
],
"fail_silently": False,
},
},
)
def test_vertical_block_render_completed_filter_execution(self):
"""
Test the VerticalBlockRenderCompleted filter's execution.
"""
self.module_system._services['bookmarks'] = Mock()
self.module_system._services['user'] = StubUserService(user=Mock())
self.module_system._services['completion'] = StubCompletionService(enabled=True, completion_value=0)

html = self.module_system.render(self.vertical, STUDENT_VIEW, self.default_context).content

assert TestVerticalBlockRenderCompletedStep.filter_content in html

@override_settings(
OPEN_EDX_FILTERS_CONFIG={
"org.openedx.learning.vertical_block.render.completed.v1": {
"pipeline": [
"xmodule.tests.test_vertical.TestPreventVerticalBlockRenderStep"
],
"fail_silently": False,
},
},
)
def test_vertical_block_render_output_is_changed_on_filter_exception(self):
"""
Test VerticalBlockRenderCompleted filter can be used to prevent vertical block from rendering.
"""
self.module_system._services['bookmarks'] = Mock()
self.module_system._services['user'] = StubUserService(user=Mock())
self.module_system._services['completion'] = StubCompletionService(enabled=True, completion_value=0)

html = self.module_system.render(self.vertical, STUDENT_VIEW, self.default_context).content

assert TestPreventVerticalBlockRenderStep.filter_content == html
28 changes: 21 additions & 7 deletions xmodule/vertical_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from web_fragments.fragment import Fragment
from xblock.core import XBlock # lint-amnesty, pylint: disable=wrong-import-order
from xblock.fields import Boolean, Scope
from openedx_filters.learning.filters import VerticalBlockChildRenderStarted
from openedx_filters.learning.filters import VerticalBlockChildRenderStarted, VerticalBlockRenderCompleted
from xmodule.mako_block import MakoTemplateBlockBase
from xmodule.progress import Progress
from xmodule.seq_block import SequenceFields
Expand Down Expand Up @@ -72,7 +72,7 @@ class VerticalBlock(

show_in_read_only_mode = True

def _student_or_public_view(self, context, view):
def _student_or_public_view(self, context, view): # lint-amnesty, pylint: disable=too-many-statements
"""
Renders the requested view type of the block in the LMS.
"""
Expand Down Expand Up @@ -117,11 +117,15 @@ def _student_or_public_view(self, context, view):
'mark-completed-on-view-after-delay': complete_on_view_delay
}

# .. filter_implemented_name: VerticalBlockChildRenderStarted
# .. filter_type: org.openedx.learning.vertical_block_child.render.started.v1
child, child_block_context = VerticalBlockChildRenderStarted.run_filter(
block=child, context=child_block_context
)
try:
# .. filter_implemented_name: VerticalBlockChildRenderStarted
# .. filter_type: org.openedx.learning.vertical_block_child.render.started.v1
child, child_block_context = VerticalBlockChildRenderStarted.run_filter(
block=child, context=child_block_context
)
except VerticalBlockChildRenderStarted.PreventChildBlockRender as exc:
log.info("Skipping %s from vertical block. Reason: %s", child, exc.message)
continue

rendered_child = child.render(view, child_block_context)
fragment.add_fragment_resources(rendered_child)
Expand Down Expand Up @@ -162,6 +166,16 @@ def _student_or_public_view(self, context, view):
add_webpack_to_fragment(fragment, 'VerticalStudentView')
fragment.initialize_js('VerticalStudentView')

try:
# .. filter_implemented_name: VerticalBlockRenderCompleted
# .. filter_type: org.openedx.learning.vertical_block.render.completed.v1
_, fragment, context, view = VerticalBlockRenderCompleted.run_filter(
block=self, fragment=fragment, context=context, view=view
)
except VerticalBlockRenderCompleted.PreventVerticalBlockRender as exc:
log.info("VerticalBlock rendering stopped. Reason: %s", exc.message)
fragment.content = exc.message

return fragment

def block_has_access_error(self, block):
Expand Down