예제 #1
0
 def test_encoded_video_set_output(self):
     """
     Tests for basic structure of EncodedVideoSetSerializer
     """
     video = Video.objects.create(**constants.VIDEO_DICT_FISH)
     EncodedVideo.objects.create(
         video=video,
         profile=Profile.objects.get(profile_name="desktop"),
         **constants.ENCODED_VIDEO_DICT_DESKTOP
     )
     EncodedVideo.objects.create(
         video=video,
         profile=Profile.objects.get(profile_name="mobile"),
         **constants.ENCODED_VIDEO_DICT_MOBILE
     )
     EncodedVideo.objects.create(
         video=video,
         profile=Profile.objects.get(profile_name="hls"),
         **constants.ENCODED_VIDEO_DICT_HLS
     )
     result = VideoSerializer(video).data
     # Check for 3 EncodedVideo entries
     self.assertEqual(len(result.get("encoded_videos")), 3)
     # Check for original Video data
     matching_dict = {k: v for k, v in result.items() if k in constants.VIDEO_DICT_FISH}
     assert constants.VIDEO_DICT_FISH == matching_dict
예제 #2
0
def create_video(video_data):
    """
    Called on to create Video objects in the database

    create_video is used to create Video objects whose children are EncodedVideo
    objects which are linked to Profile objects. This is an alternative to the HTTP
    requests so it can be used internally. The VideoSerializer is used to
    deserialize this object. If there are duplicate profile_names, the entire
    creation will be rejected. If the profile is not found in the database, the
    video will not be created.
    Args:
        data (dict):
         {
                url: api url to the video
                edx_video_id: ID of the video
                duration: Length of video in seconds
                client_video_id: client ID of video
                encoded_video: a list of EncodedVideo dicts
                    url: url of the video
                    file_size: size of the video in bytes
                    profile: ID of the profile
                courses: Courses associated with this video
         }
    """
    serializer = VideoSerializer(data=video_data)
    if serializer.is_valid():
        serializer.save()
        return video_data.get("edx_video_id")
    else:
        raise ValCannotCreateError(serializer.errors)
예제 #3
0
 def test_encoded_video_set_output(self):
     """
     Tests for basic structure of EncodedVideoSetSerializer
     """
     video = Video.objects.create(**constants.VIDEO_DICT_FISH)
     EncodedVideo.objects.create(
         video=video,
         profile=Profile.objects.get(profile_name="desktop"),
         **constants.ENCODED_VIDEO_DICT_DESKTOP
     )
     EncodedVideo.objects.create(
         video=video,
         profile=Profile.objects.get(profile_name="mobile"),
         **constants.ENCODED_VIDEO_DICT_MOBILE
     )
     EncodedVideo.objects.create(
         video=video,
         profile=Profile.objects.get(profile_name="hls"),
         **constants.ENCODED_VIDEO_DICT_HLS
     )
     result = VideoSerializer(video).data  # pylint: disable=E1101
     # Check for 3 EncodedVideo entries
     self.assertEqual(len(result.get("encoded_videos")), 3)
     # Check for original Video data
     self.assertDictContainsSubset(constants.VIDEO_DICT_FISH, result)
예제 #4
0
 def test_invalid_edx_video_id(self):
     """
     Test the Video model regex validation for edx_video_id field
     """
     serializer = VideoSerializer(data=constants.VIDEO_DICT_INVALID_ID)
     self.assertFalse(serializer.is_valid())
     message = serializer.errors.get("edx_video_id")[0]
     self.assertEqual(message, u"edx_video_id has invalid characters")
예제 #5
0
 def test_invalid_edx_video_id(self):
     """
     Test the Video model regex validation for edx_video_id field
     """
     error = VideoSerializer(data=constants.VIDEO_DICT_INVALID_ID).errors # pylint: disable=E1101
     message = error.get("edx_video_id")[0]
     self.assertEqual(
         message,
         u"edx_video_id has invalid characters")
