Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-val
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-val
Commits
bc3300fd
Commit
bc3300fd
authored
Sep 02, 2014
by
David Ormsbee
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #15 from edx/dcs/authentication
Add authentication and model permission checking to REST API.
parents
8e1dcac6
35cac655
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
71 additions
and
16 deletions
+71
-16
edxval/tests/__init__.py
+24
-0
edxval/tests/test_api.py
+4
-4
edxval/tests/test_views.py
+38
-12
edxval/views.py
+5
-0
No files found.
edxval/tests/__init__.py
View file @
bc3300fd
"""
"""
init
init
"""
"""
from
django.contrib.auth.models
import
User
,
Permission
from
rest_framework.test
import
APITestCase
class
APIAuthTestCase
(
APITestCase
):
"""
TestCase that creates a readwrite and readonly user in setUp
"""
def
setUp
(
self
):
self
.
username
=
self
.
password
=
'readwrite'
self
.
readwrite_user
=
User
.
objects
.
create_user
(
self
.
username
,
password
=
self
.
password
)
self
.
readwrite_user
.
user_permissions
=
Permission
.
objects
.
filter
(
content_type__app_label
=
'edxval'
)
self
.
readonly_user
=
User
.
objects
.
create_user
(
'readonly'
,
'readonly'
)
self
.
_login
()
def
_logout
(
self
):
self
.
client
.
logout
()
def
_login
(
self
,
readonly
=
False
):
if
readonly
:
username
=
password
=
'readonly'
else
:
username
,
password
=
self
.
username
,
self
.
password
self
.
client
.
login
(
username
=
username
,
password
=
password
)
edxval/tests/test_api.py
View file @
bc3300fd
...
@@ -10,14 +10,13 @@ from django.db import DatabaseError
...
@@ -10,14 +10,13 @@ from django.db import DatabaseError
from
django.core.urlresolvers
import
reverse
from
django.core.urlresolvers
import
reverse
from
django.core.exceptions
import
ValidationError
from
django.core.exceptions
import
ValidationError
from
rest_framework
import
status
from
rest_framework
import
status
from
rest_framework.test
import
APITestCase
from
ddt
import
ddt
,
data
from
ddt
import
ddt
,
data
from
edxval.models
import
Profile
,
Video
,
EncodedVideo
from
edxval.models
import
Profile
,
Video
,
EncodedVideo
from
edxval
import
api
as
api
from
edxval
import
api
as
api
from
edxval.api
import
ValCannotCreateError
from
edxval.api
import
ValCannotCreateError
from
edxval.serializers
import
VideoSerializer
from
edxval.serializers
import
VideoSerializer
from
edxval.tests
import
constants
from
edxval.tests
import
constants
,
APIAuthTestCase
@ddt
@ddt
class
CreateVideoTest
(
TestCase
):
class
CreateVideoTest
(
TestCase
):
...
@@ -190,7 +189,7 @@ class GetVideoInfoTest(TestCase):
...
@@ -190,7 +189,7 @@ class GetVideoInfoTest(TestCase):
)
)
class
GetVideoInfoTestWithHttpCalls
(
APITestCase
):
class
GetVideoInfoTestWithHttpCalls
(
API
Auth
TestCase
):
"""
"""
Tests for the get_info_video, using the HTTP requests to populate database
Tests for the get_info_video, using the HTTP requests to populate database
"""
"""
...
@@ -200,9 +199,10 @@ class GetVideoInfoTestWithHttpCalls(APITestCase):
...
@@ -200,9 +199,10 @@ class GetVideoInfoTestWithHttpCalls(APITestCase):
Creates EncodedVideo objects in database with HTTP requests.
Creates EncodedVideo objects in database with HTTP requests.
The tests are similar to the GetVideoInfoTest class. This class
The tests are similar to the GetVideoInfoTest class. This class
is to test
s
that we have the same results, using a populated
is to test that we have the same results, using a populated
database via HTTP uploads.
database via HTTP uploads.
"""
"""
super
(
GetVideoInfoTestWithHttpCalls
,
self
)
.
setUp
()
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_MOBILE
)
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_MOBILE
)
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_DESKTOP
)
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_DESKTOP
)
url
=
reverse
(
'video-list'
)
url
=
reverse
(
'video-list'
)
...
...
edxval/tests/test_views.py
View file @
bc3300fd
...
@@ -4,13 +4,12 @@ Tests for Video Abstraction Layer views
...
@@ -4,13 +4,12 @@ Tests for Video Abstraction Layer views
"""
"""
from
django.core.urlresolvers
import
reverse
from
django.core.urlresolvers
import
reverse
from
rest_framework
import
status
from
rest_framework
import
status
from
rest_framework.test
import
APITestCase
from
edxval.tests
import
constants
from
edxval.tests
import
constants
,
APIAuthTestCase
from
edxval.models
import
Profile
,
Video
from
edxval.models
import
Profile
,
Video
class
VideoDetail
(
APITestCase
):
class
VideoDetail
(
API
Auth
TestCase
):
"""
"""
Tests Retrieve, Update and Destroy requests
Tests Retrieve, Update and Destroy requests
"""
"""
...
@@ -21,9 +20,33 @@ class VideoDetail(APITestCase):
...
@@ -21,9 +20,33 @@ class VideoDetail(APITestCase):
"""
"""
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_MOBILE
)
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_MOBILE
)
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_DESKTOP
)
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_DESKTOP
)
super
(
VideoDetail
,
self
)
.
setUp
()
# Tests for successful PUT requests.
# Tests for successful PUT requests.
def
test_anonymous_denied
(
self
):
"""
Tests that writing checks model permissions.
"""
self
.
_logout
()
url
=
reverse
(
'video-list'
)
response
=
self
.
client
.
post
(
url
,
constants
.
VIDEO_DICT_ANIMAL
,
format
=
'json'
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_403_FORBIDDEN
)
response
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_403_FORBIDDEN
)
def
test_no_perms
(
self
):
"""
Tests that writing checks model permissions, even for logged in users.
"""
self
.
_logout
()
self
.
_login
(
readonly
=
True
)
url
=
reverse
(
'video-list'
)
response
=
self
.
client
.
post
(
url
,
constants
.
VIDEO_DICT_ANIMAL
,
format
=
'json'
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_403_FORBIDDEN
)
response
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_403_FORBIDDEN
)
def
test_update_video
(
self
):
def
test_update_video
(
self
):
"""
"""
Tests PUTting a single video with no encoded videos.
Tests PUTting a single video with no encoded videos.
...
@@ -290,7 +313,7 @@ class VideoDetail(APITestCase):
...
@@ -290,7 +313,7 @@ class VideoDetail(APITestCase):
)
)
class
VideoListTest
(
APITestCase
):
class
VideoListTest
(
API
Auth
TestCase
):
"""
"""
Tests the creations of Videos via POST/GET
Tests the creations of Videos via POST/GET
"""
"""
...
@@ -300,6 +323,7 @@ class VideoListTest(APITestCase):
...
@@ -300,6 +323,7 @@ class VideoListTest(APITestCase):
"""
"""
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_MOBILE
)
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_MOBILE
)
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_DESKTOP
)
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_DESKTOP
)
super
(
VideoListTest
,
self
)
.
setUp
()
# Tests for successful POST 201 requests.
# Tests for successful POST 201 requests.
def
test_complete_set_two_encoded_video_post
(
self
):
def
test_complete_set_two_encoded_video_post
(
self
):
...
@@ -435,7 +459,7 @@ class VideoListTest(APITestCase):
...
@@ -435,7 +459,7 @@ class VideoListTest(APITestCase):
Tests number of queries for a Video with no Encoded Videos
Tests number of queries for a Video with no Encoded Videos
"""
"""
url
=
reverse
(
'video-list'
)
url
=
reverse
(
'video-list'
)
with
self
.
assertNumQueries
(
4
):
with
self
.
assertNumQueries
(
8
):
self
.
client
.
post
(
url
,
constants
.
VIDEO_DICT_ZEBRA
,
format
=
'json'
)
self
.
client
.
post
(
url
,
constants
.
VIDEO_DICT_ZEBRA
,
format
=
'json'
)
def
test_queries_for_two_encoded_video
(
self
):
def
test_queries_for_two_encoded_video
(
self
):
...
@@ -443,7 +467,7 @@ class VideoListTest(APITestCase):
...
@@ -443,7 +467,7 @@ class VideoListTest(APITestCase):
Tests number of queries for a Video/EncodedVideo(2) pair
Tests number of queries for a Video/EncodedVideo(2) pair
"""
"""
url
=
reverse
(
'video-list'
)
url
=
reverse
(
'video-list'
)
with
self
.
assertNumQueries
(
16
):
with
self
.
assertNumQueries
(
20
):
self
.
client
.
post
(
url
,
constants
.
COMPLETE_SET_FISH
,
format
=
'json'
)
self
.
client
.
post
(
url
,
constants
.
COMPLETE_SET_FISH
,
format
=
'json'
)
def
test_queries_for_single_encoded_videos
(
self
):
def
test_queries_for_single_encoded_videos
(
self
):
...
@@ -451,11 +475,11 @@ class VideoListTest(APITestCase):
...
@@ -451,11 +475,11 @@ class VideoListTest(APITestCase):
Tests number of queries for a Video/EncodedVideo(1) pair
Tests number of queries for a Video/EncodedVideo(1) pair
"""
"""
url
=
reverse
(
'video-list'
)
url
=
reverse
(
'video-list'
)
with
self
.
assertNumQueries
(
1
0
):
with
self
.
assertNumQueries
(
1
4
):
self
.
client
.
post
(
url
,
constants
.
COMPLETE_SET_STAR
,
format
=
'json'
)
self
.
client
.
post
(
url
,
constants
.
COMPLETE_SET_STAR
,
format
=
'json'
)
class
VideoDetailTest
(
APITestCase
):
class
VideoDetailTest
(
API
Auth
TestCase
):
"""
"""
Tests for GET
Tests for GET
"""
"""
...
@@ -465,6 +489,7 @@ class VideoDetailTest(APITestCase):
...
@@ -465,6 +489,7 @@ class VideoDetailTest(APITestCase):
"""
"""
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_MOBILE
)
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_MOBILE
)
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_DESKTOP
)
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_DESKTOP
)
super
(
VideoDetailTest
,
self
)
.
setUp
()
def
test_get_all_videos
(
self
):
def
test_get_all_videos
(
self
):
"""
"""
...
@@ -487,25 +512,26 @@ class VideoDetailTest(APITestCase):
...
@@ -487,25 +512,26 @@ class VideoDetailTest(APITestCase):
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_201_CREATED
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_201_CREATED
)
response
=
self
.
client
.
post
(
url
,
constants
.
VIDEO_DICT_ZEBRA
,
format
=
'json'
)
response
=
self
.
client
.
post
(
url
,
constants
.
VIDEO_DICT_ZEBRA
,
format
=
'json'
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_201_CREATED
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_201_CREATED
)
with
self
.
assertNumQueries
(
4
):
with
self
.
assertNumQueries
(
6
):
self
.
client
.
get
(
"/edxval/video/"
)
.
data
self
.
client
.
get
(
"/edxval/video/"
)
.
data
response
=
self
.
client
.
post
(
url
,
constants
.
COMPLETE_SET_FISH
,
format
=
'json'
)
response
=
self
.
client
.
post
(
url
,
constants
.
COMPLETE_SET_FISH
,
format
=
'json'
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_201_CREATED
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_201_CREATED
)
with
self
.
assertNumQueries
(
9
):
with
self
.
assertNumQueries
(
11
):
self
.
client
.
get
(
"/edxval/video/"
)
.
data
self
.
client
.
get
(
"/edxval/video/"
)
.
data
response
=
self
.
client
.
post
(
url
,
constants
.
COMPLETE_SET_STAR
,
format
=
'json'
)
response
=
self
.
client
.
post
(
url
,
constants
.
COMPLETE_SET_STAR
,
format
=
'json'
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_201_CREATED
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_201_CREATED
)
with
self
.
assertNumQueries
(
1
2
):
with
self
.
assertNumQueries
(
1
4
):
self
.
client
.
get
(
"/edxval/video/"
)
.
data
self
.
client
.
get
(
"/edxval/video/"
)
.
data
class
SubtitleDetailTest
(
APITestCase
):
class
SubtitleDetailTest
(
API
Auth
TestCase
):
"""
"""
Tests for subtitle API
Tests for subtitle API
"""
"""
def
setUp
(
self
):
def
setUp
(
self
):
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_MOBILE
)
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_MOBILE
)
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_DESKTOP
)
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_DESKTOP
)
super
(
SubtitleDetailTest
,
self
)
.
setUp
()
def
test_get_subtitle_content
(
self
):
def
test_get_subtitle_content
(
self
):
"""
"""
...
...
edxval/views.py
View file @
bc3300fd
...
@@ -3,6 +3,7 @@ Views file for django app edxval.
...
@@ -3,6 +3,7 @@ Views file for django app edxval.
"""
"""
from
rest_framework
import
generics
from
rest_framework
import
generics
from
rest_framework.permissions
import
DjangoModelPermissions
from
django.http
import
HttpResponse
from
django.http
import
HttpResponse
from
django.shortcuts
import
get_object_or_404
from
django.shortcuts
import
get_object_or_404
from
django.views.decorators.http
import
last_modified
from
django.views.decorators.http
import
last_modified
...
@@ -32,6 +33,7 @@ class VideoList(generics.ListCreateAPIView):
...
@@ -32,6 +33,7 @@ class VideoList(generics.ListCreateAPIView):
"""
"""
GETs or POST video objects
GETs or POST video objects
"""
"""
permission_classes
=
(
DjangoModelPermissions
,)
queryset
=
Video
.
objects
.
all
()
.
prefetch_related
(
"encoded_videos"
)
queryset
=
Video
.
objects
.
all
()
.
prefetch_related
(
"encoded_videos"
)
lookup_field
=
"edx_video_id"
lookup_field
=
"edx_video_id"
serializer_class
=
VideoSerializer
serializer_class
=
VideoSerializer
...
@@ -41,6 +43,7 @@ class ProfileList(generics.ListCreateAPIView):
...
@@ -41,6 +43,7 @@ class ProfileList(generics.ListCreateAPIView):
"""
"""
GETs or POST video objects
GETs or POST video objects
"""
"""
permission_classes
=
(
DjangoModelPermissions
,)
queryset
=
Profile
.
objects
.
all
()
queryset
=
Profile
.
objects
.
all
()
lookup_field
=
"profile_name"
lookup_field
=
"profile_name"
serializer_class
=
ProfileSerializer
serializer_class
=
ProfileSerializer
...
@@ -50,6 +53,7 @@ class VideoDetail(generics.RetrieveUpdateDestroyAPIView):
...
@@ -50,6 +53,7 @@ class VideoDetail(generics.RetrieveUpdateDestroyAPIView):
"""
"""
Gets a video instance given its edx_video_id
Gets a video instance given its edx_video_id
"""
"""
permission_classes
=
(
DjangoModelPermissions
,)
lookup_field
=
"edx_video_id"
lookup_field
=
"edx_video_id"
queryset
=
Video
.
objects
.
all
()
queryset
=
Video
.
objects
.
all
()
serializer_class
=
VideoSerializer
serializer_class
=
VideoSerializer
...
@@ -59,6 +63,7 @@ class SubtitleDetail(MultipleFieldLookupMixin, generics.RetrieveUpdateDestroyAPI
...
@@ -59,6 +63,7 @@ class SubtitleDetail(MultipleFieldLookupMixin, generics.RetrieveUpdateDestroyAPI
"""
"""
Gets a subtitle instance given its id
Gets a subtitle instance given its id
"""
"""
permission_classes
=
(
DjangoModelPermissions
,)
lookup_fields
=
(
"video__edx_video_id"
,
"language"
)
lookup_fields
=
(
"video__edx_video_id"
,
"language"
)
queryset
=
Subtitle
.
objects
.
all
()
queryset
=
Subtitle
.
objects
.
all
()
serializer_class
=
SubtitleSerializer
serializer_class
=
SubtitleSerializer
...
...
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