From 664c038f2c5b56d1ce929243d29cd4e11ea5f9ea Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Mon, 16 Feb 2015 15:54:00 -0500 Subject: Moved contrib.contenttypes tests out of contrib. --- django/contrib/contenttypes/tests/__init__.py | 0 django/contrib/contenttypes/tests/models.py | 43 ---- django/contrib/contenttypes/tests/tests.py | 290 -------------------------- tests/contenttypes_tests/models.py | 41 ++++ tests/contenttypes_tests/test_models.py | 290 ++++++++++++++++++++++++++ tests/runtests.py | 2 +- 6 files changed, 332 insertions(+), 334 deletions(-) delete mode 100644 django/contrib/contenttypes/tests/__init__.py delete mode 100644 django/contrib/contenttypes/tests/models.py delete mode 100644 django/contrib/contenttypes/tests/tests.py create mode 100644 tests/contenttypes_tests/test_models.py diff --git a/django/contrib/contenttypes/tests/__init__.py b/django/contrib/contenttypes/tests/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/django/contrib/contenttypes/tests/models.py b/django/contrib/contenttypes/tests/models.py deleted file mode 100644 index a173f091bd..0000000000 --- a/django/contrib/contenttypes/tests/models.py +++ /dev/null @@ -1,43 +0,0 @@ -from django.db import models -from django.utils.encoding import python_2_unicode_compatible -from django.utils.http import urlquote - - -class ConcreteModel(models.Model): - name = models.CharField(max_length=10) - - -class ProxyModel(ConcreteModel): - class Meta: - proxy = True - - -@python_2_unicode_compatible -class FooWithoutUrl(models.Model): - """ - Fake model not defining ``get_absolute_url`` for - ContentTypesTests.test_shortcut_view_without_get_absolute_url() - """ - name = models.CharField(max_length=30, unique=True) - - def __str__(self): - return self.name - - -class FooWithUrl(FooWithoutUrl): - """ - Fake model defining ``get_absolute_url`` for - ContentTypesTests.test_shortcut_view(). - """ - - def get_absolute_url(self): - return "/users/%s/" % urlquote(self.name) - - -class FooWithBrokenAbsoluteUrl(FooWithoutUrl): - """ - Fake model defining a ``get_absolute_url`` method containing an error - """ - - def get_absolute_url(self): - return "/users/%s/" % self.unknown_field diff --git a/django/contrib/contenttypes/tests/tests.py b/django/contrib/contenttypes/tests/tests.py deleted file mode 100644 index eb436b6a64..0000000000 --- a/django/contrib/contenttypes/tests/tests.py +++ /dev/null @@ -1,290 +0,0 @@ -from __future__ import unicode_literals - -import warnings - -from django.contrib.contenttypes.models import ContentType -from django.contrib.contenttypes.views import shortcut -from django.contrib.sites.shortcuts import get_current_site -from django.db.utils import IntegrityError, OperationalError, ProgrammingError -from django.http import Http404, HttpRequest -from django.test import TestCase, mock, override_settings -from django.utils import six - -from .models import ( - ConcreteModel, FooWithBrokenAbsoluteUrl, FooWithoutUrl, FooWithUrl, - ProxyModel, -) - - -class ContentTypesTests(TestCase): - - def setUp(self): - ContentType.objects.clear_cache() - - def tearDown(self): - ContentType.objects.clear_cache() - - def test_lookup_cache(self): - """ - Make sure that the content type cache (see ContentTypeManager) - works correctly. Lookups for a particular content type -- by model, ID - or natural key -- should hit the database only on the first lookup. - """ - - # At this point, a lookup for a ContentType should hit the DB - with self.assertNumQueries(1): - ContentType.objects.get_for_model(ContentType) - - # A second hit, though, won't hit the DB, nor will a lookup by ID - # or natural key - with self.assertNumQueries(0): - ct = ContentType.objects.get_for_model(ContentType) - with self.assertNumQueries(0): - ContentType.objects.get_for_id(ct.id) - with self.assertNumQueries(0): - ContentType.objects.get_by_natural_key('contenttypes', - 'contenttype') - - # Once we clear the cache, another lookup will again hit the DB - ContentType.objects.clear_cache() - with self.assertNumQueries(1): - ContentType.objects.get_for_model(ContentType) - - # The same should happen with a lookup by natural key - ContentType.objects.clear_cache() - with self.assertNumQueries(1): - ContentType.objects.get_by_natural_key('contenttypes', - 'contenttype') - # And a second hit shouldn't hit the DB - with self.assertNumQueries(0): - ContentType.objects.get_by_natural_key('contenttypes', - 'contenttype') - - def test_get_for_models_empty_cache(self): - # Empty cache. - with self.assertNumQueries(1): - cts = ContentType.objects.get_for_models(ContentType, FooWithUrl) - self.assertEqual(cts, { - ContentType: ContentType.objects.get_for_model(ContentType), - FooWithUrl: ContentType.objects.get_for_model(FooWithUrl), - }) - - def test_get_for_models_partial_cache(self): - # Partial cache - ContentType.objects.get_for_model(ContentType) - with self.assertNumQueries(1): - cts = ContentType.objects.get_for_models(ContentType, FooWithUrl) - self.assertEqual(cts, { - ContentType: ContentType.objects.get_for_model(ContentType), - FooWithUrl: ContentType.objects.get_for_model(FooWithUrl), - }) - - def test_get_for_models_full_cache(self): - # Full cache - ContentType.objects.get_for_model(ContentType) - ContentType.objects.get_for_model(FooWithUrl) - with self.assertNumQueries(0): - cts = ContentType.objects.get_for_models(ContentType, FooWithUrl) - self.assertEqual(cts, { - ContentType: ContentType.objects.get_for_model(ContentType), - FooWithUrl: ContentType.objects.get_for_model(FooWithUrl), - }) - - def test_get_for_concrete_model(self): - """ - Make sure the `for_concrete_model` kwarg correctly works - with concrete, proxy and deferred models - """ - concrete_model_ct = ContentType.objects.get_for_model(ConcreteModel) - - self.assertEqual(concrete_model_ct, - ContentType.objects.get_for_model(ProxyModel)) - - self.assertEqual(concrete_model_ct, - ContentType.objects.get_for_model(ConcreteModel, - for_concrete_model=False)) - - proxy_model_ct = ContentType.objects.get_for_model(ProxyModel, - for_concrete_model=False) - - self.assertNotEqual(concrete_model_ct, proxy_model_ct) - - # Make sure deferred model are correctly handled - ConcreteModel.objects.create(name="Concrete") - DeferredConcreteModel = ConcreteModel.objects.only('pk').get().__class__ - DeferredProxyModel = ProxyModel.objects.only('pk').get().__class__ - - self.assertEqual(concrete_model_ct, - ContentType.objects.get_for_model(DeferredConcreteModel)) - - self.assertEqual(concrete_model_ct, - ContentType.objects.get_for_model(DeferredConcreteModel, - for_concrete_model=False)) - - self.assertEqual(concrete_model_ct, - ContentType.objects.get_for_model(DeferredProxyModel)) - - self.assertEqual(proxy_model_ct, - ContentType.objects.get_for_model(DeferredProxyModel, - for_concrete_model=False)) - - def test_get_for_concrete_models(self): - """ - Make sure the `for_concrete_models` kwarg correctly works - with concrete, proxy and deferred models. - """ - concrete_model_ct = ContentType.objects.get_for_model(ConcreteModel) - - cts = ContentType.objects.get_for_models(ConcreteModel, ProxyModel) - self.assertEqual(cts, { - ConcreteModel: concrete_model_ct, - ProxyModel: concrete_model_ct, - }) - - proxy_model_ct = ContentType.objects.get_for_model(ProxyModel, - for_concrete_model=False) - cts = ContentType.objects.get_for_models(ConcreteModel, ProxyModel, - for_concrete_models=False) - self.assertEqual(cts, { - ConcreteModel: concrete_model_ct, - ProxyModel: proxy_model_ct, - }) - - # Make sure deferred model are correctly handled - ConcreteModel.objects.create(name="Concrete") - DeferredConcreteModel = ConcreteModel.objects.only('pk').get().__class__ - DeferredProxyModel = ProxyModel.objects.only('pk').get().__class__ - - cts = ContentType.objects.get_for_models(DeferredConcreteModel, - DeferredProxyModel) - self.assertEqual(cts, { - DeferredConcreteModel: concrete_model_ct, - DeferredProxyModel: concrete_model_ct, - }) - - cts = ContentType.objects.get_for_models(DeferredConcreteModel, - DeferredProxyModel, - for_concrete_models=False) - self.assertEqual(cts, { - DeferredConcreteModel: concrete_model_ct, - DeferredProxyModel: proxy_model_ct, - }) - - @override_settings(ALLOWED_HOSTS=['example.com']) - def test_shortcut_view(self): - """ - Check that the shortcut view (used for the admin "view on site" - functionality) returns a complete URL regardless of whether the sites - framework is installed - """ - - request = HttpRequest() - request.META = { - "SERVER_NAME": "Example.com", - "SERVER_PORT": "80", - } - user_ct = ContentType.objects.get_for_model(FooWithUrl) - obj = FooWithUrl.objects.create(name="john") - - with self.modify_settings(INSTALLED_APPS={'append': 'django.contrib.sites'}): - response = shortcut(request, user_ct.id, obj.id) - self.assertEqual("http://%s/users/john/" % get_current_site(request).domain, - response._headers.get("location")[1]) - - with self.modify_settings(INSTALLED_APPS={'remove': 'django.contrib.sites'}): - response = shortcut(request, user_ct.id, obj.id) - self.assertEqual("http://Example.com/users/john/", - response._headers.get("location")[1]) - - def test_shortcut_view_without_get_absolute_url(self): - """ - Check that the shortcut view (used for the admin "view on site" - functionality) returns 404 when get_absolute_url is not defined. - """ - - request = HttpRequest() - request.META = { - "SERVER_NAME": "Example.com", - "SERVER_PORT": "80", - } - user_ct = ContentType.objects.get_for_model(FooWithoutUrl) - obj = FooWithoutUrl.objects.create(name="john") - - self.assertRaises(Http404, shortcut, request, user_ct.id, obj.id) - - def test_shortcut_view_with_broken_get_absolute_url(self): - """ - Check that the shortcut view does not catch an AttributeError raised - by the model's get_absolute_url method. - Refs #8997. - """ - request = HttpRequest() - request.META = { - "SERVER_NAME": "Example.com", - "SERVER_PORT": "80", - } - user_ct = ContentType.objects.get_for_model(FooWithBrokenAbsoluteUrl) - obj = FooWithBrokenAbsoluteUrl.objects.create(name="john") - - self.assertRaises(AttributeError, shortcut, request, user_ct.id, obj.id) - - def test_missing_model(self): - """ - Ensures that displaying content types in admin (or anywhere) doesn't - break on leftover content type records in the DB for which no model - is defined anymore. - """ - ct = ContentType.objects.create( - app_label='contenttypes', - model='OldModel', - ) - self.assertEqual(six.text_type(ct), 'OldModel') - self.assertIsNone(ct.model_class()) - - # Make sure stale ContentTypes can be fetched like any other object. - # Before Django 1.6 this caused a NoneType error in the caching mechanism. - # Instead, just return the ContentType object and let the app detect stale states. - ct_fetched = ContentType.objects.get_for_id(ct.pk) - self.assertIsNone(ct_fetched.model_class()) - - def test_name_deprecation(self): - """ - ContentType.name has been removed. Test that a warning is emitted when - creating a ContentType with a `name`, but the creation should not fail. - """ - with warnings.catch_warnings(record=True) as warns: - warnings.simplefilter('always') - ContentType.objects.create( - name='Name', - app_label='contenttypes', - model='OldModel', - ) - self.assertEqual(len(warns), 1) - self.assertEqual( - str(warns[0].message), - "ContentType.name field doesn't exist any longer. Please remove it from your code." - ) - self.assertTrue(ContentType.objects.filter(model='OldModel').exists()) - - @mock.patch('django.contrib.contenttypes.models.ContentTypeManager.get_or_create') - @mock.patch('django.contrib.contenttypes.models.ContentTypeManager.get') - def test_message_if_get_for_model_fails(self, mocked_get, mocked_get_or_create): - """ - Check that `RuntimeError` with nice error message is raised if - `get_for_model` fails because of database errors. - """ - - def _test_message(mocked_method): - for ExceptionClass in (IntegrityError, OperationalError, ProgrammingError): - mocked_method.side_effect = ExceptionClass - with self.assertRaisesMessage( - RuntimeError, - "Error creating new content types. Please make sure contenttypes " - "is migrated before trying to migrate apps individually." - ): - ContentType.objects.get_for_model(ContentType) - - _test_message(mocked_get) - - mocked_get.side_effect = ContentType.DoesNotExist - _test_message(mocked_get_or_create) diff --git a/tests/contenttypes_tests/models.py b/tests/contenttypes_tests/models.py index dadc40d3d9..15148cdebd 100644 --- a/tests/contenttypes_tests/models.py +++ b/tests/contenttypes_tests/models.py @@ -2,6 +2,7 @@ from __future__ import unicode_literals from django.db import models from django.utils.encoding import python_2_unicode_compatible +from django.utils.http import urlquote @python_2_unicode_compatible @@ -35,3 +36,43 @@ class SchemeIncludedURL(models.Model): def get_absolute_url(self): return self.url + + +class ConcreteModel(models.Model): + name = models.CharField(max_length=10) + + +class ProxyModel(ConcreteModel): + class Meta: + proxy = True + + +@python_2_unicode_compatible +class FooWithoutUrl(models.Model): + """ + Fake model not defining ``get_absolute_url`` for + ContentTypesTests.test_shortcut_view_without_get_absolute_url() + """ + name = models.CharField(max_length=30, unique=True) + + def __str__(self): + return self.name + + +class FooWithUrl(FooWithoutUrl): + """ + Fake model defining ``get_absolute_url`` for + ContentTypesTests.test_shortcut_view(). + """ + + def get_absolute_url(self): + return "/users/%s/" % urlquote(self.name) + + +class FooWithBrokenAbsoluteUrl(FooWithoutUrl): + """ + Fake model defining a ``get_absolute_url`` method containing an error + """ + + def get_absolute_url(self): + return "/users/%s/" % self.unknown_field diff --git a/tests/contenttypes_tests/test_models.py b/tests/contenttypes_tests/test_models.py new file mode 100644 index 0000000000..eb436b6a64 --- /dev/null +++ b/tests/contenttypes_tests/test_models.py @@ -0,0 +1,290 @@ +from __future__ import unicode_literals + +import warnings + +from django.contrib.contenttypes.models import ContentType +from django.contrib.contenttypes.views import shortcut +from django.contrib.sites.shortcuts import get_current_site +from django.db.utils import IntegrityError, OperationalError, ProgrammingError +from django.http import Http404, HttpRequest +from django.test import TestCase, mock, override_settings +from django.utils import six + +from .models import ( + ConcreteModel, FooWithBrokenAbsoluteUrl, FooWithoutUrl, FooWithUrl, + ProxyModel, +) + + +class ContentTypesTests(TestCase): + + def setUp(self): + ContentType.objects.clear_cache() + + def tearDown(self): + ContentType.objects.clear_cache() + + def test_lookup_cache(self): + """ + Make sure that the content type cache (see ContentTypeManager) + works correctly. Lookups for a particular content type -- by model, ID + or natural key -- should hit the database only on the first lookup. + """ + + # At this point, a lookup for a ContentType should hit the DB + with self.assertNumQueries(1): + ContentType.objects.get_for_model(ContentType) + + # A second hit, though, won't hit the DB, nor will a lookup by ID + # or natural key + with self.assertNumQueries(0): + ct = ContentType.objects.get_for_model(ContentType) + with self.assertNumQueries(0): + ContentType.objects.get_for_id(ct.id) + with self.assertNumQueries(0): + ContentType.objects.get_by_natural_key('contenttypes', + 'contenttype') + + # Once we clear the cache, another lookup will again hit the DB + ContentType.objects.clear_cache() + with self.assertNumQueries(1): + ContentType.objects.get_for_model(ContentType) + + # The same should happen with a lookup by natural key + ContentType.objects.clear_cache() + with self.assertNumQueries(1): + ContentType.objects.get_by_natural_key('contenttypes', + 'contenttype') + # And a second hit shouldn't hit the DB + with self.assertNumQueries(0): + ContentType.objects.get_by_natural_key('contenttypes', + 'contenttype') + + def test_get_for_models_empty_cache(self): + # Empty cache. + with self.assertNumQueries(1): + cts = ContentType.objects.get_for_models(ContentType, FooWithUrl) + self.assertEqual(cts, { + ContentType: ContentType.objects.get_for_model(ContentType), + FooWithUrl: ContentType.objects.get_for_model(FooWithUrl), + }) + + def test_get_for_models_partial_cache(self): + # Partial cache + ContentType.objects.get_for_model(ContentType) + with self.assertNumQueries(1): + cts = ContentType.objects.get_for_models(ContentType, FooWithUrl) + self.assertEqual(cts, { + ContentType: ContentType.objects.get_for_model(ContentType), + FooWithUrl: ContentType.objects.get_for_model(FooWithUrl), + }) + + def test_get_for_models_full_cache(self): + # Full cache + ContentType.objects.get_for_model(ContentType) + ContentType.objects.get_for_model(FooWithUrl) + with self.assertNumQueries(0): + cts = ContentType.objects.get_for_models(ContentType, FooWithUrl) + self.assertEqual(cts, { + ContentType: ContentType.objects.get_for_model(ContentType), + FooWithUrl: ContentType.objects.get_for_model(FooWithUrl), + }) + + def test_get_for_concrete_model(self): + """ + Make sure the `for_concrete_model` kwarg correctly works + with concrete, proxy and deferred models + """ + concrete_model_ct = ContentType.objects.get_for_model(ConcreteModel) + + self.assertEqual(concrete_model_ct, + ContentType.objects.get_for_model(ProxyModel)) + + self.assertEqual(concrete_model_ct, + ContentType.objects.get_for_model(ConcreteModel, + for_concrete_model=False)) + + proxy_model_ct = ContentType.objects.get_for_model(ProxyModel, + for_concrete_model=False) + + self.assertNotEqual(concrete_model_ct, proxy_model_ct) + + # Make sure deferred model are correctly handled + ConcreteModel.objects.create(name="Concrete") + DeferredConcreteModel = ConcreteModel.objects.only('pk').get().__class__ + DeferredProxyModel = ProxyModel.objects.only('pk').get().__class__ + + self.assertEqual(concrete_model_ct, + ContentType.objects.get_for_model(DeferredConcreteModel)) + + self.assertEqual(concrete_model_ct, + ContentType.objects.get_for_model(DeferredConcreteModel, + for_concrete_model=False)) + + self.assertEqual(concrete_model_ct, + ContentType.objects.get_for_model(DeferredProxyModel)) + + self.assertEqual(proxy_model_ct, + ContentType.objects.get_for_model(DeferredProxyModel, + for_concrete_model=False)) + + def test_get_for_concrete_models(self): + """ + Make sure the `for_concrete_models` kwarg correctly works + with concrete, proxy and deferred models. + """ + concrete_model_ct = ContentType.objects.get_for_model(ConcreteModel) + + cts = ContentType.objects.get_for_models(ConcreteModel, ProxyModel) + self.assertEqual(cts, { + ConcreteModel: concrete_model_ct, + ProxyModel: concrete_model_ct, + }) + + proxy_model_ct = ContentType.objects.get_for_model(ProxyModel, + for_concrete_model=False) + cts = ContentType.objects.get_for_models(ConcreteModel, ProxyModel, + for_concrete_models=False) + self.assertEqual(cts, { + ConcreteModel: concrete_model_ct, + ProxyModel: proxy_model_ct, + }) + + # Make sure deferred model are correctly handled + ConcreteModel.objects.create(name="Concrete") + DeferredConcreteModel = ConcreteModel.objects.only('pk').get().__class__ + DeferredProxyModel = ProxyModel.objects.only('pk').get().__class__ + + cts = ContentType.objects.get_for_models(DeferredConcreteModel, + DeferredProxyModel) + self.assertEqual(cts, { + DeferredConcreteModel: concrete_model_ct, + DeferredProxyModel: concrete_model_ct, + }) + + cts = ContentType.objects.get_for_models(DeferredConcreteModel, + DeferredProxyModel, + for_concrete_models=False) + self.assertEqual(cts, { + DeferredConcreteModel: concrete_model_ct, + DeferredProxyModel: proxy_model_ct, + }) + + @override_settings(ALLOWED_HOSTS=['example.com']) + def test_shortcut_view(self): + """ + Check that the shortcut view (used for the admin "view on site" + functionality) returns a complete URL regardless of whether the sites + framework is installed + """ + + request = HttpRequest() + request.META = { + "SERVER_NAME": "Example.com", + "SERVER_PORT": "80", + } + user_ct = ContentType.objects.get_for_model(FooWithUrl) + obj = FooWithUrl.objects.create(name="john") + + with self.modify_settings(INSTALLED_APPS={'append': 'django.contrib.sites'}): + response = shortcut(request, user_ct.id, obj.id) + self.assertEqual("http://%s/users/john/" % get_current_site(request).domain, + response._headers.get("location")[1]) + + with self.modify_settings(INSTALLED_APPS={'remove': 'django.contrib.sites'}): + response = shortcut(request, user_ct.id, obj.id) + self.assertEqual("http://Example.com/users/john/", + response._headers.get("location")[1]) + + def test_shortcut_view_without_get_absolute_url(self): + """ + Check that the shortcut view (used for the admin "view on site" + functionality) returns 404 when get_absolute_url is not defined. + """ + + request = HttpRequest() + request.META = { + "SERVER_NAME": "Example.com", + "SERVER_PORT": "80", + } + user_ct = ContentType.objects.get_for_model(FooWithoutUrl) + obj = FooWithoutUrl.objects.create(name="john") + + self.assertRaises(Http404, shortcut, request, user_ct.id, obj.id) + + def test_shortcut_view_with_broken_get_absolute_url(self): + """ + Check that the shortcut view does not catch an AttributeError raised + by the model's get_absolute_url method. + Refs #8997. + """ + request = HttpRequest() + request.META = { + "SERVER_NAME": "Example.com", + "SERVER_PORT": "80", + } + user_ct = ContentType.objects.get_for_model(FooWithBrokenAbsoluteUrl) + obj = FooWithBrokenAbsoluteUrl.objects.create(name="john") + + self.assertRaises(AttributeError, shortcut, request, user_ct.id, obj.id) + + def test_missing_model(self): + """ + Ensures that displaying content types in admin (or anywhere) doesn't + break on leftover content type records in the DB for which no model + is defined anymore. + """ + ct = ContentType.objects.create( + app_label='contenttypes', + model='OldModel', + ) + self.assertEqual(six.text_type(ct), 'OldModel') + self.assertIsNone(ct.model_class()) + + # Make sure stale ContentTypes can be fetched like any other object. + # Before Django 1.6 this caused a NoneType error in the caching mechanism. + # Instead, just return the ContentType object and let the app detect stale states. + ct_fetched = ContentType.objects.get_for_id(ct.pk) + self.assertIsNone(ct_fetched.model_class()) + + def test_name_deprecation(self): + """ + ContentType.name has been removed. Test that a warning is emitted when + creating a ContentType with a `name`, but the creation should not fail. + """ + with warnings.catch_warnings(record=True) as warns: + warnings.simplefilter('always') + ContentType.objects.create( + name='Name', + app_label='contenttypes', + model='OldModel', + ) + self.assertEqual(len(warns), 1) + self.assertEqual( + str(warns[0].message), + "ContentType.name field doesn't exist any longer. Please remove it from your code." + ) + self.assertTrue(ContentType.objects.filter(model='OldModel').exists()) + + @mock.patch('django.contrib.contenttypes.models.ContentTypeManager.get_or_create') + @mock.patch('django.contrib.contenttypes.models.ContentTypeManager.get') + def test_message_if_get_for_model_fails(self, mocked_get, mocked_get_or_create): + """ + Check that `RuntimeError` with nice error message is raised if + `get_for_model` fails because of database errors. + """ + + def _test_message(mocked_method): + for ExceptionClass in (IntegrityError, OperationalError, ProgrammingError): + mocked_method.side_effect = ExceptionClass + with self.assertRaisesMessage( + RuntimeError, + "Error creating new content types. Please make sure contenttypes " + "is migrated before trying to migrate apps individually." + ): + ContentType.objects.get_for_model(ContentType) + + _test_message(mocked_get) + + mocked_get.side_effect = ContentType.DoesNotExist + _test_message(mocked_get_or_create) diff --git a/tests/runtests.py b/tests/runtests.py index 53a5729d77..054a6ded30 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -144,7 +144,7 @@ def setup(verbosity, test_labels): # these 'tests.migrations' modules don't actually exist, but this lets # us skip creating migrations for the test models. 'auth': 'django.contrib.auth.tests.migrations', - 'contenttypes': 'django.contrib.contenttypes.tests.migrations', + 'contenttypes': 'contenttypes_tests.migrations', } if verbosity > 0: -- cgit v1.3