def test_youtube_video_delete_signal(mocker): """ Tests that a video's YouTubeVideo object is deleted after changing from public to private""" mock_task = mocker.patch("ui.signals.remove_youtube_video.delay") video = VideoFactory(is_public=True) yt_video = YouTubeVideoFactory(video=video) youtube_id = yt_video.id video.is_public = False video.save() mock_task.assert_called_once_with(youtube_id)
def test_async_send_notification_email_happy_path(mocker): """ Tests async_send_notification_email with happy path """ mocked_send_email = mocker.patch("mail.tasks.send_notification_email", autospec=True) video = VideoFactory(status=VideoStatus.COMPLETE) tasks.async_send_notification_email.delay(video.id) mocked_send_email.assert_called_once_with(video)
def test_video_subtitle_key(): """ Tests that the correct subtitle key is returned for a language""" video = VideoFactory(key="8494dafc-3665-4960-8e00-9790574ec93a") now = datetime.now(tz=pytz.UTC) assert (re.fullmatch( "subtitles/8494dafc366549608e009790574ec93a/subtitles_8494dafc366549608e009790574ec93a_{}_en.vtt" .format(now.strftime("%Y%m%d%H%M%S")), video.subtitle_key(now, "en"), ) is not None)
def test_video_sources_hls(): """ Tests that the video sources property returns the expected result for HLS """ video = VideoFactory(key="8494dafc-3665-4960-8e00-9790574ec93a") videofile = VideoFileFactory(video=video, encoding=EncodingNames.HLS) assert video.sources == [{ "src": videofile.cloudfront_url, "label": EncodingNames.HLS, "type": "application/x-mpegURL", }]
def test_async_send_notification_email_no_video(mocker): """ Tests async_send_notification_email for a video_id that does not exist """ mocked_send_email = mocker.patch("mail.tasks.send_notification_email", autospec=True) video = VideoFactory(status=VideoStatus.COMPLETE) tasks.async_send_notification_email.delay(video.id + 10000) assert mocked_send_email.call_count == 0
def test_download_mp4(encodings, download): """ Tests that video.download returns the most appropriate file for download """ video = VideoFactory() for encoding in encodings: VideoFileFactory(video=video, s3_object_key="{}.mp4".format(encoding), encoding=encoding) if not download: assert video.download is None else: assert video.download.encoding == download
def test_original_video(): """ Tests that the original_video property returns the VideoFile with 'original' encoding """ video = VideoFactory(key="8494dafc-3665-4960-8e00-9790574ec93a") videofiles = [ VideoFileFactory(video=video, s3_object_key="original.mp4", encoding=EncodingNames.ORIGINAL), VideoFileFactory(video=video, s3_object_key="transcoded.hls", encoding=EncodingNames.HLS), ] assert video.original_video == videofiles[0]
def test_send_notification_email_no_recipients(mocker): """ Tests send_notification_email for a video that has no recipients """ mocked_mailgun = mocker.patch("mail.api.MailgunClient", autospec=True) mocked__get_recipients_for_video = mocker.patch( "mail.tasks._get_recipients_for_video", autospec=True, return_value=[]) assert VideoStatus.COMPLETE in tasks.STATUS_TO_NOTIFICATION video = VideoFactory(status=VideoStatus.COMPLETE) tasks.send_notification_email(video) assert mocked_mailgun.send_individual_email.call_count == 0 mocked__get_recipients_for_video.assert_called_once_with(video)
def test_send_notification_email_wrong_status(mocker): """ Tests send_notification_email with a status that does not require sending an email """ mocked_mailgun = mocker.patch("mail.api.MailgunClient", autospec=True) mocked__get_recipients_for_video = mocker.patch( "mail.tasks._get_recipients_for_video", autospec=True) assert VideoStatus.UPLOADING not in tasks.STATUS_TO_NOTIFICATION video = VideoFactory(status=VideoStatus.UPLOADING) tasks.send_notification_email(video) assert mocked_mailgun.send_individual_email.call_count == 0 assert mocked__get_recipients_for_video.call_count == 0
def test_sends_debug_emails(mocker, status): """ Tests send_notification_email with statuses that should trigger sending a separate email to support. """ mocked_mailgun = mocker.patch("mail.api.MailgunClient", autospec=True) mocked_send_debug_email = mocker.patch("mail.tasks._send_debug_email", autospec=True) video = VideoFactory(status=status) tasks.send_notification_email(video) mocked_send_debug_email.assert_called_once_with( video=video, email_kwargs=mocked_mailgun.send_batch.call_args[1])
def test_transcoded_hls_video(): """ Tests that Video.transcoded_videos returns transcoded HLS videofile""" video = VideoFactory() videofiles = [ VideoFileFactory(video=video, s3_object_key="original.mp4", encoding=EncodingNames.ORIGINAL), VideoFileFactory(video=video, s3_object_key="video.m3u8", encoding=EncodingNames.HLS), ] assert len(video.transcoded_videos) == 1 assert video.transcoded_videos[0] == videofiles[1]
def test_refresh_status_video_job_othererror(mocker, status): """ Verify that refresh_status does not raise ClientError """ video = VideoFactory(status=status) EncodeJobFactory(video=video) video.status = VideoStatus.TRANSCODING mocker.patch("ui.utils.boto3", MockBoto) error = Exception("unexpected exception") mocker.patch("ui.utils.get_transcoder_client", return_value=MockClientET(error=error)) with pytest.raises(Exception): api.refresh_status(video)
def test_send_notification_email_no_mail_template(mocker): """ Tests send_notification_email for a video with a status not correspondent to a email template """ mocked_mailgun = mocker.patch("mail.api.MailgunClient", autospec=True) mock_log = mocker.patch("mail.tasks.log.error") video = VideoFactory(status=VideoStatus.RETRANSCODING) tasks.send_notification_email(video) assert mocked_mailgun.send_individual_email.call_count == 0 mock_log.assert_called_once_with( "Unexpected video status", video_hexkey=video.hexkey, video_status="Retranscoding", )
def test_video_sources_mp4(): """ Tests that the video sources property returns the expected sorted results for MP4 """ video = VideoFactory(key="8494dafc-3665-4960-8e00-9790574ec93a") videofiles = [ VideoFileFactory(video=video, s3_object_key="medium.mp4", encoding=EncodingNames.MEDIUM), VideoFileFactory(video=video, s3_object_key="small.mp4", encoding=EncodingNames.SMALL), VideoFileFactory(video=video, s3_object_key="large.mp4", encoding=EncodingNames.LARGE), VideoFileFactory(video=video, s3_object_key="basic.mp4", encoding=EncodingNames.BASIC), VideoFileFactory(video=video, s3_object_key="hd.mp4", encoding=EncodingNames.HD), ] assert video.sources == [ { "src": videofiles[4].cloudfront_url, "label": EncodingNames.HD, "type": "video/mp4", }, { "src": videofiles[2].cloudfront_url, "label": EncodingNames.LARGE, "type": "video/mp4", }, { "src": videofiles[0].cloudfront_url, "label": EncodingNames.MEDIUM, "type": "video/mp4", }, { "src": videofiles[3].cloudfront_url, "label": EncodingNames.BASIC, "type": "video/mp4", }, { "src": videofiles[1].cloudfront_url, "label": EncodingNames.SMALL, "type": "video/mp4", }, ]
def test_refresh_status_video_job_status_complete(mocker, status): """ Verify that Video.job_status property returns the status of its encoding job """ video = VideoFactory(status=status) encodejob = EncodeJobFactory(video=video) MockClientET.job = { "Job": { "Id": "1498220566931-qtmtcu", "Status": "Complete" } } mocker.patch("ui.utils.boto3", MockBoto) mocker.patch("cloudsync.api.process_transcode_results") mocker.patch("ui.models.tasks") api.refresh_status(video, encodejob) assert video.status == VideoStatus.COMPLETE
def test_get_recipients_for_video(mocker): """ Tests the _get_recipients_for_video api """ mock_client = mocker.patch("mail.tasks.get_moira_client") lists = MoiraListFactory.create_batch(3) video = VideoFactory(collection__admin_lists=lists) list_attributes = [[{"mailList": False}], [{"mailList": True}], None] list_emails = ["{}@mit.edu".format(lists[1].name)] mocker.patch("mail.tasks.has_common_lists", return_value=False) mock_client( ).client.service.getListAttributes.side_effect = list_attributes assert tasks._get_recipients_for_video( video) == list_emails + [video.collection.owner.email] mocker.patch("mail.tasks.has_common_lists", return_value=True) mock_client( ).client.service.getListAttributes.side_effect = list_attributes assert tasks._get_recipients_for_video(video) == list_emails
def test_send_notification_email_happy_path(mocker): """ Tests send_notification_email with happy path """ mocked_mailgun = mocker.patch("mail.api.MailgunClient", autospec=True) assert VideoStatus.COMPLETE in tasks.STATUS_TO_NOTIFICATION video = VideoFactory(status=VideoStatus.COMPLETE) subject, text, html = render_email_templates( STATUS_TO_NOTIFICATION[VideoStatus.COMPLETE], context_for_video(video)) tasks.send_notification_email(video) mocked_mailgun.send_batch.assert_called_once_with( **{ "subject": subject, "html_body": html, "text_body": text, "recipients": [(video.collection.owner.email, {})], "sender_address": settings.EMAIL_SUPPORT, "raise_for_status": True, })
def test_send_debug_email(mocker): """ Tests sends debug email to support. """ mocked_mailgun = mocker.patch("mail.api.MailgunClient", autospec=True) mocked_generate_debug_email_body = mocker.patch( "mail.tasks._generate_debug_email_body") mock_email_kwargs = defaultdict(mocker.MagicMock) video = VideoFactory() tasks._send_debug_email(video=video, email_kwargs=mock_email_kwargs) mocked_generate_debug_email_body.assert_called_once_with( video=video, email_kwargs=mock_email_kwargs) mocked_mailgun.send_individual_email.assert_called_once_with( **{ "subject": "DEBUG:{}".format(mock_email_kwargs["subject"]), "html_body": None, "text_body": mocked_generate_debug_email_body.return_value, "recipient": settings.EMAIL_SUPPORT, })
def test_transcoded_mp4_video(): """ Tests that Video.transcoded_videos returns transcoded MP4 videos in the correct order""" video = VideoFactory() videofiles = [ VideoFileFactory(video=video, s3_object_key="original.mp4", encoding=EncodingNames.ORIGINAL), VideoFileFactory(video=video, s3_object_key="small.mp4", encoding=EncodingNames.SMALL), VideoFileFactory(video=video, s3_object_key="basic.mp4", encoding=EncodingNames.BASIC), VideoFileFactory(video=video, s3_object_key="HD.mp4", encoding=EncodingNames.HD), ] assert len(video.transcoded_videos) == 3 assert video.transcoded_videos[0] == videofiles[3] assert video.transcoded_videos[1] == videofiles[2] assert video.transcoded_videos[2] == videofiles[1]
def test_youtube_video_permissions_signal(mocker): """ Tests that a video's public permissions are removed if it's subtitle is deleted """ mock_delete_video = mocker.patch("ui.signals.remove_youtube_video.delay") mock_delete_caption = mocker.patch("ui.signals.remove_youtube_caption.delay") mocker.patch("ui.models.VideoSubtitle.delete_from_s3") video = VideoFactory(is_public=True) YouTubeVideoFactory(video=video) VideoSubtitleFactory(video=video) VideoSubtitleFactory(video=video, language="fr") video.videosubtitle_set.get(language="fr").delete() # video's public status should not be changed as long as 1 subtitle still exists assert video.is_public is True assert mock_delete_caption.call_count == 1 video.videosubtitle_set.first().delete() # If no subtitles exists, video should be made non-public and deleted from youtube assert mock_delete_video.call_count == 1 assert not video.is_public caption = VideoSubtitleFactory(video=video) mock_video_save = mocker.patch("ui.models.Video.save") caption.delete() # If video is not public, no change to it should be saved after a caption is deleted. assert mock_video_save.call_count == 0
def test_refresh_status_video_job_status_error(mocker, prior_status, error_status): """ Verify that Video.job_status property returns the status of its encoding job """ video = VideoFactory(status=prior_status) encodejob = EncodeJobFactory(video=video) MockClientET.job = { "Job": { "Id": "1498220566931-qtmtcu", "Status": "Error", "Output": { "StatusDetail": ("4000 45585321-f360-4557-aef7-91d46460eac5: " "Amazon Elastic Transcoder could not interpret the media file." ) }, } } mocker.patch("ui.utils.boto3", MockBoto) mocker.patch("ui.models.tasks") api.refresh_status(video, encodejob) assert video.status == error_status
def test_generate_debug_email_body(mocker): """ Tests generation of debug email body. """ email_kwargs = defaultdict(mocker.MagicMock) video = VideoFactory() expected_body = textwrap.dedent(""" --- DEBUG INFO --- Video: {video} Collection: {collection} Owner: {owner} --- DEBUG INFO FOR EMAIL SENT TO USER(S) --- <RECIPIENT(S)>: {recipient} </RECIPIENT(S)>: <SUBJECT> {subject} </SUBJECT> <BODY> {body} </BODY> """).format( video=video, collection=video.collection, owner=video.collection.owner, recipient=email_kwargs["recipients"], subject=email_kwargs["subject"], body=email_kwargs["text_body"], ) actual_body = tasks._generate_debug_email_body(video=video, email_kwargs=email_kwargs) assert actual_body == expected_body
def video(): """Fixture to create a video""" return VideoFactory()
def public_video(): """Fixture to create a public video""" return VideoFactory(is_public=True, status=VideoStatus.COMPLETE)