예제 #1
0
 def test_parse_youtube_key_format(self):
     """
     Make sure that inconsistent speed keys are parsed correctly.
     """
     youtube_str = '1.00:p2Q6BrNhdh8'
     youtube_str_hack = '1.0:p2Q6BrNhdh8'
     self.assertEqual(VideoBlock._parse_youtube(youtube_str),
                      VideoBlock._parse_youtube(youtube_str_hack))
예제 #2
0
    def test_import_val_data_invalid(self, mock_val_api):
        mock_val_api.ValCannotCreateError = _MockValCannotCreateError
        mock_val_api.import_from_xml = Mock(side_effect=mock_val_api.ValCannotCreateError)
        module_system = DummySystem(load_error_modules=True)

        # Negative duration is invalid
        xml_data = """
            <video edx_video_id="test_edx_video_id">
                <video_asset client_video_id="test_client_video_id" duration="-1"/>
            </video>
        """
        with self.assertRaises(mock_val_api.ValCannotCreateError):
            VideoBlock.from_xml(xml_data, module_system, id_generator=Mock())
예제 #3
0
 def test_import_with_float_times(self):
     """
     Ensure that Video is able to read VideoBlock's model data.
     """
     module_system = DummySystem(load_error_modules=True)
     xml_data = """
         <video display_name="Test Video"
                youtube="1.0:p2Q6BrNhdh8,0.75:izygArpw-Qo,1.25:1EeWXzPdhSA,1.5:rABDYkeK0x8"
                show_captions="false"
                from="1.0"
                to="60.0">
           <source src="http://www.example.com/source.mp4"/>
           <track src="http://www.example.com/track"/>
         </video>
     """
     video = VideoBlock.from_xml(xml_data, module_system, Mock())
     self.assert_attributes_equal(video, {
         'youtube_id_0_75': 'izygArpw-Qo',
         'youtube_id_1_0': 'p2Q6BrNhdh8',
         'youtube_id_1_25': '1EeWXzPdhSA',
         'youtube_id_1_5': 'rABDYkeK0x8',
         'show_captions': False,
         'start_time': datetime.timedelta(seconds=1),
         'end_time': datetime.timedelta(seconds=60),
         'track': 'http://www.example.com/track',
         # 'download_track': True,
         'html5_sources': ['http://www.example.com/source.mp4'],
         'data': ''
     })
예제 #4
0
 def test_old_video_format(self):
     """
     Test backwards compatibility with VideoBlock's XML format.
     """
     module_system = DummySystem(load_error_modules=True)
     xml_data = """
         <video display_name="Test Video"
                youtube="1.0:p2Q6BrNhdh8,0.75:izygArpw-Qo,1.25:1EeWXzPdhSA,1.5:rABDYkeK0x8"
                show_captions="false"
                source="http://www.example.com/source.mp4"
                from="00:00:01"
                to="00:01:00">
           <source src="http://www.example.com/source.mp4"/>
           <track src="http://www.example.com/track"/>
         </video>
     """
     output = VideoBlock.from_xml(xml_data, module_system, Mock())
     self.assert_attributes_equal(output, {
         'youtube_id_0_75': 'izygArpw-Qo',
         'youtube_id_1_0': 'p2Q6BrNhdh8',
         'youtube_id_1_25': '1EeWXzPdhSA',
         'youtube_id_1_5': 'rABDYkeK0x8',
         'show_captions': False,
         'start_time': datetime.timedelta(seconds=1),
         'end_time': datetime.timedelta(seconds=60),
         'track': 'http://www.example.com/track',
         # 'download_track': True,
         'html5_sources': ['http://www.example.com/source.mp4'],
         'data': '',
     })
예제 #5
0
 def test_from_xml(self):
     module_system = DummySystem(load_error_modules=True)
     xml_data = '''
         <video display_name="Test Video"
                youtube="1.0:p2Q6BrNhdh8,0.75:izygArpw-Qo,1.25:1EeWXzPdhSA,1.5:rABDYkeK0x8"
                show_captions="false"
                download_track="false"
                start_time="00:00:01"
                download_video="false"
                end_time="00:01:00">
           <source src="http://www.example.com/source.mp4"/>
           <track src="http://www.example.com/track"/>
           <handout src="http://www.example.com/handout"/>
           <transcript language="uk" src="ukrainian_translation.srt" />
           <transcript language="de" src="german_translation.srt" />
         </video>
     '''
     output = VideoBlock.from_xml(xml_data, module_system, Mock())
     self.assert_attributes_equal(output, {
         'youtube_id_0_75': 'izygArpw-Qo',
         'youtube_id_1_0': 'p2Q6BrNhdh8',
         'youtube_id_1_25': '1EeWXzPdhSA',
         'youtube_id_1_5': 'rABDYkeK0x8',
         'show_captions': False,
         'start_time': datetime.timedelta(seconds=1),
         'end_time': datetime.timedelta(seconds=60),
         'track': 'http://www.example.com/track',
         'handout': 'http://www.example.com/handout',
         'download_track': False,
         'download_video': False,
         'html5_sources': ['http://www.example.com/source.mp4'],
         'data': '',
         'transcripts': {'uk': 'ukrainian_translation.srt', 'de': 'german_translation.srt'},
     })
예제 #6
0
 def test_from_xml_missing_download_track(self):
     """
     Ensure that attributes have the right values if they aren't
     explicitly set in XML.
     """
     module_system = DummySystem(load_error_modules=True)
     xml_data = '''
         <video display_name="Test Video"
                youtube="1.0:p2Q6BrNhdh8,1.25:1EeWXzPdhSA"
                show_captions="true">
           <source src="http://www.example.com/source.mp4"/>
           <track src="http://www.example.com/track"/>
         </video>
     '''
     output = VideoBlock.from_xml(xml_data, module_system, Mock())
     self.assert_attributes_equal(output, {
         'youtube_id_0_75': '',
         'youtube_id_1_0': 'p2Q6BrNhdh8',
         'youtube_id_1_25': '1EeWXzPdhSA',
         'youtube_id_1_5': '',
         'show_captions': True,
         'start_time': datetime.timedelta(seconds=0.0),
         'end_time': datetime.timedelta(seconds=0.0),
         'track': 'http://www.example.com/track',
         'download_track': True,
         'download_video': False,
         'html5_sources': ['http://www.example.com/source.mp4'],
         'data': '',
         'transcripts': {},
     })
예제 #7
0
 def test_parse_youtube(self):
     """Test parsing old-style Youtube ID strings into a dict."""
     youtube_str = '0.75:jNCf2gIqpeE,1.00:ZwkTiUPN0mg,1.25:rsq9auxASqI,1.50:kMyNdzVHHgg'
     output = VideoBlock._parse_youtube(youtube_str)
     self.assertEqual(output, {'0.75': 'jNCf2gIqpeE',
                               '1.00': 'ZwkTiUPN0mg',
                               '1.25': 'rsq9auxASqI',
                               '1.50': 'kMyNdzVHHgg'})
예제 #8
0
 def test_parse_youtube_one_video(self):
     """
     Ensure that all keys are present and missing speeds map to the
     empty string.
     """
     youtube_str = '0.75:jNCf2gIqpeE'
     output = VideoBlock._parse_youtube(youtube_str)
     self.assertEqual(output, {'0.75': 'jNCf2gIqpeE',
                               '1.00': '',
                               '1.25': '',
                               '1.50': ''})
예제 #9
0
 def test_parse_youtube_empty(self):
     """
     Some courses have empty youtube attributes, so we should handle
     that well.
     """
     self.assertEqual(VideoBlock._parse_youtube(''), {
         '0.75': '',
         '1.00': '',
         '1.25': '',
         '1.50': ''
     })
예제 #10
0
def instantiate_descriptor(**field_data):
    """
    Instantiate descriptor with most properties.
    """
    if field_data.get('data', None):
        field_data = VideoBlock.parse_video_xml(field_data['data'])
    system = get_test_descriptor_system()
    course_key = CourseLocator('org', 'course', 'run')
    usage_key = course_key.make_usage_key('video', 'SampleProblem')
    return system.construct_xblock_from_class(
        VideoBlock,
        scope_ids=ScopeIds(None, None, usage_key, usage_key),
        field_data=DictFieldData(field_data),
    )
예제 #11
0
    def test_parse_youtube_invalid(self):
        """Ensure that ids that are invalid return an empty dict"""
        # invalid id
        youtube_str = 'thisisaninvalidid'
        output = VideoBlock._parse_youtube(youtube_str)
        self.assertEqual(output, {'0.75': '',
                                  '1.00': '',
                                  '1.25': '',
                                  '1.50': ''})
        # another invalid id
        youtube_str = ',::,:,,'
        output = VideoBlock._parse_youtube(youtube_str)
        self.assertEqual(output, {'0.75': '',
                                  '1.00': '',
                                  '1.25': '',
                                  '1.50': ''})

        # and another one, partially invalid
        youtube_str = '0.75_BAD!!!,1.0:AXdE34_U,1.25:KLHF9K_Y,1.5:VO3SxfeD,'
        output = VideoBlock._parse_youtube(youtube_str)
        self.assertEqual(output, {'0.75': '',
                                  '1.00': 'AXdE34_U',
                                  '1.25': 'KLHF9K_Y',
                                  '1.50': 'VO3SxfeD'})
예제 #12
0
    def test_import_val_data(self, mock_val_api):
        """
        Test that `from_xml` works method works as expected.
        """
        def mock_val_import(xml, edx_video_id, resource_fs, static_dir, external_transcripts, course_id):
            """Mock edxval.api.import_from_xml"""
            self.assertEqual(xml.tag, 'video_asset')
            self.assertEqual(dict(list(xml.items())), {'mock_attr': ''})
            self.assertEqual(edx_video_id, 'test_edx_video_id')
            self.assertEqual(static_dir, EXPORT_IMPORT_STATIC_DIR)
            self.assertIsNotNone(resource_fs)
            self.assertEqual(external_transcripts, {u'en': [u'subs_3_yD_cEKoCk.srt.sjson']})
            self.assertEqual(course_id, 'test_course_id')
            return edx_video_id

        edx_video_id = 'test_edx_video_id'
        mock_val_api.import_from_xml = Mock(wraps=mock_val_import)
        module_system = DummySystem(load_error_modules=True)

        # Create static directory in import file system and place transcript files inside it.
        module_system.resources_fs.makedirs(EXPORT_IMPORT_STATIC_DIR, recreate=True)

        # import new edx_video_id
        xml_data = """
            <video edx_video_id="{edx_video_id}">
                <video_asset mock_attr=""/>
            </video>
        """.format(
            edx_video_id=edx_video_id
        )
        id_generator = Mock()
        id_generator.target_course_id = 'test_course_id'
        video = VideoBlock.from_xml(xml_data, module_system, id_generator)

        self.assert_attributes_equal(video, {'edx_video_id': edx_video_id})
        mock_val_api.import_from_xml.assert_called_once_with(
            ANY,
            edx_video_id,
            module_system.resources_fs,
            EXPORT_IMPORT_STATIC_DIR,
            {u'en': [u'subs_3_yD_cEKoCk.srt.sjson']},
            course_id='test_course_id'
        )
예제 #13
0
    def test_from_xml_when_handout_is_course_asset(self, course_id_string, expected_handout_link):
        """
        Test that if handout link is course_asset then it will contain targeted course_id in handout link.
        """
        module_system = DummySystem(load_error_modules=True)
        course_id = CourseKey.from_string(course_id_string)
        xml_data = '''
            <video display_name="Test Video"
                   youtube="1.0:p2Q6BrNhdh8,0.75:izygArpw-Qo,1.25:1EeWXzPdhSA,1.5:rABDYkeK0x8"
                   show_captions="false"
                   download_track="false"
                   start_time="00:00:01"
                   download_video="false"
                   end_time="00:01:00">
              <source src="http://www.example.com/source.mp4"/>
              <track src="http://www.example.com/track"/>
              <handout src="/asset-v1:test_org_1+test_course_1+test_run_1+type@[email protected]"/>
              <transcript language="uk" src="ukrainian_translation.srt" />
              <transcript language="de" src="german_translation.srt" />
            </video>
        '''
        id_generator = Mock()
        id_generator.target_course_id = course_id

        output = VideoBlock.from_xml(xml_data, module_system, id_generator)
        self.assert_attributes_equal(output, {
            'youtube_id_0_75': 'izygArpw-Qo',
            'youtube_id_1_0': 'p2Q6BrNhdh8',
            'youtube_id_1_25': '1EeWXzPdhSA',
            'youtube_id_1_5': 'rABDYkeK0x8',
            'show_captions': False,
            'start_time': datetime.timedelta(seconds=1),
            'end_time': datetime.timedelta(seconds=60),
            'track': 'http://www.example.com/track',
            'handout': expected_handout_link,
            'download_track': False,
            'download_video': False,
            'html5_sources': ['http://www.example.com/source.mp4'],
            'data': '',
            'transcripts': {'uk': 'ukrainian_translation.srt', 'de': 'german_translation.srt'},
        })
예제 #14
0
 def test_from_xml_no_attributes(self):
     """
     Make sure settings are correct if none are explicitly set in XML.
     """
     module_system = DummySystem(load_error_modules=True)
     xml_data = '<video></video>'
     output = VideoBlock.from_xml(xml_data, module_system, Mock())
     self.assert_attributes_equal(output, {
         'youtube_id_0_75': '',
         'youtube_id_1_0': '3_yD_cEKoCk',
         'youtube_id_1_25': '',
         'youtube_id_1_5': '',
         'show_captions': True,
         'start_time': datetime.timedelta(seconds=0.0),
         'end_time': datetime.timedelta(seconds=0.0),
         'track': '',
         'handout': None,
         'download_track': False,
         'download_video': False,
         'html5_sources': [],
         'data': '',
         'transcripts': {},
     })
예제 #15
0
 def test_from_xml_double_quote_concatenated_youtube(self):
     module_system = DummySystem(load_error_modules=True)
     xml_data = '''
         <video display_name="Test Video"
                youtube="1.0:&quot;p2Q6BrNhdh8&quot;,1.25:&quot;1EeWXzPdhSA&quot;">
         </video>
     '''
     output = VideoBlock.from_xml(xml_data, module_system, Mock())
     self.assert_attributes_equal(output, {
         'youtube_id_0_75': '',
         'youtube_id_1_0': 'p2Q6BrNhdh8',
         'youtube_id_1_25': '1EeWXzPdhSA',
         'youtube_id_1_5': '',
         'show_captions': True,
         'start_time': datetime.timedelta(seconds=0.0),
         'end_time': datetime.timedelta(seconds=0.0),
         'track': '',
         'handout': None,
         'download_track': False,
         'download_video': False,
         'html5_sources': [],
         'data': ''
     })
