Commit 98793cb7 by Martyn James

Merge pull request #28 from edx-solutions/mattdrayer/api-cbv

Migrated from Function-Based Views to Class-Based-Views
parents fa6aaf8e e5656661
...@@ -4,19 +4,24 @@ The order of the URIs really matters here, due to the slash characters present i ...@@ -4,19 +4,24 @@ 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( from rest_framework.urlpatterns import format_suffix_patterns
'api_manager.courses_views',
url(r'/*$^', 'courses_list'), from api_manager import courses_views
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/modules/(?P<module_id>[a-zA-Z0-9/_:]+)/submodules/*$', 'modules_list'),
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/modules/(?P<module_id>[a-zA-Z0-9/_:]+)$', 'modules_detail'), urlpatterns = patterns('',
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/modules/*$', 'modules_list'), url(r'/*$^', courses_views.CoursesList.as_view()),
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/groups/(?P<group_id>[0-9]+)$', 'courses_groups_detail'), url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)$', courses_views.CoursesDetail.as_view()),
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/groups/*$', 'courses_groups_list'), url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/modules/(?P<module_id>[a-zA-Z0-9/_:]+)/submodules/*$', courses_views.ModulesList.as_view()),
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/overview$', 'course_overview'), url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/modules/(?P<module_id>[a-zA-Z0-9/_:]+)$', courses_views.ModulesDetail.as_view()),
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/updates$', 'course_updates'), url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/modules/*$', courses_views.ModulesList.as_view()),
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/static_tabs/(?P<tab_id>[a-zA-Z0-9/_:]+)$', 'static_tab_detail'), url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/groups/(?P<group_id>[0-9]+)$', courses_views.CoursesGroupsDetail.as_view()),
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/static_tabs$', 'static_tabs_list'), url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/groups/*$', courses_views.CoursesGroupsList.as_view()),
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/users$', 'course_users_list'), url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/overview$', courses_views.CoursesOverview.as_view()),
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/tree/(?P<depth>[0-9]+)$', 'course_tree'), url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/updates$', courses_views.CoursesUpdates.as_view()),
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)$', 'courses_detail'), url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/static_tabs/(?P<tab_id>[a-zA-Z0-9/_:]+)$', courses_views.CoursesStaticTabsDetail.as_view()),
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/static_tabs$', courses_views.CoursesStaticTabsList.as_view()),
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/users/(?P<user_id>[0-9]+)$', courses_views.CoursesUsersDetail.as_view()),
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/users$', courses_views.CoursesUsersList.as_view()),
) )
urlpatterns = format_suffix_patterns(urlpatterns)
""" Groups API URI specification """ """ Groups API URI specification """
from django.conf.urls import patterns, url from django.conf.urls import patterns, url
urlpatterns = patterns('api_manager.groups_views', from rest_framework.urlpatterns import format_suffix_patterns
url(r'/*$^', 'group_list'),
url(r'^(?P<group_id>[0-9]+)$', 'group_detail'), from api_manager import groups_views
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'), urlpatterns = patterns('',
url(r'^(?P<group_id>[0-9]+)/users/*$', 'group_users_list'), url(r'/*$^', groups_views.GroupsList.as_view()),
url(r'^(?P<group_id>[0-9]+)/users/(?P<user_id>[0-9]+)$', 'group_users_detail'), url(r'^(?P<group_id>[0-9]+)$', groups_views.GroupsDetail.as_view()),
url(r'^(?P<group_id>[0-9]+)/groups/*$', 'group_groups_list'), url(r'^(?P<group_id>[0-9]+)/courses/*$', groups_views.GroupsCoursesList.as_view()),
url(r'^(?P<group_id>[0-9]+)/groups/(?P<related_group_id>[0-9]+)$', 'group_groups_detail'), url(r'^(?P<group_id>[0-9]+)/courses/(?P<course_id>[a-zA-Z0-9/_:]+)$', groups_views.GroupsCoursesDetail.as_view()),
) url(r'^(?P<group_id>[0-9]+)/users/*$', groups_views.GroupsUsersList.as_view()),
url(r'^(?P<group_id>[0-9]+)/users/(?P<user_id>[0-9]+)$', groups_views.GroupsUsersDetail.as_view()),
url(r'^(?P<group_id>[0-9]+)/groups/*$', groups_views.GroupsGroupsList.as_view()),
url(r'^(?P<group_id>[0-9]+)/groups/(?P<related_group_id>[0-9]+)$', groups_views.GroupsGroupsDetail.as_view()),
)
urlpatterns = format_suffix_patterns(urlpatterns)
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'GroupProfile.name'
db.add_column('auth_groupprofile', 'name',
self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True),
keep_default=False)
def backwards(self, orm):
# Deleting field 'GroupProfile.name'
db.delete_column('auth_groupprofile', 'name')
models = {
'api_manager.coursegrouprelationship': {
'Meta': {'object_name': 'CourseGroupRelationship'},
'course_id': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'api_manager.groupprofile': {
'Meta': {'object_name': 'GroupProfile', 'db_table': "'auth_groupprofile'"},
'data': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']"}),
'group_type': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
},
'api_manager.grouprelationship': {
'Meta': {'object_name': 'GroupRelationship'},
'group': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.Group']", 'unique': 'True', 'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'parent_group': ('django.db.models.fields.related.ForeignKey', [], {'default': '0', 'related_name': "'child_groups'", 'null': 'True', 'blank': 'True', 'to': "orm['api_manager.GroupRelationship']"}),
'record_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'record_date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2014, 4, 30, 0, 0)'}),
'record_date_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
},
'api_manager.linkedgrouprelationship': {
'Meta': {'object_name': 'LinkedGroupRelationship'},
'from_group_relationship': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'from_group_relationships'", 'to': "orm['api_manager.GroupRelationship']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'record_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'record_date_created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2014, 4, 30, 0, 0)'}),
'record_date_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'to_group_relationship': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'to_group_relationships'", 'to': "orm['api_manager.GroupRelationship']"})
},
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
}
}
complete_apps = ['api_manager']
\ No newline at end of file
...@@ -105,6 +105,5 @@ class GroupProfile(models.Model): ...@@ -105,6 +105,5 @@ class GroupProfile(models.Model):
group = models.ForeignKey(Group, db_index=True) group = models.ForeignKey(Group, db_index=True)
group_type = models.CharField(null=True, max_length=32, 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 data = models.TextField(blank=True) # JSON dictionary for generic key/value pairs
""" Sessions API URI specification """ """ Sessions API URI specification """
from django.conf.urls import patterns, url from django.conf.urls import patterns, url
urlpatterns = patterns('api_manager.sessions_views', from rest_framework.urlpatterns import format_suffix_patterns
url(r'/*$^', 'session_list'),
url(r'^(?P<session_id>[a-z0-9]+)$', 'session_detail'), from api_manager import sessions_views
)
urlpatterns = patterns('',
url(r'/*$^', sessions_views.SessionsList.as_view()),
url(r'^(?P<session_id>[a-z0-9]+)$', sessions_views.SessionsDetail.as_view()),
)
urlpatterns = format_suffix_patterns(urlpatterns)
...@@ -13,6 +13,8 @@ from django.utils.translation import ugettext as _ ...@@ -13,6 +13,8 @@ from django.utils.translation import ugettext as _
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 rest_framework.views import APIView
from util.bad_request_rate_limiter import BadRequestRateLimiter from util.bad_request_rate_limiter import BadRequestRateLimiter
from api_manager.permissions import ApiKeyHeaderPermission from api_manager.permissions import ApiKeyHeaderPermission
...@@ -30,14 +32,15 @@ def _generate_base_uri(request): ...@@ -30,14 +32,15 @@ def _generate_base_uri(request):
resource_uri = '{}://{}{}'.format( resource_uri = '{}://{}{}'.format(
protocol, protocol,
request.get_host(), request.get_host(),
request.path request.get_full_path()
) )
return resource_uri return resource_uri
@api_view(['POST']) class SessionsList(APIView):
@permission_classes((ApiKeyHeaderPermission,)) permission_classes = (ApiKeyHeaderPermission,)
def session_list(request):
def post(self, request, format=None):
""" """
POST creates a new system session, supported authentication modes: POST creates a new system session, supported authentication modes:
1. Open edX username/password 1. Open edX username/password
...@@ -80,7 +83,7 @@ def session_list(request): ...@@ -80,7 +83,7 @@ def session_list(request):
response_data['uri'] = '{}/{}'.format(base_uri, request.session.session_key) response_data['uri'] = '{}/{}'.format(base_uri, request.session.session_key)
response_status = status.HTTP_201_CREATED response_status = status.HTTP_201_CREATED
else: else:
response_status = status.HTTP_403_FORBIDDEN response_status = status.HTTP_401_UNAUTHORIZED
else: else:
limiter.tick_bad_request_counter(request) limiter.tick_bad_request_counter(request)
# tick the failed login counters if the user exists in the database # tick the failed login counters if the user exists in the database
...@@ -93,18 +96,17 @@ def session_list(request): ...@@ -93,18 +96,17 @@ def session_list(request):
return Response(response_data, status=response_status) return Response(response_data, status=response_status)
@api_view(['GET', 'DELETE']) class SessionsDetail(APIView):
@permission_classes((ApiKeyHeaderPermission,)) permission_classes = (ApiKeyHeaderPermission,)
def session_detail(request, session_id):
def get(self, request, session_id, format=None):
""" """
GET retrieves an existing system session GET retrieves an existing system session
DELETE flushes an existing system session from the system
""" """
response_data = {} response_data = {}
base_uri = _generate_base_uri(request) base_uri = _generate_base_uri(request)
engine = import_module(settings.SESSION_ENGINE) engine = import_module(settings.SESSION_ENGINE)
session = engine.SessionStore(session_id) session = engine.SessionStore(session_id)
if request.method == 'GET':
try: try:
user_id = session[SESSION_KEY] user_id = session[SESSION_KEY]
backend_path = session[BACKEND_SESSION_KEY] backend_path = session[BACKEND_SESSION_KEY]
...@@ -120,6 +122,14 @@ def session_detail(request, session_id): ...@@ -120,6 +122,14 @@ def session_detail(request, session_id):
return Response(response_data, status=status.HTTP_200_OK) return Response(response_data, status=status.HTTP_200_OK)
else: else:
return Response(response_data, status=status.HTTP_404_NOT_FOUND) return Response(response_data, status=status.HTTP_404_NOT_FOUND)
elif request.method == 'DELETE':
def delete(self, request, session_id, format=None):
"""
DELETE flushes an existing system session from the system
"""
response_data = {}
base_uri = _generate_base_uri(request)
engine = import_module(settings.SESSION_ENGINE)
session = engine.SessionStore(session_id)
session.flush() session.flush()
return Response(response_data, status=status.HTTP_204_NO_CONTENT) return Response(response_data, status=status.HTTP_204_NO_CONTENT)
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
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 rest_framework.views import APIView
from api_manager.permissions import ApiKeyHeaderPermission from api_manager.permissions import ApiKeyHeaderPermission
...@@ -17,14 +18,14 @@ def _generate_base_uri(request): ...@@ -17,14 +18,14 @@ def _generate_base_uri(request):
resource_uri = '{}://{}{}'.format( resource_uri = '{}://{}{}'.format(
protocol, protocol,
request.get_host(), request.get_host(),
request.path request.get_full_path()
) )
return resource_uri return resource_uri
class SystemDetail(APIView):
permission_classes = (ApiKeyHeaderPermission,)
@api_view(['GET']) def get(self, request, format=None):
@permission_classes((ApiKeyHeaderPermission,))
def system_detail(request):
"""Returns top-level descriptive information about the Open edX API""" """Returns top-level descriptive information about the Open edX API"""
base_uri = _generate_base_uri(request) base_uri = _generate_base_uri(request)
response_data = {} response_data = {}
...@@ -35,9 +36,10 @@ def system_detail(request): ...@@ -35,9 +36,10 @@ def system_detail(request):
return Response(response_data, status=status.HTTP_200_OK) return Response(response_data, status=status.HTTP_200_OK)
@api_view(['GET']) class ApiDetail(APIView):
@permission_classes((ApiKeyHeaderPermission,)) permission_classes = (ApiKeyHeaderPermission,)
def api_detail(request):
def get(self, request, format=None):
"""Returns top-level descriptive information about the Open edX API""" """Returns top-level descriptive information about the Open edX API"""
base_uri = _generate_base_uri(request) base_uri = _generate_base_uri(request)
response_data = {} response_data = {}
......
...@@ -30,7 +30,6 @@ class PermissionsTestsDebug(TestCase): ...@@ -30,7 +30,6 @@ class PermissionsTestsDebug(TestCase):
response = self.client.post(uri, headers=headers, data=data) response = self.client.post(uri, headers=headers, data=data)
return response return response
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_has_permission_debug_enabled(self): def test_has_permission_debug_enabled(self):
test_uri = '/api/users' test_uri = '/api/users'
local_username = self.test_username + str(randint(11, 99)) local_username = self.test_username + str(randint(11, 99))
...@@ -57,7 +56,6 @@ class PermissionsTestsApiKey(TestCase): ...@@ -57,7 +56,6 @@ class PermissionsTestsApiKey(TestCase):
response = self.client.post(uri, headers=headers, data=data) response = self.client.post(uri, headers=headers, data=data)
return response return response
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_has_permission_valid_api_key(self): def test_has_permission_valid_api_key(self):
test_uri = '/api/users' test_uri = '/api/users'
local_username = self.test_username + str(randint(11, 99)) local_username = self.test_username + str(randint(11, 99))
...@@ -84,7 +82,6 @@ class PermissionsTestDeniedMissingServerKey(TestCase): ...@@ -84,7 +82,6 @@ class PermissionsTestDeniedMissingServerKey(TestCase):
response = self.client.post(uri, headers=headers, data=data) response = self.client.post(uri, headers=headers, data=data)
return response return response
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_has_permission_missing_server_key(self): def test_has_permission_missing_server_key(self):
test_uri = '/api/users' test_uri = '/api/users'
local_username = self.test_username + str(randint(11, 99)) local_username = self.test_username + str(randint(11, 99))
...@@ -110,7 +107,6 @@ class PermissionsTestDeniedMissingClientKey(TestCase): ...@@ -110,7 +107,6 @@ class PermissionsTestDeniedMissingClientKey(TestCase):
response = self.client.post(uri, headers=headers, data=data) response = self.client.post(uri, headers=headers, data=data)
return response return response
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_has_permission_invalid_client_key(self): def test_has_permission_invalid_client_key(self):
test_uri = '/api/users' test_uri = '/api/users'
local_username = self.test_username + str(randint(11, 99)) local_username = self.test_username + str(randint(11, 99))
...@@ -137,7 +133,6 @@ class PermissionsTestDeniedInvalidClientKey(TestCase): ...@@ -137,7 +133,6 @@ class PermissionsTestDeniedInvalidClientKey(TestCase):
response = self.client.post(uri, headers=headers, data=data) response = self.client.post(uri, headers=headers, data=data)
return response return response
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_has_permission_invalid_client_key(self): def test_has_permission_invalid_client_key(self):
test_uri = '/api/users' test_uri = '/api/users'
local_username = self.test_username + str(randint(11, 99)) local_username = self.test_username + str(randint(11, 99))
......
...@@ -68,7 +68,6 @@ class SessionsApiTests(TestCase): ...@@ -68,7 +68,6 @@ class SessionsApiTests(TestCase):
response = self.client.delete(uri, headers=headers) response = self.client.delete(uri, headers=headers)
return response return response
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_session_list_post_valid(self): def test_session_list_post_valid(self):
local_username = self.test_username + str(randint(11, 99)) local_username = self.test_username + str(randint(11, 99))
local_username = local_username[3:-1] # username is a 32-character field local_username = local_username[3:-1] # username is a 32-character field
...@@ -86,7 +85,6 @@ class SessionsApiTests(TestCase): ...@@ -86,7 +85,6 @@ class SessionsApiTests(TestCase):
self.assertEqual(str(response.data['user']['username']), local_username) self.assertEqual(str(response.data['user']['username']), local_username)
self.assertEqual(response.data['user']['id'], user_id) self.assertEqual(response.data['user']['id'], user_id)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_session_list_post_invalid(self): def test_session_list_post_invalid(self):
local_username = self.test_username + str(randint(11, 99)) local_username = self.test_username + str(randint(11, 99))
local_username = local_username[3:-1] # username is a 32-character field local_username = local_username[3:-1] # username is a 32-character field
...@@ -97,7 +95,6 @@ class SessionsApiTests(TestCase): ...@@ -97,7 +95,6 @@ class SessionsApiTests(TestCase):
response = self.do_post(self.base_sessions_uri, data) response = self.do_post(self.base_sessions_uri, data)
self.assertEqual(response.status_code, 401) self.assertEqual(response.status_code, 401)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_session_list_post_valid_inactive(self): def test_session_list_post_valid_inactive(self):
local_username = self.test_username + str(randint(11, 99)) local_username = self.test_username + str(randint(11, 99))
local_username = local_username[3:-1] # username is a 32-character field local_username = local_username[3:-1] # username is a 32-character field
...@@ -108,15 +105,13 @@ class SessionsApiTests(TestCase): ...@@ -108,15 +105,13 @@ class SessionsApiTests(TestCase):
user.save() user.save()
data = {'username': local_username, 'password': self.test_password} data = {'username': local_username, 'password': self.test_password}
response = self.do_post(self.base_sessions_uri, data) response = self.do_post(self.base_sessions_uri, data)
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 401)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_session_list_post_invalid_notfound(self): def test_session_list_post_invalid_notfound(self):
data = {'username': 'user_12321452334', 'password': self.test_password} data = {'username': 'user_12321452334', 'password': self.test_password}
response = self.do_post(self.base_sessions_uri, data) response = self.do_post(self.base_sessions_uri, data)
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_session_detail_get(self): def test_session_detail_get(self):
local_username = self.test_username + str(randint(11, 99)) local_username = self.test_username + str(randint(11, 99))
local_username = local_username[3:-1] # username is a 32-character field local_username = local_username[3:-1] # username is a 32-character field
...@@ -134,13 +129,11 @@ class SessionsApiTests(TestCase): ...@@ -134,13 +129,11 @@ class SessionsApiTests(TestCase):
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_session_detail_get_undefined(self): def test_session_detail_get_undefined(self):
test_uri = self.base_sessions_uri + "/123456789" test_uri = self.base_sessions_uri + "/123456789"
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_session_detail_delete(self): def test_session_detail_delete(self):
local_username = self.test_username + str(randint(11, 99)) local_username = self.test_username + str(randint(11, 99))
local_username = local_username[3:-1] # username is a 32-character field local_username = local_username[3:-1] # username is a 32-character field
......
...@@ -46,7 +46,6 @@ class SystemApiTests(TestCase): ...@@ -46,7 +46,6 @@ class SystemApiTests(TestCase):
response = self.client.get(uri, headers=headers) response = self.client.get(uri, headers=headers)
return response return response
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_system_detail_get(self): def test_system_detail_get(self):
""" Ensure the system returns base data about the system """ """ Ensure the system returns base data about the system """
test_uri = self.test_server_prefix + '/system' test_uri = self.test_server_prefix + '/system'
...@@ -62,7 +61,6 @@ class SystemApiTests(TestCase): ...@@ -62,7 +61,6 @@ class SystemApiTests(TestCase):
self.assertIsNotNone(response.data['description']) self.assertIsNotNone(response.data['description'])
self.assertGreater(len(response.data['description']), 0) self.assertGreater(len(response.data['description']), 0)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_system_detail_api_get(self): def test_system_detail_api_get(self):
""" Ensure the system returns base data about the API """ """ Ensure the system returns base data about the API """
test_uri = self.test_server_prefix test_uri = self.test_server_prefix
......
...@@ -10,9 +10,11 @@ ...@@ -10,9 +10,11 @@
from django.conf.urls import include, patterns, url from django.conf.urls import include, patterns, url
urlpatterns = patterns('api_manager.system_views', from api_manager import system_views
url(r'^$', 'api_detail'),
url(r'^system$', 'system_detail'), urlpatterns = patterns('',
url(r'^$', system_views.ApiDetail.as_view()),
url(r'^system$', system_views.SystemDetail.as_view()),
url(r'^users/*', include('api_manager.users_urls')), url(r'^users/*', include('api_manager.users_urls')),
url(r'^groups/*', include('api_manager.groups_urls')), url(r'^groups/*', include('api_manager.groups_urls')),
url(r'^sessions/*', include('api_manager.sessions_urls')), url(r'^sessions/*', include('api_manager.sessions_urls')),
......
""" Users API URI specification """ """ Users API URI specification """
from django.conf.urls import patterns, url from django.conf.urls import patterns, url
urlpatterns = patterns('api_manager.users_views', from rest_framework.urlpatterns import format_suffix_patterns
url(r'/*$^', 'user_list'),
url(r'^(?P<user_id>[0-9]+)$', 'user_detail'), from api_manager import users_views
url(r'^(?P<user_id>[0-9]+)/courses/*$', 'user_courses_list'),
url(r'^(?P<user_id>[0-9]+)/courses/(?P<course_id>[a-zA-Z0-9/_:]+)$', 'user_courses_detail'), urlpatterns = patterns('',
url(r'^(?P<user_id>[0-9]+)/groups/*$', 'user_groups_list'), url(r'/*$^', users_views.UsersList.as_view()),
url(r'^(?P<user_id>[0-9]+)/groups/(?P<group_id>[0-9]+)$', 'user_groups_detail'), 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>[a-zA-Z0-9/_:]+)$', users_views.UsersCoursesDetail.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()),
)
urlpatterns = format_suffix_patterns(urlpatterns)
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