Files
edx-platform/lms/djangoapps/course_blocks/transformers/split_test.py
2017-06-11 21:48:06 -04:00

88 lines
3.2 KiB
Python

"""
Split Test Block Transformer
"""
from openedx.core.djangoapps.content.block_structure.transformer import (
BlockStructureTransformer,
FilteringTransformerMixin
)
class SplitTestTransformer(FilteringTransformerMixin, BlockStructureTransformer):
"""
A nested transformer of the UserPartitionTransformer that honors the
block structure pathways created by split_test modules.
To avoid code duplication, the implementation transforms its block
access representation to the representation used by user_partitions.
Namely, the 'group_id_to_child' field on a split_test module is
transformed into the, now standard, 'group_access' fields in the
split_test module's children.
The implementation therefore relies on the UserPartitionTransformer
to actually enforce the access using the 'user_partitions' and
'group_access' fields.
"""
WRITE_VERSION = 1
READ_VERSION = 1
@classmethod
def name(cls):
"""
Unique identifier for the transformer's class;
same identifier used in setup.py.
"""
return "split_test"
@classmethod
def collect(cls, block_structure):
"""
Collects any information that's necessary to execute this
transformer's transform method.
"""
root_block = block_structure.get_xblock(block_structure.root_block_usage_key)
user_partitions = getattr(root_block, 'user_partitions', [])
for block_key in block_structure.topological_traversal(
filter_func=lambda block_key: block_key.block_type == 'split_test',
yield_descendants_of_unyielded=True,
):
xblock = block_structure.get_xblock(block_key)
partition_for_this_block = next(
(
partition for partition in user_partitions
if partition.id == xblock.user_partition_id
),
None
)
if not partition_for_this_block:
continue
# Create dict of child location to group_id, using the
# group_id_to_child field on the split_test module.
child_to_group = {
xblock.group_id_to_child.get(unicode(group.id), None): group.id
for group in partition_for_this_block.groups
}
# Set group access for each child using its group_access
# field so the user partitions transformer enforces it.
for child_location in xblock.children:
child = block_structure.get_xblock(child_location)
group = child_to_group.get(child_location, None)
child.group_access[partition_for_this_block.id] = [group] if group is not None else []
def transform_block_filters(self, usage_info, block_structure):
"""
Mutates block_structure based on the given usage_info.
"""
# The UserPartitionTransformer will enforce group access, so
# go ahead and remove all extraneous split_test modules.
return [
block_structure.create_removal_filter(
lambda block_key: block_key.block_type == 'split_test',
keep_descendants=True,
)
]