diff options
| author | Tom Christie | 2014-12-17 12:54:31 +0000 |
|---|---|---|
| committer | Tom Christie | 2014-12-17 12:54:31 +0000 |
| commit | 47fe6977077ae33dfe2f8b6d04d81083b9b9f4d7 (patch) | |
| tree | 58488ee2e6533032d942dc65f038bbbc43462a87 /tests | |
| parent | b6ee784240b3c7f6cd62af5b6fe6d1014d7bf6d4 (diff) | |
| parent | 05a6eaec8aebdca2248b9e1069a15769fd85a480 (diff) | |
| download | django-rest-framework-47fe6977077ae33dfe2f8b6d04d81083b9b9f4d7.tar.bz2 | |
Merge pull request #2285 from tomchristie/versioning
Versioning
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/extras/__init__.py | 0 | ||||
| -rw-r--r-- | tests/extras/bad_import.py | 1 | ||||
| -rw-r--r-- | tests/test_settings.py | 27 | ||||
| -rw-r--r-- | tests/test_versioning.py | 223 |
4 files changed, 234 insertions, 17 deletions
diff --git a/tests/extras/__init__.py b/tests/extras/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/tests/extras/__init__.py +++ /dev/null diff --git a/tests/extras/bad_import.py b/tests/extras/bad_import.py deleted file mode 100644 index 68263d94..00000000 --- a/tests/extras/bad_import.py +++ /dev/null @@ -1 +0,0 @@ -raise ValueError diff --git a/tests/test_settings.py b/tests/test_settings.py index e29fc34a..f2ff4ca1 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -1,22 +1,17 @@ -"""Tests for the settings module""" from __future__ import unicode_literals from django.test import TestCase - -from rest_framework.settings import APISettings, DEFAULTS, IMPORT_STRINGS +from rest_framework.settings import APISettings class TestSettings(TestCase): - """Tests relating to the api settings""" - - def test_non_import_errors(self): - """Make sure other errors aren't suppressed.""" - settings = APISettings({'DEFAULT_MODEL_SERIALIZER_CLASS': 'tests.extras.bad_import.ModelSerializer'}, DEFAULTS, IMPORT_STRINGS) - with self.assertRaises(ValueError): - settings.DEFAULT_MODEL_SERIALIZER_CLASS - def test_import_error_message_maintained(self): - """Make sure real import errors are captured and raised sensibly.""" - settings = APISettings({'DEFAULT_MODEL_SERIALIZER_CLASS': 'tests.extras.not_here.ModelSerializer'}, DEFAULTS, IMPORT_STRINGS) - with self.assertRaises(ImportError) as cm: - settings.DEFAULT_MODEL_SERIALIZER_CLASS - self.assertTrue('ImportError' in str(cm.exception)) + """ + Make sure import errors are captured and raised sensibly. + """ + settings = APISettings({ + 'DEFAULT_RENDERER_CLASSES': [ + 'tests.invalid_module.InvalidClassName' + ] + }) + with self.assertRaises(ImportError): + settings.DEFAULT_RENDERER_CLASSES diff --git a/tests/test_versioning.py b/tests/test_versioning.py new file mode 100644 index 00000000..c44f727d --- /dev/null +++ b/tests/test_versioning.py @@ -0,0 +1,223 @@ +from django.conf.urls import include, url +from rest_framework import status, versioning +from rest_framework.decorators import APIView +from rest_framework.response import Response +from rest_framework.reverse import reverse +from rest_framework.test import APIRequestFactory, APITestCase + + +class RequestVersionView(APIView): + def get(self, request, *args, **kwargs): + return Response({'version': request.version}) + + +class ReverseView(APIView): + def get(self, request, *args, **kwargs): + return Response({'url': reverse('another', request=request)}) + + +class RequestInvalidVersionView(APIView): + def determine_version(self, request, *args, **kwargs): + scheme = self.versioning_class() + scheme.allowed_versions = ('v1', 'v2') + return (scheme.determine_version(request, *args, **kwargs), scheme) + + def get(self, request, *args, **kwargs): + return Response({'version': request.version}) + + +factory = APIRequestFactory() + +mock_view = lambda request: None + +included_patterns = [ + url(r'^namespaced/$', mock_view, name='another'), +] + +urlpatterns = [ + url(r'^v1/', include(included_patterns, namespace='v1')), + url(r'^another/$', mock_view, name='another'), + url(r'^(?P<version>[^/]+)/another/$', mock_view, name='another') +] + + +class TestRequestVersion: + def test_unversioned(self): + view = RequestVersionView.as_view() + + request = factory.get('/endpoint/') + response = view(request) + assert response.data == {'version': None} + + def test_query_param_versioning(self): + scheme = versioning.QueryParameterVersioning + view = RequestVersionView.as_view(versioning_class=scheme) + + request = factory.get('/endpoint/?version=1.2.3') + response = view(request) + assert response.data == {'version': '1.2.3'} + + request = factory.get('/endpoint/') + response = view(request) + assert response.data == {'version': None} + + def test_host_name_versioning(self): + scheme = versioning.HostNameVersioning + view = RequestVersionView.as_view(versioning_class=scheme) + + request = factory.get('/endpoint/', HTTP_HOST='v1.example.org') + response = view(request) + assert response.data == {'version': 'v1'} + + request = factory.get('/endpoint/') + response = view(request) + assert response.data == {'version': None} + + def test_accept_header_versioning(self): + scheme = versioning.AcceptHeaderVersioning + view = RequestVersionView.as_view(versioning_class=scheme) + + request = factory.get('/endpoint/', HTTP_ACCEPT='application/json; version=1.2.3') + response = view(request) + assert response.data == {'version': '1.2.3'} + + request = factory.get('/endpoint/', HTTP_ACCEPT='application/json') + response = view(request) + assert response.data == {'version': None} + + def test_url_path_versioning(self): + scheme = versioning.URLPathVersioning + view = RequestVersionView.as_view(versioning_class=scheme) + + request = factory.get('/1.2.3/endpoint/') + response = view(request, version='1.2.3') + assert response.data == {'version': '1.2.3'} + + request = factory.get('/endpoint/') + response = view(request) + assert response.data == {'version': None} + + def test_namespace_versioning(self): + class FakeResolverMatch: + namespace = 'v1' + + scheme = versioning.NamespaceVersioning + view = RequestVersionView.as_view(versioning_class=scheme) + + request = factory.get('/v1/endpoint/') + request.resolver_match = FakeResolverMatch + response = view(request, version='v1') + assert response.data == {'version': 'v1'} + + request = factory.get('/endpoint/') + response = view(request) + assert response.data == {'version': None} + + +class TestURLReversing(APITestCase): + urls = 'tests.test_versioning' + + def test_reverse_unversioned(self): + view = ReverseView.as_view() + + request = factory.get('/endpoint/') + response = view(request) + assert response.data == {'url': 'http://testserver/another/'} + + def test_reverse_query_param_versioning(self): + scheme = versioning.QueryParameterVersioning + view = ReverseView.as_view(versioning_class=scheme) + + request = factory.get('/endpoint/?version=v1') + response = view(request) + assert response.data == {'url': 'http://testserver/another/?version=v1'} + + request = factory.get('/endpoint/') + response = view(request) + assert response.data == {'url': 'http://testserver/another/'} + + def test_reverse_host_name_versioning(self): + scheme = versioning.HostNameVersioning + view = ReverseView.as_view(versioning_class=scheme) + + request = factory.get('/endpoint/', HTTP_HOST='v1.example.org') + response = view(request) + assert response.data == {'url': 'http://v1.example.org/another/'} + + request = factory.get('/endpoint/') + response = view(request) + assert response.data == {'url': 'http://testserver/another/'} + + def test_reverse_url_path_versioning(self): + scheme = versioning.URLPathVersioning + view = ReverseView.as_view(versioning_class=scheme) + + request = factory.get('/v1/endpoint/') + response = view(request, version='v1') + assert response.data == {'url': 'http://testserver/v1/another/'} + + request = factory.get('/endpoint/') + response = view(request) + assert response.data == {'url': 'http://testserver/another/'} + + def test_reverse_namespace_versioning(self): + class FakeResolverMatch: + namespace = 'v1' + + scheme = versioning.NamespaceVersioning + view = ReverseView.as_view(versioning_class=scheme) + + request = factory.get('/v1/endpoint/') + request.resolver_match = FakeResolverMatch + response = view(request, version='v1') + assert response.data == {'url': 'http://testserver/v1/namespaced/'} + + request = factory.get('/endpoint/') + response = view(request) + assert response.data == {'url': 'http://testserver/another/'} + + +class TestInvalidVersion: + def test_invalid_query_param_versioning(self): + scheme = versioning.QueryParameterVersioning + view = RequestInvalidVersionView.as_view(versioning_class=scheme) + + request = factory.get('/endpoint/?version=v3') + response = view(request) + assert response.status_code == status.HTTP_404_NOT_FOUND + + def test_invalid_host_name_versioning(self): + scheme = versioning.HostNameVersioning + view = RequestInvalidVersionView.as_view(versioning_class=scheme) + + request = factory.get('/endpoint/', HTTP_HOST='v3.example.org') + response = view(request) + assert response.status_code == status.HTTP_404_NOT_FOUND + + def test_invalid_accept_header_versioning(self): + scheme = versioning.AcceptHeaderVersioning + view = RequestInvalidVersionView.as_view(versioning_class=scheme) + + request = factory.get('/endpoint/', HTTP_ACCEPT='application/json; version=v3') + response = view(request) + assert response.status_code == status.HTTP_406_NOT_ACCEPTABLE + + def test_invalid_url_path_versioning(self): + scheme = versioning.URLPathVersioning + view = RequestInvalidVersionView.as_view(versioning_class=scheme) + + request = factory.get('/v3/endpoint/') + response = view(request, version='v3') + assert response.status_code == status.HTTP_404_NOT_FOUND + + def test_invalid_namespace_versioning(self): + class FakeResolverMatch: + namespace = 'v3' + + scheme = versioning.NamespaceVersioning + view = RequestInvalidVersionView.as_view(versioning_class=scheme) + + request = factory.get('/v3/endpoint/') + request.resolver_match = FakeResolverMatch + response = view(request, version='v3') + assert response.status_code == status.HTTP_404_NOT_FOUND |
