Exemplo n.º 1
0
def test_video_youtube_id():
    """test for Video youtube_id"""
    video = VideoFactory.create()
    assert video.youtube_id() is None
    VideoFileFactory.create(destination=DESTINATION_YOUTUBE,
                            video=video,
                            destination_id="expected_id")
    assert video.youtube_id() == "expected_id"
Exemplo n.º 2
0
def test_update_youtube_metadata_error(mocker, youtube_website):
    """Log any error and move on"""
    mock_log = mocker.patch("videos.youtube.log.exception")
    mock_youtube = mocker.patch("videos.youtube.YouTubeApi")
    mock_youtube.return_value.update_video = mocker.Mock(
        side_effect=Exception("generic exception"))
    mocker.patch("videos.youtube.is_ocw_site", return_value=True)
    mocker.patch("videos.youtube.is_youtube_enabled", return_value=True)
    VideoFileFactory.create(
        video=VideoFactory.create(website=youtube_website),
        destination=DESTINATION_YOUTUBE,
        destination_id="abc123",
    )
    update_youtube_metadata(youtube_website, version=VERSION_DRAFT)
    mock_log.assert_any_call(
        "Unexpected error updating metadata for video resource %d", mocker.ANY)
Exemplo n.º 3
0
def test_delete_video_file_signal(mocker):
    """Deleting a youtube VideoFile should trigger the Youtube API delete function"""
    mock_remove = mocker.patch("videos.signals.remove_youtube_video")
    mock_delete_s3_objects = mocker.patch("videos.signals.delete_s3_objects")
    video_file = VideoFileFactory.create(destination=DESTINATION_YOUTUBE)
    video_file.delete()
    mock_remove.delay.assert_called_once_with(video_file.destination_id)
    mock_delete_s3_objects.delay.assert_called_once_with(video_file.s3_key)
Exemplo n.º 4
0
def youtube_video_files_processing():
    """Return 3 Youtube video files"""
    return VideoFileFactory.create_batch(
        3,
        status=VideoFileStatus.UPLOADED,
        destination=DESTINATION_YOUTUBE,
        destination_status=YouTubeStatus.PROCESSING,
    )
Exemplo n.º 5
0
def youtube_video_files_new():
    """Return 3 Youtube video files"""
    return VideoFileFactory.create_batch(
        3,
        status=VideoStatus.CREATED,
        destination=DESTINATION_YOUTUBE,
        destination_id=None,
    )
Exemplo n.º 6
0
def test_upload_errors_retryable(mocker, youtube_mocker, error, retryable):
    """
    Test that uploads are retried 10x for retryable exceptions
    """
    mocker.patch("videos.youtube.time")
    videofile = VideoFileFactory()
    youtube_mocker(
    ).videos.return_value.insert.return_value.next_chunk.side_effect = (error)
    with pytest.raises(Exception) as exc:
        YouTubeApi().upload_video(videofile)
    assert str(exc.value).startswith("Retried YouTube upload 10x") == retryable
Exemplo n.º 7
0
def test_update_youtube_metadata(  # pylint:disable=too-many-arguments
    mocker,
    settings,
    youtube_website,
    video_file_exists,
    youtube_enabled,
    is_ocw,
    version,
    privacy,
):
    """ Check that youtube.update_video is called for appropriate resources and not others"""
    mock_youtube = mocker.patch("videos.youtube.YouTubeApi")
    mock_update_video = mock_youtube.return_value.update_video
    mocker.patch("videos.youtube.is_ocw_site", return_value=is_ocw)
    mocker.patch("videos.youtube.is_youtube_enabled",
                 return_value=youtube_enabled)
    for youtube_id in ["", None, "abc123", "def456"]:
        if video_file_exists:
            VideoFileFactory.create(
                video=VideoFactory.create(website=youtube_website),
                destination=DESTINATION_YOUTUBE,
                destination_id=youtube_id,
            )
    update_youtube_metadata(youtube_website, version=version)
    if youtube_enabled and is_ocw:
        mock_youtube.assert_called_once()
        # Don't update metadata for imported ocw course videos except on production
        if video_file_exists:
            assert mock_update_video.call_count == 2
            for youtube_id in ["abc123", "def456"]:
                mock_update_video.assert_any_call(
                    WebsiteContent.objects.get(
                        website=youtube_website,
                        metadata__video_metadata__youtube_id=youtube_id,
                    ),
                    privacy=privacy,
                )
        else:
            mock_update_video.assert_not_called()
    else:
        mock_update_video.assert_not_called()