예제 #6
0
 def test_wrong_input_type(self):
     """
     Tests an non dict input in the VideoSerializer
     """
     data = "hello"
     serializer = VideoSerializer(data=data)
     self.assertFalse(serializer.is_valid())
     self.assertEqual(
         serializer.errors.get("non_field_errors")[0],
         "Invalid data. Expected a dictionary, but got str.")
예제 #7
0
    def test_negative_fields_for_video_serializer(self):
        """
        Tests negative inputs for VideoSerializer

        Tests negative inputs for duration in model Video
        """
        errors = VideoSerializer( # pylint: disable=E1101
            data=constants.VIDEO_DICT_NEGATIVE_DURATION).errors
        self.assertEqual(errors.get('duration')[0],
                         u"Ensure this value is greater than or equal to 0.")
예제 #8
0
 def test_invalid_edx_video_id(self):
     """
     Test the Video model regex validation for edx_video_id field
     """
     serializer = VideoSerializer(data=constants.VIDEO_DICT_INVALID_ID)
     self.assertFalse(serializer.is_valid())
     message = serializer.errors.get("edx_video_id")[0]
     self.assertEqual(
         message,
         u"edx_video_id has invalid characters"
     )
예제 #9
0
 def test_wrong_input_type(self):
     """
     Tests an non dict input in the VideoSerializer
     """
     data = "hello"
     serializer = VideoSerializer(data=data)
     self.assertFalse(serializer.is_valid())
     self.assertEqual(
         serializer.errors.get("non_field_errors")[0],
         "Invalid data. Expected a dictionary, but got str."
     )
예제 #10
0
    def test_negative_fields_for_video_serializer(self):
        """
        Tests negative inputs for VideoSerializer

        Tests negative inputs for duration in model Video
        """
        serializer = VideoSerializer(
            data=constants.VIDEO_DICT_NEGATIVE_DURATION)
        self.assertFalse(serializer.is_valid())
        self.assertEqual(
            serializer.errors.get('duration')[0],
            u"Ensure this value is greater than or equal to 0.")
예제 #11
0
    def test_negative_fields_for_video_serializer(self):
        """
        Tests negative inputs for VideoSerializer

        Tests negative inputs for duration in model Video
        """
        serializer = VideoSerializer(data=constants.VIDEO_DICT_NEGATIVE_DURATION)
        self.assertFalse(serializer.is_valid())
        self.assertEqual(
            serializer.errors.get('duration')[0],
            u"Ensure this value is greater than or equal to 0."
        )
예제 #12
0
    def test_no_profile_validation(self):
        """
        Tests when there are no profiles to validation when deserializing
        """

        data = dict(encoded_videos=[constants.ENCODED_VIDEO_DICT_MOBILE],
                    **constants.VIDEO_DICT_FISH)
        serializer = VideoSerializer(data=data)
        self.assertFalse(serializer.is_valid())
        self.assertEqual(serializer.errors.get("encoded_videos"), [{
            "profile": ["This field is required."]
        }])
예제 #13
0
    def test_no_profile_validation(self):
        """
        Tests when there are no profiles to validation when deserializing
        """

        data = dict(
            encoded_videos=[
                constants.ENCODED_VIDEO_DICT_MOBILE
            ],
            **constants.VIDEO_DICT_FISH
        )
        serializer = VideoSerializer(data=data)
        with self.assertRaises(ValidationError):
            serializer.is_valid()
예제 #14
0
 def test_invalid_course_id(self):
     serializer = VideoSerializer(
         data={
             "edx_video_id": "dummy",
             "client_video_id": "dummy",
             "duration": 0,
             "status": "dummy",
             "encoded_videos": [],
             "courses": ["x" * 300],
         }
     )
     self.assertFalse(serializer.is_valid())
     self.assertEqual(
         serializer.errors,
         {"courses": ["Ensure this value has at most 255 characters (it has 300)."]}
     )
