Commit 47840b72 by Greg Price

Add sorting parameters to get_videos_for_ids

parent ba00a5f2
......@@ -3,6 +3,7 @@
"""
The internal API for VAL. This is not yet stable
"""
from enum import Enum
import logging
from edxval.models import Video, EncodedVideo
......@@ -52,6 +53,21 @@ class ValCannotCreateError(ValError):
pass
class VideoSortField(Enum):
"""An enum representing sortable fields in the Video model"""
created = "created"
edx_video_id = "edx_video_id"
client_video_id = "client_video_id"
duration = "duration"
# status omitted because user-facing strings do not match data
class SortDirection(Enum):
"""An enum representing sort direction"""
asc = "asc"
desc = "desc"
def create_video(video_data):
"""
Called on to create Video objects in the database
......@@ -234,17 +250,30 @@ def get_videos_for_course(course_id):
return (VideoSerializer(video).data for video in videos)
def get_videos_for_ids(edx_video_ids):
def get_videos_for_ids(
edx_video_ids,
sort_field=None,
sort_dir=SortDirection.asc
):
"""
Returns an iterator of videos that match the given list of ids
Args:
edx_video_ids (list)
sort_field (VideoSortField)
sort_dir (SortDirection)
Returns:
A generator expression that contains the videos found
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(edx_video_id__in=edx_video_ids)
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)
......
......@@ -14,7 +14,7 @@ from ddt import ddt, data
from edxval.models import Profile, Video, EncodedVideo, CourseVideo
from edxval import api as api
from edxval.api import ValCannotCreateError
from edxval.api import SortDirection, ValCannotCreateError, VideoSortField
from edxval.serializers import VideoSerializer
from edxval.tests import constants, APIAuthTestCase
......@@ -334,6 +334,44 @@ class GetVideosForIds(TestCase):
videos = list(api.get_videos_for_ids([edx_video_id, edx_video_id]))
self.assertEqual(len(videos), 1)
def test_get_videos_for_ids_sort(self):
fish_id = constants.VIDEO_DICT_FISH["edx_video_id"]
star_id = constants.VIDEO_DICT_STAR["edx_video_id"]
other_id = "other-video"
Video.objects.create(**constants.VIDEO_DICT_STAR)
# This is made to sort with the other videos differently by each field
Video.objects.create(
client_video_id="other video",
duration=555.0,
edx_video_id=other_id
)
def check_sort(sort_field, expected_ids_for_asc):
"""
Assert that sorting by given field returns videos in the expected
order (checking both ascending and descending)
"""
def check_direction(sort_dir, expected_ids):
"""Assert that the given videos match the expected ids"""
actual_videos = api.get_videos_for_ids(
# Make sure it's not just returning the order given
list(reversed(expected_ids)),
sort_field,
sort_dir
)
actual_ids = [video["edx_video_id"] for video in actual_videos]
self.assertEqual(actual_ids, expected_ids)
check_direction(SortDirection.asc, expected_ids_for_asc)
check_direction(
SortDirection.desc,
list(reversed(expected_ids_for_asc))
)
check_sort(VideoSortField.client_video_id, [fish_id, star_id, other_id])
check_sort(VideoSortField.edx_video_id, [star_id, other_id, fish_id])
# Check a field with a tie
check_sort(VideoSortField.duration, [star_id, fish_id, other_id])
class GetVideoInfoTestWithHttpCalls(APIAuthTestCase):
"""
......
django>=1.4,<1.5
djangorestframework<2.4
enum34==1.0.4
South==0.7.6
-e git+https://github.com/edx/django-oauth2-provider.git@0.2.7-fork-edx-1#egg=django-oauth2-provider
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment