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
d2ee2430
Commit
d2ee2430
authored
Aug 27, 2014
by
Dave St.Germain
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add authentication and model permission checking to REST API.
parent
8e1dcac6
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
69 additions
and
16 deletions
+69
-16
edxval/tests/__init__.py
+24
-0
edxval/tests/test_api.py
+4
-4
edxval/tests/test_views.py
+36
-12
edxval/views.py
+5
-0
No files found.
edxval/tests/__init__.py
View file @
d2ee2430
"""
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 @
d2ee2430
...
...
@@ -10,14 +10,13 @@ from django.db import DatabaseError
from
django.core.urlresolvers
import
reverse
from
django.core.exceptions
import
ValidationError
from
rest_framework
import
status
from
rest_framework.test
import
APITestCase
from
ddt
import
ddt
,
data
from
edxval.models
import
Profile
,
Video
,
EncodedVideo
from
edxval
import
api
as
api
from
edxval.api
import
ValCannotCreateError
from
edxval.serializers
import
VideoSerializer
from
edxval.tests
import
constants
from
edxval.tests
import
constants
,
APIAuthTestCase
@ddt
class
CreateVideoTest
(
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
"""
...
...
@@ -200,9 +199,10 @@ class GetVideoInfoTestWithHttpCalls(APITestCase):
Creates EncodedVideo objects in database with HTTP requests.
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.
"""
super
(
GetVideoInfoTestWithHttpCalls
,
self
)
.
setUp
()
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_MOBILE
)
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_DESKTOP
)
url
=
reverse
(
'video-list'
)
...
...
edxval/tests/test_views.py
View file @
d2ee2430
...
...
@@ -4,13 +4,12 @@ Tests for Video Abstraction Layer views
"""
from
django.core.urlresolvers
import
reverse
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
class
VideoDetail
(
APITestCase
):
class
VideoDetail
(
API
Auth
TestCase
):
"""
Tests Retrieve, Update and Destroy requests
"""
...
...
@@ -21,9 +20,29 @@ class VideoDetail(APITestCase):
"""
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_MOBILE
)
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_DESKTOP
)
super
(
VideoDetail
,
self
)
.
setUp
()
# Tests for successful PUT requests.
def
test_anonymous_readonly
(
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
)
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
)
def
test_update_video
(
self
):
"""
Tests PUTting a single video with no encoded videos.
...
...
@@ -290,7 +309,7 @@ class VideoDetail(APITestCase):
)
class
VideoListTest
(
APITestCase
):
class
VideoListTest
(
API
Auth
TestCase
):
"""
Tests the creations of Videos via POST/GET
"""
...
...
@@ -300,6 +319,7 @@ class VideoListTest(APITestCase):
"""
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_MOBILE
)
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_DESKTOP
)
super
(
VideoListTest
,
self
)
.
setUp
()
# Tests for successful POST 201 requests.
def
test_complete_set_two_encoded_video_post
(
self
):
...
...
@@ -310,6 +330,8 @@ class VideoListTest(APITestCase):
response
=
self
.
client
.
post
(
url
,
constants
.
COMPLETE_SET_FISH
,
format
=
'json'
)
# we can log out here, to test read-only
self
.
_logout
()
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_201_CREATED
)
video
=
self
.
client
.
get
(
"/edxval/video/"
)
.
data
self
.
assertEqual
(
len
(
video
),
1
)
...
...
@@ -435,7 +457,7 @@ class VideoListTest(APITestCase):
Tests number of queries for a Video with no Encoded Videos
"""
url
=
reverse
(
'video-list'
)
with
self
.
assertNumQueries
(
4
):
with
self
.
assertNumQueries
(
8
):
self
.
client
.
post
(
url
,
constants
.
VIDEO_DICT_ZEBRA
,
format
=
'json'
)
def
test_queries_for_two_encoded_video
(
self
):
...
...
@@ -443,7 +465,7 @@ class VideoListTest(APITestCase):
Tests number of queries for a Video/EncodedVideo(2) pair
"""
url
=
reverse
(
'video-list'
)
with
self
.
assertNumQueries
(
16
):
with
self
.
assertNumQueries
(
20
):
self
.
client
.
post
(
url
,
constants
.
COMPLETE_SET_FISH
,
format
=
'json'
)
def
test_queries_for_single_encoded_videos
(
self
):
...
...
@@ -451,11 +473,11 @@ class VideoListTest(APITestCase):
Tests number of queries for a Video/EncodedVideo(1) pair
"""
url
=
reverse
(
'video-list'
)
with
self
.
assertNumQueries
(
1
0
):
with
self
.
assertNumQueries
(
1
4
):
self
.
client
.
post
(
url
,
constants
.
COMPLETE_SET_STAR
,
format
=
'json'
)
class
VideoDetailTest
(
APITestCase
):
class
VideoDetailTest
(
API
Auth
TestCase
):
"""
Tests for GET
"""
...
...
@@ -465,6 +487,7 @@ class VideoDetailTest(APITestCase):
"""
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_MOBILE
)
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_DESKTOP
)
super
(
VideoDetailTest
,
self
)
.
setUp
()
def
test_get_all_videos
(
self
):
"""
...
...
@@ -487,25 +510,26 @@ class VideoDetailTest(APITestCase):
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_201_CREATED
)
response
=
self
.
client
.
post
(
url
,
constants
.
VIDEO_DICT_ZEBRA
,
format
=
'json'
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_201_CREATED
)
with
self
.
assertNumQueries
(
4
):
with
self
.
assertNumQueries
(
6
):
self
.
client
.
get
(
"/edxval/video/"
)
.
data
response
=
self
.
client
.
post
(
url
,
constants
.
COMPLETE_SET_FISH
,
format
=
'json'
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_201_CREATED
)
with
self
.
assertNumQueries
(
9
):
with
self
.
assertNumQueries
(
11
):
self
.
client
.
get
(
"/edxval/video/"
)
.
data
response
=
self
.
client
.
post
(
url
,
constants
.
COMPLETE_SET_STAR
,
format
=
'json'
)
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
class
SubtitleDetailTest
(
APITestCase
):
class
SubtitleDetailTest
(
API
Auth
TestCase
):
"""
Tests for subtitle API
"""
def
setUp
(
self
):
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_MOBILE
)
Profile
.
objects
.
create
(
**
constants
.
PROFILE_DICT_DESKTOP
)
super
(
SubtitleDetailTest
,
self
)
.
setUp
()
def
test_get_subtitle_content
(
self
):
"""
...
...
edxval/views.py
View file @
d2ee2430
...
...
@@ -3,6 +3,7 @@ Views file for django app edxval.
"""
from
rest_framework
import
generics
from
rest_framework.permissions
import
DjangoModelPermissionsOrAnonReadOnly
from
django.http
import
HttpResponse
from
django.shortcuts
import
get_object_or_404
from
django.views.decorators.http
import
last_modified
...
...
@@ -32,6 +33,7 @@ class VideoList(generics.ListCreateAPIView):
"""
GETs or POST video objects
"""
permission_classes
=
(
DjangoModelPermissionsOrAnonReadOnly
,)
queryset
=
Video
.
objects
.
all
()
.
prefetch_related
(
"encoded_videos"
)
lookup_field
=
"edx_video_id"
serializer_class
=
VideoSerializer
...
...
@@ -41,6 +43,7 @@ class ProfileList(generics.ListCreateAPIView):
"""
GETs or POST video objects
"""
permission_classes
=
(
DjangoModelPermissionsOrAnonReadOnly
,)
queryset
=
Profile
.
objects
.
all
()
lookup_field
=
"profile_name"
serializer_class
=
ProfileSerializer
...
...
@@ -50,6 +53,7 @@ class VideoDetail(generics.RetrieveUpdateDestroyAPIView):
"""
Gets a video instance given its edx_video_id
"""
permission_classes
=
(
DjangoModelPermissionsOrAnonReadOnly
,)
lookup_field
=
"edx_video_id"
queryset
=
Video
.
objects
.
all
()
serializer_class
=
VideoSerializer
...
...
@@ -59,6 +63,7 @@ class SubtitleDetail(MultipleFieldLookupMixin, generics.RetrieveUpdateDestroyAPI
"""
Gets a subtitle instance given its id
"""
permission_classes
=
(
DjangoModelPermissionsOrAnonReadOnly
,)
lookup_fields
=
(
"video__edx_video_id"
,
"language"
)
queryset
=
Subtitle
.
objects
.
all
()
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