From 6b8f372178e548dec6d2e2f9f3467a85c27e5cf7 Mon Sep 17 00:00:00 2001 From: George Schneeloch Date: Wed, 24 Feb 2016 16:39:45 -0500 Subject: [PATCH] Added visible_to_staff_only field to course blocks API --- .../blocks/tests/test_serializers.py | 79 +++++++++++++++++-- .../blocks/transformers/__init__.py | 8 ++ 2 files changed, 81 insertions(+), 6 deletions(-) diff --git a/lms/djangoapps/course_api/blocks/tests/test_serializers.py b/lms/djangoapps/course_api/blocks/tests/test_serializers.py index 179970b30b..b4b4235c3a 100644 --- a/lms/djangoapps/course_api/blocks/tests/test_serializers.py +++ b/lms/djangoapps/course_api/blocks/tests/test_serializers.py @@ -6,10 +6,12 @@ from mock import MagicMock from course_blocks.tests.helpers import EnableTransformerRegistryMixin from openedx.core.lib.block_structure.transformers import BlockStructureTransformers from student.tests.factories import UserFactory +from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import ToyCourseFactory from lms.djangoapps.course_blocks.api import get_course_blocks, COURSE_BLOCK_ACCESS_TRANSFORMERS +from student.roles import CourseStaffRole from ..transformers.blocks_api import BlocksAPITransformer from ..serializers import BlockSerializer, BlockDictSerializer from .helpers import deserialize_usage_key @@ -25,10 +27,17 @@ class TestBlockSerializerBase(EnableTransformerRegistryMixin, SharedModuleStoreT cls.course = ToyCourseFactory.create() + # Hide the html block + key = cls.course.id.make_usage_key('html', 'secret:toylab') + cls.html_block = cls.store.get_item(key) + cls.html_block.visible_to_staff_only = True + cls.store.update_item(cls.html_block, ModuleStoreEnum.UserID.test) + def setUp(self): super(TestBlockSerializerBase, self).setUp() self.user = UserFactory.create() + blocks_api_transformer = BlocksAPITransformer( block_types_to_count=['video'], requested_student_view_data=['video'], @@ -58,11 +67,13 @@ class TestBlockSerializerBase(EnableTransformerRegistryMixin, SharedModuleStoreT {'id', 'type', 'lms_web_url', 'student_view_url'}, ) - def add_additional_requested_fields(self): + def add_additional_requested_fields(self, context=None): """ Adds additional fields to the requested_fields context for the serializer. """ - self.serializer_context['requested_fields'].extend([ + if context is None: + context = self.serializer_context + context['requested_fields'].extend([ 'children', 'display_name', 'graded', @@ -71,6 +82,7 @@ class TestBlockSerializerBase(EnableTransformerRegistryMixin, SharedModuleStoreT 'student_view_data', 'student_view_multi_device', 'lti_url', + 'visible_to_staff_only', ]) def assert_extended_block(self, serialized_block): @@ -83,6 +95,7 @@ class TestBlockSerializerBase(EnableTransformerRegistryMixin, SharedModuleStoreT 'display_name', 'graded', 'block_counts', 'student_view_multi_device', 'lti_url', + 'visible_to_staff_only', }, set(serialized_block.iterkeys()), ) @@ -96,18 +109,48 @@ class TestBlockSerializerBase(EnableTransformerRegistryMixin, SharedModuleStoreT self.assertIn('student_view_multi_device', serialized_block) self.assertTrue(serialized_block['student_view_multi_device']) + def create_staff_context(self): + """ + Create staff user and course blocks accessible by that user + """ + # Create a staff user to be able to test visible_to_staff_only + staff_user = UserFactory.create() + CourseStaffRole(self.course.location.course_key).add_users(staff_user) + + block_structure = get_course_blocks( + staff_user, + self.course.location, + BlockStructureTransformers(COURSE_BLOCK_ACCESS_TRANSFORMERS), + ) + return { + 'request': MagicMock(), + 'block_structure': block_structure, + 'requested_fields': ['type'], + } + + def assert_staff_fields(self, serialized_block): + """ + Test fields accessed by a staff user + """ + if serialized_block['id'] == unicode(self.html_block.location): + self.assertTrue(serialized_block['visible_to_staff_only']) + else: + self.assertFalse(serialized_block['visible_to_staff_only']) + class TestBlockSerializer(TestBlockSerializerBase): """ Tests the BlockSerializer class, which returns a list of blocks. """ - def create_serializer(self): + def create_serializer(self, context=None): """ creates a BlockSerializer """ + if context is None: + context = self.serializer_context return BlockSerializer( - self.block_structure, many=True, context=self.serializer_context, + context['block_structure'], many=True, context=context, ) def test_basic(self): @@ -121,18 +164,31 @@ class TestBlockSerializer(TestBlockSerializerBase): for serialized_block in serializer.data: self.assert_extended_block(serialized_block) + def test_staff_fields(self): + """ + Test fields accessed by a staff user + """ + context = self.create_staff_context() + self.add_additional_requested_fields(context) + serializer = self.create_serializer(context) + for serialized_block in serializer.data: + self.assert_extended_block(serialized_block) + self.assert_staff_fields(serialized_block) + class TestBlockDictSerializer(TestBlockSerializerBase): """ Tests the BlockDictSerializer class, which returns a dict of blocks key-ed by its block_key. """ - def create_serializer(self): + def create_serializer(self, context=None): """ creates a BlockDictSerializer """ + if context is None: + context = self.serializer_context return BlockDictSerializer( - self.block_structure, many=False, context=self.serializer_context, + context['block_structure'], many=False, context=context, ) def test_basic(self): @@ -151,3 +207,14 @@ class TestBlockDictSerializer(TestBlockSerializerBase): serializer = self.create_serializer() for serialized_block in serializer.data['blocks'].itervalues(): self.assert_extended_block(serialized_block) + + def test_staff_fields(self): + """ + Test fields accessed by a staff user + """ + context = self.create_staff_context() + self.add_additional_requested_fields(context) + serializer = self.create_serializer(context) + for serialized_block in serializer.data['blocks'].itervalues(): + self.assert_extended_block(serialized_block) + self.assert_staff_fields(serialized_block) diff --git a/lms/djangoapps/course_api/blocks/transformers/__init__.py b/lms/djangoapps/course_api/blocks/transformers/__init__.py index 31967e2ce2..c4f28bc791 100644 --- a/lms/djangoapps/course_api/blocks/transformers/__init__.py +++ b/lms/djangoapps/course_api/blocks/transformers/__init__.py @@ -2,6 +2,7 @@ Course API Block Transformers """ +from lms.djangoapps.course_blocks.transformers.visibility import VisibilityTransformer from .student_view import StudentViewTransformer from .block_counts import BlockCountsTransformer from .navigation import BlockNavigationTransformer @@ -50,5 +51,12 @@ SUPPORTED_FIELDS = [ BlockNavigationTransformer, requested_field_name='nav_depth', serializer_field_name='descendants', + ), + + # Provide the staff visibility info stored when VisibilityTransformer ran previously + SupportedFieldType( + 'merged_visible_to_staff_only', + VisibilityTransformer, + requested_field_name='visible_to_staff_only', ) ]