diff --git a/rest_framework/compat.py b/rest_framework/compat.py index e435618a2..7a0aea3db 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -58,6 +58,23 @@ def distinct(queryset, base): return queryset.distinct() +def get_names_and_managers(options): + if django.VERSION >= (1, 10): + # Django 1.10 onwards provides a `.managers` property on the Options. + return [ + (manager.name, manager) + for manager + in options.managers + ] + # For Django 1.8 and 1.9, use the three-tuple information provided + # by .concrete_managers and .abstract_managers + return [ + (manager_info[1], manager_info[2]) + for manager_info + in (options.concrete_managers + options.abstract_managers) + ] + + # contrib.postgres only supported from 1.8 onwards. try: from django.contrib.postgres import fields as postgres_fields diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py index 63e0d836f..264f7ac3b 100644 --- a/rest_framework/renderers.py +++ b/rest_framework/renderers.py @@ -635,6 +635,7 @@ class BrowsableAPIRenderer(BaseRenderer): 'view': view, 'request': request, 'response': response, + 'user': request.user, 'description': self.get_description(view, response.status_code), 'name': self.get_name(view), 'version': VERSION, diff --git a/rest_framework/urlpatterns.py b/rest_framework/urlpatterns.py index 5347b3bc1..7a02bb0f0 100644 --- a/rest_framework/urlpatterns.py +++ b/rest_framework/urlpatterns.py @@ -24,7 +24,7 @@ def apply_suffix_patterns(urlpatterns, suffix_pattern, suffix_required): else: # Regular URL pattern regex = urlpattern.regex.pattern.rstrip('$').rstrip('/') + suffix_pattern - view = urlpattern._callback or urlpattern._callback_str + view = urlpattern.callback kwargs = urlpattern.default_args name = urlpattern.name # Add in both the existing and the new urlpattern diff --git a/rest_framework/utils/representation.py b/rest_framework/utils/representation.py index 49f829c10..32e6d246a 100644 --- a/rest_framework/utils/representation.py +++ b/rest_framework/utils/representation.py @@ -10,15 +10,15 @@ from django.db import models from django.utils.encoding import force_text from django.utils.functional import Promise -from rest_framework.compat import unicode_repr +from rest_framework.compat import get_names_and_managers, unicode_repr def manager_repr(value): model = value.model opts = model._meta - for _, name, manager in opts.concrete_managers + opts.abstract_managers: - if manager == value: - return '%s.%s.all()' % (model._meta.object_name, name) + for manager_name, manager_instance in get_names_and_managers(opts): + if manager_instance == value: + return '%s.%s.all()' % (model._meta.object_name, manager_name) return repr(value) diff --git a/runtests.py b/runtests.py index a7e8b45a9..1627e33b2 100755 --- a/runtests.py +++ b/runtests.py @@ -14,7 +14,7 @@ PYTEST_ARGS = { FLAKE8_ARGS = ['rest_framework', 'tests', '--ignore=E501'] -ISORT_ARGS = ['--recursive', '--check-only', 'rest_framework', 'tests'] +ISORT_ARGS = ['--recursive', '--check-only', '-p', 'tests', 'rest_framework', 'tests'] sys.path.append(os.path.dirname(__file__)) diff --git a/tests/browsable_api/test_browsable_api.py b/tests/browsable_api/test_browsable_api.py index 153b4c189..3d49c353b 100644 --- a/tests/browsable_api/test_browsable_api.py +++ b/tests/browsable_api/test_browsable_api.py @@ -1,16 +1,14 @@ from __future__ import unicode_literals from django.contrib.auth.models import User -from django.test import TestCase +from django.test import TestCase, override_settings from rest_framework.test import APIClient +@override_settings(ROOT_URLCONF='tests.browsable_api.auth_urls') class DropdownWithAuthTests(TestCase): """Tests correct dropdown behaviour with Auth views enabled.""" - - urls = 'tests.browsable_api.auth_urls' - def setUp(self): self.client = APIClient(enforce_csrf_checks=True) self.username = 'john' @@ -40,11 +38,9 @@ class DropdownWithAuthTests(TestCase): self.assertContains(response, '>Log in<') +@override_settings(ROOT_URLCONF='tests.browsable_api.no_auth_urls') class NoDropdownWithoutAuthTests(TestCase): """Tests correct dropdown behaviour with Auth views NOT enabled.""" - - urls = 'tests.browsable_api.no_auth_urls' - def setUp(self): self.client = APIClient(enforce_csrf_checks=True) self.username = 'john' diff --git a/tests/browsable_api/views.py b/tests/browsable_api/views.py index cd020cd32..03758f10b 100644 --- a/tests/browsable_api/views.py +++ b/tests/browsable_api/views.py @@ -6,9 +6,8 @@ from rest_framework.views import APIView class MockView(APIView): - authentication_classes = (authentication.SessionAuthentication,) - renderer_classes = (renderers.BrowsableAPIRenderer,) + renderer_classes = (renderers.BrowsableAPIRenderer, renderers.JSONRenderer) def get(self, request): return Response({'a': 1, 'b': 2, 'c': 3}) diff --git a/tests/conftest.py b/tests/conftest.py index 03b4e3285..a5123b9d8 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,18 +3,24 @@ def pytest_configure(): settings.configure( DEBUG_PROPAGATE_EXCEPTIONS=True, - DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', - 'NAME': ':memory:'}}, + DATABASES={ + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': ':memory:' + } + }, SITE_ID=1, SECRET_KEY='not very secret in tests', USE_I18N=True, USE_L10N=True, STATIC_URL='/static/', ROOT_URLCONF='tests.urls', - TEMPLATE_LOADERS=( - 'django.template.loaders.filesystem.Loader', - 'django.template.loaders.app_directories.Loader', - ), + TEMPLATES=[ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'APP_DIRS': True, + }, + ], MIDDLEWARE_CLASSES=( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', @@ -27,7 +33,6 @@ def pytest_configure(): 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.staticfiles', - 'rest_framework', 'rest_framework.authtoken', 'tests', diff --git a/tests/models.py b/tests/models.py index cde5f8cda..85143566e 100644 --- a/tests/models.py +++ b/tests/models.py @@ -27,9 +27,6 @@ class BasicModel(RESTFrameworkModel): class BaseFilterableItem(RESTFrameworkModel): text = models.CharField(max_length=100) - class Meta: - abstract = True - class FilterableItem(BaseFilterableItem): decimal = models.DecimalField(max_digits=4, decimal_places=2) diff --git a/tests/test_authentication.py b/tests/test_authentication.py index e7d2dd421..b6377f6e8 100644 --- a/tests/test_authentication.py +++ b/tests/test_authentication.py @@ -8,7 +8,7 @@ from django.conf.urls import include, url from django.contrib.auth.models import User from django.db import models from django.http import HttpResponse -from django.test import TestCase +from django.test import TestCase, override_settings from django.utils import six from rest_framework import ( @@ -19,6 +19,7 @@ from rest_framework.authentication import ( TokenAuthentication ) from rest_framework.authtoken.models import Token +from rest_framework.authtoken.views import obtain_auth_token from rest_framework.response import Response from rest_framework.test import APIClient, APIRequestFactory from rest_framework.views import APIView @@ -75,15 +76,14 @@ urlpatterns = [ authentication_classes=[CustomKeywordTokenAuthentication] ) ), - url(r'^auth-token/$', 'rest_framework.authtoken.views.obtain_auth_token'), + url(r'^auth-token/$', obtain_auth_token), url(r'^auth/', include('rest_framework.urls', namespace='rest_framework')), ] +@override_settings(ROOT_URLCONF='tests.test_authentication') class BasicAuthTests(TestCase): """Basic authentication""" - urls = 'tests.test_authentication' - def setUp(self): self.csrf_client = APIClient(enforce_csrf_checks=True) self.username = 'john' @@ -151,10 +151,9 @@ class BasicAuthTests(TestCase): self.assertEqual(response['WWW-Authenticate'], 'Basic realm="api"') +@override_settings(ROOT_URLCONF='tests.test_authentication') class SessionAuthTests(TestCase): """User session authentication""" - urls = 'tests.test_authentication' - def setUp(self): self.csrf_client = APIClient(enforce_csrf_checks=True) self.non_csrf_client = APIClient(enforce_csrf_checks=False) @@ -223,7 +222,6 @@ class SessionAuthTests(TestCase): class BaseTokenAuthTests(object): """Token authentication""" - urls = 'tests.test_authentication' model = None path = None header_prefix = 'Token ' @@ -311,6 +309,7 @@ class BaseTokenAuthTests(object): self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) +@override_settings(ROOT_URLCONF='tests.test_authentication') class TokenAuthTests(BaseTokenAuthTests, TestCase): model = Token path = '/token/' @@ -367,11 +366,13 @@ class TokenAuthTests(BaseTokenAuthTests, TestCase): self.assertEqual(response.data['token'], self.key) +@override_settings(ROOT_URLCONF='tests.test_authentication') class CustomTokenAuthTests(BaseTokenAuthTests, TestCase): model = CustomToken path = '/customtoken/' +@override_settings(ROOT_URLCONF='tests.test_authentication') class CustomKeywordTokenAuthTests(BaseTokenAuthTests, TestCase): model = Token path = '/customkeywordtoken/' diff --git a/tests/test_filters.py b/tests/test_filters.py index 8493c96af..fd71764f7 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -274,12 +274,11 @@ class IntegrationTestFiltering(CommonFilteringTestCase): self.assertEqual(response.status_code, status.HTTP_200_OK) +@override_settings(ROOT_URLCONF='tests.test_filters') class IntegrationTestDetailFiltering(CommonFilteringTestCase): """ Integration tests for filtered detail views. """ - urls = 'tests.test_filters' - def _get_url(self, item): return reverse('detail-view', kwargs=dict(pk=item.pk)) diff --git a/tests/test_htmlrenderer.py b/tests/test_htmlrenderer.py index 01ef46d35..3dfe6ef74 100644 --- a/tests/test_htmlrenderer.py +++ b/tests/test_htmlrenderer.py @@ -5,7 +5,7 @@ from django.conf.urls import url from django.core.exceptions import PermissionDenied from django.http import Http404 from django.template import Template, TemplateDoesNotExist -from django.test import TestCase +from django.test import TestCase, override_settings from django.utils import six from rest_framework import status @@ -43,9 +43,8 @@ urlpatterns = [ ] +@override_settings(ROOT_URLCONF='tests.test_htmlrenderer') class TemplateHTMLRendererTests(TestCase): - urls = 'tests.test_htmlrenderer' - def setUp(self): """ Monkeypatch get_template @@ -89,9 +88,8 @@ class TemplateHTMLRendererTests(TestCase): self.assertEqual(response['Content-Type'], 'text/html; charset=utf-8') +@override_settings(ROOT_URLCONF='tests.test_htmlrenderer') class TemplateHTMLRendererExceptionTests(TestCase): - urls = 'tests.test_htmlrenderer' - def setUp(self): """ Monkeypatch get_template diff --git a/tests/test_middleware.py b/tests/test_middleware.py index 49124da61..a9f620c0e 100644 --- a/tests/test_middleware.py +++ b/tests/test_middleware.py @@ -1,6 +1,6 @@ - from django.conf.urls import url from django.contrib.auth.models import User +from django.test import override_settings from rest_framework.authentication import TokenAuthentication from rest_framework.authtoken.models import Token @@ -20,10 +20,8 @@ class MyMiddleware(object): return response +@override_settings(ROOT_URLCONF='tests.test_middleware') class TestMiddleware(APITestCase): - - urls = 'tests.test_middleware' - def test_middleware_can_access_user_when_processing_response(self): user = User.objects.create_user('john', 'john@example.com', 'password') key = 'abcd1234' diff --git a/tests/test_relations_hyperlink.py b/tests/test_relations_hyperlink.py index c0642eda2..05d8689a3 100644 --- a/tests/test_relations_hyperlink.py +++ b/tests/test_relations_hyperlink.py @@ -1,7 +1,7 @@ from __future__ import unicode_literals from django.conf.urls import url -from django.test import TestCase +from django.test import TestCase, override_settings from rest_framework import serializers from rest_framework.test import APIRequestFactory @@ -71,10 +71,8 @@ class NullableOneToOneTargetSerializer(serializers.HyperlinkedModelSerializer): # TODO: Add test that .data cannot be accessed prior to .is_valid - +@override_settings(ROOT_URLCONF='tests.test_relations_hyperlink') class HyperlinkedManyToManyTests(TestCase): - urls = 'tests.test_relations_hyperlink' - def setUp(self): for idx in range(1, 4): target = ManyToManyTarget(name='target-%d' % idx) @@ -188,9 +186,8 @@ class HyperlinkedManyToManyTests(TestCase): self.assertEqual(serializer.data, expected) +@override_settings(ROOT_URLCONF='tests.test_relations_hyperlink') class HyperlinkedForeignKeyTests(TestCase): - urls = 'tests.test_relations_hyperlink' - def setUp(self): target = ForeignKeyTarget(name='target-1') target.save() @@ -318,9 +315,8 @@ class HyperlinkedForeignKeyTests(TestCase): self.assertEqual(serializer.errors, {'target': ['This field may not be null.']}) +@override_settings(ROOT_URLCONF='tests.test_relations_hyperlink') class HyperlinkedNullableForeignKeyTests(TestCase): - urls = 'tests.test_relations_hyperlink' - def setUp(self): target = ForeignKeyTarget(name='target-1') target.save() @@ -425,9 +421,8 @@ class HyperlinkedNullableForeignKeyTests(TestCase): self.assertEqual(serializer.data, expected) +@override_settings(ROOT_URLCONF='tests.test_relations_hyperlink') class HyperlinkedNullableOneToOneTests(TestCase): - urls = 'tests.test_relations_hyperlink' - def setUp(self): target = OneToOneTarget(name='target-1') target.save() diff --git a/tests/test_renderers.py b/tests/test_renderers.py index de89e50aa..5793fc734 100644 --- a/tests/test_renderers.py +++ b/tests/test_renderers.py @@ -8,7 +8,7 @@ from collections import MutableMapping, OrderedDict from django.conf.urls import include, url from django.core.cache import cache from django.db import models -from django.test import TestCase +from django.test import TestCase, override_settings from django.utils import six from django.utils.safestring import SafeText from django.utils.translation import ugettext_lazy as _ @@ -148,13 +148,11 @@ class DocumentingRendererTests(TestCase): self.assertContains(response, '>PATCH<') +@override_settings(ROOT_URLCONF='tests.test_renderers') class RendererEndToEndTests(TestCase): """ End-to-end testing of renderers using an RendererMixin on a generic view. """ - - urls = 'tests.test_renderers' - def test_default_renderer_serializes_content(self): """If the Accept header is not set the default renderer should serialize the response.""" resp = self.client.get('/') @@ -397,13 +395,11 @@ class AsciiJSONRendererTests(TestCase): # Tests for caching issue, #346 +@override_settings(ROOT_URLCONF='tests.test_renderers') class CacheRenderTest(TestCase): """ Tests specific to caching responses """ - - urls = 'tests.test_renderers' - def test_head_caching(self): """ Test caching of HEAD requests diff --git a/tests/test_request.py b/tests/test_request.py index 7a0575789..dee636d76 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -7,7 +7,7 @@ from django.conf.urls import url from django.contrib.auth import authenticate, login, logout from django.contrib.auth.models import User from django.contrib.sessions.middleware import SessionMiddleware -from django.test import TestCase +from django.test import TestCase, override_settings from django.utils import six from rest_framework import status @@ -113,9 +113,8 @@ urlpatterns = [ ] +@override_settings(ROOT_URLCONF='tests.test_request') class TestContentParsingWithAuthentication(TestCase): - urls = 'tests.test_request' - def setUp(self): self.csrf_client = APIClient(enforce_csrf_checks=True) self.username = 'john' diff --git a/tests/test_response.py b/tests/test_response.py index df2d7b4ec..c8ae6475a 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -1,7 +1,7 @@ from __future__ import unicode_literals from django.conf.urls import include, url -from django.test import TestCase +from django.test import TestCase, override_settings from django.utils import six from rest_framework import generics, routers, serializers, status, viewsets @@ -131,13 +131,11 @@ urlpatterns = [ # TODO: Clean tests bellow - remove duplicates with above, better unit testing, ... +@override_settings(ROOT_URLCONF='tests.test_response') class RendererIntegrationTests(TestCase): """ End-to-end testing of renderers using an ResponseMixin on a generic view. """ - - urls = 'tests.test_response' - def test_default_renderer_serializes_content(self): """If the Accept header is not set the default renderer should serialize the response.""" resp = self.client.get('/') @@ -201,9 +199,8 @@ class RendererIntegrationTests(TestCase): self.assertEqual(resp.status_code, DUMMYSTATUS) +@override_settings(ROOT_URLCONF='tests.test_response') class UnsupportedMediaTypeTests(TestCase): - urls = 'tests.test_response' - def test_should_allow_posting_json(self): response = self.client.post('/json', data='{"test": 123}', content_type='application/json') @@ -220,12 +217,11 @@ class UnsupportedMediaTypeTests(TestCase): self.assertEqual(response.status_code, 415) +@override_settings(ROOT_URLCONF='tests.test_response') class Issue122Tests(TestCase): """ Tests that covers #122. """ - urls = 'tests.test_response' - def test_only_html_renderer(self): """ Test if no infinite recursion occurs. @@ -239,13 +235,11 @@ class Issue122Tests(TestCase): self.client.get('/html1') +@override_settings(ROOT_URLCONF='tests.test_response') class Issue467Tests(TestCase): """ Tests for #467 """ - - urls = 'tests.test_response' - def test_form_has_label_and_help_text(self): resp = self.client.get('/html_new_model') self.assertEqual(resp['Content-Type'], 'text/html; charset=utf-8') @@ -253,13 +247,11 @@ class Issue467Tests(TestCase): # self.assertContains(resp, 'Text description.') +@override_settings(ROOT_URLCONF='tests.test_response') class Issue807Tests(TestCase): """ Covers #807 """ - - urls = 'tests.test_response' - def test_does_not_append_charset_by_default(self): """ Renderers don't include a charset unless set explicitly. diff --git a/tests/test_reverse.py b/tests/test_reverse.py index c5486e5db..03d31f1f9 100644 --- a/tests/test_reverse.py +++ b/tests/test_reverse.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals from django.conf.urls import url from django.core.urlresolvers import NoReverseMatch -from django.test import TestCase +from django.test import TestCase, override_settings from rest_framework.reverse import reverse from rest_framework.test import APIRequestFactory @@ -30,12 +30,11 @@ class MockVersioningScheme(object): return 'http://scheme-reversed/view' +@override_settings(ROOT_URLCONF='tests.test_reverse') class ReverseTests(TestCase): """ Tests for fully qualified URLs when using `reverse`. """ - urls = 'tests.test_reverse' - def test_reversed_urls_are_fully_qualified(self): request = factory.get('/view') url = reverse('view', request=request) diff --git a/tests/test_routers.py b/tests/test_routers.py index ae2639bf2..acab660d8 100644 --- a/tests/test_routers.py +++ b/tests/test_routers.py @@ -5,7 +5,7 @@ from collections import namedtuple from django.conf.urls import include, url from django.core.exceptions import ImproperlyConfigured from django.db import models -from django.test import TestCase +from django.test import TestCase, override_settings from rest_framework import permissions, serializers, viewsets from rest_framework.decorators import detail_route, list_route @@ -113,9 +113,8 @@ class TestSimpleRouter(TestCase): self.assertEqual(route.mapping[method], endpoint) +@override_settings(ROOT_URLCONF='tests.test_routers') class TestRootView(TestCase): - urls = 'tests.test_routers' - def test_retrieve_namespaced_root(self): response = self.client.get('/namespaced/') self.assertEqual( @@ -135,12 +134,11 @@ class TestRootView(TestCase): ) +@override_settings(ROOT_URLCONF='tests.test_routers') class TestCustomLookupFields(TestCase): """ Ensure that custom lookup fields are correctly routed. """ - urls = 'tests.test_routers' - def setUp(self): RouterTestModel.objects.create(uuid='123', text='foo bar') @@ -191,14 +189,13 @@ class TestLookupValueRegex(TestCase): self.assertEqual(expected[idx], self.urls[idx].regex.pattern) +@override_settings(ROOT_URLCONF='tests.test_routers') class TestLookupUrlKwargs(TestCase): """ Ensure the router honors lookup_url_kwarg. Setup a deep lookup_field, but map it to a simple URL kwarg. """ - urls = 'tests.test_routers' - def setUp(self): RouterTestModel.objects.create(uuid='123', text='foo bar') diff --git a/tests/test_testing.py b/tests/test_testing.py index e0bf759a4..e6c8de22d 100644 --- a/tests/test_testing.py +++ b/tests/test_testing.py @@ -6,7 +6,7 @@ from io import BytesIO from django.conf.urls import url from django.contrib.auth.models import User from django.shortcuts import redirect -from django.test import TestCase +from django.test import TestCase, override_settings from rest_framework.decorators import api_view from rest_framework.response import Response @@ -44,9 +44,8 @@ urlpatterns = [ ] +@override_settings(ROOT_URLCONF='tests.test_testing') class TestAPITestClient(TestCase): - urls = 'tests.test_testing' - def setUp(self): self.client = APIClient() diff --git a/tests/test_utils.py b/tests/test_utils.py index ca3d43061..cd6a6af9a 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals from django.conf.urls import url from django.core.exceptions import ImproperlyConfigured -from django.test import TestCase +from django.test import TestCase, override_settings from django.utils import six import rest_framework.utils.model_meta @@ -47,12 +47,11 @@ urlpatterns = [ ] +@override_settings(ROOT_URLCONF='tests.test_utils') class BreadcrumbTests(TestCase): """ Tests the breadcrumb functionality used by the HTML renderer. """ - urls = 'tests.test_utils' - def test_root_breadcrumbs(self): url = '/' self.assertEqual( diff --git a/tests/test_versioning.py b/tests/test_versioning.py index 4029e0e43..d4d8cfccb 100644 --- a/tests/test_versioning.py +++ b/tests/test_versioning.py @@ -1,5 +1,6 @@ import pytest from django.conf.urls import include, url +from django.test import override_settings from rest_framework import serializers, status, versioning from rest_framework.decorators import APIView @@ -9,7 +10,28 @@ from rest_framework.reverse import reverse from rest_framework.test import APIRequestFactory, APITestCase from rest_framework.versioning import NamespaceVersioning -from .utils import UsingURLPatterns + +@override_settings(ROOT_URLCONF='tests.test_versioning') +class URLPatternsTestCase(APITestCase): + """ + Isolates URL patterns used during testing on the test class itself. + For example: + + class MyTestCase(URLPatternsTestCase): + urlpatterns = [ + ... + ] + + def test_something(self): + ... + """ + def setUp(self): + global urlpatterns + urlpatterns = self.urlpatterns + + def tearDown(self): + global urlpatterns + urlpatterns = [] class RequestVersionView(APIView): @@ -120,7 +142,7 @@ class TestRequestVersion: assert response.data == {'version': None} -class TestURLReversing(UsingURLPatterns, APITestCase): +class TestURLReversing(URLPatternsTestCase): included = [ url(r'^namespaced/$', dummy_view, name='another'), url(r'^example/(?P\d+)/$', dummy_pk_view, name='example-detail') @@ -238,7 +260,7 @@ class TestInvalidVersion: assert response.status_code == status.HTTP_404_NOT_FOUND -class TestHyperlinkedRelatedField(UsingURLPatterns, APITestCase): +class TestHyperlinkedRelatedField(URLPatternsTestCase): included = [ url(r'^namespaced/(?P\d+)/$', dummy_pk_view, name='namespaced'), ] @@ -270,7 +292,7 @@ class TestHyperlinkedRelatedField(UsingURLPatterns, APITestCase): self.field.to_internal_value('/v2/namespaced/3/') -class TestNamespaceVersioningHyperlinkedRelatedFieldScheme(UsingURLPatterns, APITestCase): +class TestNamespaceVersioningHyperlinkedRelatedFieldScheme(URLPatternsTestCase): included = [ url(r'^namespaced/(?P\d+)/$', dummy_pk_view, name='namespaced'), ] diff --git a/tests/utils.py b/tests/utils.py index b90349967..5b2d75864 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -2,30 +2,6 @@ from django.core.exceptions import ObjectDoesNotExist from django.core.urlresolvers import NoReverseMatch -class UsingURLPatterns(object): - """ - Isolates URL patterns used during testing on the test class itself. - For example: - - class MyTestCase(UsingURLPatterns, TestCase): - urlpatterns = [ - ... - ] - - def test_something(self): - ... - """ - urls = __name__ - - def setUp(self): - global urlpatterns - urlpatterns = self.urlpatterns - - def tearDown(self): - global urlpatterns - urlpatterns = [] - - class MockObject(object): def __init__(self, **kwargs): self._kwargs = kwargs diff --git a/tox.ini b/tox.ini index 15442991e..ba500a2a0 100644 --- a/tox.ini +++ b/tox.ini @@ -5,8 +5,8 @@ addopts=--tb=short envlist = py27-{lint,docs}, {py27,py32,py33,py34,py35}-django18, - {py27,py34,py35}-django{19} - {py27,py34,py35}-django{110} + {py27,py34,py35}-django19, + {py27,py34,py35}-django110 [testenv] commands = ./runtests.py --fast {posargs} --coverage -rw @@ -19,6 +19,12 @@ deps = django110: Django==1.10a1 -rrequirements/requirements-testing.txt -rrequirements/requirements-optionals.txt +basepython = + py35: python3.5 + py34: python3.4 + py33: python3.3 + py32: python3.2 + py27: python2.7 [testenv:py27-lint] commands = ./runtests.py --lintonly