def test_list_videos_with_different_owners(self): video1 = factories.VideoFactory(owner=self.user) factories.VideoFactory(owner=factories.UserFactory()) videos = self.client.get(reverse("api:v1:video-list")).json() self.assertEqual(1, len(videos)) self.assertEqual(video1.public_id, videos[0]["id"])
def test_list_videos_in_playlist(self): playlist = factories.PlaylistFactory(name="Funkadelic playlist", owner=self.user) video_in_playlist = factories.VideoFactory(owner=self.user) _video_not_in_playlist = factories.VideoFactory(owner=self.user) playlist.videos.add(video_in_playlist) response = self.client.get(reverse('api:v1:video-list'), data={'playlist_id': playlist.public_id}) videos = response.json() self.assertEqual(1, len(videos)) self.assertEqual(video_in_playlist.public_id, videos[0]["id"])
def test_list_videos_in_playlist(self): playlist = factories.PlaylistFactory(name="Funkadelic playlist", owner=self.user) # Create a video attached to a playlist video_in_playlist = factories.VideoFactory(owner=self.user) playlist.videos.add(video_in_playlist) # Create a video not attached to a playlist factories.VideoFactory(owner=self.user) response = self.client.get(reverse("api:v1:video-list"), data={"playlist_id": playlist.public_id}) videos = response.json() self.assertEqual(1, len(videos)) self.assertEqual(video_in_playlist.public_id, videos[0]["id"])
def test_get_video_with_subtitles(self): video = factories.VideoFactory(public_id="videoid", owner=self.user) video.subtitles.create(language="fr", public_id="subid1") video.subtitles.create(language="en", public_id="subid2") with self.assertNumQueries(self.VIDEOS_LIST_NUM_QUERIES): video = self.client.get( reverse("api:v1:video-detail", kwargs={"id": "videoid"})).json() self.assertEqual( [ { "id": "subid1", "language": "fr", "url": "http://example.com/subid1.vtt", }, { "id": "subid2", "language": "en", "url": "http://example.com/subid2.vtt", }, ], video["subtitles"], )
def test_get_video_with_formats(self): video = factories.VideoFactory(public_id="videoid", owner=self.user) video.formats.create(name="SD", bitrate=128) video.formats.create(name="HD", bitrate=256) with self.assertNumQueries(self.VIDEOS_LIST_NUM_QUERIES): video = self.client.get( reverse("api:v1:video-detail", kwargs={"id": "videoid"})).json() self.assertEqual( [ { "name": "SD", "url": "http://example.com/videoid/SD.mp4", "bitrate": 128.0, }, { "name": "HD", "url": "http://example.com/videoid/HD.mp4", "bitrate": 256.0, }, ], video["formats"], )
def test_video_transcoding_failure_invalidates_cache(self): # Login user = models.User.objects.create(username="******", is_active=True) user.set_password("password") user.save() self.client.login(username="******", password="******") factories.VideoFactory(public_id="videoid", owner=user) mock_backend = Mock(return_value=Mock( start_transcoding=Mock(return_value=["job"]), check_progress=Mock(side_effect=exceptions.TranscodingFailed), )) video_pre_transcoding = self.client.get( reverse("api:v1:video-detail", kwargs={"id": "videoid"})).json() with override_settings(PLUGIN_BACKEND=mock_backend): tasks.transcode_video("videoid") video_post_transcoding = self.client.get( reverse("api:v1:video-detail", kwargs={"id": "videoid"})).json() self.assertEqual("pending", video_pre_transcoding["processing"]["status"]) self.assertEqual("failed", video_post_transcoding["processing"]["status"])
def test_transcode_video_failure(self): factories.VideoFactory(public_id="videoid") def check_progress(job): if job == "job1": # job1 finishes raise exceptions.TranscodingFailed("error message") else: # job2 finishes return 100, True mock_backend = Mock(return_value=Mock( start_transcoding=Mock(return_value=["job1", "job2"]), check_progress=check_progress, iter_formats=Mock(return_value=[]), )) with override_settings(PLUGIN_BACKEND=mock_backend): tasks.transcode_video("videoid") self.assertEqual(1, models.ProcessingState.objects.count()) video_processing_state = models.ProcessingState.objects.get() self.assertEqual(models.ProcessingState.STATUS_FAILED, video_processing_state.status) self.assertEqual("error message", video_processing_state.message) self.assertEqual(50, video_processing_state.progress) mock_backend.return_value.create_thumbnail.assert_not_called()
def test_transcode_video_success(self): factories.VideoFactory(public_id="videoid", public_thumbnail_id="thumbid") mock_backend = Mock(return_value=Mock( start_transcoding=Mock(return_value=["job1"]), check_progress=Mock(return_value=(42, True)), iter_formats=Mock(return_value=[("SD", 128)]), create_thumbnail=Mock(), )) with override_settings(PLUGIN_BACKEND=mock_backend): tasks.transcode_video("videoid") self.assertEqual(1, models.ProcessingState.objects.count()) video_processing_state = models.ProcessingState.objects.get() self.assertEqual(models.ProcessingState.STATUS_SUCCESS, video_processing_state.status) self.assertEqual("", video_processing_state.message) self.assertEqual(42, video_processing_state.progress) mock_backend.return_value.create_thumbnail.assert_called_once_with( "videoid", "thumbid") mock_backend.return_value.check_progress.assert_called_once_with( "job1") self.assertEqual(1, models.VideoFormat.objects.count()) video_format = models.VideoFormat.objects.get() self.assertEqual("videoid", video_format.video.public_id) self.assertEqual("SD", video_format.name) self.assertEqual(128, video_format.bitrate)
def test_upload_subtitle_missing_file(self): factories.VideoFactory(public_id="videoid", owner=self.user) url = reverse("api:v1:video-subtitles", kwargs={'id': 'videoid'}) response = self.client.post(url, data={'language': 'fr'}) self.assertEqual(400, response.status_code) self.assertIn('file', response.json()) self.assertEqual(0, models.Subtitle.objects.count())
def test_list_failed_videos(self): video = factories.VideoFactory(public_id="videoid", title="videotitle", owner=self.user) video.processing_state.status = models.ProcessingState.STATUS_FAILED video.processing_state.save() videos = self.client.get(reverse("api:v1:video-list")).json() self.assertEqual([], videos)
def test_get_video_thumbnail(self): factories.VideoFactory(public_id="videoid", owner=self.user, public_thumbnail_id="thumbid") video = self.client.get( reverse("api:v1:video-detail", kwargs={"id": "videoid"})).json() self.assertIn("thumbnail", video) self.assertEqual("http://imgur.com/videoid/thumbs/thumbid.jpg", video["thumbnail"])
def test_upload_subtitle_invalid_language(self): factories.VideoFactory(public_id="videoid", owner=self.user) url = reverse("api:v1:video-subtitles", kwargs={'id': 'videoid'}) # only country codes are accepted response = self.client.post(url, data={'language': 'french'}) self.assertEqual(400, response.status_code) self.assertIn('language', response.json()) self.assertEqual(0, models.Subtitle.objects.count())
def test_delete_video(self): mock_delete_video = Mock() factories.VideoFactory(public_id="videoid", owner=self.user) with override_plugin_backend(delete_video=mock_delete_video): response = self.client.delete( reverse("api:v1:video-detail", kwargs={"id": "videoid"})) self.assertEqual(204, response.status_code) self.assertEqual(0, models.Video.objects.count()) mock_delete_video.assert_called_once_with("videoid")
def test_update_video_title(self): factories.VideoFactory(public_id="videoid", title='videotitle', owner=self.user) response = self.client.put(reverse('api:v1:video-detail', kwargs={'id': 'videoid'}), data=json.dumps({'title': 'title2'}), content_type='application/json') self.assertEqual(200, response.status_code) self.assertEqual('title2', models.Video.objects.get().title)
def test_insert_video_in_playlist(self): playlist = factories.PlaylistFactory(name="Funkadelic playlist", owner=self.user) factories.VideoFactory(public_id="videoid", owner=self.user) response = self.client.post(reverse("api:v1:playlist-add-video", kwargs={'id': playlist.public_id}), data={"id": 'videoid'}) self.assertEqual(204, response.status_code) self.assertEqual(1, playlist.videos.count())
def test_get_processing_video(self): video = factories.VideoFactory(public_id="videoid", title="videotitle", owner=self.user) video.processing_state.progress = 42 video.processing_state.status = models.ProcessingState.STATUS_PROCESSING video.processing_state.save() videos = self.client.get(reverse("api:v1:video-list")).json() self.assertEqual("processing", videos[0]["processing"]["status"]) self.assertEqual(42, videos[0]["processing"]["progress"])
def test_update_video_title(self): factories.VideoFactory(public_id="videoid", title="videotitle", owner=self.user) response = self.client.put( reverse("api:v1:video-detail", kwargs={"id": "videoid"}), data=json.dumps({"title": "title2"}), content_type="application/json", ) self.assertEqual(200, response.status_code) self.assertEqual("title2", models.Video.objects.get().title)
def test_insert_video_from_different_user_in_playlist(self): playlist = factories.PlaylistFactory(name="Funkadelic playlist", owner=self.user) different_user = factories.UserFactory() factories.VideoFactory(public_id="videoid", owner=different_user) response = self.client.post(reverse("api:v1:playlist-add-video", kwargs={'id': playlist.public_id}), data={"id": 'videoid'}) self.assertEqual(404, response.status_code)
def test_remove_video_from_playlist(self): playlist = factories.PlaylistFactory(name="Funkadelic playlist", owner=self.user) video = factories.VideoFactory(public_id="videoid", owner=self.user) playlist.videos.add(video) response = self.client.post(reverse("api:v1:playlist-remove-video", kwargs={'id': playlist.public_id}), data={"id": 'videoid'}) self.assertEqual(204, response.status_code)
def test_upload_invalid_video_thumbnail(self): factories.VideoFactory(public_id="videoid", owner=self.user) url = reverse("api:v1:video-thumbnail", kwargs={"id": "videoid"}) thumb_file = BytesIO(b"invalid thumb content") thumb_file.name = "thumb.jpg" response = self.client.post(url, { "name": "thumb.jpg", "file": thumb_file }) self.assertEqual(400, response.status_code) self.assertIn("file", response.json())
def test_get_not_processing_video(self): factories.VideoFactory(public_id="videoid", title="videotitle", owner=self.user) url = reverse("api:v1:video-list") videos = self.client.get(url).json() self.assertEqual(1, len(videos)) self.assertEqual("videoid", videos[0]["id"]) self.assertEqual("videotitle", videos[0]["title"]) self.assertIn("processing", videos[0]) self.assertIsNotNone(videos[0]["processing"]) self.assertEqual("pending", videos[0]["processing"]["status"])
def test_transcode_video_unexpected_failure(self): factories.VideoFactory(public_id="videoid") mock_backend = Mock(return_value=Mock(start_transcoding=Mock( side_effect=ValueError(666, "random error")))) with override_settings(PLUGIN_BACKEND=mock_backend): self.assertRaises(ValueError, tasks.transcode_video, "videoid") video_processing_state = models.ProcessingState.objects.get() self.assertEqual(models.ProcessingState.STATUS_FAILED, video_processing_state.status) self.assertEqual("666\nrandom error", video_processing_state.message)
def test_get_video_with_cache(self): factories.VideoFactory(public_id="videoid", title="Some title", owner=self.user) with self.assertNumQueries(self.VIDEOS_LIST_NUM_QUERIES): response1 = self.client.get( reverse("api:v1:video-detail", kwargs={"id": "videoid"})) with self.assertNumQueries(self.VIDEOS_LIST_NUM_QUERIES_AUTH): response2 = self.client.get( reverse("api:v1:video-detail", kwargs={"id": "videoid"})) self.assertEqual(200, response1.status_code) self.assertEqual(200, response2.status_code)
def test_get_not_processing_video(self): factories.VideoFactory(public_id="videoid", title='videotitle', owner=self.user) url = reverse("api:v1:video-list") videos = self.client.get(url).json() self.assertEqual(1, len(videos)) self.assertEqual('videoid', videos[0]['id']) self.assertEqual('videotitle', videos[0]['title']) self.assertIn('processing', videos[0]) self.assertIsNotNone(videos[0]['processing']) self.assertEqual('pending', videos[0]['processing']['status'])
def test_get_failed_video(self): video = factories.VideoFactory(public_id="videoid", title="videotitle", owner=self.user) video.processing_state.status = models.ProcessingState.STATUS_FAILED video.processing_state.save() response_detail = self.client.get( reverse("api:v1:video-detail", kwargs={"id": "videoid"})) response_list = self.client.get(reverse("api:v1:video-list")) self.assertEqual(200, response_detail.status_code) self.assertEqual(200, response_list.status_code) self.assertEqual([], response_list.json())
def test_upload_thumbnail(self): factories.VideoFactory(public_id="videoid", public_thumbnail_id="old_thumbid") img = open( os.path.join(os.path.dirname(__file__), "fixtures", "elcapitan.jpg"), "rb") mock_backend = Mock(return_value=Mock(upload_thumbnail=Mock(), delete_thumbnail=Mock())) with override_settings(PLUGIN_BACKEND=mock_backend): tasks.upload_thumbnail("videoid", img) mock_backend.return_value.upload_thumbnail.assert_called_once() mock_backend.return_value.delete_thumbnail.assert_called_once_with( "videoid", "old_thumbid")
def test_delete_subtitle(self): video = factories.VideoFactory(public_id='videoid', owner=self.user) factories.SubtitleFactory(video=video, public_id='subid', language='fr') mock_backend = Mock(return_value=Mock(delete_subtitle=Mock())) with override_settings(PLUGIN_BACKEND=mock_backend): response = self.client.delete( reverse("api:v1:subtitle-detail", kwargs={'id': 'subid'})) self.assertEqual(204, response.status_code) self.assertEqual(0, models.Subtitle.objects.count()) mock_backend.return_value.delete_subtitle.assert_called_once_with( 'videoid', 'subid')
def test_upload_subtitle_invalid_format(self): factories.VideoFactory(public_id="videoid", owner=self.user) subfile = StringIO("Some invalid content here.") response = self.client.post(reverse("api:v1:video-subtitles", kwargs={'id': 'videoid'}), data={ 'language': 'en', 'name': 'sub.srt', 'file': subfile }) self.assertEqual(400, response.status_code) self.assertIn('file', response.json()) self.assertEqual('Could not detect subtitle format', response.json()['file']) self.assertEqual(0, models.Subtitle.objects.count())
def test_get_subtitle(self): video = factories.VideoFactory(public_id='videoid', owner=self.user) factories.SubtitleFactory(video=video, public_id='subid', language='fr') with override_plugin_backend( subtitle_url=lambda *args: "http://sub.vtt"): response = self.client.get( reverse("api:v1:subtitle-detail", kwargs={'id': 'subid'})) self.assertEqual(200, response.status_code) subtitle = response.json() self.assertEqual('fr', subtitle['language']) self.assertEqual('subid', subtitle['id']) self.assertEqual('http://sub.vtt', subtitle['url'])
def test_get_video(self): video = factories.VideoFactory(public_id="videoid", title="Some title", owner=self.user) video.processing_state.status = models.ProcessingState.STATUS_SUCCESS video.processing_state.save() response = self.client.get( reverse("api:v1:video-detail", kwargs={"id": "videoid"})) self.assertEqual(200, response.status_code) video = response.json() self.assertEqual("videoid", video["id"]) self.assertEqual("Some title", video["title"]) self.assertEqual([], video["subtitles"]) self.assertEqual([], video["formats"]) self.assertEqual("success", video["processing"]["status"])