Skip to content

Commit

Permalink
feat: add filter for hooking XBlock Render Started
Browse files Browse the repository at this point in the history
- chore: bump version to 1.9.0
  • Loading branch information
nsprenkle committed Jun 14, 2024
1 parent 2cbc5af commit 2b7e510
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 1 deletion.
8 changes: 8 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ Change Log
Unreleased
----------

[1.9.0] - 2024-06-14
--------------------

Added
~~~~~~~

* RenderXBlockStarted filter added which allows reading / modifying of XBlock context prior to render.

[1.8.1] - 2024-04-12
--------------------

Expand Down
2 changes: 1 addition & 1 deletion openedx_filters/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
"""
from openedx_filters.filters import *

__version__ = "1.8.1"
__version__ = "1.9.0"
40 changes: 40 additions & 0 deletions openedx_filters/learning/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,46 @@ def run_filter(cls, enrollments):
return data.get("enrollments")


class RenderXBlockStarted(OpenEdxPublicFilter):
"""
Filter in between context generation and rendering of XBlock scope.
"""

filter_type = "org.openedx.learning.xblock.render.started.v1"

class PreventXBlockBlockRender(OpenEdxFilterException):
"""
Custom class used to prevent the XBlock from rendering for the user.
"""

class RenderCustomResponse(OpenEdxFilterException):
"""
Custom class used to stop the XBlock rendering process and return a custom response.
"""

def __init__(self, message, response=None):
"""
Override init that defines specific arguments used in the XBlock render process.
Arguments:
message: error message for the exception.
response: custom response which will be returned by the XBlock render view.
"""
super().__init__(message, response=response)

@classmethod
def run_filter(cls, context, student_view_context):
"""
Execute a filter with the specified signature.
Arguments:
context (dict): rendering context values like is_mobile_app, show_title, etc.
student_view_context (dict): context passed to the student_view of the block context
"""
data = super().run_pipeline(context=context, student_view_context=student_view_context)
return data.get("context"), data.get("student_view_context")

Check warning on line 586 in openedx_filters/learning/filters.py

View check run for this annotation

Codecov / codecov/patch

openedx_filters/learning/filters.py#L585-L586

Added lines #L585 - L586 were not covered by tests


class VerticalBlockRenderCompleted(OpenEdxPublicFilter):
"""
Custom class used to create filters to act on vertical block rendering completed.
Expand Down
63 changes: 63 additions & 0 deletions openedx_filters/learning/tests/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
DashboardRenderStarted,
InstructorDashboardRenderStarted,
ORASubmissionViewRenderStarted,
RenderXBlockStarted,
StudentLoginRequested,
StudentRegistrationRequested,
VerticalBlockChildRenderStarted,
Expand Down Expand Up @@ -479,6 +480,68 @@ def test_halt_vertical_block_render(self, render_exception, attributes):

self.assertDictContainsSubset(attributes, exception.__dict__)

def test_xblock_render_started(self):
"""
Test RenderXBlockStarted filter behavior under normal conditions.
Expected behavior:
- The filter must have the signature specified.
- The filter should return the expected values
"""
context = {
"foo": False,
"bar": "baz",
"buzz": 1337,
}
student_view_context = {
"arbitrary_context": "value",
"more_arbitrary_context": True
}

result = VerticalBlockChildRenderStarted.run_filter(context, student_view_context)

self.assertTupleEqual((context, student_view_context), result)

@data(
(
RenderXBlockStarted.PreventXBlockBlockRender,
{
"message": "Danger, Will Robinson!"
}
)
)
@unpack
def test_halt_xblock_render(self, xblock_render_exception, attributes):
"""
Test for xblock render exception attributes.
Expected behavior:
- The exception must have the attributes specified.
"""
exception = xblock_render_exception(**attributes)

self.assertDictContainsSubset(attributes, exception.__dict__)

@data(
(
RenderXBlockStarted.RenderCustomResponse,
{
"message": "Danger, Will Robinson!"
}
)
)
@unpack
def test_halt_xblock_render_custom_response(self, xblock_render_exception, attributes):
"""
Test for xblock render exception attributes.
Expected behavior:
- The exception must have the attributes specified.
"""
exception = xblock_render_exception(**attributes)

self.assertDictContainsSubset(attributes, exception.__dict__)

def test_account_settings_render_started(self):
"""
Test AccountSettingsRenderStarted filter behavior under normal conditions.
Expand Down

0 comments on commit 2b7e510

Please sign in to comment.