Beispiel #1
0
def test_post_hls_to_edx_wrong_type(mocker):
    """
    post_hls_to_edx should raise an exception if the given video file is not
    configured correctly for posting to edX
    """
    video_file = VideoFileFactory.create(encoding=EncodingNames.ORIGINAL)
    with pytest.raises(Exception):
        api.post_hls_to_edx(video_file)
Beispiel #2
0
    def handle(self, *args, **options):
        if not options["video_file_id"] and not any(
            (options["edx_course_id"], options["video_title"])):
            raise CommandError(
                "Please provide --video-file-id or at least one of --edx-course-id and --video-title"
            )
        if options["video_file_id"] and options["video_title"]:
            raise CommandError(
                "Please provide --video-file-id or --video-title, not both")

        filters = dict(encoding=EncodingNames.HLS)
        if options["video_file_id"]:
            filters["pk"] = options["video_file_id"]
        else:
            if options["edx_course_id"]:
                filters["video__collection__edx_course_id"] = options[
                    "edx_course_id"]
            if options["video_title"]:
                filters["video__title"] = options["video_title"]
        video_files = list(VideoFile.objects.filter(**filters).all())
        if not video_files:
            raise CommandError(
                "No HLS-encoded VideoFiles found that match the given parameters ({})"
                .format(filters))

        self.stdout.write("Attempting to post video(s) to edX...")
        for video_file in video_files:
            response_dict = post_hls_to_edx(video_file)
            good_responses = {
                endpoint: resp
                for endpoint, resp in response_dict.items()
                if getattr(resp, "ok", None)
            }
            bad_responses = {
                endpoint: resp
                for endpoint, resp in response_dict.items()
                if endpoint not in good_responses
            }
            for _, resp in good_responses.items():
                self.stdout.write(
                    self.style.SUCCESS(
                        "Video successfully added to edX – VideoFile: {} ({}), edX url: {}"
                        .format(
                            video_file.video.title,
                            video_file.pk,
                            resp.url,
                        )))
            for edx_endpoint, resp in bad_responses.items():
                resp_summary = (None if resp is None else
                                get_error_response_summary_dict(resp))
                self.stdout.write(
                    self.style.ERROR(
                        "Request to add HLS video to edX failed – "
                        "VideoFile: {} ({}), edX url: {}, API response: {}".
                        format(
                            video_file.video.title,
                            video_file.pk,
                            edx_endpoint.full_api_url,
                            resp_summary,
                        )))
Beispiel #3
0
def test_post_hls_to_edx_no_endpoints(mocker):
    """post_hls_to_edx should log an error if no endpoints are configured for some video's collection"""
    patched_log_error = mocker.patch("ui.api.log.error")
    video_file = VideoFileFactory.create(
        encoding=EncodingNames.HLS,
        video__collection__edx_course_id="some-course-id",
    )
    responses = api.post_hls_to_edx(video_file)
    patched_log_error.assert_called_once()
    assert responses == {}
Beispiel #4
0
def test_post_hls_to_edx(mocker, reqmocker, edx_api_scenario):
    """
    post_hls_to_edx should make POST requests to all edX API endpoints that are configured
    for a video file's collection
    """
    mocked_posts = [
        reqmocker.register_uri(
            "POST",
            edx_endpoint.full_api_url,
            headers={
                "Authorization": "JWT {}".format(edx_endpoint.access_token),
            },
            status_code=200,
        )
        for edx_endpoint in [
            edx_api_scenario.collection_endpoint,
        ]
    ]

    refresh_token_mock = mocker.patch("ui.models.EdxEndpoint.refresh_access_token")
    api.post_hls_to_edx(edx_api_scenario.video_file)
    assert refresh_token_mock.call_count == 1
    for mocked_post in mocked_posts:
        assert mocked_post.call_count == 1
        request_body = mocked_post.last_request.json()
        assert request_body == {
            "client_video_id": edx_api_scenario.video_file.video.title,
            "edx_video_id": any_instance_of(str),
            "encoded_videos": [
                {
                    "url": edx_api_scenario.video_file.cloudfront_url,
                    "file_size": 0,
                    "bitrate": 0,
                    "profile": "hls",
                }
            ],
            "courses": [{edx_api_scenario.course_id: None}],
            "status": "file_complete",
            "duration": 0.0,
        }
        assert len(request_body["edx_video_id"]) == 36
Beispiel #5
0
def post_hls_to_edx(video_file_id):
    """Loads a VideoFile and calls our API method to add it to edX"""
    video_file = (
        VideoFile.objects.filter(id=video_file_id)
        .select_related("video__collection")
        .first()
    )
    if not video_file:
        log.error("VideoFile doesn't exist", videofile_id=video_file_id)
        return
    response_dict = ovs_api.post_hls_to_edx(video_file)
    return [
        (endpoint.full_api_url, getattr(resp, "status_code", None))
        for endpoint, resp in response_dict.items()
    ]
Beispiel #6
0
def test_post_hls_to_edx_bad_resp(mocker, reqmocker, edx_api_scenario):
    """post_hls_to_edx should log an error if an edX API POST request does not return a 2** status code"""
    patched_log_error = mocker.patch("ui.api.log.error")
    collection_endpoint = edx_api_scenario.collection_endpoint
    mocked_post = reqmocker.register_uri(
        "POST",
        collection_endpoint.full_api_url,
        headers={
            "Authorization": "JWT {}".format(collection_endpoint.access_token),
        },
        status_code=403,
    )
    refresh_token_mock = mocker.patch("ui.models.EdxEndpoint.refresh_access_token")
    responses = api.post_hls_to_edx(edx_api_scenario.video_file)
    assert refresh_token_mock.call_count == 1
    assert mocked_post.call_count == 1
    patched_log_error.assert_called_once()
    assert "Can not add HLS video to edX" in patched_log_error.call_args[0][0]
    assert len(responses) == 1