Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
f1d08b3b
Commit
f1d08b3b
authored
Sep 29, 2014
by
Dave St.Germain
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #5406 from edx/dcs/mobile-api-tests
Added tests for mobile API
parents
872221a6
575a8123
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
316 additions
and
13 deletions
+316
-13
lms/djangoapps/mobile_api/course_info/tests.py
+37
-0
lms/djangoapps/mobile_api/course_info/views.py
+11
-3
lms/djangoapps/mobile_api/users/tests.py
+92
-0
lms/djangoapps/mobile_api/users/views.py
+0
-8
lms/djangoapps/mobile_api/video_outlines/serializers.py
+2
-1
lms/djangoapps/mobile_api/video_outlines/tests.py
+172
-0
lms/djangoapps/mobile_api/video_outlines/views.py
+2
-1
No files found.
lms/djangoapps/mobile_api/course_info/tests.py
0 → 100644
View file @
f1d08b3b
"""
Tests for course_info
"""
from
django.test.utils
import
override_settings
from
django.core.urlresolvers
import
reverse
from
rest_framework.test
import
APITestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
,
ItemFactory
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
courseware.tests.factories
import
UserFactory
from
courseware.tests.tests
import
TEST_DATA_MONGO_MODULESTORE
@override_settings
(
MODULESTORE
=
TEST_DATA_MONGO_MODULESTORE
)
class
TestVideoOutline
(
ModuleStoreTestCase
,
APITestCase
):
def
setUp
(
self
):
super
(
TestVideoOutline
,
self
)
.
setUp
()
self
.
user
=
UserFactory
.
create
()
self
.
course
=
CourseFactory
.
create
(
mobile_available
=
True
)
self
.
client
.
login
(
username
=
self
.
user
.
username
,
password
=
'test'
)
def
test_about
(
self
):
url
=
reverse
(
'course-about-detail'
,
kwargs
=
{
'course_id'
:
unicode
(
self
.
course
.
id
)})
response
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertTrue
(
'overview'
in
response
.
data
)
def
test_handouts
(
self
):
url
=
reverse
(
'course-handouts-list'
,
kwargs
=
{
'course_id'
:
unicode
(
self
.
course
.
id
)})
response
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
response
.
status_code
,
404
)
def
test_updates
(
self
):
url
=
reverse
(
'course-updates-list'
,
kwargs
=
{
'course_id'
:
unicode
(
self
.
course
.
id
)})
response
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertEqual
(
response
.
data
,
[])
# TODO: add handouts and updates, somehow
lms/djangoapps/mobile_api/course_info/views.py
View file @
f1d08b3b
"""
Views for course info API
"""
from
django.http
import
Http404
from
rest_framework
import
generics
,
permissions
from
rest_framework.authentication
import
OAuth2Authentication
,
SessionAuthentication
from
rest_framework.response
import
Response
...
...
@@ -25,9 +29,8 @@ class CourseUpdatesList(generics.ListAPIView):
course_id
=
CourseKey
.
from_string
(
kwargs
[
'course_id'
])
course
=
modulestore
()
.
get_course
(
course_id
)
course_updates_module
=
get_course_info_section_module
(
request
,
course
,
'updates'
)
updates_to_show
=
[
update
for
update
in
reversed
(
course_updates_module
.
items
)
update
for
update
in
reversed
(
getattr
(
course_updates_module
,
'items'
,
[])
)
if
update
.
get
(
"status"
)
!=
"deleted"
]
return
Response
(
updates_to_show
)
...
...
@@ -43,7 +46,12 @@ class CourseHandoutsList(generics.ListAPIView):
course_id
=
CourseKey
.
from_string
(
kwargs
[
'course_id'
])
course
=
modulestore
()
.
get_course
(
course_id
)
course_handouts_module
=
get_course_info_section_module
(
request
,
course
,
'handouts'
)
return
Response
({
'handouts_html'
:
course_handouts_module
.
data
})
if
course_handouts_module
:
return
Response
({
'handouts_html'
:
course_handouts_module
.
data
})
else
:
# course_handouts_module could be None if there are no handouts
# (such as while running tests)
raise
Http404
(
u"No handouts for {}"
.
format
(
unicode
(
course_id
)))
class
CourseAboutDetail
(
generics
.
RetrieveAPIView
):
...
...
lms/djangoapps/mobile_api/users/tests.py
0 → 100644
View file @
f1d08b3b
"""
Tests for users API
"""
from
rest_framework.test
import
APITestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
courseware.tests.factories
import
StaffFactory
,
UserFactory
from
django.core.urlresolvers
import
reverse
from
mobile_api.users.serializers
import
CourseEnrollmentSerializer
from
student.models
import
CourseEnrollment
class
TestUserApi
(
ModuleStoreTestCase
,
APITestCase
):
"""
Test the user info API
"""
def
setUp
(
self
):
super
(
TestUserApi
,
self
)
.
setUp
()
self
.
course
=
CourseFactory
.
create
(
mobile_available
=
True
)
self
.
user
=
UserFactory
.
create
()
self
.
password
=
'test'
self
.
username
=
self
.
user
.
username
def
tearDown
(
self
):
super
(
TestUserApi
,
self
)
.
tearDown
()
self
.
client
.
logout
()
def
enroll
(
self
):
resp
=
self
.
client
.
post
(
reverse
(
'change_enrollment'
),
{
'enrollment_action'
:
'enroll'
,
'course_id'
:
self
.
course
.
id
.
to_deprecated_string
(),
'check_access'
:
True
,
})
self
.
assertEqual
(
resp
.
status_code
,
200
)
def
test_user_enrollments
(
self
):
url
=
reverse
(
'courseenrollment-detail'
,
kwargs
=
{
'username'
:
self
.
user
.
username
})
self
.
client
.
login
(
username
=
self
.
username
,
password
=
self
.
password
)
response
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertEqual
(
response
.
data
,
[])
self
.
enroll
()
response
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
response
.
status_code
,
200
)
courses
=
response
.
data
self
.
assertTrue
(
len
(
courses
),
1
)
course
=
courses
[
0
][
'course'
]
self
.
assertTrue
(
'video_outline'
in
course
)
self
.
assertTrue
(
'course_handouts'
in
course
)
self
.
assertEqual
(
course
[
'id'
],
self
.
course
.
id
.
to_deprecated_string
())
self
.
assertEqual
(
courses
[
0
][
'mode'
],
'honor'
)
def
test_user_overview
(
self
):
self
.
client
.
login
(
username
=
self
.
username
,
password
=
self
.
password
)
url
=
reverse
(
'user-detail'
,
kwargs
=
{
'username'
:
self
.
user
.
username
})
response
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
response
.
status_code
,
200
)
data
=
response
.
data
self
.
assertEqual
(
data
[
'username'
],
self
.
user
.
username
)
self
.
assertEqual
(
data
[
'email'
],
self
.
user
.
email
)
def
test_overview_anon
(
self
):
# anonymous disallowed
url
=
reverse
(
'user-detail'
,
kwargs
=
{
'username'
:
self
.
user
.
username
})
response
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
response
.
status_code
,
401
)
# can't get info on someone else
other
=
UserFactory
.
create
()
self
.
client
.
login
(
username
=
self
.
username
,
password
=
self
.
password
)
response
=
self
.
client
.
get
(
reverse
(
'user-detail'
,
kwargs
=
{
'username'
:
other
.
username
}))
self
.
assertEqual
(
response
.
status_code
,
403
)
def
test_redirect_userinfo
(
self
):
url
=
'/api/mobile/v0.5/my_user_info'
response
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
response
.
status_code
,
401
)
self
.
client
.
login
(
username
=
self
.
username
,
password
=
self
.
password
)
response
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
response
.
status_code
,
302
)
self
.
assertTrue
(
self
.
username
in
response
[
'location'
])
def
test_course_serializer
(
self
):
self
.
client
.
login
(
username
=
self
.
username
,
password
=
self
.
password
)
self
.
enroll
()
serialized
=
CourseEnrollmentSerializer
(
CourseEnrollment
.
enrollments_for_user
(
self
.
user
)[
0
])
.
data
self
.
assertEqual
(
serialized
[
'course'
][
'video_outline'
],
None
)
self
.
assertEqual
(
serialized
[
'course'
][
'name'
],
self
.
course
.
display_name
)
lms/djangoapps/mobile_api/users/views.py
View file @
f1d08b3b
...
...
@@ -51,19 +51,11 @@ class UserCourseEnrollmentsList(generics.ListAPIView):
)
.
order_by
(
'created'
)
return
mobile_course_enrollments
(
qset
,
self
.
request
.
user
)
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
if
request
.
user
.
username
!=
kwargs
[
'username'
]:
raise
PermissionDenied
return
super
(
UserCourseEnrollmentsList
,
self
)
.
get
(
self
,
request
,
*
args
,
**
kwargs
)
@api_view
([
"GET"
])
@authentication_classes
((
OAuth2Authentication
,
SessionAuthentication
))
@permission_classes
((
IsAuthenticated
,))
def
my_user_info
(
request
):
if
not
request
.
user
:
raise
PermissionDenied
return
redirect
(
"user-detail"
,
username
=
request
.
user
.
username
)
def
mobile_course_enrollments
(
enrollments
,
user
):
...
...
lms/djangoapps/mobile_api/video_outlines/serializers.py
View file @
f1d08b3b
...
...
@@ -20,7 +20,7 @@ class BlockOutline(object):
self
.
local_cache
[
'course_videos'
]
=
get_video_info_for_course_and_profile
(
unicode
(
course_id
),
"mobile_low"
)
except
ValInternalError
:
except
ValInternalError
:
# pragma: nocover
self
.
local_cache
[
'course_videos'
]
=
{}
def
__iter__
(
self
):
...
...
@@ -114,6 +114,7 @@ def video_summary(course, course_id, video_descriptor, request, local_cache):
# Transcripts...
transcript_langs
=
video_descriptor
.
available_translations
(
verify_assets
=
False
)
transcripts
=
{
lang
:
reverse
(
'video-transcripts-detail'
,
...
...
lms/djangoapps/mobile_api/video_outlines/tests.py
0 → 100644
View file @
f1d08b3b
"""
Tests for video outline API
"""
from
xmodule.modulestore.tests.factories
import
CourseFactory
,
ItemFactory
from
xmodule.video_module
import
transcripts_utils
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
courseware.tests.factories
import
UserFactory
from
courseware.tests.tests
import
TEST_DATA_MONGO_MODULESTORE
from
django.core.urlresolvers
import
reverse
from
django.test.utils
import
override_settings
from
django.conf
import
settings
from
rest_framework.test
import
APITestCase
from
edxval
import
api
from
uuid
import
uuid4
import
copy
TEST_DATA_CONTENTSTORE
=
copy
.
deepcopy
(
settings
.
CONTENTSTORE
)
TEST_DATA_CONTENTSTORE
[
'DOC_STORE_CONFIG'
][
'db'
]
=
'test_xcontent_
%
s'
%
uuid4
()
.
hex
@override_settings
(
MODULESTORE
=
TEST_DATA_MONGO_MODULESTORE
,
CONTENTSTORE
=
TEST_DATA_CONTENTSTORE
)
class
TestVideoOutline
(
ModuleStoreTestCase
,
APITestCase
):
def
setUp
(
self
):
super
(
TestVideoOutline
,
self
)
.
setUp
()
self
.
user
=
UserFactory
.
create
()
self
.
course
=
CourseFactory
.
create
(
mobile_available
=
True
)
section
=
ItemFactory
.
create
(
parent_location
=
self
.
course
.
location
,
category
=
"chapter"
,
display_name
=
u"test factory section omega
\u03a9
"
,
)
self
.
sub_section
=
ItemFactory
.
create
(
parent_location
=
section
.
location
,
category
=
"sequential"
,
display_name
=
u"test subsection omega
\u03a9
"
,
)
self
.
unit
=
ItemFactory
.
create
(
parent_location
=
self
.
sub_section
.
location
,
category
=
"vertical"
,
metadata
=
{
'graded'
:
True
,
'format'
:
'Homework'
},
display_name
=
u"test unit omega
\u03a9
"
,
)
self
.
other_unit
=
ItemFactory
.
create
(
parent_location
=
self
.
sub_section
.
location
,
category
=
"vertical"
,
metadata
=
{
'graded'
:
True
,
'format'
:
'Homework'
},
display_name
=
u"test unit omega 2
\u03a9
"
,
)
self
.
edx_video_id
=
'testing-123'
self
.
video_url
=
'http://val.edx.org/val/video.mp4'
self
.
html5_video_url
=
'http://video.edx.org/html5/video.mp4'
api
.
create_profile
({
'profile_name'
:
'youtube'
,
'extension'
:
'mp4'
,
'width'
:
1280
,
'height'
:
720
})
api
.
create_profile
({
'profile_name'
:
'mobile_low'
,
'extension'
:
'mp4'
,
'width'
:
640
,
'height'
:
480
})
val_video
=
api
.
create_video
({
'edx_video_id'
:
self
.
edx_video_id
,
'client_video_id'
:
u"test video omega
\u03a9
"
,
'duration'
:
12
,
'courses'
:
[
unicode
(
self
.
course
.
id
)],
'encoded_videos'
:
[
{
'profile'
:
'youtube'
,
'url'
:
'xyz123'
,
'file_size'
:
0
,
'bitrate'
:
1500
},
{
'profile'
:
'mobile_low'
,
'url'
:
self
.
video_url
,
'file_size'
:
12345
,
'bitrate'
:
250
}
]})
subid
=
uuid4
()
.
hex
self
.
video
=
ItemFactory
.
create
(
parent_location
=
self
.
unit
.
location
,
category
=
"video"
,
edx_video_id
=
self
.
edx_video_id
,
display_name
=
u"test video omega
\u03a9
"
,
sub
=
subid
)
result_location
=
transcripts_utils
.
save_subs_to_store
({
'start'
:
[
100
,
200
,
240
,
390
,
1000
],
'end'
:
[
200
,
240
,
380
,
1000
,
1500
],
'text'
:
[
'subs #1'
,
'subs #2'
,
'subs #3'
,
'subs #4'
,
'subs #5'
]},
subid
,
self
.
course
)
self
.
client
.
login
(
username
=
self
.
user
.
username
,
password
=
'test'
)
def
test_course_not_available
(
self
):
nonmobile
=
CourseFactory
.
create
()
url
=
reverse
(
'video-summary-list'
,
kwargs
=
{
'course_id'
:
unicode
(
nonmobile
.
id
)})
response
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
response
.
status_code
,
403
)
def
test_course_list
(
self
):
second_video
=
ItemFactory
.
create
(
parent_location
=
self
.
other_unit
.
location
,
category
=
"video"
,
display_name
=
u"test video omega 2
\u03a9
"
,
html5_sources
=
[
self
.
html5_video_url
]
)
third_video
=
ItemFactory
.
create
(
parent_location
=
self
.
other_unit
.
location
,
category
=
"video"
,
display_name
=
u"test video omega 3
\u03a9
"
,
source
=
self
.
html5_video_url
)
draft_video
=
ItemFactory
.
create
(
parent_location
=
self
.
unit
.
location
,
category
=
"video"
,
edx_video_id
=
self
.
edx_video_id
,
display_name
=
u"test draft video omega
\u03a9
"
,
visible_to_staff_only
=
True
,
)
url
=
reverse
(
'video-summary-list'
,
kwargs
=
{
'course_id'
:
unicode
(
self
.
course
.
id
)})
response
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
response
.
status_code
,
200
)
course_outline
=
response
.
data
self
.
assertEqual
(
len
(
course_outline
),
3
)
vid
=
course_outline
[
0
]
self
.
assertTrue
(
'test_subsection_omega_
%
CE
%
A9'
in
vid
[
'section_url'
])
self
.
assertTrue
(
'test_subsection_omega_
%
CE
%
A9/1'
in
vid
[
'unit_url'
])
self
.
assertTrue
(
u'test_video_omega_
\u03a9
'
in
vid
[
'summary'
][
'id'
])
self
.
assertEqual
(
vid
[
'summary'
][
'video_url'
],
self
.
video_url
)
self
.
assertEqual
(
vid
[
'summary'
][
'size'
],
12345
)
self
.
assertTrue
(
'en'
in
vid
[
'summary'
][
'transcripts'
])
self
.
assertEqual
(
course_outline
[
1
][
'summary'
][
'video_url'
],
self
.
html5_video_url
)
self
.
assertEqual
(
course_outline
[
1
][
'summary'
][
'size'
],
0
)
self
.
assertEqual
(
course_outline
[
2
][
'summary'
][
'video_url'
],
self
.
html5_video_url
)
self
.
assertEqual
(
course_outline
[
2
][
'summary'
][
'size'
],
0
)
def
test_transcripts
(
self
):
kwargs
=
{
'course_id'
:
unicode
(
self
.
course
.
id
),
'block_id'
:
unicode
(
self
.
video
.
scope_ids
.
usage_id
.
block_id
),
'lang'
:
'pl'
}
url
=
reverse
(
'video-transcripts-detail'
,
kwargs
=
kwargs
)
response
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
response
.
status_code
,
404
)
kwargs
[
'lang'
]
=
'en'
url
=
reverse
(
'video-transcripts-detail'
,
kwargs
=
kwargs
)
response
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
response
.
status_code
,
200
)
lms/djangoapps/mobile_api/video_outlines/views.py
View file @
f1d08b3b
...
...
@@ -15,6 +15,7 @@ from rest_framework import generics, permissions
from
rest_framework.authentication
import
OAuth2Authentication
,
SessionAuthentication
from
rest_framework.response
import
Response
from
rest_framework.views
import
APIView
from
rest_framework.exceptions
import
PermissionDenied
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.locator
import
BlockUsageLocator
...
...
@@ -66,7 +67,7 @@ class VideoTranscripts(generics.RetrieveAPIView):
video_descriptor
=
modulestore
()
.
get_item
(
usage_key
)
content
,
filename
,
mimetype
=
video_descriptor
.
get_transcript
(
lang
=
lang
)
except
(
NotFoundError
,
ValueError
,
KeyError
):
raise
Http404
(
"Transcript not found for {}, lang: {}"
.
format
(
block_id
,
lang
))
raise
Http404
(
u
"Transcript not found for {}, lang: {}"
.
format
(
block_id
,
lang
))
response
=
HttpResponse
(
content
,
content_type
=
mimetype
)
response
[
'Content-Disposition'
]
=
'attachment; filename="{}"'
.
format
(
filename
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment