def test_create_video(self): # Videos without authors should not have any followers. video = get_video(1) self._assertFollowers(video, []) # But submitters automatically follow their videos. user = get_user() video = get_video(2, user=user) self._assertFollowers(video, [user])
def test_url_cache(self): test_utils.invalidate_widget_video_cache.run_original_for_test() video = get_video(1) video_url = video.get_video_url() # After adding the video, we should be able to look up its ID in the # cache, given just the URL. cache_id_1 = video_cache.get_video_id(video_url) self.assertIsNotNone(cache_id_1) self.assertTrue(Video.objects.filter(video_id=cache_id_1).exists()) # Remove the video (and make sure it's gone). video.delete() self.assertFalse( Video.objects.filter(videourl__url=video_url).exists()) # Trying to get the video ID out of the cache now actually *creates* the # video! cache_id_2 = video_cache.get_video_id(video_url) self.assertTrue(Video.objects.filter(videourl__url=video_url).exists()) # The video_id will be different than before (since this is a new Video # record) and the cache should have been updated properly. self.assertNotEqual(cache_id_1, cache_id_2) self.assertTrue(Video.objects.filter(video_id=cache_id_2).exists())
def test_video_languages_count(self): # TODO: Merge this into the metadata tests file? video = get_video() # Start with no languages. self.assertEqual(video.languages_count, 0) self.assertEqual( video.newsubtitlelanguage_set.having_nonempty_tip().count(), 0) # Create one. sl_en = make_subtitle_language(video, 'en') make_subtitle_version(sl_en, [(100, 200, "foo")]) # The query should immediately show it. self.assertEqual( video.newsubtitlelanguage_set.having_nonempty_tip().count(), 1) # But the model object will not. self.assertEqual(video.languages_count, 0) # Even if we refresh it, the model still doesn't show it. video = Video.objects.get(pk=video.pk) self.assertEqual(video.languages_count, 0) # Until we run the proper tasks. video_changed_tasks.delay(video.pk) test_utils.video_changed_tasks.run_original() # But we still need to refresh it to see the change. self.assertEqual(video.languages_count, 0) video = Video.objects.get(pk=video.pk) self.assertEqual(video.languages_count, 1)
def test_upload_and_rollbacks(self): video = get_video() self._assertCounts(video, {}) self._upload(video, 'en', 'en', None, True, 'test.srt') self._upload(video, 'en', 'en', None, True, 'test_fewer_subs.srt') self._upload(video, 'fr', 'en', 'en', True, 'test_fewer_subs.srt') self._assertCounts(video, {'en': 2, 'fr': 1}) # We now have: # # en fr # 1 # / # / # 2 # | # 1 # Let's sanity check that we can still upload to English now that it has # a dependent language (French). self._upload(video, 'en', 'en', None, True, 'test_fewer_subs.srt') self._assertCounts(video, {'en': 3, 'fr': 1}) # The translation should now be forked. self.assertTrue(video.subtitle_language('fr').is_forked) # Now let's roll English back to v1. pipeline.rollback_to(video, 'en', 1) self._assertCounts(video, {'en': 4, 'fr': 1}) # And try uploading something on top of the rollback. self._upload(video, 'en', 'en', None, True, 'test_fewer_subs.srt') self._assertCounts(video, {'en': 5, 'fr': 1})
def test_upload_origin_on_version(self): # Start with a fresh video. video = get_video() self._upload(video, 'fr', 'en', None, True, 'test.srt') sv = video.newsubtitlelanguage_set.get(language_code='fr').get_tip() self.assertEqual(sv.origin, ORIGIN_UPLOAD)
def test_upload_subtitles_non_primary_language(self): # Start with a fresh video. video = get_video() self.assertEqual(video.primary_audio_language_code, '') self.assertFalse(video.has_original_language()) self.assertIsNone(video.complete_date) # Upload subtitles in a language other than the primary. response = self._upload(video, 'fr', 'en', None, True, 'test.srt') self.assertEqual(response.status_code, 200) video = refresh(video) # The writelock should be gone once the subtitles have been uploaded. self.assertFalse(video.is_writelocked) # The video should now have a primary audio language, since it was set # as part of the upload process. self.assertEqual(video.primary_audio_language_code, 'en') # But it doesn't have a SubtitleLanguage for it. self.assertFalse(video.has_original_language()) self.assertIsNone(video.subtitle_language()) self.assertIsNone(video.get_primary_audio_subtitle_language()) # Ensure that the subtitles actually got uploaded too. sl_fr = video.subtitle_language('fr') self.assertIsNotNone(sl_fr) self.assertEqual(sl_fr.subtitleversion_set.full().count(), 1) fr1 = sl_fr.get_tip() subtitles = fr1.get_subtitles() self.assertEqual(fr1.subtitle_count, 32) self.assertEqual(len(subtitles), 32) # Now that we've uploaded a complete set of subtitles, the video and # language should be marked as completed. self.assertIsNotNone(video.complete_date) self.assertTrue(sl_fr.subtitles_complete) # Let's make sure they didn't get mistakenly marked as a translation. # They're not in the primary language but are still a transcription. self.assertIsNone(sl_fr.get_translation_source_language()) # Upload another version just to be sure. response = self._upload(video, 'fr', 'en', None, True, 'test.srt') self.assertEqual(response.status_code, 200) video = refresh(video) sl_fr = refresh(sl_fr) self.assertFalse(video.has_original_language()) self.assertIsNone(video.subtitle_language()) self.assertIsNone(video.get_primary_audio_subtitle_language()) self.assertIsNotNone(video.complete_date) self.assertTrue(sl_fr.subtitles_complete) self.assertEqual(sl_fr.subtitleversion_set.full().count(), 2)
def test_upload_translation_over_other_translation(self): video = get_video() self._assertVersionCount(video, 0) self._upload(video, 'en', 'en', None, True, 'test.srt') self._upload(video, 'de', 'en', None, True, 'test.srt') self._upload(video, 'fr', 'en', 'en', True, 'test.srt') self._assertVersionCount(video, 3) # Now fr is translated from de, this should fail self._upload(video, 'fr', 'en', 'de', True, 'test.srt') self._assertVersionCount(video, 3)
def test_upload_to_language_with_dependents(self): video = get_video() self._assertVersionCount(video, 0) # You CAN upload subtitles to a language that already has dependents (it # will just fork the dependents). self._upload(video, 'en', 'en', None, True, 'test.srt') self._upload(video, 'fr', 'en', 'en', True, 'test.srt') self._assertVersionCount(video, 2) self._upload(video, 'en', 'en', None, True, 'test.srt') self._assertVersionCount(video, 3)
def test_upload_translation_over_nontranslation(self): video = get_video() self._assertVersionCount(video, 0) self._upload(video, 'en', 'en', None, True, 'test.srt') self._upload(video, 'de', 'en', None, True, 'test.srt') self._assertVersionCount(video, 2) # You can't upload a translation over an existing non-translation # language. self._upload(video, 'de', 'en', 'en', True, 'test.srt') self._assertVersionCount(video, 2)
def test_upload_translation_with_fewer_subs(self): video = get_video() self._assertVersionCount(video, 0) self._upload(video, 'en', 'en', None, True, 'test.srt') self._assertVersionCount(video, 1) # Uploading a translation with a different number of subs than the # original language is not allowed. self._upload(video, 'is', 'en', 'en', True, 'test_fewer_subs.srt') self.assertEqual(video.newsubtitlelanguage_set.count(), 2) self._upload(video, 'is', 'en', 'en', True, 'test.srt') self.assertEqual(video.newsubtitlelanguage_set.count(), 2)
def test_subtitle_language_save(self): def _refresh(video): video_changed_tasks.delay(video.pk) test_utils.video_changed_tasks.run_original() return Video.objects.get(pk=video.pk) # Start out with a video with one language. # By default languages are not complete, so the video should not be # complete either. video = get_video() sl_en = make_subtitle_language(video, 'en') self.assertIsNone(video.complete_date) self.assertEqual(video.newsubtitlelanguage_set.count(), 1) # Marking the language as complete doesn't complete the video on its own # -- we need at least one version! sl_en.subtitles_complete = True sl_en.save() video = _refresh(video) self.assertIsNone(video.complete_date) # But an unsynced version can't be complete either! # TODO: uncomment once babelsubs supports unsynced subs... # make_subtitle_version(sl_en, [(100, None, "foo")]) # video = _refresh(video) # self.assertIsNone(video.complete_date) # A synced version (plus the previously set flag on the language) should # result in a completed video. make_subtitle_version(sl_en, [(100, 200, "foo")]) video = _refresh(video) self.assertIsNotNone(video.complete_date) # Unmarking the language as complete should uncomplete the video. sl_en.subtitles_complete = False sl_en.save() video = _refresh(video) self.assertIsNone(video.complete_date) # Any completed language is enough to complete the video. sl_ru = make_subtitle_language(video, 'ru') make_subtitle_version(sl_ru, [(100, 200, "bar")]) sl_ru.subtitles_complete = True sl_ru.save() video = _refresh(video) self.assertIsNotNone(video.complete_date)
def test_upload_unsynced_subs(self): video = get_video() self._upload(video, 'en', 'en', None, True, 'subs-with-unsynced.srt') self._assertCounts(video, {'en': 1}) subs = video.subtitle_language('en').get_tip().get_subtitles() fully_synced = len([1 for start, end, _, _ in subs if start and end]) synced_begin = len([1 for start, _, _, _ in subs if start]) synced_end = len([1 for _, end, _, _ in subs if end]) fully_unsynced = len( [1 for start, end, _, _ in subs if (not start) and (not end)]) self.assertEqual(fully_synced, 56) self.assertEqual(synced_begin, 57) self.assertEqual(synced_end, 56) self.assertEqual(fully_unsynced, 5)
def test_upload_subtitles_primary_language(self): # Start with a fresh video. video = get_video() self.assertEqual(video.primary_audio_language_code, '') self.assertFalse(video.has_original_language()) self.assertIsNone(video.complete_date) # Upload subtitles in the primary audio language. response = self._upload(video, 'en', 'en', None, True, 'test.srt') self.assertEqual(response.status_code, 200) video = refresh(video) # The video should now have a primary audio language, since it was set # as part of the upload process. self.assertEqual(video.primary_audio_language_code, 'en') self.assertTrue(video.has_original_language()) # Ensure that the subtitles actually got uploaded too. sl_en = video.subtitle_language() self.assertIsNotNone(sl_en) self.assertEqual(sl_en.subtitleversion_set.full().count(), 1) en1 = sl_en.get_tip() subtitles = en1.get_subtitles() self.assertEqual(en1.subtitle_count, 32) self.assertEqual(len(subtitles), 32) # Now that we've uploaded a complete set of subtitles, the video and # language should be marked as completed. self.assertIsNotNone(video.complete_date) self.assertTrue(sl_en.subtitles_complete) # Let's make sure they didn't get mistakenly marked as a translation. self.assertIsNone(sl_en.get_translation_source_language()) # Upload another version just to be sure. response = self._upload(video, 'en', 'en', None, True, 'test.srt') self.assertEqual(response.status_code, 200) video = refresh(video) sl_en = refresh(sl_en) self.assertEqual(sl_en.subtitleversion_set.full().count(), 2)
def test_dfxp_serializer(self): video = get_video() sl_en = make_subtitle_language(video, 'en') video.primary_audio_language_code = 'en' video.save() make_subtitle_version(sl_en, [(100, 200, 'Here we go!')], title='title') content = self._download_subs(sl_en, 'dfxp') serialized = DFXPParser(content) subtitle_set = serialized.to_internal() self.assertEqual(len(subtitle_set), 1) start, end, content, meta = list(subtitle_set)[0] self.assertEqual(start, 100) self.assertEqual(end, 200) self.assertEqual(content, 'Here we go!')
def test_upload_respects_lock(self): user1 = get_user(1) user2 = get_user(2) video = get_video() sl_en = make_subtitle_language(video, 'en') # Lock the language for user 1. sl_en.writelock(user1, 'test-browser-id') self.assertTrue(sl_en.is_writelocked) # Now try to upload subtitles as user 2. self._login(user2) self._upload(video, 'en', 'en', None, True, 'test.srt') # The subtitles should not have been created. # # We can't really tests the response here because the upload_subtitles # view is terrible and always returns a 200 with a horrible mix of HTML # and JSON as a response. So instead we'll just make sure that the # subtitles were not actually created. self.assertFalse(sl_en.subtitleversion_set.full().exists()) # User 1 has the writelock, so uploading subtitles should work for them. self._login(user1) self._upload(video, 'en', 'en', None, True, 'test.srt') self.assertEqual(sl_en.subtitleversion_set.full().count(), 1) # User 1 still has the writelock, so user 2 still can't upload. self._login(user2) self._upload(video, 'en', 'en', None, True, 'test.srt') self.assertEqual(sl_en.subtitleversion_set.full().count(), 1) # Release the writelock. sl_en.release_writelock() # Now user 2 can finally upload their subtitles. self._login(user2) self._upload(video, 'en', 'en', None, True, 'test.srt') self.assertEqual(sl_en.subtitleversion_set.full().count(), 2)
def test_model_rollback(self): video = get_video() sl_en = make_subtitle_language(video, 'en') en1 = make_subtitle_version(sl_en, []) en2 = make_subtitle_version(sl_en, [(1, 2, "foo")]) self._login() def _assert_tip_subs(subs): sl_en.clear_tip_cache() self.assertEqual([(start, end, txt) for start, end, txt, meta in list(sl_en.get_tip().get_subtitles())], subs) # Ensure the rollback works through the view. self.client.get(reverse('videos:rollback', args=[en1.id])) _assert_tip_subs([]) self.client.get(reverse('videos:rollback', args=[en2.id])) _assert_tip_subs([(1, 2, 'foo')]) self.assertEqual(sl_en.subtitleversion_set.full().count(), 4)
def test_create_edit_subs(self): video = get_video(1) sl_en = make_subtitle_language(video, 'en') # Start off with zero followers. self._assertFollowers(video, []) self._assertFollowers(sl_en, []) # Transcriber/translator should follow only the language, not the video. en_author = get_user(1) make_subtitle_version(sl_en, author=en_author) self._assertFollowers(video, []) self._assertFollowers(sl_en, [en_author]) # Create a "translation". sl_ru = make_subtitle_language(video, 'ru') self.assertEqual(sl_ru.followers.count(), 0) ru_author = get_user(2) make_subtitle_version(sl_ru, author=ru_author, parents=[('en', 1)]) # Translation editors should follow only the language, not the video. self.assertEqual(sl_ru.get_translation_source_language_code(), 'en') self._assertFollowers(video, []) self._assertFollowers(sl_en, [en_author]) self._assertFollowers(sl_ru, [ru_author]) # Editors should also follow only the language, not the video. editor = get_user(3) make_subtitle_version(sl_en, author=editor) self._assertFollowers(video, []) self._assertFollowers(sl_en, [en_author, editor]) self._assertFollowers(sl_ru, [ru_author]) make_subtitle_version(sl_ru, author=editor) self._assertFollowers(video, []) self._assertFollowers(sl_en, [en_author, editor]) self._assertFollowers(sl_ru, [ru_author, editor])
def test_upload_translation(self): video = get_video() self._assertVersionCount(video, 0) # Try uploading a translation of language that doesn't exist. self._upload(video, 'fr', 'en', 'en', True, 'test.srt') # This should fail. Translations need to be based on an existing # langauge. self._assertVersionCount(video, 0) # Let's upload the first language. self._upload(video, 'en', 'en', None, True, 'test.srt') self._assertVersionCount(video, 1) # And now uploading a translation should work. self._upload(video, 'fr', 'en', 'en', True, 'test.srt') self._assertVersionCount(video, 2) # Translations of translations are okay too I guess. self._upload(video, 'ru', 'en', 'fr', True, 'test.srt') self._assertVersionCount(video, 3)
def test_video_title(self): video = get_video(url='http://www.youtube.com/watch?v=pQ9qX8lcaBQ') def _assert_title(correct_title): self.assertEquals(refresh(video).title, correct_title) # Test title before any subtitles are added. _assert_title(test_utils.test_video_info.title) # Make a subtitle language in the primary language. video.primary_audio_language_code = 'en' video.save() sl_en = make_subtitle_language(video, 'en') # Just adding languages shouldn't affect the title. _assert_title(test_utils.test_video_info.title) # Add subtitles with a custom title. The title should be updated to # reflect this. make_subtitle_version(sl_en, [], title="New Title") _assert_title("New Title") # New versions should continue update the title properly. make_subtitle_version(sl_en, [], title="New Title 2") _assert_title("New Title 2") # Versions in a non-primary-audio-language should not affect the video # title. sl_ru = make_subtitle_language(video, 'ru') make_subtitle_version(sl_ru, [], title="New Title 3") _assert_title("New Title 2") # Rollbacks (of the primary audio language) should affect the title just # like a new version. make_rollback_to(sl_en, 1) _assert_title("New Title")
def test_language_url_for_empty_lang(self): v = get_video(1) sl = make_subtitle_language(v, 'en') self.assertIsNotNone(language_url(None, sl))