예제 #15
0
def _get_videos_for_filter(video_filter, sort_field=None, sort_dir=SortDirection.asc, pagination_conf=None):
    """
    Returns a generator expression that contains the videos found, sorted by
    the given field and direction, with ties broken by edx_video_id to ensure a
    total order.
    """
    videos = Video.objects.filter(**video_filter)
    paginator_context = {}

    if sort_field:
        # Refining by edx_video_id ensures a total order
        videos = videos.order_by(sort_field.value, "edx_video_id")
        if sort_dir == SortDirection.desc:
            videos = videos.reverse()

    if pagination_conf:
        videos_per_page = pagination_conf.get('videos_per_page')
        paginator = Paginator(videos, videos_per_page)
        videos = paginator.page(pagination_conf.get('page_number'))
        paginator_context = {
            'current_page': videos.number,
            'total_pages': videos.paginator.num_pages,
            'items_on_one_page': videos_per_page
        }

    return (VideoSerializer(video).data for video in videos), paginator_context
예제 #16
0
 def test_invalid_course_id(self):
     serializer = VideoSerializer(
         data={
             "edx_video_id": "dummy",
             "client_video_id": "dummy",
             "duration": 0,
             "status": "dummy",
             "encoded_videos": [],
             "courses": ["x" * 300],
         })
     self.assertFalse(serializer.is_valid())
     self.assertEqual(
         serializer.errors, {
             "courses":
             ["Ensure this value has at most 255 characters (it has 300)."]
         })
예제 #17
0
    def test_no_profile_validation(self):
        """
        Tests when there are no profiles to validation when deserializing
        """

        data = dict(
            encoded_videos=[
                constants.ENCODED_VIDEO_DICT_MOBILE
            ],
            **constants.VIDEO_DICT_FISH
        )
        serializer = VideoSerializer(data=data)
        self.assertFalse(serializer.is_valid())
        self.assertEqual(
            serializer.errors.get("encoded_videos"),
            [{"profile": ["This field is required."]}]
        )
예제 #18
0
 def test_encoded_video_set_output(self):
     """
     Tests for basic structure of EncodedVideoSetSerializer
     """
     video = Video.objects.create(**constants.VIDEO_DICT_FISH)
     EncodedVideo.objects.create(
         video=video,
         profile=Profile.objects.get(profile_name="desktop"),
         **constants.ENCODED_VIDEO_DICT_DESKTOP)
     EncodedVideo.objects.create(
         video=video,
         profile=Profile.objects.get(profile_name="mobile"),
         **constants.ENCODED_VIDEO_DICT_MOBILE)
     result = VideoSerializer(video).data  # pylint: disable=E1101
     # Check for 2 EncodedVideo entries
     self.assertEqual(len(result.get("encoded_videos")), 2)
     # Check for original Video data
     self.assertDictContainsSubset(constants.VIDEO_DICT_FISH, result)
예제 #19
0
 def test_non_latin_serialization(self):
     """
     Tests if the serializers can accept non-latin chars
     """
     # TODO not the best test. Need to understand what result we want
     self.assertIsInstance(
         VideoSerializer(
             Video.objects.get(edx_video_id=constants.
                               VIDEO_DICT_NON_LATIN_ID["edx_video_id"])),
         VideoSerializer)
예제 #20
0
def update_video(video_data):
    """
    Called on to update Video objects in the database

    update_video is used to update Video objects by the given edx_video_id in the video_data.

    Args:
        video_data (dict):
         {
                url: api url to the video
                edx_video_id: ID of the video
                duration: Length of video in seconds
                client_video_id: client ID of video
                encoded_video: a list of EncodedVideo dicts
                    url: url of the video
                    file_size: size of the video in bytes
                    profile: ID of the profile
                courses: Courses associated with this video
         }

    Raises:
        Raises ValVideoNotFoundError if the video cannot be retrieved.
        Raises ValCannotUpdateError if the video cannot be updated.

    Returns the successfully updated Video object
    """

    try:
        video = _get_video(video_data.get("edx_video_id"))
    except Video.DoesNotExist:
        error_message = u"Video not found when trying to update video with edx_video_id: {0}".format(
            video_data.get("edx_video_id"))
        raise ValVideoNotFoundError(error_message)

    serializer = VideoSerializer(video, data=video_data)
    if serializer.is_valid():
        serializer.save()
        return video_data.get("edx_video_id")
    else:
        raise ValCannotUpdateError(serializer.errors)
