test_serializers.py 8.43 KB
Newer Older
Nimisha Asthagiri committed
1 2 3 4 5
"""
Tests for Course Blocks serializers
"""
from mock import MagicMock

6
from lms.djangoapps.course_blocks.api import COURSE_BLOCK_ACCESS_TRANSFORMERS, get_course_blocks
7
from openedx.core.djangoapps.content.block_structure.transformers import BlockStructureTransformers
8
from student.roles import CourseStaffRole
Nimisha Asthagiri committed
9
from student.tests.factories import UserFactory
10
from xmodule.modulestore import ModuleStoreEnum
Nimisha Asthagiri committed
11 12 13
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import ToyCourseFactory

14
from ..serializers import BlockDictSerializer, BlockSerializer
Nimisha Asthagiri committed
15
from ..transformers.blocks_api import BlocksAPITransformer
16
from .helpers import deserialize_usage_key
Nimisha Asthagiri committed
17 18


19
class TestBlockSerializerBase(SharedModuleStoreTestCase):
Nimisha Asthagiri committed
20 21 22 23 24 25 26 27 28
    """
    Base class for testing BlockSerializer and BlockDictSerializer
    """
    @classmethod
    def setUpClass(cls):
        super(TestBlockSerializerBase, cls).setUpClass()

        cls.course = ToyCourseFactory.create()

29 30 31 32 33 34
        # 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)

Nimisha Asthagiri committed
35 36 37 38
    def setUp(self):
        super(TestBlockSerializerBase, self).setUp()

        self.user = UserFactory.create()
39

Nimisha Asthagiri committed
40 41 42 43
        blocks_api_transformer = BlocksAPITransformer(
            block_types_to_count=['video'],
            requested_student_view_data=['video'],
        )
44
        self.transformers = BlockStructureTransformers(COURSE_BLOCK_ACCESS_TRANSFORMERS + [blocks_api_transformer])
Nimisha Asthagiri committed
45 46
        self.block_structure = get_course_blocks(
            self.user,
47
            self.course.location,
48
            self.transformers,
Nimisha Asthagiri committed
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
        )
        self.serializer_context = {
            'request': MagicMock(),
            'block_structure': self.block_structure,
            'requested_fields': ['type'],
        }

    def assert_basic_block(self, block_key_string, serialized_block):
        """
        Verifies the given serialized_block when basic fields are requested.
        """
        block_key = deserialize_usage_key(block_key_string, self.course.id)
        self.assertEquals(
            self.block_structure.get_xblock_field(block_key, 'category'),
            serialized_block['type'],
        )
        self.assertEquals(
            set(serialized_block.iterkeys()),
67
            {'id', 'block_id', 'type', 'lms_web_url', 'student_view_url'},
Nimisha Asthagiri committed
68 69
        )

70
    def add_additional_requested_fields(self, context=None):
Nimisha Asthagiri committed
71 72 73
        """
        Adds additional fields to the requested_fields context for the serializer.
        """
74 75 76
        if context is None:
            context = self.serializer_context
        context['requested_fields'].extend([
Nimisha Asthagiri committed
77 78 79 80 81 82 83
            'children',
            'display_name',
            'graded',
            'format',
            'block_counts',
            'student_view_data',
            'student_view_multi_device',
84
            'lti_url',
85
            'visible_to_staff_only',
Nimisha Asthagiri committed
86 87 88 89 90 91 92 93 94 95
        ])

    def assert_extended_block(self, serialized_block):
        """
        Verifies the given serialized_block when additional fields are requested.
        """
        self.assertLessEqual(
            {
                'id', 'type', 'lms_web_url', 'student_view_url',
                'display_name', 'graded',
96
                'student_view_multi_device',
97
                'lti_url',
98
                'visible_to_staff_only',
Nimisha Asthagiri committed
99 100 101 102 103 104 105 106 107 108 109 110 111
            },
            set(serialized_block.iterkeys()),
        )

        # video blocks should have student_view_data
        if serialized_block['type'] == 'video':
            self.assertIn('student_view_data', serialized_block)

        # html blocks should have student_view_multi_device set to True
        if serialized_block['type'] == 'html':
            self.assertIn('student_view_multi_device', serialized_block)
            self.assertTrue(serialized_block['student_view_multi_device'])

112 113 114 115 116 117 118
        # chapters with video should have block_counts
        if serialized_block['type'] == 'chapter':
            if serialized_block['display_name'] not in ('poll_test', 'handout_container'):
                self.assertIn('block_counts', serialized_block)
            else:
                self.assertNotIn('block_counts', serialized_block)

119 120 121 122 123 124 125 126 127 128 129
    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,
130
            self.transformers,
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
        )
        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'])

Nimisha Asthagiri committed
147 148 149 150 151 152

class TestBlockSerializer(TestBlockSerializerBase):
    """
    Tests the BlockSerializer class, which returns a list of blocks.
    """

153
    def create_serializer(self, context=None):
Nimisha Asthagiri committed
154 155 156
        """
        creates a BlockSerializer
        """
157 158
        if context is None:
            context = self.serializer_context
Nimisha Asthagiri committed
159
        return BlockSerializer(
160
            context['block_structure'], many=True, context=context,
Nimisha Asthagiri committed
161 162 163 164 165 166
        )

    def test_basic(self):
        serializer = self.create_serializer()
        for serialized_block in serializer.data:
            self.assert_basic_block(serialized_block['id'], serialized_block)
167
        self.assertEquals(len(serializer.data), 28)
Nimisha Asthagiri committed
168 169 170 171

    def test_additional_requested_fields(self):
        self.add_additional_requested_fields()
        serializer = self.create_serializer()
172 173
        for serialized_block in serializer.data:
            self.assert_extended_block(serialized_block)
174
        self.assertEquals(len(serializer.data), 28)
Nimisha Asthagiri committed
175

176 177 178 179 180 181 182 183 184 185
    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)
186
        self.assertEquals(len(serializer.data), 29)
187

Nimisha Asthagiri committed
188 189 190 191 192 193

class TestBlockDictSerializer(TestBlockSerializerBase):
    """
    Tests the BlockDictSerializer class, which returns a dict of blocks key-ed by its block_key.
    """

194
    def create_serializer(self, context=None):
Nimisha Asthagiri committed
195 196 197
        """
        creates a BlockDictSerializer
        """
198 199
        if context is None:
            context = self.serializer_context
Nimisha Asthagiri committed
200
        return BlockDictSerializer(
201
            context['block_structure'], many=False, context=context,
Nimisha Asthagiri committed
202 203 204 205 206
        )

    def test_basic(self):
        serializer = self.create_serializer()

lenacom committed
207 208 209
        # verify root
        self.assertEquals(serializer.data['root'], unicode(self.block_structure.root_block_usage_key))

Nimisha Asthagiri committed
210 211 212 213
        # verify blocks
        for block_key_string, serialized_block in serializer.data['blocks'].iteritems():
            self.assertEquals(serialized_block['id'], block_key_string)
            self.assert_basic_block(block_key_string, serialized_block)
214
        self.assertEquals(len(serializer.data['blocks']), 28)
Nimisha Asthagiri committed
215 216 217 218 219 220

    def test_additional_requested_fields(self):
        self.add_additional_requested_fields()
        serializer = self.create_serializer()
        for serialized_block in serializer.data['blocks'].itervalues():
            self.assert_extended_block(serialized_block)
221
        self.assertEquals(len(serializer.data['blocks']), 28)
222 223 224 225 226 227 228 229 230 231 232

    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)
233
        self.assertEquals(len(serializer.data['blocks']), 29)