Exemplo n.º 8
0
def test_upload_video_long_fields(mocker, youtube_mocker):
    """
    Test that the upload_youtube_video task truncates title and description if too long
    """
    name = "".join(random.choice(string.ascii_lowercase) for c in range(105))
    video_file = VideoFileFactory.create()
    video_file.video.source_key = video_file.s3_key.replace("file_", name)
    mocker.patch("videos.youtube.resumable_upload")
    mock_upload = youtube_mocker().videos.return_value.insert
    YouTubeApi().upload_video(video_file)
    called_args, called_kwargs = mock_upload.call_args
    assert called_kwargs["body"]["snippet"]["title"] == f"{name[:97]}..."
Exemplo n.º 9
0
def test_upload_video_no_id(youtube_mocker):
    """
    Test that the upload_video task fails if the response contains no id
    """
    videofile = VideoFileFactory()
    youtube_mocker(
    ).videos.return_value.insert.return_value.next_chunk.return_value = (
        None,
        {},
    )
    with pytest.raises(YouTubeUploadException):
        YouTubeApi().upload_video(videofile)
Exemplo n.º 10
0
def test_attempt_to_update_missing_transcripts(mocker):
    """Test attempt_to_update_missing_transcripts"""

    videofile = VideoFileFactory.create(
        destination=DESTINATION_YOUTUBE, destination_id="reference_id"
    )
    website = videofile.video.website
    website.publish_date = datetime.now(pytz.timezone("America/New_York"))
    website.save()

    update_transcript_mock = mocker.patch("videos.tasks.update_transcripts_for_video")

    attempt_to_update_missing_transcripts()

    update_transcript_mock.delay.assert_called_once_with(videofile.video.id)
Exemplo n.º 11
0
def mock_mail(mocker):
    """ Objects and mocked functions for mail tests"""
    mock_get_message_sender = mocker.patch("videos.youtube.get_message_sender")
    mock_sender = mock_get_message_sender.return_value.__enter__.return_value
    video_file = VideoFileFactory.create()
    users = UserFactory.create_batch(4)
    for user in users[:2]:
        user.groups.add(video_file.video.website.admin_group)
    for user in users[2:]:
        user.groups.add(video_file.video.website.editor_group)
    return SimpleNamespace(
        mock_get_message_sender=mock_get_message_sender,
        mock_sender=mock_sender,
        video_file=video_file,
        users=users,
    )
Exemplo n.º 12
0
def test_start_transcript_job(mocker, settings, video_resource):
    """test start_transcript_job"""
    youtube_id = "test"
    threeplay_file_id = 1
    settings.YT_FIELD_ID = "youtube_id"

    video_file = VideoFileFactory.create(
        status=VideoStatus.CREATED,
        destination=DESTINATION_YOUTUBE,
        destination_id=youtube_id,
    )

    video = video_file.video
    video.source_key = "the/file"
    video.save()

    mock_threeplay_upload_video_request = mocker.patch(
        "videos.tasks.threeplay_api.threeplay_upload_video_request",
        return_value={"data": {"id": threeplay_file_id}},
    )

    mock_order_transcript_request_request = mocker.patch(
        "videos.tasks.threeplay_api.threeplay_order_transcript_request"
    )

    if video_resource:
        title = "title"
        WebsiteContentFactory.create(
            website=video.website, metadata={"youtube_id": youtube_id}, title=title
        )
    else:
        title = "file"

    start_transcript_job(video.id)

    mock_threeplay_upload_video_request.assert_called_once_with(
        video.website.short_id, youtube_id, title
    )
    mock_order_transcript_request_request.assert_called_once_with(
        video.id, threeplay_file_id
    )
