Commit 91153aea by Nimisha Asthagiri

Update Course About API to include effort and video

MA-1661
parent d6ced072
...@@ -11,6 +11,7 @@ from rest_framework import serializers ...@@ -11,6 +11,7 @@ from rest_framework import serializers
from lms.djangoapps.courseware.courses import get_course_about_section from lms.djangoapps.courseware.courses import get_course_about_section
from openedx.core.lib.courses import course_image_url from openedx.core.lib.courses import course_image_url
from openedx.core.djangoapps.models.course_details import CourseDetails
from xmodule.course_module import DEFAULT_START_DATE from xmodule.course_module import DEFAULT_START_DATE
...@@ -36,6 +37,10 @@ class _CourseApiMediaCollectionSerializer(serializers.Serializer): # pylint: di ...@@ -36,6 +37,10 @@ class _CourseApiMediaCollectionSerializer(serializers.Serializer): # pylint: di
Nested serializer to represent a collection of media objects Nested serializer to represent a collection of media objects
""" """
course_image = _MediaSerializer(source='*', uri_parser=course_image_url) course_image = _MediaSerializer(source='*', uri_parser=course_image_url)
course_video = _MediaSerializer(
source='*',
uri_parser=lambda course: CourseDetails.fetch_video_url(course.id),
)
class CourseSerializer(serializers.Serializer): # pylint: disable=abstract-method class CourseSerializer(serializers.Serializer): # pylint: disable=abstract-method
...@@ -47,14 +52,19 @@ class CourseSerializer(serializers.Serializer): # pylint: disable=abstract-meth ...@@ -47,14 +52,19 @@ class CourseSerializer(serializers.Serializer): # pylint: disable=abstract-meth
name = serializers.CharField(source='display_name_with_default') name = serializers.CharField(source='display_name_with_default')
number = serializers.CharField(source='display_number_with_default') number = serializers.CharField(source='display_number_with_default')
org = serializers.CharField(source='display_org_with_default') org = serializers.CharField(source='display_org_with_default')
description = serializers.SerializerMethodField() short_description = serializers.SerializerMethodField()
effort = serializers.SerializerMethodField()
media = _CourseApiMediaCollectionSerializer(source='*') media = _CourseApiMediaCollectionSerializer(source='*')
start = serializers.DateTimeField() start = serializers.DateTimeField()
start_type = serializers.SerializerMethodField() start_type = serializers.SerializerMethodField()
start_display = serializers.SerializerMethodField() start_display = serializers.SerializerMethodField()
end = serializers.DateTimeField() end = serializers.DateTimeField()
enrollment_start = serializers.DateTimeField() enrollment_start = serializers.DateTimeField()
enrollment_end = serializers.DateTimeField() enrollment_end = serializers.DateTimeField()
blocks_url = serializers.SerializerMethodField() blocks_url = serializers.SerializerMethodField()
def get_start_type(self, course): def get_start_type(self, course):
...@@ -79,9 +89,9 @@ class CourseSerializer(serializers.Serializer): # pylint: disable=abstract-meth ...@@ -79,9 +89,9 @@ class CourseSerializer(serializers.Serializer): # pylint: disable=abstract-meth
else: else:
return None return None
def get_description(self, course): def get_short_description(self, course):
""" """
Get the representation for SerializerMethodField `description` Get the representation for SerializerMethodField `short_description`
""" """
return get_course_about_section(self.context['request'], course, 'short_description').strip() return get_course_about_section(self.context['request'], course, 'short_description').strip()
...@@ -94,3 +104,9 @@ class CourseSerializer(serializers.Serializer): # pylint: disable=abstract-meth ...@@ -94,3 +104,9 @@ class CourseSerializer(serializers.Serializer): # pylint: disable=abstract-meth
urllib.urlencode({'course_id': course.id}), urllib.urlencode({'course_id': course.id}),
]) ])
return self.context['request'].build_absolute_uri(base_url) return self.context['request'].build_absolute_uri(base_url)
def get_effort(self, course):
"""
Get the representation for SerializerMethodField `effort`
"""
return CourseDetails.fetch_effort(course.id)
...@@ -19,44 +19,18 @@ class CourseApiTestMixin(CourseApiFactoryMixin): ...@@ -19,44 +19,18 @@ class CourseApiTestMixin(CourseApiFactoryMixin):
""" """
Establish basic functionality for Course API tests Establish basic functionality for Course API tests
""" """
@classmethod
def setUpClass(cls):
super(CourseApiTestMixin, cls).setUpClass()
cls.request_factory = APIRequestFactory()
maxDiff = 5000 # long enough to show mismatched dicts def verify_course(self, course, course_id=u'edX/toy/2012_Fall'):
expected_course_data = {
'course_id': u'edX/toy/2012_Fall',
'name': u'Toy Course',
'number': u'toy',
'org': u'edX',
'description': u'A course about toys.',
'media': {
'course_image': {
'uri': u'/c4x/edX/toy/asset/just_a_test.jpg',
}
},
'start': u'2015-07-17T12:00:00Z',
'start_type': u'timestamp',
'start_display': u'July 17, 2015',
'end': u'2015-09-19T18:00:00Z',
'enrollment_start': u'2015-06-15T00:00:00Z',
'enrollment_end': u'2015-07-15T00:00:00Z',
'blocks_url': '/api/courses/v1/blocks/?course_id=edX%2Ftoy%2F2012_Fall',
}
def verify_course(self, course, course_id=None):
""" """
Ensure that the returned course is the course we just created Ensure that the returned course is the course we just created
""" """
if course_id is None:
course_id = self.expected_course_data['course_id']
self.assertIsInstance(course, CourseDescriptor) self.assertIsInstance(course, CourseDescriptor)
self.assertEqual(course_id, str(course.id)) self.assertEqual(course_id, str(course.id))
@classmethod
def setUpClass(cls):
super(CourseApiTestMixin, cls).setUpClass()
cls.request_factory = APIRequestFactory()
class CourseDetailTestMixin(CourseApiTestMixin): class CourseDetailTestMixin(CourseApiTestMixin):
""" """
......
...@@ -4,6 +4,7 @@ Test data created by CourseSerializer ...@@ -4,6 +4,7 @@ Test data created by CourseSerializer
from datetime import datetime from datetime import datetime
from openedx.core.djangoapps.models.course_details import CourseDetails
from rest_framework.test import APIRequestFactory from rest_framework.test import APIRequestFactory
from rest_framework.request import Request from rest_framework.request import Request
...@@ -18,6 +19,7 @@ class TestCourseSerializerFields(CourseApiFactoryMixin, ModuleStoreTestCase): ...@@ -18,6 +19,7 @@ class TestCourseSerializerFields(CourseApiFactoryMixin, ModuleStoreTestCase):
""" """
Test variations of start_date field responses Test variations of start_date field responses
""" """
maxDiff = 5000 # long enough to show mismatched dicts, in case of error
def setUp(self): def setUp(self):
super(TestCourseSerializerFields, self).setUp() super(TestCourseSerializerFields, self).setUp()
...@@ -35,6 +37,35 @@ class TestCourseSerializerFields(CourseApiFactoryMixin, ModuleStoreTestCase): ...@@ -35,6 +37,35 @@ class TestCourseSerializerFields(CourseApiFactoryMixin, ModuleStoreTestCase):
request.user = user request.user = user
return request return request
def test_basic(self):
expected_data = {
'course_id': u'edX/toy/2012_Fall',
'name': u'Toy Course',
'number': u'toy',
'org': u'edX',
'short_description': u'A course about toys.',
'media': {
'course_image': {
'uri': u'/c4x/edX/toy/asset/just_a_test.jpg',
},
'course_video': {
'uri': u'http://www.youtube.com/watch?v=test_youtube_id',
}
},
'start': u'2015-07-17T12:00:00Z',
'start_type': u'timestamp',
'start_display': u'July 17, 2015',
'end': u'2015-09-19T18:00:00',
'enrollment_start': u'2015-06-15T00:00:00',
'enrollment_end': u'2015-07-15T00:00:00',
'blocks_url': u'http://testserver/api/courses/v1/blocks/?course_id=edX%2Ftoy%2F2012_Fall',
'effort': u'6 hours',
}
course = self.create_course()
CourseDetails.update_about_video(course, 'test_youtube_id', self.staff_user.id) # pylint: disable=no-member
result = CourseSerializer(course, context={'request': self._get_request()}).data
self.assertDictEqual(result, expected_data)
def test_advertised_start(self): def test_advertised_start(self):
course = self.create_course( course = self.create_course(
course=u'custom', course=u'custom',
...@@ -52,16 +83,3 @@ class TestCourseSerializerFields(CourseApiFactoryMixin, ModuleStoreTestCase): ...@@ -52,16 +83,3 @@ class TestCourseSerializerFields(CourseApiFactoryMixin, ModuleStoreTestCase):
self.assertEqual(result['course_id'], u'edX/custom/2012_Fall') self.assertEqual(result['course_id'], u'edX/custom/2012_Fall')
self.assertEqual(result['start_type'], u'empty') self.assertEqual(result['start_type'], u'empty')
self.assertIsNone(result['start_display']) self.assertIsNone(result['start_display'])
def test_description(self):
course = self.create_course()
result = CourseSerializer(course, context={'request': self._get_request()}).data
self.assertEqual(result['description'], u'A course about toys.')
def test_blocks_url(self):
course = self.create_course()
result = CourseSerializer(course, context={'request': self._get_request()}).data
self.assertEqual(
result['blocks_url'],
u'http://testserver/api/courses/v1/blocks/?course_id=edX%2Ftoy%2F2012_Fall'
)
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