예제 #21
0
def get_video_info(edx_video_id):
    """
    Retrieves all encoded videos of a video found with given video edx_video_id

    Args:
        edx_video_id (str): id for video content.

    Returns:
        (dict): Deserialized Video Object with related field EncodedVideo
            Returns all the Video object fields, and it's related EncodedVideo
            objects in a list.
            {
                url: api url to the video
                edx_video_id: ID of the video
                status: Status of the video as a string
                duration: Length of video in seconds
                client_video_id: client ID of video
                encoded_video: a list of EncodedVideo dicts
                    url: url of the video
                    file_size: size of the video in bytes
                    profile: ID of the profile
                subtitles: a list of Subtitle dicts
                    fmt: file format (SRT or SJSON)
                    language: language code
                    content_url: url of file
                    url: api url to subtitle
            }

    Raises:
        ValVideoNotFoundError: Raised if video doesn't exist
        ValInternalError: Raised for unknown errors

    Example:
        Given one EncodedVideo with edx_video_id "example"
        >>> get_video_info("example")
        Returns (dict):
        {
            'url' : '/edxval/videos/example',
            'edx_video_id': u'example',
            'duration': 111.0,
            'client_video_id': u'The example video',
            'encoded_videos': [
                {
                    'url': u'http://www.example.com',
                    'file_size': 25556,
                    'bitrate': 9600,
                    'profile': u'mobile'
                 }
            ]
        }
    """
    return VideoSerializer(_get_video(edx_video_id)).data
예제 #22
0
파일: api.py 프로젝트: edx/edx-val
def update_video(video_data):
    """
    Called on to update Video objects in the database

    update_video is used to update Video objects by the given edx_video_id in the video_data.

    Args:
        video_data (dict):
         {
                url: api url to the video
                edx_video_id: ID of the video
                duration: Length of video in seconds
                client_video_id: client ID of video
                encoded_video: a list of EncodedVideo dicts
                    url: url of the video
                    file_size: size of the video in bytes
                    profile: ID of the profile
                courses: Courses associated with this video
         }

    Raises:
        Raises ValVideoNotFoundError if the video cannot be retrieved.
        Raises ValCannotUpdateError if the video cannot be updated.

    Returns the successfully updated Video object
    """

    try:
        video = _get_video(video_data.get("edx_video_id"))
    except Video.DoesNotExist:
        error_message = u"Video not found when trying to update video with edx_video_id: {0}".format(video_data.get("edx_video_id"))
        raise ValVideoNotFoundError(error_message)

    serializer = VideoSerializer(video, data=video_data)
    if serializer.is_valid():
        serializer.save()
        return video_data.get("edx_video_id")
    else:
        raise ValCannotUpdateError(serializer.errors)
예제 #23
0
def _get_videos_for_filter(video_filter,
                           sort_field=None,
                           sort_dir=SortDirection.asc):
    """
    Returns a generator expression that contains the videos found, sorted by
    the given field and direction, with ties broken by edx_video_id to ensure a
    total order.
    """
    videos = Video.objects.filter(**video_filter)
    if sort_field:
        # Refining by edx_video_id ensures a total order
        videos = videos.order_by(sort_field.value, "edx_video_id")
        if sort_dir == SortDirection.desc:
            videos = videos.reverse()
    return (VideoSerializer(video).data for video in videos)