Exemplo n.º 13
0
def test_update_transcripts_for_updated_videos(mocker):
    """Test update_transcripts_for_updated_videos"""

    video_file = VideoFileFactory.create(
        destination=DESTINATION_YOUTUBE, destination_id="reference_id"
    )

    updated_files_mock = mocker.patch(
        "videos.tasks.threeplay_api.threeplay_updated_media_file_request",
        return_value=updated_transctipts_reponse(),
    )
    update_transcript_mock = mocker.patch(
        "videos.tasks.update_transcripts_for_video", return_value=True
    )
    remove_tags_mock = mocker.patch("videos.tasks.threeplay_api.threeplay_remove_tags")

    update_transcripts_for_updated_videos()

    updated_files_mock.assert_called_once()
    update_transcript_mock.assert_called_once_with(video_file.video.id)
    remove_tags_mock.assert_called_once_with(6737396)
Exemplo n.º 14
0
def test_upload_video(youtube_mocker):
    """
    Test that the upload_video task calls the YouTube API execute method
    """
    videofile = VideoFileFactory()
    youtube_id = "M6LymW_8qVk"
    video_upload_response = {
        "id": youtube_id,
        "kind": "youtube#video",
        "snippet": {
            "description": "Testing description",
            "title": "Testing123"
        },
        "status": {
            "uploadStatus": "uploaded"
        },
    }
    youtube_mocker(
    ).videos.return_value.insert.return_value.next_chunk.side_effect = [
        (None, None),
        (None, video_upload_response),
    ]
    response = YouTubeApi().upload_video(videofile)
    assert response == video_upload_response
Exemplo n.º 15
0
def test_update_captions(settings, mocker, youtube_mocker, existing_captions):
    """
    Test update_captions
    """
    youtube_id = "abc123"
    captions = b"these are the file contents!"

    videofile = VideoFileFactory.create(destination=DESTINATION_YOUTUBE,
                                        destination_id=youtube_id)
    video = videofile.video

    video.webvtt_transcript_file = SimpleUploadedFile("file.txt", captions)
    video.save()

    content = WebsiteContentFactory.create(
        metadata={
            "resourcetype": RESOURCE_TYPE_VIDEO,
            "video_metadata": {
                "youtube_id": youtube_id,
            },
        },
        website=video.website,
    )

    if existing_captions:
        existing_captions_response = {
            "items": [{
                "id": "youtube_caption_id",
                "snippet": {
                    "name": CAPTION_UPLOAD_NAME
                }
            }]
        }
    else:
        existing_captions_response = {"items": []}

    mock_media_upload = mocker.patch("videos.youtube.MediaIoBaseUpload")
    mock_bytes_io = mocker.patch("videos.youtube.BytesIO")

    youtube_mocker(
    ).captions.return_value.list.return_value.execute.return_value = (
        existing_captions_response)

    YouTubeApi().update_captions(content, youtube_id)
    youtube_mocker().captions.return_value.list.assert_any_call(
        part="snippet", videoId=youtube_id)

    mock_bytes_io.assert_called_once_with(captions)

    mock_media_upload.assert_called_once_with(mock_bytes_io.return_value,
                                              mimetype="text/vtt",
                                              chunksize=-1,
                                              resumable=True)

    if existing_captions:
        youtube_mocker().captions.return_value.update.assert_any_call(
            part="snippet",
            body={"id": "youtube_caption_id"},
            media_body=mock_media_upload.return_value,
        )
    else:
        youtube_mocker().captions.return_value.insert.assert_any_call(
            part="snippet",
            sync=False,
            body={
                "snippet": {
                    "language": "en",
                    "name": CAPTION_UPLOAD_NAME,
                    "videoId": youtube_id,
                }
            },
            media_body=mock_media_upload.return_value,
        )
