Commit bcddcd3a by Matt Drayer

Course-Group Relationships

parent 64a6147d
...@@ -4,10 +4,13 @@ The order of the URIs really matters here, due to the slash characters present i ...@@ -4,10 +4,13 @@ The order of the URIs really matters here, due to the slash characters present i
""" """
from django.conf.urls import patterns, url from django.conf.urls import patterns, url
urlpatterns = patterns('api_manager.courses_views', urlpatterns = patterns(
url(r'/*$^', 'courses_list'), 'api_manager.courses_views',
url(r'^(?P<course_id>[a-zA-Z0-9/_:]+)/modules/(?P<module_id>[a-zA-Z0-9/_:]+)/submodules/*$', 'modules_list'), url(r'/*$^', 'courses_list'),
url(r'^(?P<course_id>[a-zA-Z0-9/_:]+)/modules/(?P<module_id>[a-zA-Z0-9/_:]+)$', 'modules_detail'), url(r'^(?P<course_id>[a-zA-Z0-9/_:]+)/modules/(?P<module_id>[a-zA-Z0-9/_:]+)/submodules/*$', 'modules_list'),
url(r'^(?P<course_id>[a-zA-Z0-9/_:]+)/modules/*$', 'modules_list'), url(r'^(?P<course_id>[a-zA-Z0-9/_:]+)/modules/(?P<module_id>[a-zA-Z0-9/_:]+)$', 'modules_detail'),
url(r'^(?P<course_id>[a-zA-Z0-9/_:]+)$', 'courses_detail'), url(r'^(?P<course_id>[a-zA-Z0-9/_:]+)/modules/*$', 'modules_list'),
) url(r'^(?P<course_id>[a-zA-Z0-9/_:]+)/groups/(?P<group_id>[0-9]+)$', 'courses_groups_detail'),
url(r'^(?P<course_id>[a-zA-Z0-9/_:]+)/groups/*$', 'courses_groups_list'),
url(r'^(?P<course_id>[a-zA-Z0-9/_:]+)$', 'courses_detail'),
)
""" API implementation for course-oriented interactions. """ """ API implementation for course-oriented interactions. """
from django.contrib.auth.models import Group
from django.core.exceptions import ObjectDoesNotExist
from rest_framework import status from rest_framework import status
from rest_framework.decorators import api_view, permission_classes from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response from rest_framework.response import Response
from api_manager.permissions import ApiKeyHeaderPermission from api_manager.permissions import ApiKeyHeaderPermission
from api_manager.models import CourseGroupRelationship
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore import Location, InvalidLocationError from xmodule.modulestore import Location, InvalidLocationError
def _generate_base_uri(request):
"""
Constructs the protocol:host:path component of the resource uri
"""
protocol = 'http'
if request.is_secure():
protocol = protocol + 's'
resource_uri = '{}://{}{}'.format(
protocol,
request.get_host(),
request.path
)
return resource_uri
def _get_module_submodules(module, submodule_type=None): def _get_module_submodules(module, submodule_type=None):
""" """
Parses the provided module looking for child modules Parses the provided module looking for child modules
...@@ -196,3 +215,83 @@ def courses_detail(request, course_id): ...@@ -196,3 +215,83 @@ def courses_detail(request, course_id):
else: else:
status_code = status.HTTP_404_NOT_FOUND status_code = status.HTTP_404_NOT_FOUND
return Response(response_data, status=status_code) return Response(response_data, status=status_code)
@api_view(['POST'])
@permission_classes((ApiKeyHeaderPermission,))
def courses_groups_list(request, course_id):
"""
POST creates a new course-group relationship in the system
"""
response_data = {}
group_id = request.DATA['group_id']
base_uri = _generate_base_uri(request)
store = modulestore()
try:
existing_course = store.get_course(course_id)
except ValueError:
existing_course = None
try:
existing_group = Group.objects.get(id=group_id)
except ObjectDoesNotExist:
existing_group = None
if existing_course and existing_group:
try:
existing_relationship = CourseGroupRelationship.objects.get(course_id=course_id, group=existing_group)
except ObjectDoesNotExist:
existing_relationship = None
if existing_relationship is None:
CourseGroupRelationship.objects.create(course_id=course_id, group=existing_group)
response_data['course_id'] = str(existing_course.id)
response_data['group_id'] = str(existing_group.id)
response_data['uri'] = '{}/{}'.format(base_uri, existing_group.id)
response_status = status.HTTP_201_CREATED
else:
response_data['message'] = "Relationship already exists."
response_status = status.HTTP_409_CONFLICT
else:
response_status = status.HTTP_404_NOT_FOUND
return Response(response_data, status=response_status)
@api_view(['GET', 'DELETE'])
@permission_classes((ApiKeyHeaderPermission,))
def courses_groups_detail(request, course_id, group_id):
"""
GET retrieves an existing course-group relationship from the system
DELETE removes/inactivates/etc. an existing course-group relationship
"""
if request.method == 'GET':
response_data = {}
base_uri = _generate_base_uri(request)
response_data['uri'] = base_uri
response_data['course_id'] = course_id
response_data['group_id'] = group_id
store = modulestore()
try:
existing_course = store.get_course(course_id)
except ValueError:
existing_course = None
try:
existing_group = Group.objects.get(id=group_id)
except ObjectDoesNotExist:
existing_group = None
if existing_course and existing_group:
try:
existing_relationship = CourseGroupRelationship.objects.get(course_id=course_id, group=existing_group)
except ObjectDoesNotExist:
existing_relationship = None
if existing_relationship:
response_status = status.HTTP_200_OK
else:
response_status = status.HTTP_404_NOT_FOUND
else:
response_status = status.HTTP_404_NOT_FOUND
return Response(response_data, status=response_status)
elif request.method == 'DELETE':
try:
existing_group = Group.objects.get(id=group_id)
existing_relationship = CourseGroupRelationship.objects.get(course_id=course_id, group=existing_group).delete()
except ObjectDoesNotExist:
pass
return Response({}, status=status.HTTP_204_NO_CONTENT)
...@@ -4,6 +4,8 @@ from django.conf.urls import patterns, url ...@@ -4,6 +4,8 @@ from django.conf.urls import patterns, url
urlpatterns = patterns('api_manager.groups_views', urlpatterns = patterns('api_manager.groups_views',
url(r'/*$^', 'group_list'), url(r'/*$^', 'group_list'),
url(r'^(?P<group_id>[0-9]+)$', 'group_detail'), url(r'^(?P<group_id>[0-9]+)$', 'group_detail'),
url(r'^(?P<group_id>[0-9]+)/courses/*$', 'group_courses_list'),
url(r'^(?P<group_id>[0-9]+)/courses/(?P<course_id>[a-zA-Z0-9/_:]+)$', 'group_courses_detail'),
url(r'^(?P<group_id>[0-9]+)/users/*$', 'group_users_list'), url(r'^(?P<group_id>[0-9]+)/users/*$', 'group_users_list'),
url(r'^(?P<group_id>[0-9]+)/users/(?P<user_id>[0-9]+)$', 'group_users_detail'), url(r'^(?P<group_id>[0-9]+)/users/(?P<user_id>[0-9]+)$', 'group_users_detail'),
url(r'^(?P<group_id>[0-9]+)/groups/*$', 'group_groups_list'), url(r'^(?P<group_id>[0-9]+)/groups/*$', 'group_groups_list'),
......
""" API implementation for gourse-oriented interactions. """ """ API implementation for group-oriented interactions. """
import uuid import uuid
from django.contrib.auth.models import Group, User from django.contrib.auth.models import Group, User
...@@ -10,7 +10,9 @@ from rest_framework.decorators import api_view, permission_classes ...@@ -10,7 +10,9 @@ from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response from rest_framework.response import Response
from api_manager.permissions import ApiKeyHeaderPermission from api_manager.permissions import ApiKeyHeaderPermission
from api_manager.models import GroupRelationship from api_manager.models import GroupRelationship, CourseGroupRelationship
from xmodule.modulestore.django import modulestore
from xmodule.modulestore import Location, InvalidLocationError
RELATIONSHIP_TYPES = {'hierarchical': 'h', 'graph': 'g'} RELATIONSHIP_TYPES = {'hierarchical': 'h', 'graph': 'g'}
...@@ -269,3 +271,81 @@ def group_groups_detail(request, group_id, related_group_id): ...@@ -269,3 +271,81 @@ def group_groups_detail(request, group_id, related_group_id):
else: else:
response_status = status.HTTP_404_NOT_FOUND response_status = status.HTTP_404_NOT_FOUND
return Response({}, status=response_status) return Response({}, status=response_status)
@api_view(['POST'])
@permission_classes((ApiKeyHeaderPermission,))
def group_courses_list(request, group_id):
"""
POST creates a new group-course relationship in the system
"""
response_data = {}
group_id = group_id
course_id = request.DATA['course_id']
base_uri = _generate_base_uri(request)
response_data['uri'] = '{}/{}'.format(base_uri, course_id)
store = modulestore()
print "GROUP COURSES LIST"
try:
existing_group = Group.objects.get(id=group_id)
except ObjectDoesNotExist:
existing_group = None
try:
existing_course = store.get_course(course_id)
except ValueError:
existing_course = None
print existing_group
print existing_course
if existing_group and existing_course:
try:
existing_relationship = CourseGroupRelationship.objects.get(course_id=course_id, group=existing_group)
except ObjectDoesNotExist:
existing_relationship = None
print existing_relationship
if existing_relationship is None:
new_relationship = CourseGroupRelationship.objects.create(course_id=course_id, group=existing_group)
print new_relationship.__dict__
response_data['group_id'] = str(new_relationship.group_id)
response_data['course_id'] = str(new_relationship.course_id)
response_status = status.HTTP_201_CREATED
else:
response_data['message'] = "Relationship already exists."
response_status = status.HTTP_409_CONFLICT
else:
print request.DATA
response_status = status.HTTP_404_NOT_FOUND
return Response(response_data, status=response_status)
@api_view(['GET', 'DELETE'])
@permission_classes((ApiKeyHeaderPermission,))
def group_courses_detail(request, group_id, course_id):
"""
GET retrieves an existing group-course relationship from the system
DELETE removes/inactivates/etc. an existing group-course relationship
"""
if request.method == 'GET':
response_data = {}
base_uri = _generate_base_uri(request)
response_data['uri'] = base_uri
try:
existing_group = Group.objects.get(id=group_id)
existing_relationship = CourseGroupRelationship.objects.get(course_id=course_id, group=existing_group)
except ObjectDoesNotExist:
existing_group = None
existing_relationship = None
if existing_group and existing_relationship:
response_data['group_id'] = existing_group.id
response_data['course_id'] = existing_relationship.course_id
response_status = status.HTTP_200_OK
else:
response_status = status.HTTP_404_NOT_FOUND
return Response(response_data, status=response_status)
elif request.method == 'DELETE':
try:
existing_group = Group.objects.get(id=group_id)
existing_group.coursegrouprelationship_set.get(course_id=course_id).delete()
existing_group.save()
except ObjectDoesNotExist:
pass
return Response({}, status=status.HTTP_204_NO_CONTENT)
...@@ -82,3 +82,13 @@ class LinkedGroupRelationship(models.Model): ...@@ -82,3 +82,13 @@ class LinkedGroupRelationship(models.Model):
record_active = models.BooleanField(default=True) record_active = models.BooleanField(default=True)
record_date_created = models.DateTimeField(default=timezone.now()) record_date_created = models.DateTimeField(default=timezone.now())
record_date_modified = models.DateTimeField(auto_now=True) record_date_modified = models.DateTimeField(auto_now=True)
class CourseGroupRelationship(models.Model):
"""
The CourseGroupRelationship model contains information describing the
link between a course and a group. A typical use case for this table
is to manage the courses for an XSeries or other sort of program.
"""
course_id = models.CharField(max_length=255, db_index=True)
group = models.ForeignKey(Group, db_index=True)
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
Run these tests @ Devstack: Run these tests @ Devstack:
rake fasttest_lms[common/djangoapps/api_manager/tests/test_group_views.py] rake fasttest_lms[common/djangoapps/api_manager/tests/test_group_views.py]
""" """
import simplejson as json
import unittest import unittest
import uuid import uuid
...@@ -35,6 +36,8 @@ class CoursesApiTests(TestCase): ...@@ -35,6 +36,8 @@ class CoursesApiTests(TestCase):
def setUp(self): def setUp(self):
self.test_server_prefix = 'https://testserver' self.test_server_prefix = 'https://testserver'
self.base_courses_uri = '/api/courses' self.base_courses_uri = '/api/courses'
self.base_groups_uri = '/api/groups'
self.test_group_name = 'Alpha Group'
self.course = CourseFactory.create() self.course = CourseFactory.create()
self.test_data = '<html>{}</html>'.format(str(uuid.uuid4())) self.test_data = '<html>{}</html>'.format(str(uuid.uuid4()))
...@@ -83,6 +86,28 @@ class CoursesApiTests(TestCase): ...@@ -83,6 +86,28 @@ class CoursesApiTests(TestCase):
response = self.client.get(uri, headers=headers) response = self.client.get(uri, headers=headers)
return response return response
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)
print "POST: " + uri
print json_data
print ""
response = self.client.post(uri, headers=headers, content_type='application/json', data=json_data)
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
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_course_list_get(self): def test_course_list_get(self):
test_uri = self.base_courses_uri test_uri = self.base_courses_uri
...@@ -199,3 +224,90 @@ class CoursesApiTests(TestCase): ...@@ -199,3 +224,90 @@ class CoursesApiTests(TestCase):
test_uri = self.base_modules_uri + '/2p38fp2hjfp9283/submodules?type=video' test_uri = self.base_modules_uri + '/2p38fp2hjfp9283/submodules?type=video'
response = self.do_get(test_uri) response = self.do_get(test_uri)
self.assertEqual(response.status_code, 404) self.assertEqual(response.status_code, 404)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_course_groups_list_post(self):
data = {'name': self.test_group_name}
response = self.do_post(self.base_groups_uri, data)
group_id = response.data['id']
test_uri = '{}/{}/groups'.format(self.base_courses_uri, self.test_course_id)
data = {'group_id': group_id}
response = self.do_post(test_uri, data)
self.assertEqual(response.status_code, 201)
confirm_uri = self.test_server_prefix + test_uri + '/' + str(group_id)
self.assertEqual(response.data['uri'], confirm_uri)
self.assertEqual(response.data['course_id'], str(self.test_course_id))
self.assertEqual(response.data['group_id'], str(group_id))
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_course_groups_list_post_duplicate(self):
data = {'name': self.test_group_name}
response = self.do_post(self.base_groups_uri, data)
group_id = response.data['id']
test_uri = '{}/{}/groups'.format(self.base_courses_uri, self.test_course_id)
data = {'group_id': group_id}
response = self.do_post(test_uri, data)
self.assertEqual(response.status_code, 201)
response = self.do_post(test_uri, data)
self.assertEqual(response.status_code, 409)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_group_courses_list_post_invalid_resources(self):
test_uri = self.base_courses_uri + '/1239878976/groups'
data = {'group_id': "98723896"}
response = self.do_post(test_uri, data)
self.assertEqual(response.status_code, 404)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_course_groups_detail_get(self):
data = {'name': self.test_group_name}
response = self.do_post(self.base_groups_uri, data)
group_id = response.data['id']
test_uri = '{}/{}/groups'.format(self.base_courses_uri, self.test_course_id)
data = {'group_id': response.data['id']}
response = self.do_post(test_uri, data)
test_uri = response.data['uri']
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['uri'], test_uri)
self.assertEqual(response.data['course_id'], self.test_course_id)
self.assertEqual(response.data['group_id'], str(group_id))
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_course_groups_detail_delete(self):
data = {'name': self.test_group_name}
response = self.do_post(self.base_groups_uri, data)
test_uri = '{}/{}/groups'.format(self.base_courses_uri, self.test_course_id)
data = {'group_id': response.data['id']}
response = self.do_post(test_uri, data)
test_uri = response.data['uri']
response = self.do_delete(test_uri)
self.assertEqual(response.status_code, 204)
response = self.do_delete(test_uri)
self.assertEqual(response.status_code, 204) # Idempotent
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 404)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_course_groups_detail_delete_invalid_course(self):
test_uri = '{}/123987102/groups/123124'.format(self.base_courses_uri)
response = self.do_delete(test_uri)
self.assertEqual(response.status_code, 204)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_course_groups_detail_delete_invalid_group(self):
test_uri = '{}/{}/groups/123124'.format(self.base_courses_uri, self.test_course_id)
response = self.do_delete(test_uri)
self.assertEqual(response.status_code, 204)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_course_groups_detail_get_undefined(self):
data = {'name': self.test_group_name}
response = self.do_post(self.base_groups_uri, data)
group_id = response.data['id']
test_uri = '{}/{}/groups/{}'.format(self.base_courses_uri, self.test_course_id, group_id)
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 404)
...@@ -14,6 +14,8 @@ from django.test import TestCase, Client ...@@ -14,6 +14,8 @@ from django.test import TestCase, Client
from django.test.utils import override_settings from django.test.utils import override_settings
from api_manager.models import GroupRelationship from api_manager.models import GroupRelationship
from courseware.tests.modulestore_config import TEST_DATA_MIXED_MODULESTORE
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
TEST_API_KEY = str(uuid.uuid4()) TEST_API_KEY = str(uuid.uuid4())
...@@ -26,6 +28,7 @@ class SecureClient(Client): ...@@ -26,6 +28,7 @@ class SecureClient(Client):
super(SecureClient, self).__init__(*args, **kwargs) super(SecureClient, self).__init__(*args, **kwargs)
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
@override_settings(EDX_API_KEY=TEST_API_KEY) @override_settings(EDX_API_KEY=TEST_API_KEY)
class GroupsApiTests(TestCase): class GroupsApiTests(TestCase):
""" Test suite for Groups API views """ """ Test suite for Groups API views """
...@@ -39,6 +42,9 @@ class GroupsApiTests(TestCase): ...@@ -39,6 +42,9 @@ class GroupsApiTests(TestCase):
self.base_users_uri = '/api/users' self.base_users_uri = '/api/users'
self.base_groups_uri = '/api/groups' self.base_groups_uri = '/api/groups'
self.course = CourseFactory.create()
self.test_course_id = self.course.id
self.client = SecureClient() self.client = SecureClient()
cache.clear() cache.clear()
...@@ -511,3 +517,104 @@ class GroupsApiTests(TestCase): ...@@ -511,3 +517,104 @@ class GroupsApiTests(TestCase):
test_uri = self.base_groups_uri + '/1231234232/groups/1' test_uri = self.base_groups_uri + '/1231234232/groups/1'
response = self.do_delete(test_uri) response = self.do_delete(test_uri)
self.assertEqual(response.status_code, 404) self.assertEqual(response.status_code, 404)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_group_courses_list_post(self):
data = {'name': self.test_group_name}
response = self.do_post(self.base_groups_uri, data)
self.assertEqual(response.status_code, 201)
group_id = response.data['id']
test_uri = response.data['uri'] + '/courses'
data = {'course_id': self.test_course_id}
response = self.do_post(test_uri, data)
self.assertEqual(response.status_code, 201)
confirm_uri = test_uri + '/' + self.course.id
self.assertEqual(response.data['uri'], confirm_uri)
self.assertEqual(response.data['group_id'], str(group_id))
self.assertEqual(response.data['course_id'], self.test_course_id)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_group_courses_list_post_duplicate(self):
data = {'name': self.test_group_name}
response = self.do_post(self.base_groups_uri, data)
self.assertEqual(response.status_code, 201)
group_id = response.data['id']
test_uri = response.data['uri'] + '/courses'
data = {'course_id': self.test_course_id}
response = self.do_post(test_uri, data)
self.assertEqual(response.status_code, 201)
response = self.do_post(test_uri, data)
self.assertEqual(response.status_code, 409)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_group_courses_list_post_invalid_resources(self):
test_uri = self.base_groups_uri + '/1239878976/courses'
data = {'course_id': "98723896"}
response = self.do_post(test_uri, data)
self.assertEqual(response.status_code, 404)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_group_courses_detail_get(self):
data = {'name': self.test_group_name}
response = self.do_post(self.base_groups_uri, data)
self.assertEqual(response.status_code, 201)
group_id = response.data['id']
test_uri = response.data['uri'] + '/courses'
data = {'course_id': self.test_course_id}
response = self.do_post(test_uri, data)
self.assertEqual(response.status_code, 201)
test_uri = '{}/{}/courses/{}'.format(self.base_groups_uri, group_id, self.test_course_id)
print test_uri
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 200)
confirm_uri = '{}{}/{}/courses/{}'.format(
self.test_server_prefix,
self.base_groups_uri,
group_id,
self.test_course_id
)
self.assertEqual(response.data['uri'], confirm_uri)
self.assertEqual(response.data['group_id'], group_id)
self.assertEqual(response.data['course_id'], self.test_course_id)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_group_courses_detail_delete(self):
data = {'name': self.test_group_name}
response = self.do_post(self.base_groups_uri, data)
self.assertEqual(response.status_code, 201)
test_uri = response.data['uri'] + '/courses'
data = {'course_id': self.test_course_id}
response = self.do_post(test_uri, data)
self.assertEqual(response.status_code, 201)
test_uri = response.data['uri']
response = self.do_delete(test_uri)
self.assertEqual(response.status_code, 204)
response = self.do_delete(test_uri)
self.assertEqual(response.status_code, 204) # Idempotent
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 404)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_group_courses_detail_delete_invalid_group(self):
test_uri = self.base_groups_uri + '/123987102/courses/123124'
response = self.do_delete(test_uri)
self.assertEqual(response.status_code, 204)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_group_courses_detail_delete_invalid_course(self):
data = {'name': self.test_group_name}
response = self.do_post(self.base_groups_uri, data)
self.assertEqual(response.status_code, 201)
test_uri = response.data['uri'] + '/courses/123124'
response = self.do_delete(test_uri)
self.assertEqual(response.status_code, 204)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_group_courses_detail_get_undefined(self):
data = {'name': self.test_group_name}
response = self.do_post(self.base_groups_uri, data)
self.assertEqual(response.status_code, 201)
group_id = response.data['id']
test_uri = '{}/courses/{}'.format(response.data['uri'], self.course.id)
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 404)
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