예제 #16
0
 def test_from_xml_double_quotes(self):
     """
     Make sure we can handle the double-quoted string format (which was used for exporting for
     a few weeks).
     """
     module_system = DummySystem(load_error_modules=True)
     xml_data = '''
         <video display_name="&quot;display_name&quot;"
             html5_sources="[&quot;source_1&quot;, &quot;source_2&quot;]"
             show_captions="false"
             download_video="true"
             sub="&quot;html5_subtitles&quot;"
             track="&quot;http://www.example.com/track&quot;"
             handout="&quot;http://www.example.com/handout&quot;"
             download_track="true"
             youtube_id_0_75="&quot;OEoXaMPEzf65&quot;"
             youtube_id_1_25="&quot;OEoXaMPEzf125&quot;"
             youtube_id_1_5="&quot;OEoXaMPEzf15&quot;"
             youtube_id_1_0="&quot;OEoXaMPEzf10&quot;"
             />
     '''
     output = VideoBlock.from_xml(xml_data, module_system, Mock())
     self.assert_attributes_equal(output, {
         'youtube_id_0_75': 'OEoXaMPEzf65',
         'youtube_id_1_0': 'OEoXaMPEzf10',
         'youtube_id_1_25': 'OEoXaMPEzf125',
         'youtube_id_1_5': 'OEoXaMPEzf15',
         'show_captions': False,
         'start_time': datetime.timedelta(seconds=0.0),
         'end_time': datetime.timedelta(seconds=0.0),
         'track': 'http://www.example.com/track',
         'handout': 'http://www.example.com/handout',
         'download_track': True,
         'download_video': True,
         'html5_sources': ["source_1", "source_2"],
         'data': ''
     })
    def setUp(self):
        """ Common setup. """
        super(TestMigrateTranscripts, self).setUp()
        self.store = modulestore()
        self.course = CourseFactory.create()
        self.course_2 = CourseFactory.create()

        video = {
            'edx_video_id': 'test_edx_video_id',
            'client_video_id': 'test1.mp4',
            'duration': 42.0,
            'status': 'upload',
            'courses': [six.text_type(self.course.id)],
            'encoded_videos': [],
            'created': datetime.now(pytz.utc)
        }
        api.create_video(video)

        video_sample_xml = '''
            <video display_name="Test Video"
                   edx_video_id="test_edx_video_id"
                   youtube="1.0:p2Q6BrNhdh8,0.75:izygArpw-Qo,1.25:1EeWXzPdhSA,1.5:rABDYkeK0x8"
                   show_captions="false"
                   download_track="false"
                   start_time="1.0"
                   download_video="false"
                   end_time="60.0">
              <source src="http://www.example.com/source.mp4"/>
              <track src="http://www.example.com/track"/>
              <handout src="http://www.example.com/handout"/>
              <transcript language="ge" src="subs_grmtran1.srt" />
              <transcript language="hr" src="subs_croatian1.srt" />
            </video>
        '''

        video_sample_xml_2 = '''
            <video display_name="Test Video 2"
                   edx_video_id="test_edx_video_id_2"
                   youtube="1.0:p2Q6BrNhdh8,0.75:izygArpw-Qo,1.25:1EeWXzPdhSA,1.5:rABDYkeK0x8"
                   show_captions="false"
                   download_track="false"
                   start_time="1.0"
                   download_video="false"
                   end_time="60.0">
              <source src="http://www.example.com/source.mp4"/>
              <track src="http://www.example.com/track"/>
              <handout src="http://www.example.com/handout"/>
              <transcript language="ge" src="not_found.srt" />
            </video>
        '''
        self.video_descriptor = ItemFactory.create(
            parent_location=self.course.location, category='video',
            **VideoBlock.parse_video_xml(video_sample_xml)
        )
        self.video_descriptor_2 = ItemFactory.create(
            parent_location=self.course_2.location, category='video',
            **VideoBlock.parse_video_xml(video_sample_xml_2)
        )

        save_to_store(SRT_FILEDATA, 'subs_grmtran1.srt', 'text/srt', self.video_descriptor.location)
        save_to_store(CRO_SRT_FILEDATA, 'subs_croatian1.srt', 'text/srt', self.video_descriptor.location)
예제 #18
0
 def set_fields_from_xml(self, item, xml):
     fields_data = VideoBlock.parse_video_xml(xml)
     for key, value in fields_data.items():
         setattr(item, key, value)
예제 #19
0
    def test_student_video_data(self):
        module_system = DummySystem(load_error_modules=True)

        video_field_data = {
            "display_name": "Video",
            "youtube": "1.0:p2Q6BrNhdh8,0.75:izygArpw-Qo,1.25:1EeWXzPdhSA,1.5:rABDYkeK0x8",
            "show_captions": False,
        }
        video_block_keys = ScopeIds("a_user", "video", "def_id_video", "usage_id_video")
        video_block = VideoBlock(
            module_system,
            scope_ids=video_block_keys,
            field_data=DictFieldData(video_field_data),
        )

        field_data = {
            "display_name": "Annotated video",
            "video_id": video_block.scope_ids.usage_id,
            "annotations": [
                {
                    "id": "715ad1df-1be0-4fe7-b0d0-fc21e2a0d050",
                    "title": "Title",
                    "description": "Description",
                    "image_url": "/static/image.png",
                    "start": 10,
                }
            ],
        }
        block = self._construct_xblock_mock(
            self.block_class,
            self.keys,
            field_data=DictFieldData(field_data),
        )
        block.children.append(video_block.scope_ids.block_type)

        def get_block(usage_id):
            if usage_id == "video":
                return video_block

        self.runtime_mock.get_block.side_effect = get_block

        response = block.student_view_data_and_user_state(request=None)
        data = response.json

        self.assertDictEqual(
            data,
            {
                "child_blocks": [
                    {
                        "block_type": "video",
                        "display_name": "Video",
                        "usage_id": "video",
                    },
                ],
                "display_name": "Annotated video",
                "video_id": video_block.scope_ids.usage_id,
                "annotations": [
                    {
                        "description": "Description",
                        "id": "715ad1df-1be0-4fe7-b0d0-fc21e2a0d050",
                        "start": 10,
                        "title": "Title",
                        "image_url": "/static/image.png",
                    }
                ],
            },
        )