Exemplo n.º 16
0
def test_update_transcripts_for_video(mocker, settings, pdf_transcript_content,
                                      webvtt_transcript_content):
    """test update_transcripts_for_video"""

    settings.THREEPLAY_PROJECT_ID = 1

    video_file = VideoFileFactory.create(destination=DESTINATION_YOUTUBE,
                                         destination_id="123")
    video = video_file.video
    video.pdf_transcript_file = ""
    video.webvtt_transcript_file = ""
    video.save()

    threeplay_response = {
        "code": 200,
        "data": [{
            "id": 2,
            "media_file_id": 3,
        }],
    }

    mocker.patch(
        "videos.threeplay_api.threeplay_transcript_api_request",
        return_value=threeplay_response,
    )

    mock_fetch_file = mocker.patch("videos.threeplay_api.fetch_file")
    mock_fetch_file.side_effect = [
        pdf_transcript_content, webvtt_transcript_content
    ]

    update_transcripts_for_video(video)

    mock_fetch_file.assert_any_call(
        "https://static.3playmedia.com/p/files/3/threeplay_transcripts/2?project_id=1&format_id=51"
    )

    mock_fetch_file.assert_any_call(
        "https://static.3playmedia.com/p/files/3/threeplay_transcripts/2?project_id=1&format_id=46"
    )

    site_config = SiteConfig(video.website.starter.config)
    url_base = "/".join([
        settings.MEDIA_ROOT.rstrip("/"),
        site_config.root_url_path,
        video.website.name,
        video.source_key.split("/")[-2],
    ])

    if pdf_transcript_content:
        assert video_file.video.pdf_transcript_file.path.startswith(
            url_base + "_transcript")
        assert video_file.video.pdf_transcript_file.path.endswith(".pdf")
    else:
        assert video_file.video.pdf_transcript_file == ""

    if webvtt_transcript_content:
        assert video_file.video.webvtt_transcript_file.path.startswith(
            url_base + "_transcript_webvtt")
    else:
        assert video_file.video.webvtt_transcript_file == ""
Exemplo n.º 17
0
def test_update_transcripts_for_video(
    settings,
    mocker,
    update_transcript_return_value,
    is_ocw,
    initial_status,
    other_incomplete_video,
):
    """Test update_transcripts_for_video"""
    mocker.patch("videos.tasks.is_ocw_site", return_value=is_ocw)
    mocker.patch("websites.api.is_ocw_site", return_value=is_ocw)

    transcripts_notification_mock = mocker.patch(
        "videos.tasks.mail_transcripts_complete_notification"
    )

    videofile = VideoFileFactory.create(
        destination=DESTINATION_YOUTUBE, destination_id="expected_id"
    )
    video = videofile.video
    video.pdf_transcript_file = "pdf_transcript"
    video.webvtt_transcript_file = "webvtt_transcript"
    video.status = initial_status
    video.save()

    resource = WebsiteContentFactory.create(website=video.website, metadata={})
    metadata = resource.metadata

    set_nested_dicts(metadata, settings.FIELD_RESOURCETYPE, RESOURCE_TYPE_VIDEO)
    set_nested_dicts(metadata, settings.YT_FIELD_ID, "expected_id")
    set_nested_dicts(metadata, settings.YT_FIELD_CAPTIONS, None)
    set_nested_dicts(metadata, settings.YT_FIELD_TRANSCRIPT, None)

    resource.save()

    if other_incomplete_video:
        other_resource = WebsiteContentFactory.create(
            website=video.website, metadata={}
        )
        metadata = other_resource.metadata
        set_nested_dicts(metadata, settings.FIELD_RESOURCETYPE, RESOURCE_TYPE_VIDEO)
        set_nested_dicts(metadata, settings.YT_FIELD_CAPTIONS, None)
        other_resource.save()

    update_transcript_mock = mocker.patch(
        "videos.tasks.threeplay_api.update_transcripts_for_video",
        return_value=update_transcript_return_value,
    )

    update_transcripts_for_video(video.id)
    update_transcript_mock.assert_called_with(video)

    resource.refresh_from_db()

    if update_transcript_return_value and is_ocw:
        assert (
            get_dict_field(resource.metadata, settings.YT_FIELD_CAPTIONS)
            == "webvtt_transcript"
        )
        assert (
            get_dict_field(resource.metadata, settings.YT_FIELD_TRANSCRIPT)
            == "pdf_transcript"
        )

        if initial_status == VideoStatus.SUBMITTED_FOR_TRANSCRIPTION and (
            not other_incomplete_video
        ):
            transcripts_notification_mock.assert_called_once()
        else:
            transcripts_notification_mock.assert_not_called()

    else:
        assert get_dict_field(resource.metadata, settings.YT_FIELD_CAPTIONS) is None
        assert get_dict_field(resource.metadata, settings.YT_FIELD_TRANSCRIPT) is None