Files
edx-platform/lms/djangoapps/course_blocks/tests/test_api.py
2024-11-01 11:58:35 +05:00

150 lines
5.3 KiB
Python

# pylint: disable=attribute-defined-outside-init
"""
Tests for course_blocks API
"""
from unittest.mock import Mock, patch
import ddt
from django.http.request import HttpRequest
from common.djangoapps.student.tests.factories import UserFactory
from lms.djangoapps.course_blocks.api import get_course_blocks
from lms.djangoapps.course_blocks.transformers.tests.helpers import CourseStructureTestCase
from lms.djangoapps.course_blocks.transformers.tests.test_user_partitions import UserPartitionTestMixin
from lms.djangoapps.courseware.block_render import make_track_function, prepare_runtime_for_user
from openedx.core.djangoapps.content.block_structure.transformers import BlockStructureTransformers
from openedx.core.djangoapps.course_groups.cohorts import add_user_to_cohort
from xmodule.modulestore.django import modulestore
def get_block_side_effect(block_locator, user_known):
"""
Side effect for `CachingDescriptorSystem.get_block`
"""
store = modulestore()
course = store.get_course(block_locator.course_key)
block = store.get_item(block_locator)
runtime = block.runtime
user = UserFactory.create()
user.known = user_known
prepare_runtime_for_user(
user=user,
student_data=Mock(),
runtime=runtime,
course_id=block_locator.course_key,
track_function=make_track_function(HttpRequest()),
request_token=Mock(),
course=course,
)
return block.runtime.get_block_for_descriptor(block)
def get_block_side_effect_for_known_user(self, *args, **kwargs):
"""
Side effect for known user test.
"""
return get_block_side_effect(self, True)
def get_block_side_effect_for_unknown_user(self, *args, **kwargs):
"""
Side effect for unknown user test.
"""
return get_block_side_effect(self, False)
@ddt.ddt
class TestGetCourseBlocks(UserPartitionTestMixin, CourseStructureTestCase):
"""
Tests `get_course_blocks` API
"""
def setup_partitions_and_course(self):
"""
Setup course structure.
"""
# Set up user partitions and groups.
self.setup_groups_partitions(active=True, num_groups=1)
self.user_partition = self.user_partitions[0]
# Build course.
self.course_hierarchy = self.get_course_hierarchy()
self.blocks = self.build_course(self.course_hierarchy)
self.course = self.blocks['course']
# Set up cohorts.
self.setup_cohorts(self.course)
def get_course_hierarchy(self):
"""
Returns a course hierarchy to test with.
"""
# course
# / \
# / \
# A[0] B
# |
# |
# O
return [
{
'org': 'UserPartitionTransformer',
'course': 'UP101F',
'run': 'test_run',
'user_partitions': [self.user_partition],
'#type': 'course',
'#ref': 'course',
'#children': [
{
'#type': 'vertical',
'#ref': 'A',
'metadata': {'group_access': {self.user_partition.id: [0]}},
},
{'#type': 'vertical', '#ref': 'B'},
],
},
{
'#type': 'vertical',
'#ref': 'O',
'#parents': ['B'],
},
]
@ddt.data(
(1, ('course', 'B', 'O'), True),
(1, ('course', 'A', 'B', 'O'), False),
(None, ('course', 'B', 'O'), True),
(None, ('course', 'A', 'B', 'O'), False),
)
@ddt.unpack
def test_get_course_blocks(self, group_id, expected_blocks, user_known):
"""
Tests that `get_course_blocks` returns blocks without access checks for unknown users.
Access checks are done through the transformers and through Runtime get_block_for_descriptor. Due
to the runtime limitations during the tests, the Runtime access checks are not performed as
get_block_for_descriptor is never called and Block is returned by CachingDescriptorSystem.get_block.
In this test, we mock the CachingDescriptorSystem.get_block and check block access for known and unknown users.
For known users, it performs the Runtime access checks through get_block_for_descriptor. For unknown, it
skips the access checks.
"""
self.setup_partitions_and_course()
if group_id:
cohort = self.partition_cohorts[self.user_partition.id - 1][group_id - 1]
add_user_to_cohort(cohort, self.user.username)
side_effect = get_block_side_effect_for_known_user if user_known else get_block_side_effect_for_unknown_user
with patch('xmodule.modulestore.split_mongo.split.CachingDescriptorSystem.get_block', side_effect=side_effect):
block_structure = get_course_blocks(
self.user,
self.course.location,
BlockStructureTransformers([]),
)
self.assertSetEqual(
set(block_structure.get_block_keys()),
self.get_block_key_set(self.blocks, *expected_blocks)
)