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
3ee8fc13
Commit
3ee8fc13
authored
Nov 07, 2016
by
Jeremy Bowman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
PLAT-1074 Add support for django-user-tasks
parent
4319a828
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
135 additions
and
1 deletions
+135
-1
cms/djangoapps/contentstore/rules.py
+9
-0
cms/envs/common.py
+16
-1
cms/tests/test_user_tasks.py
+107
-0
cms/urls.py
+1
-0
requirements/edx/base.txt
+2
-0
No files found.
cms/djangoapps/contentstore/rules.py
0 → 100644
View file @
3ee8fc13
"""
Authorization rules related to content management.
"""
from
__future__
import
absolute_import
,
unicode_literals
import
user_tasks.rules
user_tasks
.
rules
.
add_rules
()
cms/envs/common.py
View file @
3ee8fc13
...
...
@@ -39,9 +39,12 @@ When refering to XBlocks, we use the entry-point name. For example,
# want to import all variables from base settings files
# pylint: disable=unused-import
from
__future__
import
absolute_import
import
imp
import
os
import
sys
from
datetime
import
timedelta
import
lms.envs.common
# Although this module itself may not use these imported variables, other dependent modules may.
from
lms.envs.common
import
(
...
...
@@ -300,6 +303,7 @@ LOGIN_URL = EDX_ROOT_URL + '/signin'
# use the ratelimit backend to prevent brute force attacks
AUTHENTICATION_BACKENDS
=
(
'rules.permissions.ObjectPermissionBackend'
,
'ratelimitbackend.backends.RateLimitModelBackend'
,
)
...
...
@@ -933,7 +937,13 @@ INSTALLED_APPS = (
'django_sites_extensions'
,
# additional release utilities to ease automation
'release_util'
'release_util'
,
# rule-based authorization
'rules.apps.AutodiscoverRulesConfig'
,
# management of user-triggered async tasks (course import/export, etc.)
'user_tasks'
,
)
...
...
@@ -1212,3 +1222,8 @@ OAUTH2_PROVIDER_APPLICATION_MODEL = 'oauth2_provider.Application'
# Used with Email sending
RETRY_ACTIVATION_EMAIL_MAX_ATTEMPTS
=
5
RETRY_ACTIVATION_EMAIL_TIMEOUT
=
0.5
############## DJANGO-USER-TASKS ##############
# How long until database records about the outcome of a task and its artifacts get deleted?
USER_TASKS_MAX_AGE
=
timedelta
(
days
=
7
)
cms/tests/test_user_tasks.py
0 → 100644
View file @
3ee8fc13
"""
Unit tests for integration of the django-user-tasks app and its REST API.
"""
from
__future__
import
absolute_import
,
print_function
,
unicode_literals
from
uuid
import
uuid4
from
django.contrib.auth.models
import
User
from
django.core.urlresolvers
import
reverse
from
django.test
import
override_settings
from
rest_framework.test
import
APITestCase
from
user_tasks.models
import
UserTaskArtifact
,
UserTaskStatus
from
user_tasks.serializers
import
ArtifactSerializer
,
StatusSerializer
# Helper functions for stuff that pylint complains about without disable comments
def
_context
(
response
):
"""
Get a context dictionary for a serializer appropriate for the given response.
"""
return
{
'request'
:
response
.
wsgi_request
}
# pylint: disable=no-member
def
_data
(
response
):
"""
Get the serialized data dictionary from the given REST API test response.
"""
return
response
.
data
# pylint: disable=no-member
@override_settings
(
BROKER_URL
=
'memory://localhost/'
)
class
TestUserTasks
(
APITestCase
):
"""
Tests of the django-user-tasks REST API endpoints.
Detailed tests of the default authorization rules are in the django-user-tasks code.
These tests just verify that the API is exposed and functioning.
"""
@classmethod
def
setUpTestData
(
cls
):
cls
.
user
=
User
.
objects
.
create_user
(
'test_user'
,
'test@example.com'
,
'password'
)
cls
.
status
=
UserTaskStatus
.
objects
.
create
(
user
=
cls
.
user
,
task_id
=
str
(
uuid4
()),
task_class
=
'test_rest_api.sample_task'
,
name
=
'SampleTask 2'
,
total_steps
=
5
)
cls
.
artifact
=
UserTaskArtifact
.
objects
.
create
(
status
=
cls
.
status
,
text
=
'Lorem ipsum'
)
def
setUp
(
self
):
super
(
TestUserTasks
,
self
)
.
setUp
()
self
.
status
.
refresh_from_db
()
self
.
client
.
force_authenticate
(
self
.
user
)
# pylint: disable=no-member
def
test_artifact_detail
(
self
):
"""
Users should be able to access artifacts for tasks they triggered.
"""
response
=
self
.
client
.
get
(
reverse
(
'usertaskartifact-detail'
,
args
=
[
self
.
artifact
.
uuid
]))
assert
response
.
status_code
==
200
serializer
=
ArtifactSerializer
(
self
.
artifact
,
context
=
_context
(
response
))
assert
_data
(
response
)
==
serializer
.
data
def
test_artifact_list
(
self
):
"""
Users should be able to access a list of their tasks' artifacts.
"""
response
=
self
.
client
.
get
(
reverse
(
'usertaskartifact-list'
))
assert
response
.
status_code
==
200
serializer
=
ArtifactSerializer
(
self
.
artifact
,
context
=
_context
(
response
))
assert
_data
(
response
)[
'results'
]
==
[
serializer
.
data
]
def
test_status_cancel
(
self
):
"""
Users should be able to cancel tasks they no longer wish to complete.
"""
response
=
self
.
client
.
post
(
reverse
(
'usertaskstatus-cancel'
,
args
=
[
self
.
status
.
uuid
]))
assert
response
.
status_code
==
200
self
.
status
.
refresh_from_db
()
assert
self
.
status
.
state
==
UserTaskStatus
.
CANCELED
def
test_status_delete
(
self
):
"""
Users should be able to delete their own task status records when they're done with them.
"""
response
=
self
.
client
.
delete
(
reverse
(
'usertaskstatus-detail'
,
args
=
[
self
.
status
.
uuid
]))
assert
response
.
status_code
==
204
assert
not
UserTaskStatus
.
objects
.
filter
(
pk
=
self
.
status
.
id
)
.
exists
()
def
test_status_detail
(
self
):
"""
Users should be able to access status records for tasks they triggered.
"""
response
=
self
.
client
.
get
(
reverse
(
'usertaskstatus-detail'
,
args
=
[
self
.
status
.
uuid
]))
assert
response
.
status_code
==
200
serializer
=
StatusSerializer
(
self
.
status
,
context
=
_context
(
response
))
assert
_data
(
response
)
==
serializer
.
data
def
test_status_list
(
self
):
"""
Users should be able to access a list of their tasks' status records.
"""
response
=
self
.
client
.
get
(
reverse
(
'usertaskstatus-list'
))
assert
response
.
status_code
==
200
serializer
=
StatusSerializer
([
self
.
status
],
context
=
_context
(
response
),
many
=
True
)
assert
_data
(
response
)[
'results'
]
==
serializer
.
data
cms/urls.py
View file @
3ee8fc13
...
...
@@ -113,6 +113,7 @@ urlpatterns += patterns(
url
(
r'^group_configurations/{}/(?P<group_configuration_id>\d+)(/)?(?P<group_id>\d+)?$'
.
format
(
settings
.
COURSE_KEY_PATTERN
),
'group_configurations_detail_handler'
),
url
(
r'^api/val/v0/'
,
include
(
'edxval.urls'
)),
url
(
r'^api/tasks/v0/'
,
include
(
'user_tasks.urls'
)),
)
JS_INFO_DICT
=
{
...
...
requirements/edx/base.txt
View file @
3ee8fc13
...
...
@@ -34,6 +34,7 @@ django-simple-history==1.6.3
django-statici18n==1.1.5
django-storages==1.4.1
django-method-override==0.1.0
django-user-tasks==0.1.1
# We need a fix to DRF 3.2.x, for now use it from our own cherry-picked repo
#djangorestframework>=3.1,<3.2
git+https://github.com/edx/django-rest-framework.git@3c72cb5ee5baebc4328947371195eae2077197b0#egg=djangorestframework==3.2.3
...
...
@@ -94,6 +95,7 @@ pysrt==0.4.7
PyYAML==3.10
requests==2.9.1
requests-oauthlib==0.4.1
rules==1.1.1
scipy==0.14.0
Shapely==1.2.16
singledispatch==3.4.0.2
...
...
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