Commit 9ceddb49 by Greg Price

Merge pull request #36 from edx/gprice/add-order-alt

Add sorting parameters to get_videos_for_ids
parents ba00a5f2 47840b72
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
""" """
The internal API for VAL. This is not yet stable The internal API for VAL. This is not yet stable
""" """
from enum import Enum
import logging import logging
from edxval.models import Video, EncodedVideo from edxval.models import Video, EncodedVideo
...@@ -52,6 +53,21 @@ class ValCannotCreateError(ValError): ...@@ -52,6 +53,21 @@ class ValCannotCreateError(ValError):
pass 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): def create_video(video_data):
""" """
Called on to create Video objects in the database Called on to create Video objects in the database
...@@ -234,17 +250,30 @@ def get_videos_for_course(course_id): ...@@ -234,17 +250,30 @@ def get_videos_for_course(course_id):
return (VideoSerializer(video).data for video in videos) 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 Returns an iterator of videos that match the given list of ids
Args: Args:
edx_video_ids (list) edx_video_ids (list)
sort_field (VideoSortField)
sort_dir (SortDirection)
Returns: 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) 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) return (VideoSerializer(video).data for video in videos)
......
...@@ -14,7 +14,7 @@ from ddt import ddt, data ...@@ -14,7 +14,7 @@ from ddt import ddt, data
from edxval.models import Profile, Video, EncodedVideo, CourseVideo from edxval.models import Profile, Video, EncodedVideo, CourseVideo
from edxval import api as api 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.serializers import VideoSerializer
from edxval.tests import constants, APIAuthTestCase from edxval.tests import constants, APIAuthTestCase
...@@ -334,6 +334,44 @@ class GetVideosForIds(TestCase): ...@@ -334,6 +334,44 @@ class GetVideosForIds(TestCase):
videos = list(api.get_videos_for_ids([edx_video_id, edx_video_id])) videos = list(api.get_videos_for_ids([edx_video_id, edx_video_id]))
self.assertEqual(len(videos), 1) 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): class GetVideoInfoTestWithHttpCalls(APIAuthTestCase):
""" """
......
django>=1.4,<1.5 django>=1.4,<1.5
djangorestframework<2.4 djangorestframework<2.4
enum34==1.0.4
South==0.7.6 South==0.7.6
-e git+https://github.com/edx/django-oauth2-provider.git@0.2.7-fork-edx-1#egg=django-oauth2-provider -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