Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-notes-api
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-notes-api
Commits
4310403b
Commit
4310403b
authored
Feb 08, 2016
by
ehtesham
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[TNL-4029] user can't add more than maximum number of allowed annotations
parent
05dba592
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
100 additions
and
4 deletions
+100
-4
notesapi/v1/tests/test_views.py
+68
-1
notesapi/v1/views.py
+26
-3
notesserver/settings/common.py
+3
-0
notesserver/settings/test.py
+3
-0
No files found.
notesapi/v1/tests/test_views.py
View file @
4310403b
...
...
@@ -18,6 +18,7 @@ from rest_framework.test import APITestCase
from
.helpers
import
get_id_token
TEST_USER
=
"test_user_id"
TEST_OTHER_USER
=
"test_other_user_id"
if
not
settings
.
ES_DISABLED
:
import
haystack
...
...
@@ -65,6 +66,16 @@ class BaseAnnotationViewTests(APITestCase):
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_201_CREATED
)
return
response
.
data
.
copy
()
def
_create_annotation_without_assert
(
self
,
**
kwargs
):
"""
Create annotation but do not check for 201
"""
opts
=
self
.
payload
.
copy
()
opts
.
update
(
kwargs
)
url
=
reverse
(
'api:v1:annotations'
)
response
=
self
.
client
.
post
(
url
,
opts
,
format
=
'json'
)
return
response
def
_do_annotation_update
(
self
,
data
,
updated_fields
):
"""
Helper method for updating an annotation.
...
...
@@ -98,7 +109,7 @@ class BaseAnnotationViewTests(APITestCase):
result
=
self
.
client
.
get
(
url
,
data
=
data
)
return
result
.
data
@ddt.ddt
class
AnnotationListViewTests
(
BaseAnnotationViewTests
):
"""
Test annotation creation and listing by user and course
...
...
@@ -222,6 +233,62 @@ class AnnotationListViewTests(BaseAnnotationViewTests):
del
annotation
[
'created'
]
self
.
assertEqual
(
annotation
,
note
)
@ddt.data
(
(
6
,
False
),
(
4
,
True
)
)
@ddt.unpack
def
test_create_maximum_allowed
(
self
,
num_notes
,
should_create
):
"""
Tests user can not create more than allowed notes/annotations per course
"""
for
i
in
xrange
(
num_notes
-
1
):
kwargs
=
{
'text'
:
'Foo_{}'
.
format
(
i
)}
self
.
_create_annotation
(
**
kwargs
)
# Creating more notes should result in 400 error
kwargs
=
{
'text'
:
'Foo_{}'
.
format
(
num_notes
)}
response
=
self
.
_create_annotation_without_assert
(
**
kwargs
)
if
not
should_create
:
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_400_BAD_REQUEST
,
'Creating more than allowed notes'
)
self
.
assertEqual
(
response
.
data
[
'error_msg'
],
u'You can create up to {0} notes.'
u' You must remove some notes before you can add new ones.'
.
format
(
settings
.
MAX_ANNOTATIONS_PER_COURSE
)
)
else
:
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_201_CREATED
)
def
test_create_maximum_allowed_other
(
self
):
# if user tries to create notes in another course it should succeed
for
i
in
xrange
(
5
):
kwargs
=
{
'text'
:
'Foo_{}'
.
format
(
i
)}
self
.
_create_annotation
(
**
kwargs
)
# Creating more notes should result in 400 error
kwargs
=
{
'text'
:
'Foo_{}'
.
format
(
6
)}
response
=
self
.
_create_annotation_without_assert
(
**
kwargs
)
self
.
assertEqual
(
response
.
status_code
,
status
.
HTTP_400_BAD_REQUEST
,
'Creating more than allowed notes'
)
self
.
assertEqual
(
response
.
data
[
'error_msg'
],
u'You can create up to {0} notes.'
u' You must remove some notes before you can add new ones.'
.
format
(
settings
.
MAX_ANNOTATIONS_PER_COURSE
)
)
# if user tries to create note in a different course it should succeed
kwargs
=
{
'course_id'
:
'test-course-id-2'
}
response
=
self
.
_create_annotation
(
**
kwargs
)
self
.
assertFalse
(
hasattr
(
response
,
'data'
))
# if another user to tries to create note in first course it should succeed
token
=
get_id_token
(
TEST_OTHER_USER
)
self
.
client
.
credentials
(
HTTP_X_ANNOTATOR_AUTH_TOKEN
=
token
)
self
.
headers
=
{
'user'
:
TEST_OTHER_USER
}
kwargs
=
{
'user'
:
TEST_OTHER_USER
}
response
=
self
.
_create_annotation
(
**
kwargs
)
self
.
assertFalse
(
hasattr
(
response
,
'data'
))
def
test_read_all_no_annotations
(
self
):
"""
Tests list all annotations endpoint when no annotations are present in database.
...
...
notesapi/v1/views.py
View file @
4310403b
...
...
@@ -5,6 +5,7 @@ from django.conf import settings
from
django.core.urlresolvers
import
reverse
from
django.core.exceptions
import
ValidationError
from
django.db.models
import
Q
from
django.utils.translation
import
ugettext_noop
from
rest_framework
import
status
from
rest_framework.response
import
Response
...
...
@@ -20,6 +21,13 @@ if not settings.ES_DISABLED:
log
=
logging
.
getLogger
(
__name__
)
class
AnnotationsLimitReachedError
(
Exception
):
"""
Exception when trying to create more than allowed annotations
"""
pass
class
AnnotationSearchView
(
APIView
):
"""
Search annotations.
...
...
@@ -117,20 +125,35 @@ class AnnotationListView(APIView):
Returns 400 request if bad payload is sent or it was empty object.
"""
if
'id'
in
self
.
request
.
data
:
if
not
self
.
request
.
data
or
'id'
in
self
.
request
.
data
:
return
Response
(
status
=
status
.
HTTP_400_BAD_REQUEST
)
try
:
if
Note
.
objects
.
filter
(
user_id
=
self
.
request
.
data
[
'user'
],
course_id
=
self
.
request
.
data
[
'course_id'
]
)
.
count
()
>=
settings
.
MAX_ANNOTATIONS_PER_COURSE
:
raise
AnnotationsLimitReachedError
note
=
Note
.
create
(
self
.
request
.
data
)
note
.
full_clean
()
except
ValidationError
as
error
:
log
.
debug
(
error
,
exc_info
=
True
)
return
Response
(
status
=
status
.
HTTP_400_BAD_REQUEST
)
except
AnnotationsLimitReachedError
:
error_message
=
ugettext_noop
(
u'You can create up to {max_num_annotations_per_course} notes.'
u' You must remove some notes before you can add new ones.'
)
.
format
(
max_num_annotations_per_course
=
settings
.
MAX_ANNOTATIONS_PER_COURSE
)
log
.
info
(
u'Attempted to create more than
%
s annotations'
,
settings
.
MAX_ANNOTATIONS_PER_COURSE
)
return
Response
({
'error_msg'
:
error_message
},
status
=
status
.
HTTP_400_BAD_REQUEST
)
note
.
save
()
location
=
reverse
(
'api:v1:annotations_detail'
,
kwargs
=
{
'annotation_id'
:
note
.
id
})
return
Response
(
note
.
as_dict
(),
status
=
status
.
HTTP_201_CREATED
,
headers
=
{
'Location'
:
location
})
...
...
notesserver/settings/common.py
View file @
4310403b
...
...
@@ -80,3 +80,6 @@ CORS_ALLOW_HEADERS = (
TEMPLATE_DIRS
=
(
'templates'
,
)
### Maximum number of allowed notes per course ###
MAX_ANNOTATIONS_PER_COURSE
=
500
notesserver/settings/test.py
View file @
4310403b
...
...
@@ -42,3 +42,6 @@ LOGGING = {
}
},
}
### Maximum number of allowed notes per course ###
MAX_ANNOTATIONS_PER_COURSE
=
5
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