diff options
| author | Simon Charette <charette.s@gmail.com> | 2015-12-17 20:12:05 -0500 |
|---|---|---|
| committer | Simon Charette <charette.s@gmail.com> | 2016-05-17 12:14:58 -0400 |
| commit | f179113e6cbc8ba0a8d4e87e1d4410fb61d63e75 (patch) | |
| tree | 3d37340aee66ff6b3f492fb81efdb547ab24061f /tests | |
| parent | 354acd04af524ad82002b903df1189581c51cabe (diff) | |
Fixed #24067 -- Renamed content types upon model renaming.
Thanks to Tim for the extensive review.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/contenttypes_tests/operations_migrations/0001_initial.py | 34 | ||||
| -rw-r--r-- | tests/contenttypes_tests/operations_migrations/__init__.py | 0 | ||||
| -rw-r--r-- | tests/contenttypes_tests/tests.py | 84 |
3 files changed, 110 insertions, 8 deletions
diff --git a/tests/contenttypes_tests/operations_migrations/0001_initial.py b/tests/contenttypes_tests/operations_migrations/0001_initial.py new file mode 100644 index 0000000000..0df7a8ef9c --- /dev/null +++ b/tests/contenttypes_tests/operations_migrations/0001_initial.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +def assert_foo_contenttype_not_cached(apps, schema_editor): + ContentType = apps.get_model('contenttypes', 'ContentType') + try: + content_type = ContentType.objects.get_by_natural_key('contenttypes_tests', 'foo') + except ContentType.DoesNotExist: + pass + else: + if not ContentType.objects.filter(app_label='contenttypes_tests', model='foo').exists(): + raise AssertionError('The contenttypes_tests.Foo ContentType should not be cached.') + elif content_type.model != 'foo': + raise AssertionError( + "The cached contenttypes_tests.Foo ContentType should have " + "its model set to 'foo'." + ) + + +class Migration(migrations.Migration): + + operations = [ + migrations.CreateModel( + 'Foo', + [ + ('id', models.AutoField(primary_key=True)), + ], + ), + migrations.RenameModel('Foo', 'RenamedFoo'), + migrations.RunPython(assert_foo_contenttype_not_cached, migrations.RunPython.noop) + ] diff --git a/tests/contenttypes_tests/operations_migrations/__init__.py b/tests/contenttypes_tests/operations_migrations/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/contenttypes_tests/operations_migrations/__init__.py diff --git a/tests/contenttypes_tests/tests.py b/tests/contenttypes_tests/tests.py index 5db01773a4..7f65fb6f9b 100644 --- a/tests/contenttypes_tests/tests.py +++ b/tests/contenttypes_tests/tests.py @@ -4,15 +4,18 @@ from __future__ import unicode_literals import datetime from django.apps.registry import Apps, apps -from django.contrib.contenttypes import management +from django.conf import settings +from django.contrib.contenttypes import management as contenttypes_management from django.contrib.contenttypes.fields import ( GenericForeignKey, GenericRelation, ) from django.contrib.contenttypes.models import ContentType from django.contrib.sites.models import Site -from django.core import checks -from django.db import connections, models -from django.test import SimpleTestCase, TestCase, mock, override_settings +from django.core import checks, management +from django.db import connections, migrations, models +from django.test import ( + SimpleTestCase, TestCase, TransactionTestCase, mock, override_settings, +) from django.test.utils import captured_stdout, isolate_apps from django.utils.encoding import force_str, force_text @@ -388,9 +391,9 @@ class UpdateContentTypesTests(TestCase): interactive mode of update_contenttypes() (the default) should delete stale contenttypes. """ - management.input = lambda x: force_str("yes") + contenttypes_management.input = lambda x: force_str("yes") with captured_stdout() as stdout: - management.update_contenttypes(self.app_config) + contenttypes_management.update_contenttypes(self.app_config) self.assertIn("Deleting stale content type", stdout.getvalue()) self.assertEqual(ContentType.objects.count(), self.before_count) @@ -400,7 +403,7 @@ class UpdateContentTypesTests(TestCase): content types. """ with captured_stdout() as stdout: - management.update_contenttypes(self.app_config, interactive=False) + contenttypes_management.update_contenttypes(self.app_config, interactive=False) self.assertIn("Stale content types remain.", stdout.getvalue()) self.assertEqual(ContentType.objects.count(), self.before_count + 1) @@ -411,7 +414,7 @@ class UpdateContentTypesTests(TestCase): """ apps = Apps() with self.assertNumQueries(0): - management.update_contenttypes(self.app_config, interactive=False, verbosity=0, apps=apps) + contenttypes_management.update_contenttypes(self.app_config, interactive=False, verbosity=0, apps=apps) self.assertEqual(ContentType.objects.count(), self.before_count + 1) @@ -445,3 +448,68 @@ class ContentTypesMultidbTestCase(TestCase): with self.assertNumQueries(0, using='default'), \ self.assertNumQueries(1, using='other'): ContentType.objects.get_for_model(Author) + + +@override_settings( + MIGRATION_MODULES=dict(settings.MIGRATION_MODULES, contenttypes_tests='contenttypes_tests.operations_migrations'), +) +class ContentTypeOperationsTests(TransactionTestCase): + available_apps = ['django.contrib.contenttypes', 'contenttypes_tests'] + + def setUp(self): + app_config = apps.get_app_config('contenttypes_tests') + models.signals.post_migrate.connect(self.assertOperationsInjected, sender=app_config) + + def tearDown(self): + app_config = apps.get_app_config('contenttypes_tests') + models.signals.post_migrate.disconnect(self.assertOperationsInjected, sender=app_config) + + def assertOperationsInjected(self, plan, **kwargs): + for migration, _backward in plan: + operations = iter(migration.operations) + for operation in operations: + if isinstance(operation, migrations.RenameModel): + next_operation = next(operations) + self.assertIsInstance(next_operation, contenttypes_management.RenameContentType) + self.assertEqual(next_operation.app_label, migration.app_label) + self.assertEqual(next_operation.old_model, operation.old_name_lower) + self.assertEqual(next_operation.new_model, operation.new_name_lower) + + def test_existing_content_type_rename(self): + ContentType.objects.create(app_label='contenttypes_tests', model='foo') + management.call_command( + 'migrate', 'contenttypes_tests', database='default', interactive=False, verbosity=0, + ) + self.assertFalse(ContentType.objects.filter(app_label='contenttypes_tests', model='foo').exists()) + self.assertTrue(ContentType.objects.filter(app_label='contenttypes_tests', model='renamedfoo').exists()) + management.call_command( + 'migrate', 'contenttypes_tests', 'zero', database='default', interactive=False, verbosity=0, + ) + self.assertTrue(ContentType.objects.filter(app_label='contenttypes_tests', model='foo').exists()) + self.assertFalse(ContentType.objects.filter(app_label='contenttypes_tests', model='renamedfoo').exists()) + + def test_missing_content_type_rename_ignore(self): + management.call_command( + 'migrate', 'contenttypes_tests', database='default', interactive=False, verbosity=0, + ) + self.assertFalse(ContentType.objects.filter(app_label='contenttypes_tests', model='foo').exists()) + self.assertTrue(ContentType.objects.filter(app_label='contenttypes_tests', model='renamedfoo').exists()) + management.call_command( + 'migrate', 'contenttypes_tests', 'zero', database='default', interactive=False, verbosity=0, + ) + self.assertTrue(ContentType.objects.filter(app_label='contenttypes_tests', model='foo').exists()) + self.assertFalse(ContentType.objects.filter(app_label='contenttypes_tests', model='renamedfoo').exists()) + + def test_content_type_rename_conflict(self): + ContentType.objects.create(app_label='contenttypes_tests', model='foo') + ContentType.objects.create(app_label='contenttypes_tests', model='renamedfoo') + management.call_command( + 'migrate', 'contenttypes_tests', database='default', interactive=False, verbosity=0, + ) + self.assertTrue(ContentType.objects.filter(app_label='contenttypes_tests', model='foo').exists()) + self.assertTrue(ContentType.objects.filter(app_label='contenttypes_tests', model='renamedfoo').exists()) + management.call_command( + 'migrate', 'contenttypes_tests', 'zero', database='default', interactive=False, verbosity=0, + ) + self.assertTrue(ContentType.objects.filter(app_label='contenttypes_tests', model='foo').exists()) + self.assertTrue(ContentType.objects.filter(app_label='contenttypes_tests', model='renamedfoo').exists()) |
