Commit 7da84af9 by Matt Drayer Committed by Jonathan Piacenti

mattdrayer/api-workgroups: Added new models and viewsets to support workgroups/projects

parent 483a9a06
......@@ -3,7 +3,7 @@
Run these tests @ Devstack:
rake fasttest_lms[common/djangoapps/api_manager/courses/tests.py]
"""
import simplejson as json
import json
import uuid
from random import randint
......
......@@ -2,11 +2,13 @@
""" Database ORM models managed by this Django app """
from django.contrib.auth.models import Group
from django.contrib.auth.models import Group, User
from django.db import models
from django.utils import timezone
from model_utils.models import TimeStampedModel
from projects.models import Workgroup
class GroupRelationship(TimeStampedModel):
"""
......@@ -101,7 +103,7 @@ class GroupProfile(TimeStampedModel):
class Meta:
db_table = "auth_groupprofile"
group = models.ForeignKey(Group, db_index=True)
group = models.OneToOneField(Group, db_index=True)
group_type = models.CharField(null=True, max_length=32, db_index=True)
name = models.CharField(max_length=255, null=True, blank=True)
data = models.TextField(blank=True) # JSON dictionary for generic key/value pairs
......@@ -126,3 +128,13 @@ class CourseContentGroupRelationship(TimeStampedModel):
Mapping model to enable grouping of course content such as chapters
"""
unique_together = ("course_id", "content_id", "group_profile")
class Organization(TimeStampedModel):
"""
Main table representing the Organization concept. Organizations are
primarily a collection of Users.
"""
name = models.CharField(max_length=255)
workgroups = models.ManyToManyField(Workgroup, related_name="organizations")
users = models.ManyToManyField(User, related_name="organizations")
""" Django REST Framework Serializers """
from rest_framework import serializers
from api_manager.models import Organization
class OrganizationSerializer(serializers.HyperlinkedModelSerializer):
""" Serializer for Organization model interactions """
class Meta:
""" Serializer/field specification """
model = Organization
fields = ('url', 'id', 'name', 'workgroups', 'users', 'created', 'modified')
read_only = ('url', 'id', 'created')
# pylint: disable=E1103
"""
Run these tests @ Devstack:
rake fasttest_lms[common/djangoapps/api_manager/organizations/tests.py]
"""
import json
import uuid
from django.core.cache import cache
from django.test import TestCase, Client
from django.test.utils import override_settings
TEST_API_KEY = str(uuid.uuid4())
class SecureClient(Client):
""" Django test client using a "secure" connection. """
def __init__(self, *args, **kwargs):
kwargs = kwargs.copy()
kwargs.update({'SERVER_PORT': 443, 'wsgi.url_scheme': 'https'})
super(SecureClient, self).__init__(*args, **kwargs)
@override_settings(EDX_API_KEY=TEST_API_KEY)
class OrganizationsApiTests(TestCase):
""" Test suite for Users API views """
def setUp(self):
self.test_server_prefix = 'https://testserver'
self.test_organizations_uri = '/api/organizations/'
self.test_organization_name = str(uuid.uuid4())
self.client = SecureClient()
cache.clear()
def do_post(self, uri, data):
"""Submit an HTTP POST request"""
headers = {
'X-Edx-Api-Key': str(TEST_API_KEY),
}
json_data = json.dumps(data)
response = self.client.post(
uri, headers=headers, content_type='application/json', data=json_data)
return response
def do_get(self, uri):
"""Submit an HTTP GET request"""
headers = {
'Content-Type': 'application/json',
'X-Edx-Api-Key': str(TEST_API_KEY),
}
response = self.client.get(uri, headers=headers)
return response
def do_delete(self, uri):
"""Submit an HTTP DELETE request"""
headers = {
'Content-Type': 'application/json',
'X-Edx-Api-Key': str(TEST_API_KEY),
}
response = self.client.delete(uri, headers=headers)
return response
def test_organizations_list_post(self):
data = {
'name': self.test_organization_name
}
response = self.do_post(self.test_organizations_uri, data)
self.assertEqual(response.status_code, 201)
self.assertGreater(response.data['id'], 0)
confirm_uri = '{}{}{}/'.format(
self.test_server_prefix,
self.test_organizations_uri,
str(response.data['id'])
)
self.assertEqual(response.data['url'], confirm_uri)
self.assertGreater(response.data['id'], 0)
self.assertEqual(response.data['name'], self.test_organization_name)
self.assertIsNotNone(response.data['workgroups'])
self.assertIsNotNone(response.data['users'])
self.assertIsNotNone(response.data['created'])
self.assertIsNotNone(response.data['modified'])
def test_organizations_detail_get(self):
data = {'name': self.test_organization_name}
response = self.do_post(self.test_organizations_uri, data)
self.assertEqual(response.status_code, 201)
test_uri = '{}{}/'.format(self.test_organizations_uri, str(response.data['id']))
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 200)
confirm_uri = self.test_server_prefix + test_uri
self.assertEqual(response.data['url'], confirm_uri)
self.assertGreater(response.data['id'], 0)
self.assertEqual(response.data['name'], self.test_organization_name)
self.assertIsNotNone(response.data['workgroups'])
self.assertIsNotNone(response.data['users'])
self.assertIsNotNone(response.data['created'])
self.assertIsNotNone(response.data['modified'])
def test_organizations_detail_get_undefined(self):
test_uri = '/api/organizations/123456789/'
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 404)
def test_organizations_detail_delete(self):
data = {'name': self.test_organization_name}
response = self.do_post(self.test_organizations_uri, data)
self.assertEqual(response.status_code, 201)
test_uri = '{}{}/'.format(self.test_organizations_uri, str(response.data['id']))
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 200)
response = self.do_delete(test_uri)
self.assertEqual(response.status_code, 204)
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 404)
""" ORGANIZATIONS API VIEWS """
from rest_framework import viewsets
from api_manager.models import Organization
from .serializers import OrganizationSerializer
class OrganizationsViewSet(viewsets.ModelViewSet):
"""
Django Rest Framework ViewSet for the Organization model.
"""
serializer_class = OrganizationSerializer
model = Organization
......@@ -28,7 +28,7 @@ class SystemApiTests(TestCase):
""" Test suite for base API views """
def setUp(self):
self.test_server_prefix = "https://testserver/api"
self.test_server_prefix = "https://testserver/api/"
self.test_username = str(uuid.uuid4())
self.test_password = str(uuid.uuid4())
self.test_email = str(uuid.uuid4()) + '@test.org'
......@@ -48,7 +48,7 @@ class SystemApiTests(TestCase):
def test_system_detail_get(self):
""" Ensure the system returns base data about the system """
test_uri = self.test_server_prefix + '/system'
test_uri = self.test_server_prefix + 'system'
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 200)
self.assertIsNotNone(response.data['uri'])
......
......@@ -10,7 +10,11 @@
from django.conf.urls import include, patterns, url
from rest_framework.routers import SimpleRouter
from api_manager.organizations.views import OrganizationsViewSet
from api_manager.system import views as system_views
from projects import views as project_views
urlpatterns = patterns(
'',
......@@ -21,3 +25,16 @@ urlpatterns = patterns(
url(r'^sessions/*', include('api_manager.sessions.urls')),
url(r'^courses/*', include('api_manager.courses.urls')),
)
router = SimpleRouter()
router.register(r'organizations', OrganizationsViewSet)
# Project-related ViewSets
router.register(r'projects', project_views.ProjectsViewSet)
router.register(r'workgroups', project_views.WorkgroupsViewSet)
router.register(r'submissions', project_views.SubmissionsViewSet)
router.register(r'submission_reviews', project_views.SubmissionReviewsViewSet)
router.register(r'peer_reviews', project_views.PeerReviewsViewSet)
router.register(r'groups', project_views.GroupViewSet)
router.register(r'users', project_views.UserViewSet)
urlpatterns += router.urls
......@@ -5,7 +5,7 @@ Run these tests @ Devstack:
rake fasttest_lms[common/djangoapps/api_manager/tests/test_user_views.py]
"""
from random import randint
import simplejson as json
import json
import unittest
import uuid
from mock import patch
......
......@@ -7,14 +7,14 @@ from api_manager.users import views as users_views
urlpatterns = patterns(
'',
url(r'/*$^', users_views.UsersList.as_view()),
url(r'^(?P<user_id>[0-9]+)$', users_views.UsersDetail.as_view()),
url(r'^(?P<user_id>[0-9]+)/courses/*$', users_views.UsersCoursesList.as_view()),
url(r'^(?P<user_id>[0-9]+)/courses/(?P<course_id>[^/]+/[^/]+/[^/]+)$', users_views.UsersCoursesDetail.as_view()),
url(r'^(?P<user_id>[0-9]+)/courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/grades$', users_views.UsersCoursesGradesDetail.as_view()),
url(r'^(?P<user_id>[0-9]+)/groups/*$', users_views.UsersGroupsList.as_view()),
url(r'^(?P<user_id>[0-9]+)/groups/(?P<group_id>[0-9]+)$', users_views.UsersGroupsDetail.as_view()),
url(r'^(?P<user_id>[0-9]+)/preferences$', users_views.UsersPreferences.as_view()),
url(r'/*$^', users_views.UsersList.as_view(), name='apimgr-users-list'),
url(r'^(?P<user_id>[0-9]+)$', users_views.UsersDetail.as_view(), name='apimgr-users-detail'),
url(r'^(?P<user_id>[0-9]+)/courses/*$', users_views.UsersCoursesList.as_view(), name='users-courses-list'),
url(r'^(?P<user_id>[0-9]+)/courses/(?P<course_id>[^/]+/[^/]+/[^/]+)$', users_views.UsersCoursesDetail.as_view(), name='users-courses-detail'),
url(r'^(?P<user_id>[0-9]+)/courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/grades$', users_views.UsersCoursesGradesDetail.as_view(), name='users-courses-grades-detail'),
url(r'^(?P<user_id>[0-9]+)/groups/*$', users_views.UsersGroupsList.as_view(), name='users-groups-list'),
url(r'^(?P<user_id>[0-9]+)/groups/(?P<group_id>[0-9]+)$', users_views.UsersGroupsDetail.as_view(), name='users-groups-detail'),
url(r'^(?P<user_id>[0-9]+)/preferences$', users_views.UsersPreferences.as_view(), name='users-preferences-list'),
)
urlpatterns = format_suffix_patterns(urlpatterns)
""" Database ORM models managed by this Django app """
from django.contrib.auth.models import Group, User
from django.db import models
from model_utils.models import TimeStampedModel
class Workgroup(TimeStampedModel):
"""
Model representing the Workgroup concept. Workgroups are an
intersection of Users and CourseContent, although they can also be
related to other Groups.
"""
name = models.CharField(max_length=255, null=True, blank=True)
users = models.ManyToManyField(User, related_name="workgroups")
groups = models.ManyToManyField(Group, related_name="workgroups")
class Project(TimeStampedModel):
"""
Model representing the Project concept. Projects are an
intersection of Courses, CourseContent, and Workgroups.
"""
course_id = models.CharField(max_length=255)
content_id = models.CharField(max_length=255)
workgroups = models.ManyToManyField(Workgroup, related_name="projects")
class Meta:
""" Meta class for defining additional model characteristics """
unique_together = ("course_id", "content_id")
class Submission(TimeStampedModel):
"""
Model representing the Submission concept. A Submission is a project artifact
created by the Users in a Workgroup. The document fields are defined by the
'Group Project' XBlock and data for a specific instance is persisted here
"""
user = models.ForeignKey(User)
workgroup = models.ForeignKey(Workgroup, related_name="submissions")
project = models.ForeignKey(Project, related_name="projects")
document_id = models.CharField(max_length=255)
document_url = models.CharField(max_length=255)
document_mime_type = models.CharField(max_length=255)
class SubmissionReview(TimeStampedModel):
"""
Model representing the Submission Review concept. A Submission Review is
essentially a single question/answer combination for a particular Submission,
defined in the Group Project XBlock schema. There can be more than one
Submission Review for a given Submission.
"""
submission = models.ForeignKey(Submission, related_name="submission_reviews")
reviewer = models.ForeignKey(User, related_name="submission_reviews")
question = models.CharField(max_length=255)
answer = models.CharField(max_length=255)
class PeerReview(TimeStampedModel):
"""
Model representing the Peer Review concept. A Peer Review is a record of a
specific question/answer defined in the Group Project XBlock schema. There
can be more than one Peer Review for a given User.
"""
user = models.ForeignKey(User, related_name="peer_reviewees")
reviewer = models.ForeignKey(User, related_name="peer_reviewers")
question = models.CharField(max_length=255)
answer = models.CharField(max_length=255)
""" Django REST Framework Serializers """
from django.contrib.auth.models import Group, User
from django.core.exceptions import ObjectDoesNotExist
from rest_framework import serializers
from .models import Workgroup, Project, Submission
from .models import SubmissionReview, PeerReview
class UserSerializer(serializers.HyperlinkedModelSerializer):
""" Serializer for model interactions """
class Meta:
""" Meta class for defining additional serializer characteristics """
model = User
fields = ('id', 'url', 'username', 'email')
class GroupSerializer(serializers.HyperlinkedModelSerializer):
""" Serializer for model interactions """
name = serializers.SerializerMethodField('get_group_name')
def get_group_name(self, group):
"""
Group name is actually stored on the profile record, in order to
allow for duplicate name values in the system.
"""
try:
group_profile = group.groupprofile
if group_profile:
return group_profile.name
except ObjectDoesNotExist:
return group.name
class Meta:
""" Meta class for defining additional serializer characteristics """
model = Group
fields = ('id', 'url', 'name')
class WorkgroupSerializer(serializers.HyperlinkedModelSerializer):
""" Serializer for model interactions """
groups = GroupSerializer(many=True, required=False)
users = UserSerializer(many=True, required=False)
class Meta:
""" Meta class for defining additional serializer characteristics """
model = Workgroup
fields = ('id', 'url', 'created', 'modified', 'name', 'groups', 'users')
class ProjectSerializer(serializers.HyperlinkedModelSerializer):
""" Serializer for model interactions """
workgroups = WorkgroupSerializer(many=True, required=False)
class Meta:
""" Meta class for defining additional serializer characteristics """
model = Project
fields = ('id', 'url', 'created', 'modified', 'course_id', 'content_id', 'workgroups')
class SubmissionSerializer(serializers.HyperlinkedModelSerializer):
""" Serializer for model interactions """
user = serializers.PrimaryKeyRelatedField(required=True)
project = serializers.PrimaryKeyRelatedField(required=True)
workgroup = serializers.PrimaryKeyRelatedField(required=True)
class Meta:
""" Meta class for defining additional serializer characteristics """
model = Submission
fields = ('id', 'url', 'created', 'modified', 'user', 'project', 'workgroup', 'document_id', 'document_url', 'document_mime_type')
class SubmissionReviewSerializer(serializers.HyperlinkedModelSerializer):
""" Serializer for model interactions """
submission = serializers.PrimaryKeyRelatedField(required=True)
reviewer = serializers.PrimaryKeyRelatedField(required=True)
class Meta:
""" Meta class for defining additional serializer characteristics """
model = SubmissionReview
fields = ('id', 'url', 'created', 'modified', 'submission', 'reviewer', 'question', 'answer')
class PeerReviewSerializer(serializers.HyperlinkedModelSerializer):
""" Serializer for model interactions """
user = serializers.PrimaryKeyRelatedField(required=True)
reviewer = serializers.PrimaryKeyRelatedField(required=True)
class Meta:
""" Meta class for defining additional serializer characteristics """
model = PeerReview
fields = ('id', 'url', 'created', 'modified', 'user', 'reviewer', 'question', 'answer')
# pylint: disable=E1103
"""
Run these tests @ Devstack:
rake fasttest_lms[common/djangoapps/projects/tests/test_submissions.py]
"""
import json
import uuid
from django.contrib.auth.models import User
from django.core.cache import cache
from django.test import TestCase, Client
from django.test.utils import override_settings
from projects.models import Project, Workgroup
TEST_API_KEY = str(uuid.uuid4())
class SecureClient(Client):
""" Django test client using a "secure" connection. """
def __init__(self, *args, **kwargs):
kwargs = kwargs.copy()
kwargs.update({'SERVER_PORT': 443, 'wsgi.url_scheme': 'https'})
super(SecureClient, self).__init__(*args, **kwargs)
@override_settings(EDX_API_KEY=TEST_API_KEY)
class PeerReviewsApiTests(TestCase):
""" Test suite for Users API views """
def setUp(self):
self.test_server_prefix = 'https://testserver'
self.test_users_uri = '/api/users/'
self.test_workgroups_uri = '/api/workgroups/'
self.test_projects_uri = '/api/projects/'
self.test_peer_reviews_uri = '/api/peer_reviews/'
self.test_course_id = 'edx/demo/course'
self.test_bogus_course_id = 'foo/bar/baz'
self.test_course_content_id = "i4x://blah"
self.test_bogus_course_content_id = "14x://foo/bar/baz"
self.test_question = "Does the question data come from the XBlock definition?"
self.test_answer = "It sure does! And so does the answer data!"
self.test_peer_user = User.objects.create(
email="peer_user@edx.org",
username="peer",
is_active=True
)
self.test_reviewer_user = User.objects.create(
email="reviewer_user@edx.org",
username="reviewer",
is_active=True
)
self.test_workgroup = Workgroup.objects.create(
name="Test Workgroup",
)
self.test_workgroup.users.add(self.test_peer_user)
self.test_workgroup.users.add(self.test_reviewer_user)
self.test_workgroup.save()
self.test_project = Project.objects.create(
course_id=self.test_course_id,
content_id=self.test_course_content_id,
)
self.test_project.workgroups.add(self.test_workgroup)
self.test_project.save()
self.client = SecureClient()
cache.clear()
def do_post(self, uri, data):
"""Submit an HTTP POST request"""
headers = {
'X-Edx-Api-Key': str(TEST_API_KEY),
}
json_data = json.dumps(data)
response = self.client.post(
uri, headers=headers, content_type='application/json', data=json_data)
return response
def do_get(self, uri):
"""Submit an HTTP GET request"""
headers = {
'Content-Type': 'application/json',
'X-Edx-Api-Key': str(TEST_API_KEY),
}
response = self.client.get(uri, headers=headers)
return response
def do_delete(self, uri):
"""Submit an HTTP DELETE request"""
headers = {
'Content-Type': 'application/json',
'X-Edx-Api-Key': str(TEST_API_KEY),
}
response = self.client.delete(uri, headers=headers)
return response
def test_peer_reviews_list_post(self):
data = {
'user': self.test_peer_user.id,
'reviewer': self.test_reviewer_user.id,
'question': self.test_question,
'answer': self.test_answer,
}
response = self.do_post(self.test_peer_reviews_uri, data)
self.assertEqual(response.status_code, 201)
self.assertGreater(response.data['id'], 0)
confirm_uri = '{}{}{}/'.format(
self.test_server_prefix,
self.test_peer_reviews_uri,
str(response.data['id'])
)
self.assertEqual(response.data['url'], confirm_uri)
self.assertGreater(response.data['id'], 0)
self.assertEqual(response.data['user'], self.test_peer_user.id)
self.assertEqual(response.data['reviewer'], self.test_reviewer_user.id)
self.assertEqual(response.data['question'], self.test_question)
self.assertEqual(response.data['answer'], self.test_answer)
self.assertIsNotNone(response.data['created'])
self.assertIsNotNone(response.data['modified'])
def test_peer_reviews_list_post_invalid_relationships(self):
data = {
'user': 123456,
'reviewer': self.test_reviewer_user.id,
'question': self.test_question,
'answer': self.test_answer,
}
response = self.do_post(self.test_peer_reviews_uri, data)
self.assertEqual(response.status_code, 400)
data = {
'user': self.test_peer_user.id,
'reviewer': 123456,
'question': self.test_question,
'answer': self.test_answer,
}
response = self.do_post(self.test_peer_reviews_uri, data)
self.assertEqual(response.status_code, 400)
def test_peer_reviews_detail_get(self):
data = {
'user': self.test_peer_user.id,
'reviewer': self.test_reviewer_user.id,
'question': self.test_question,
'answer': self.test_answer,
}
response = self.do_post(self.test_peer_reviews_uri, data)
self.assertEqual(response.status_code, 201)
test_uri = '{}{}/'.format(self.test_peer_reviews_uri, str(response.data['id']))
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 200)
confirm_uri = '{}{}{}/'.format(
self.test_server_prefix,
self.test_peer_reviews_uri,
str(response.data['id'])
)
self.assertEqual(response.data['url'], confirm_uri)
self.assertGreater(response.data['id'], 0)
self.assertEqual(response.data['user'], self.test_peer_user.id)
self.assertEqual(response.data['reviewer'], self.test_reviewer_user.id)
self.assertEqual(response.data['question'], self.test_question)
self.assertEqual(response.data['answer'], self.test_answer)
self.assertIsNotNone(response.data['created'])
self.assertIsNotNone(response.data['modified'])
def test_peer_reviews_detail_get_undefined(self):
test_uri = '/api/peer_reviews/123456789/'
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 404)
def test_peer_reviews_detail_delete(self):
data = {
'user': self.test_peer_user.id,
'reviewer': self.test_reviewer_user.id,
'question': self.test_question,
'answer': self.test_answer,
}
response = self.do_post(self.test_peer_reviews_uri, data)
self.assertEqual(response.status_code, 201)
test_uri = '{}{}/'.format(self.test_peer_reviews_uri, str(response.data['id']))
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 200)
response = self.do_delete(test_uri)
self.assertEqual(response.status_code, 204)
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 404)
# pylint: disable=E1103
"""
Run these tests @ Devstack:
rake fasttest_lms[common/djangoapps/projects/tests/test_projects.py]
"""
import json
import uuid
from django.core.cache import cache
from django.test import TestCase, Client
from django.test.utils import override_settings
from projects.models import Workgroup
TEST_API_KEY = str(uuid.uuid4())
class SecureClient(Client):
""" Django test client using a "secure" connection. """
def __init__(self, *args, **kwargs):
kwargs = kwargs.copy()
kwargs.update({'SERVER_PORT': 443, 'wsgi.url_scheme': 'https'})
super(SecureClient, self).__init__(*args, **kwargs)
@override_settings(EDX_API_KEY=TEST_API_KEY)
class ProjectsApiTests(TestCase):
""" Test suite for Users API views """
def setUp(self):
self.test_server_prefix = 'https://testserver'
self.test_projects_uri = '/api/projects/'
self.test_project_name = str(uuid.uuid4())
self.test_course_id = 'edx/demo/course'
self.test_bogus_course_id = 'foo/bar/baz'
self.test_course_content_id = "i4x://blah"
self.test_bogus_course_content_id = "14x://foo/bar/baz"
self.test_workgroup = Workgroup.objects.create(
name="Test Workgroup",
)
self.client = SecureClient()
cache.clear()
def do_post(self, uri, data):
"""Submit an HTTP POST request"""
headers = {
'X-Edx-Api-Key': str(TEST_API_KEY),
}
json_data = json.dumps(data)
response = self.client.post(
uri, headers=headers, content_type='application/json', data=json_data)
return response
def do_get(self, uri):
"""Submit an HTTP GET request"""
headers = {
'Content-Type': 'application/json',
'X-Edx-Api-Key': str(TEST_API_KEY),
}
response = self.client.get(uri, headers=headers)
return response
def do_delete(self, uri):
"""Submit an HTTP DELETE request"""
headers = {
'Content-Type': 'application/json',
'X-Edx-Api-Key': str(TEST_API_KEY),
}
response = self.client.delete(uri, headers=headers)
return response
def test_projects_list_post(self):
data = {
'name': self.test_project_name,
'course_id': self.test_course_id,
'content_id': self.test_course_content_id
}
response = self.do_post(self.test_projects_uri, data)
self.assertEqual(response.status_code, 201)
self.assertGreater(response.data['id'], 0)
confirm_uri = '{}{}{}/'.format(
self.test_server_prefix,
self.test_projects_uri,
str(response.data['id'])
)
self.assertEqual(response.data['url'], confirm_uri)
self.assertGreater(response.data['id'], 0)
self.assertEqual(response.data['course_id'], self.test_course_id)
self.assertEqual(response.data['content_id'], self.test_course_content_id)
self.assertIsNotNone(response.data['workgroups'])
self.assertIsNotNone(response.data['created'])
self.assertIsNotNone(response.data['modified'])
def test_projects_detail_get(self):
data = {
'name': self.test_project_name,
'course_id': self.test_course_id,
'content_id': self.test_course_content_id
}
response = self.do_post(self.test_projects_uri, data)
self.assertEqual(response.status_code, 201)
test_uri = '{}{}/'.format(self.test_projects_uri, str(response.data['id']))
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 200)
confirm_uri = self.test_server_prefix + test_uri
self.assertEqual(response.data['url'], confirm_uri)
self.assertGreater(response.data['id'], 0)
self.assertEqual(response.data['course_id'], self.test_course_id)
self.assertEqual(response.data['content_id'], self.test_course_content_id)
self.assertIsNotNone(response.data['workgroups'])
self.assertIsNotNone(response.data['created'])
self.assertIsNotNone(response.data['modified'])
def test_projects_workgroups_post(self):
data = {
'name': self.test_project_name,
'course_id': self.test_course_id,
'content_id': self.test_course_content_id
}
response = self.do_post(self.test_projects_uri, data)
self.assertEqual(response.status_code, 201)
test_uri = '{}{}/'.format(self.test_projects_uri, str(response.data['id']))
workgroups_uri = '{}workgroups/'.format(test_uri)
data = {"id": self.test_workgroup.id}
response = self.do_post(workgroups_uri, data)
self.assertEqual(response.status_code, 201)
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['workgroups'][0]['id'], self.test_workgroup.id)
def test_projects_workgroups_post_invalid_workgroup(self):
data = {
'name': self.test_project_name,
'course_id': self.test_course_id,
'content_id': self.test_course_content_id
}
response = self.do_post(self.test_projects_uri, data)
self.assertEqual(response.status_code, 201)
test_uri = '{}{}/'.format(self.test_projects_uri, str(response.data['id']))
workgroups_uri = '{}workgroups/'.format(test_uri)
data = {
'id': 123456,
}
response = self.do_post(workgroups_uri, data)
self.assertEqual(response.status_code, 400)
def test_projects_detail_get_undefined(self):
test_uri = '/api/projects/123456789/'
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 404)
def test_projects_detail_delete(self):
data = {
'name': self.test_project_name,
'course_id': self.test_course_id,
'content_id': self.test_course_content_id
}
response = self.do_post(self.test_projects_uri, data)
self.assertEqual(response.status_code, 201)
test_uri = '{}{}/'.format(self.test_projects_uri, str(response.data['id']))
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 200)
response = self.do_delete(test_uri)
self.assertEqual(response.status_code, 204)
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 404)
# pylint: disable=E1103
"""
Run these tests @ Devstack:
rake fasttest_lms[common/djangoapps/projects/tests/test_submissions.py]
"""
import json
import uuid
from django.contrib.auth.models import User
from django.core.cache import cache
from django.test import TestCase, Client
from django.test.utils import override_settings
from projects.models import Project, Workgroup, Submission
TEST_API_KEY = str(uuid.uuid4())
class SecureClient(Client):
""" Django test client using a "secure" connection. """
def __init__(self, *args, **kwargs):
kwargs = kwargs.copy()
kwargs.update({'SERVER_PORT': 443, 'wsgi.url_scheme': 'https'})
super(SecureClient, self).__init__(*args, **kwargs)
@override_settings(EDX_API_KEY=TEST_API_KEY)
class SubmissionReviewsApiTests(TestCase):
""" Test suite for Users API views """
def setUp(self):
self.test_server_prefix = 'https://testserver'
self.test_users_uri = '/api/users/'
self.test_workgroups_uri = '/api/workgroups/'
self.test_projects_uri = '/api/projects/'
self.test_submission_reviews_uri = '/api/submission_reviews/'
self.test_course_id = 'edx/demo/course'
self.test_bogus_course_id = 'foo/bar/baz'
self.test_course_content_id = "i4x://blah"
self.test_bogus_course_content_id = "14x://foo/bar/baz"
self.test_question = "Does the question data come from the XBlock definition?"
self.test_answer = "It sure does! And so does the answer data!"
self.test_user = User.objects.create(
email="test@edx.org",
username="testing",
is_active=True
)
self.test_workgroup = Workgroup.objects.create(
name="Test Workgroup",
)
self.test_workgroup.users.add(self.test_user)
self.test_workgroup.save()
self.test_project = Project.objects.create(
course_id=self.test_course_id,
content_id=self.test_course_content_id,
)
self.test_project.workgroups.add(self.test_workgroup)
self.test_project.save()
self.test_submission = Submission.objects.create(
user=self.test_user,
workgroup=self.test_workgroup,
project=self.test_project,
document_id="Document12345.pdf",
document_url="http://test-s3.amazonaws.com/bucketname",
document_mime_type="application/pdf"
)
self.client = SecureClient()
cache.clear()
def do_post(self, uri, data):
"""Submit an HTTP POST request"""
headers = {
'X-Edx-Api-Key': str(TEST_API_KEY),
}
json_data = json.dumps(data)
response = self.client.post(
uri, headers=headers, content_type='application/json', data=json_data)
return response
def do_get(self, uri):
"""Submit an HTTP GET request"""
headers = {
'Content-Type': 'application/json',
'X-Edx-Api-Key': str(TEST_API_KEY),
}
response = self.client.get(uri, headers=headers)
return response
def do_delete(self, uri):
"""Submit an HTTP DELETE request"""
headers = {
'Content-Type': 'application/json',
'X-Edx-Api-Key': str(TEST_API_KEY),
}
response = self.client.delete(uri, headers=headers)
return response
def test_submission_reviews_list_post(self):
data = {
'submission': self.test_submission.id,
'reviewer': self.test_user.id,
'question': self.test_question,
'answer': self.test_answer,
}
response = self.do_post(self.test_submission_reviews_uri, data)
self.assertEqual(response.status_code, 201)
self.assertGreater(response.data['id'], 0)
confirm_uri = '{}{}{}/'.format(
self.test_server_prefix,
self.test_submission_reviews_uri,
str(response.data['id'])
)
self.assertEqual(response.data['url'], confirm_uri)
self.assertGreater(response.data['id'], 0)
self.assertEqual(response.data['reviewer'], self.test_user.id)
self.assertEqual(response.data['submission'], self.test_submission.id)
self.assertEqual(response.data['question'], self.test_question)
self.assertEqual(response.data['answer'], self.test_answer)
self.assertIsNotNone(response.data['created'])
self.assertIsNotNone(response.data['modified'])
def test_submission_reviews_detail_get(self):
data = {
'submission': self.test_submission.id,
'reviewer': self.test_user.id,
'question': self.test_question,
'answer': self.test_answer,
}
response = self.do_post(self.test_submission_reviews_uri, data)
self.assertEqual(response.status_code, 201)
test_uri = '{}{}/'.format(self.test_submission_reviews_uri, str(response.data['id']))
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 200)
confirm_uri = '{}{}{}/'.format(
self.test_server_prefix,
self.test_submission_reviews_uri,
str(response.data['id'])
)
self.assertEqual(response.data['url'], confirm_uri)
self.assertGreater(response.data['id'], 0)
self.assertEqual(response.data['reviewer'], self.test_user.id)
self.assertEqual(response.data['submission'], self.test_submission.id)
self.assertEqual(response.data['question'], self.test_question)
self.assertEqual(response.data['answer'], self.test_answer)
self.assertIsNotNone(response.data['created'])
self.assertIsNotNone(response.data['modified'])
def test_submission_reviews_detail_get_undefined(self):
test_uri = '/api/submission_reviews/123456789/'
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 404)
def test_submission_reviews_detail_delete(self):
data = {
'submission': self.test_submission.id,
'reviewer': self.test_user.id,
'question': self.test_question,
'answer': self.test_answer,
}
response = self.do_post(self.test_submission_reviews_uri, data)
self.assertEqual(response.status_code, 201)
test_uri = '{}{}/'.format(self.test_submission_reviews_uri, str(response.data['id']))
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 200)
response = self.do_delete(test_uri)
self.assertEqual(response.status_code, 204)
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 404)
# pylint: disable=E1103
"""
Run these tests @ Devstack:
rake fasttest_lms[common/djangoapps/projects/tests/test_submissions.py]
"""
import json
import uuid
from django.contrib.auth.models import User
from django.core.cache import cache
from django.test import TestCase, Client
from django.test.utils import override_settings
from projects.models import Project, Workgroup
TEST_API_KEY = str(uuid.uuid4())
class SecureClient(Client):
""" Django test client using a "secure" connection. """
def __init__(self, *args, **kwargs):
kwargs = kwargs.copy()
kwargs.update({'SERVER_PORT': 443, 'wsgi.url_scheme': 'https'})
super(SecureClient, self).__init__(*args, **kwargs)
@override_settings(EDX_API_KEY=TEST_API_KEY)
class SubmissionsApiTests(TestCase):
""" Test suite for Users API views """
def setUp(self):
self.test_server_prefix = 'https://testserver'
self.test_users_uri = '/api/users/'
self.test_workgroups_uri = '/api/workgroups/'
self.test_projects_uri = '/api/projects/'
self.test_submissions_uri = '/api/submissions/'
self.test_course_id = 'edx/demo/course'
self.test_bogus_course_id = 'foo/bar/baz'
self.test_course_content_id = "i4x://blah"
self.test_bogus_course_content_id = "14x://foo/bar/baz"
self.test_document_id = "Document12345.pdf"
self.test_document_url = "http://test-s3.amazonaws.com/bucketname"
self.test_document_mime_type = "application/pdf"
self.test_user = User.objects.create(
email="test@edx.org",
username="testing",
is_active=True
)
self.test_workgroup = Workgroup.objects.create(
name="Test Workgroup",
)
self.test_workgroup.users.add(self.test_user)
self.test_workgroup.save()
self.test_project = Project.objects.create(
course_id=self.test_course_id,
content_id=self.test_course_content_id,
)
self.test_project.workgroups.add(self.test_workgroup)
self.test_project.save()
self.client = SecureClient()
cache.clear()
def do_post(self, uri, data):
"""Submit an HTTP POST request"""
headers = {
'X-Edx-Api-Key': str(TEST_API_KEY),
}
json_data = json.dumps(data)
response = self.client.post(
uri, headers=headers, content_type='application/json', data=json_data)
return response
def do_get(self, uri):
"""Submit an HTTP GET request"""
headers = {
'Content-Type': 'application/json',
'X-Edx-Api-Key': str(TEST_API_KEY),
}
response = self.client.get(uri, headers=headers)
return response
def do_delete(self, uri):
"""Submit an HTTP DELETE request"""
headers = {
'Content-Type': 'application/json',
'X-Edx-Api-Key': str(TEST_API_KEY),
}
response = self.client.delete(uri, headers=headers)
return response
def test_submissions_list_post(self):
submission_data = {
'user': self.test_user.id,
'project': self.test_project.id,
'workgroup': self.test_workgroup.id,
'document_id': self.test_document_id,
'document_url': self.test_document_url,
'document_mime_type': self.test_document_mime_type,
}
response = self.do_post(self.test_submissions_uri, submission_data)
self.assertEqual(response.status_code, 201)
self.assertGreater(response.data['id'], 0)
confirm_uri = '{}{}{}/'.format(
self.test_server_prefix,
self.test_submissions_uri,
str(response.data['id'])
)
self.assertEqual(response.data['url'], confirm_uri)
self.assertGreater(response.data['id'], 0)
self.assertEqual(response.data['user'], self.test_user.id)
self.assertEqual(response.data['workgroup'], self.test_workgroup.id)
self.assertEqual(response.data['project'], self.test_project.id)
self.assertEqual(response.data['document_id'], self.test_document_id)
self.assertEqual(response.data['document_url'], self.test_document_url)
self.assertEqual(response.data['document_mime_type'], self.test_document_mime_type)
self.assertIsNotNone(response.data['created'])
self.assertIsNotNone(response.data['modified'])
def test_submissions_list_post_invalid_relationships(self):
submission_data = {
'user': 123456,
'project': self.test_project.id,
'workgroup': self.test_workgroup.id,
'document_id': self.test_document_id,
'document_url': self.test_document_url,
'document_mime_type': self.test_document_mime_type,
}
response = self.do_post(self.test_submissions_uri, submission_data)
self.assertEqual(response.status_code, 400)
submission_data = {
'user': self.test_user.id,
'project': 123456,
'workgroup': self.test_workgroup.id,
'document_id': self.test_document_id,
'document_url': self.test_document_url,
'document_mime_type': self.test_document_mime_type,
}
response = self.do_post(self.test_submissions_uri, submission_data)
self.assertEqual(response.status_code, 400)
submission_data = {
'user': self.test_user.id,
'project': self.test_project.id,
'workgroup': 123456,
'document_id': self.test_document_id,
'document_url': self.test_document_url,
'document_mime_type': self.test_document_mime_type,
}
response = self.do_post(self.test_submissions_uri, submission_data)
self.assertEqual(response.status_code, 400)
def test_submissions_detail_get(self):
submission_data = {
'user': self.test_user.id,
'project': self.test_project.id,
'workgroup': self.test_workgroup.id,
'document_id': self.test_document_id,
'document_url': self.test_document_url,
'document_mime_type': self.test_document_mime_type,
}
response = self.do_post(self.test_submissions_uri, submission_data)
self.assertEqual(response.status_code, 201)
test_uri = '{}{}/'.format(self.test_submissions_uri, str(response.data['id']))
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 200)
confirm_uri = '{}{}{}/'.format(
self.test_server_prefix,
self.test_submissions_uri,
str(response.data['id'])
)
self.assertEqual(response.data['url'], confirm_uri)
self.assertGreater(response.data['id'], 0)
self.assertEqual(response.data['user'], self.test_user.id)
self.assertEqual(response.data['workgroup'], self.test_workgroup.id)
self.assertEqual(response.data['project'], self.test_project.id)
self.assertEqual(response.data['document_id'], self.test_document_id)
self.assertEqual(response.data['document_url'], self.test_document_url)
self.assertEqual(response.data['document_mime_type'], self.test_document_mime_type)
self.assertIsNotNone(response.data['created'])
self.assertIsNotNone(response.data['modified'])
def test_submissions_detail_get_undefined(self):
test_uri = '/api/submissions/123456789/'
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 404)
def test_submnissions_detail_delete(self):
submission_data = {
'user': self.test_user.id,
'project': self.test_project.id,
'workgroup': self.test_workgroup.id,
'document_id': self.test_document_id,
'document_url': self.test_document_url,
'document_mime_type': self.test_document_mime_type,
}
response = self.do_post(self.test_submissions_uri, submission_data)
self.assertEqual(response.status_code, 201)
test_uri = '{}{}/'.format(self.test_submissions_uri, str(response.data['id']))
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 200)
response = self.do_delete(test_uri)
self.assertEqual(response.status_code, 204)
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 404)
# pylint: disable=E1103
"""
Run these tests @ Devstack:
rake fasttest_lms[common/djangoapps/projects/tests/test_workgroups.py]
"""
import json
import uuid
from django.contrib.auth.models import Group, User
from django.core.cache import cache
from django.test import TestCase, Client
from django.test.utils import override_settings
from api_manager.models import GroupProfile
TEST_API_KEY = str(uuid.uuid4())
class SecureClient(Client):
""" Django test client using a "secure" connection. """
def __init__(self, *args, **kwargs):
kwargs = kwargs.copy()
kwargs.update({'SERVER_PORT': 443, 'wsgi.url_scheme': 'https'})
super(SecureClient, self).__init__(*args, **kwargs)
@override_settings(EDX_API_KEY=TEST_API_KEY)
class WorkgroupsApiTests(TestCase):
""" Test suite for Users API views """
def setUp(self):
self.test_server_prefix = 'https://testserver'
self.test_workgroups_uri = '/api/workgroups/'
self.test_course_id = 'edx/demo/course'
self.test_bogus_course_id = 'foo/bar/baz'
self.test_course_content_id = "i4x://blah"
self.test_bogus_course_content_id = "14x://foo/bar/baz"
self.test_group_id = '1'
self.test_bogus_group_id = "2131241123"
self.test_workgroup_name = str(uuid.uuid4())
self.test_group_name = str(uuid.uuid4())
self.test_group = Group.objects.create(
name=self.test_group_name
)
GroupProfile.objects.create(
name=self.test_group_name,
group_id=self.test_group.id,
group_type="series"
)
self.test_user_email = str(uuid.uuid4())
self.test_user_username = str(uuid.uuid4())
self.test_user = User.objects.create(
email=self.test_user_email,
username=self.test_user_username
)
self.client = SecureClient()
cache.clear()
def do_post(self, uri, data):
"""Submit an HTTP POST request"""
headers = {
'X-Edx-Api-Key': str(TEST_API_KEY),
}
json_data = json.dumps(data)
response = self.client.post(
uri, headers=headers, content_type='application/json', data=json_data)
return response
def do_get(self, uri):
"""Submit an HTTP GET request"""
headers = {
'Content-Type': 'application/json',
'X-Edx-Api-Key': str(TEST_API_KEY),
}
response = self.client.get(uri, headers=headers)
return response
def do_delete(self, uri):
"""Submit an HTTP DELETE request"""
headers = {
'Content-Type': 'application/json',
'X-Edx-Api-Key': str(TEST_API_KEY),
}
response = self.client.delete(uri, headers=headers)
return response
def test_workgroups_list_post(self):
data = {
'name': self.test_workgroup_name,
}
response = self.do_post(self.test_workgroups_uri, data)
self.assertEqual(response.status_code, 201)
self.assertGreater(response.data['id'], 0)
confirm_uri = '{}{}{}/'.format(
self.test_server_prefix,
self.test_workgroups_uri,
str(response.data['id'])
)
self.assertEqual(response.data['url'], confirm_uri)
self.assertGreater(response.data['id'], 0)
self.assertIsNotNone(response.data['users'])
self.assertIsNotNone(response.data['groups'])
self.assertIsNotNone(response.data['created'])
self.assertIsNotNone(response.data['modified'])
def test_workgroups_detail_get(self):
data = {
'name': self.test_workgroup_name,
}
response = self.do_post(self.test_workgroups_uri, data)
self.assertEqual(response.status_code, 201)
test_uri = '{}{}/'.format(self.test_workgroups_uri, str(response.data['id']))
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 200)
confirm_uri = self.test_server_prefix + test_uri
self.assertEqual(response.data['url'], confirm_uri)
self.assertGreater(response.data['id'], 0)
self.assertIsNotNone(response.data['users'])
self.assertIsNotNone(response.data['groups'])
self.assertIsNotNone(response.data['created'])
self.assertIsNotNone(response.data['modified'])
def test_workgroups_groups_post(self):
data = {
'name': self.test_workgroup_name,
}
response = self.do_post(self.test_workgroups_uri, data)
self.assertEqual(response.status_code, 201)
test_uri = '{}{}/'.format(self.test_workgroups_uri, str(response.data['id']))
groups_uri = '{}groups/'.format(test_uri)
data = {"id": self.test_group.id}
response = self.do_post(groups_uri, data)
self.assertEqual(response.status_code, 201)
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['groups'][0]['id'], self.test_group.id)
test_groupnoprofile_name = str(uuid.uuid4())
test_groupnoprofile = Group.objects.create(
name=test_groupnoprofile_name
)
data = {"id": test_groupnoprofile.id}
response = self.do_post(groups_uri, data)
self.assertEqual(response.status_code, 201)
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['groups'][1]['id'], test_groupnoprofile.id)
self.assertEqual(response.data['groups'][1]['name'], test_groupnoprofile_name)
def test_workgroups_users_post(self):
data = {
'name': self.test_workgroup_name,
}
response = self.do_post(self.test_workgroups_uri, data)
self.assertEqual(response.status_code, 201)
test_uri = '{}{}/'.format(self.test_workgroups_uri, str(response.data['id']))
users_uri = '{}users/'.format(test_uri)
data = {"id": self.test_user.id}
response = self.do_post(users_uri, data)
self.assertEqual(response.status_code, 201)
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['users'][0]['id'], self.test_user.id)
def test_submissions_list_post_invalid_relationships(self):
data = {
'name': self.test_workgroup_name,
}
response = self.do_post(self.test_workgroups_uri, data)
self.assertEqual(response.status_code, 201)
test_uri = '{}{}/'.format(self.test_workgroups_uri, str(response.data['id']))
users_uri = '{}users/'.format(test_uri)
data = {"id": 123456}
response = self.do_post(users_uri, data)
self.assertEqual(response.status_code, 400)
groups_uri = '{}groups/'.format(test_uri)
data = {"id": 123456}
response = self.do_post(groups_uri, data)
self.assertEqual(response.status_code, 400)
def test_workgroups_detail_get_undefined(self):
test_uri = '/api/workgroups/123456789/'
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 404)
def test_workgroups_detail_delete(self):
data = {
'name': self.test_workgroup_name,
}
response = self.do_post(self.test_workgroups_uri, data)
self.assertEqual(response.status_code, 201)
test_uri = '{}{}/'.format(self.test_workgroups_uri, str(response.data['id']))
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 200)
response = self.do_delete(test_uri)
self.assertEqual(response.status_code, 204)
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 404)
# pylint: disable=C0103
# pylint: disable=W0613
""" WORKGROUPS API VIEWS """
from django.contrib.auth.models import Group, User
from django.core.exceptions import ObjectDoesNotExist
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework import status
from rest_framework.response import Response
from .models import Workgroup, Project, Submission
from .models import SubmissionReview, PeerReview
from .serializers import UserSerializer, GroupSerializer
from .serializers import WorkgroupSerializer, ProjectSerializer, SubmissionSerializer
from .serializers import SubmissionReviewSerializer, PeerReviewSerializer
class GroupViewSet(viewsets.ModelViewSet):
"""
Django Rest Framework ViewSet for the Group model (auth_group).
"""
serializer_class = GroupSerializer
model = Group
class UserViewSet(viewsets.ModelViewSet):
"""
Django Rest Framework ViewSet for the User model (auth_user).
"""
serializer_class = UserSerializer
model = User
class WorkgroupsViewSet(viewsets.ModelViewSet):
"""
Django Rest Framework ViewSet for the Workgroup model.
"""
serializer_class = WorkgroupSerializer
model = Workgroup
@action()
def groups(self, request, pk):
"""
Add a Group to a Workgroup
"""
group_id = request.DATA.get('id')
try:
group = Group.objects.get(id=group_id)
except ObjectDoesNotExist:
message = 'Group {} does not exist'.format(group_id)
return Response({"detail": message}, status.HTTP_400_BAD_REQUEST)
workgroup = self.get_object()
workgroup.groups.add(group)
workgroup.save()
return Response({}, status=status.HTTP_201_CREATED)
@action()
def users(self, request, pk):
"""
Add a User to a Workgroup
"""
user_id = request.DATA.get('id')
try:
user = User.objects.get(id=user_id)
except ObjectDoesNotExist:
message = 'User {} does not exist'.format(user_id)
return Response({"detail": message}, status.HTTP_400_BAD_REQUEST)
workgroup = self.get_object()
workgroup.users.add(user)
workgroup.save()
return Response({}, status=status.HTTP_201_CREATED)
class ProjectsViewSet(viewsets.ModelViewSet):
"""
Django Rest Framework ViewSet for the Project model.
"""
serializer_class = ProjectSerializer
model = Project
@action()
def workgroups(self, request, pk):
"""
Add a Workgroup to a Project
"""
workgroup_id = request.DATA.get('id')
try:
workgroup = Workgroup.objects.get(id=workgroup_id)
except ObjectDoesNotExist:
message = 'Workgroup {} does not exist'.format(workgroup_id)
return Response({"detail": message}, status.HTTP_400_BAD_REQUEST)
project = self.get_object()
project.workgroups.add(workgroup)
project.save()
return Response({}, status=status.HTTP_201_CREATED)
class SubmissionsViewSet(viewsets.ModelViewSet):
"""
Django Rest Framework ViewSet for the Submission model.
"""
serializer_class = SubmissionSerializer
model = Submission
class SubmissionReviewsViewSet(viewsets.ModelViewSet):
"""
Django Rest Framework ViewSet for the SubmissionReview model.
"""
serializer_class = SubmissionReviewSerializer
model = SubmissionReview
class PeerReviewsViewSet(viewsets.ModelViewSet):
"""
Django Rest Framework ViewSet for the PeerReview model.
"""
serializer_class = PeerReviewSerializer
model = PeerReview
......@@ -1926,6 +1926,7 @@ INSTALLED_APPS = (
# EDX API application
'api_manager',
'projects',
)
######################### CSRF #########################################
......
......@@ -125,7 +125,7 @@ if settings.FEATURES["ENABLE_MOBILE_REST_API"]:
# OPEN EDX API
if settings.FEATURES["API"]:
urlpatterns += (
url(r'^api/*', include('api_manager.urls')),
url(r'^api/', include('api_manager.urls')),
)
# if settings.FEATURES.get("MULTIPLE_ENROLLMENT_ROLES"):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment