diff options
| author | django-bot <ops@djangoproject.com> | 2022-02-03 20:24:19 +0100 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2022-02-07 20:37:05 +0100 |
| commit | 9c19aff7c7561e3a82978a272ecdaad40dda5c00 (patch) | |
| tree | f0506b668a013d0063e5fba3dbf4863b466713ba /tests/contenttypes_tests | |
| parent | f68fa8b45dfac545cfc4111d4e52804c86db68d3 (diff) | |
Refs #33476 -- Reformatted code with Black.
Diffstat (limited to 'tests/contenttypes_tests')
| -rw-r--r-- | tests/contenttypes_tests/models.py | 20 | ||||
| -rw-r--r-- | tests/contenttypes_tests/operations_migrations/0001_initial.py | 4 | ||||
| -rw-r--r-- | tests/contenttypes_tests/operations_migrations/0002_rename_foo.py | 24 | ||||
| -rw-r--r-- | tests/contenttypes_tests/test_checks.py | 249 | ||||
| -rw-r--r-- | tests/contenttypes_tests/test_fields.py | 25 | ||||
| -rw-r--r-- | tests/contenttypes_tests/test_management.py | 68 | ||||
| -rw-r--r-- | tests/contenttypes_tests/test_models.py | 197 | ||||
| -rw-r--r-- | tests/contenttypes_tests/test_operations.py | 188 | ||||
| -rw-r--r-- | tests/contenttypes_tests/test_views.py | 171 | ||||
| -rw-r--r-- | tests/contenttypes_tests/urls.py | 2 |
10 files changed, 613 insertions, 335 deletions
diff --git a/tests/contenttypes_tests/models.py b/tests/contenttypes_tests/models.py index 2e0640459f..5e40217c30 100644 --- a/tests/contenttypes_tests/models.py +++ b/tests/contenttypes_tests/models.py @@ -1,8 +1,6 @@ from urllib.parse import quote -from django.contrib.contenttypes.fields import ( - GenericForeignKey, GenericRelation, -) +from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation from django.contrib.contenttypes.models import ContentType from django.contrib.sites.models import SiteManager from django.db import models @@ -17,7 +15,7 @@ class Author(models.Model): name = models.CharField(max_length=100) def get_absolute_url(self): - return '/authors/%s/' % self.id + return "/authors/%s/" % self.id class Article(models.Model): @@ -48,6 +46,7 @@ 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) @@ -72,7 +71,7 @@ class FooWithBrokenAbsoluteUrl(FooWithoutUrl): class Question(models.Model): text = models.CharField(max_length=200) - answer_set = GenericRelation('Answer') + answer_set = GenericRelation("Answer") class Answer(models.Model): @@ -82,19 +81,20 @@ class Answer(models.Model): question = GenericForeignKey() class Meta: - order_with_respect_to = 'question' + order_with_respect_to = "question" class Post(models.Model): """An ordered tag on an item.""" + title = models.CharField(max_length=200) content_type = models.ForeignKey(ContentType, models.CASCADE, null=True) object_id = models.PositiveIntegerField(null=True) parent = GenericForeignKey() - children = GenericRelation('Post') + children = GenericRelation("Post") class Meta: - order_with_respect_to = 'parent' + order_with_respect_to = "parent" class ModelWithNullFKToSite(models.Model): @@ -103,7 +103,7 @@ class ModelWithNullFKToSite(models.Model): post = models.ForeignKey(Post, null=True, on_delete=models.CASCADE) def get_absolute_url(self): - return '/title/%s/' % quote(self.title) + return "/title/%s/" % quote(self.title) class ModelWithM2MToSite(models.Model): @@ -111,4 +111,4 @@ class ModelWithM2MToSite(models.Model): sites = models.ManyToManyField(Site) def get_absolute_url(self): - return '/title/%s/' % quote(self.title) + return "/title/%s/" % quote(self.title) diff --git a/tests/contenttypes_tests/operations_migrations/0001_initial.py b/tests/contenttypes_tests/operations_migrations/0001_initial.py index 9d43117529..0c8e96038e 100644 --- a/tests/contenttypes_tests/operations_migrations/0001_initial.py +++ b/tests/contenttypes_tests/operations_migrations/0001_initial.py @@ -5,9 +5,9 @@ class Migration(migrations.Migration): operations = [ migrations.CreateModel( - 'Foo', + "Foo", [ - ('id', models.AutoField(primary_key=True)), + ("id", models.AutoField(primary_key=True)), ], ), ] diff --git a/tests/contenttypes_tests/operations_migrations/0002_rename_foo.py b/tests/contenttypes_tests/operations_migrations/0002_rename_foo.py index 3a1527dc03..e40a33ac0b 100644 --- a/tests/contenttypes_tests/operations_migrations/0002_rename_foo.py +++ b/tests/contenttypes_tests/operations_migrations/0002_rename_foo.py @@ -2,15 +2,21 @@ from django.db import migrations def assert_foo_contenttype_not_cached(apps, schema_editor): - ContentType = apps.get_model('contenttypes', 'ContentType') + ContentType = apps.get_model("contenttypes", "ContentType") try: - content_type = ContentType.objects.get_by_natural_key('contenttypes_tests', 'foo') + 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': + 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'." @@ -20,10 +26,12 @@ def assert_foo_contenttype_not_cached(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('contenttypes_tests', '0001_initial'), + ("contenttypes_tests", "0001_initial"), ] operations = [ - migrations.RenameModel('Foo', 'RenamedFoo'), - migrations.RunPython(assert_foo_contenttype_not_cached, migrations.RunPython.noop) + migrations.RenameModel("Foo", "RenamedFoo"), + migrations.RunPython( + assert_foo_contenttype_not_cached, migrations.RunPython.noop + ), ] diff --git a/tests/contenttypes_tests/test_checks.py b/tests/contenttypes_tests/test_checks.py index 44cd3c2758..b3f4a0f4ba 100644 --- a/tests/contenttypes_tests/test_checks.py +++ b/tests/contenttypes_tests/test_checks.py @@ -1,9 +1,7 @@ from unittest import mock from django.contrib.contenttypes.checks import check_model_name_lengths -from django.contrib.contenttypes.fields import ( - GenericForeignKey, GenericRelation, -) +from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation from django.contrib.contenttypes.models import ContentType from django.core import checks from django.db import models @@ -11,9 +9,8 @@ from django.test import SimpleTestCase, override_settings from django.test.utils import isolate_apps -@isolate_apps('contenttypes_tests', attr_name='apps') +@isolate_apps("contenttypes_tests", attr_name="apps") class GenericForeignKeyTests(SimpleTestCase): - def test_missing_content_type_field(self): class TaggedItem(models.Model): # no content_type field @@ -25,7 +22,7 @@ class GenericForeignKeyTests(SimpleTestCase): "The GenericForeignKey content type references the nonexistent " "field 'TaggedItem.content_type'.", obj=TaggedItem.content_object, - id='contenttypes.E002', + id="contenttypes.E002", ) ] self.assertEqual(TaggedItem.content_object.check(), expected) @@ -34,37 +31,45 @@ class GenericForeignKeyTests(SimpleTestCase): class Model(models.Model): content_type = models.IntegerField() # should be ForeignKey object_id = models.PositiveIntegerField() - content_object = GenericForeignKey('content_type', 'object_id') + content_object = GenericForeignKey("content_type", "object_id") - self.assertEqual(Model.content_object.check(), [ - checks.Error( - "'Model.content_type' is not a ForeignKey.", - hint=( - "GenericForeignKeys must use a ForeignKey to " - "'contenttypes.ContentType' as the 'content_type' field." - ), - obj=Model.content_object, - id='contenttypes.E003', - ) - ]) + self.assertEqual( + Model.content_object.check(), + [ + checks.Error( + "'Model.content_type' is not a ForeignKey.", + hint=( + "GenericForeignKeys must use a ForeignKey to " + "'contenttypes.ContentType' as the 'content_type' field." + ), + obj=Model.content_object, + id="contenttypes.E003", + ) + ], + ) def test_content_type_field_pointing_to_wrong_model(self): class Model(models.Model): - content_type = models.ForeignKey('self', models.CASCADE) # should point to ContentType + content_type = models.ForeignKey( + "self", models.CASCADE + ) # should point to ContentType object_id = models.PositiveIntegerField() - content_object = GenericForeignKey('content_type', 'object_id') + content_object = GenericForeignKey("content_type", "object_id") - self.assertEqual(Model.content_object.check(), [ - checks.Error( - "'Model.content_type' is not a ForeignKey to 'contenttypes.ContentType'.", - hint=( - "GenericForeignKeys must use a ForeignKey to " - "'contenttypes.ContentType' as the 'content_type' field." - ), - obj=Model.content_object, - id='contenttypes.E004', - ) - ]) + self.assertEqual( + Model.content_object.check(), + [ + checks.Error( + "'Model.content_type' is not a ForeignKey to 'contenttypes.ContentType'.", + hint=( + "GenericForeignKeys must use a ForeignKey to " + "'contenttypes.ContentType' as the 'content_type' field." + ), + obj=Model.content_object, + id="contenttypes.E004", + ) + ], + ) def test_missing_object_id_field(self): class TaggedItem(models.Model): @@ -72,42 +77,53 @@ class GenericForeignKeyTests(SimpleTestCase): # missing object_id field content_object = GenericForeignKey() - self.assertEqual(TaggedItem.content_object.check(), [ - checks.Error( - "The GenericForeignKey object ID references the nonexistent " - "field 'object_id'.", - obj=TaggedItem.content_object, - id='contenttypes.E001', - ) - ]) + self.assertEqual( + TaggedItem.content_object.check(), + [ + checks.Error( + "The GenericForeignKey object ID references the nonexistent " + "field 'object_id'.", + obj=TaggedItem.content_object, + id="contenttypes.E001", + ) + ], + ) def test_field_name_ending_with_underscore(self): class Model(models.Model): content_type = models.ForeignKey(ContentType, models.CASCADE) object_id = models.PositiveIntegerField() - content_object_ = GenericForeignKey('content_type', 'object_id') + content_object_ = GenericForeignKey("content_type", "object_id") - self.assertEqual(Model.content_object_.check(), [ - checks.Error( - 'Field names must not end with an underscore.', - obj=Model.content_object_, - id='fields.E001', - ) - ]) + self.assertEqual( + Model.content_object_.check(), + [ + checks.Error( + "Field names must not end with an underscore.", + obj=Model.content_object_, + id="fields.E001", + ) + ], + ) - @override_settings(INSTALLED_APPS=['django.contrib.auth', 'django.contrib.contenttypes', 'contenttypes_tests']) + @override_settings( + INSTALLED_APPS=[ + "django.contrib.auth", + "django.contrib.contenttypes", + "contenttypes_tests", + ] + ) def test_generic_foreign_key_checks_are_performed(self): class Model(models.Model): content_object = GenericForeignKey() - with mock.patch.object(GenericForeignKey, 'check') as check: + with mock.patch.object(GenericForeignKey, "check") as check: checks.run_checks(app_configs=self.apps.get_app_configs()) check.assert_called_once_with() -@isolate_apps('contenttypes_tests') +@isolate_apps("contenttypes_tests") class GenericRelationTests(SimpleTestCase): - def test_valid_generic_relationship(self): class TaggedItem(models.Model): content_type = models.ForeignKey(ContentType, models.CASCADE) @@ -115,7 +131,7 @@ class GenericRelationTests(SimpleTestCase): content_object = GenericForeignKey() class Bookmark(models.Model): - tags = GenericRelation('TaggedItem') + tags = GenericRelation("TaggedItem") self.assertEqual(Bookmark.tags.field.check(), []) @@ -123,36 +139,41 @@ class GenericRelationTests(SimpleTestCase): class TaggedItem(models.Model): custom_content_type = models.ForeignKey(ContentType, models.CASCADE) custom_object_id = models.PositiveIntegerField() - content_object = GenericForeignKey('custom_content_type', 'custom_object_id') + content_object = GenericForeignKey( + "custom_content_type", "custom_object_id" + ) class Bookmark(models.Model): tags = GenericRelation( - 'TaggedItem', - content_type_field='custom_content_type', - object_id_field='custom_object_id', + "TaggedItem", + content_type_field="custom_content_type", + object_id_field="custom_object_id", ) self.assertEqual(Bookmark.tags.field.check(), []) def test_pointing_to_missing_model(self): class Model(models.Model): - rel = GenericRelation('MissingModel') + rel = GenericRelation("MissingModel") - self.assertEqual(Model.rel.field.check(), [ - checks.Error( - "Field defines a relation with model 'MissingModel', " - "which is either not installed, or is abstract.", - obj=Model.rel.field, - id='fields.E300', - ) - ]) + self.assertEqual( + Model.rel.field.check(), + [ + checks.Error( + "Field defines a relation with model 'MissingModel', " + "which is either not installed, or is abstract.", + obj=Model.rel.field, + id="fields.E300", + ) + ], + ) def test_valid_self_referential_generic_relationship(self): class Model(models.Model): - rel = GenericRelation('Model') + rel = GenericRelation("Model") content_type = models.ForeignKey(ContentType, models.CASCADE) object_id = models.PositiveIntegerField() - content_object = GenericForeignKey('content_type', 'object_id') + content_object = GenericForeignKey("content_type", "object_id") self.assertEqual(Model.rel.field.check(), []) @@ -162,19 +183,22 @@ class GenericRelationTests(SimpleTestCase): object_id = models.PositiveIntegerField() class Bookmark(models.Model): - tags = GenericRelation('TaggedItem') + tags = GenericRelation("TaggedItem") - self.assertEqual(Bookmark.tags.field.check(), [ - checks.Error( - "The GenericRelation defines a relation with the model " - "'contenttypes_tests.TaggedItem', but that model does not have a " - "GenericForeignKey.", - obj=Bookmark.tags.field, - id='contenttypes.E004', - ) - ]) + self.assertEqual( + Bookmark.tags.field.check(), + [ + checks.Error( + "The GenericRelation defines a relation with the model " + "'contenttypes_tests.TaggedItem', but that model does not have a " + "GenericForeignKey.", + obj=Bookmark.tags.field, + id="contenttypes.E004", + ) + ], + ) - @override_settings(TEST_SWAPPED_MODEL='contenttypes_tests.Replacement') + @override_settings(TEST_SWAPPED_MODEL="contenttypes_tests.Replacement") def test_pointing_to_swapped_model(self): class Replacement(models.Model): pass @@ -185,21 +209,24 @@ class GenericRelationTests(SimpleTestCase): content_object = GenericForeignKey() class Meta: - swappable = 'TEST_SWAPPED_MODEL' + swappable = "TEST_SWAPPED_MODEL" class Model(models.Model): - rel = GenericRelation('SwappedModel') + rel = GenericRelation("SwappedModel") - self.assertEqual(Model.rel.field.check(), [ - checks.Error( - "Field defines a relation with the model " - "'contenttypes_tests.SwappedModel', " - "which has been swapped out.", - hint="Update the relation to point at 'settings.TEST_SWAPPED_MODEL'.", - obj=Model.rel.field, - id='fields.E301', - ) - ]) + self.assertEqual( + Model.rel.field.check(), + [ + checks.Error( + "Field defines a relation with the model " + "'contenttypes_tests.SwappedModel', " + "which has been swapped out.", + hint="Update the relation to point at 'settings.TEST_SWAPPED_MODEL'.", + obj=Model.rel.field, + id="fields.E301", + ) + ], + ) def test_field_name_ending_with_underscore(self): class TaggedItem(models.Model): @@ -208,29 +235,35 @@ class GenericRelationTests(SimpleTestCase): content_object = GenericForeignKey() class InvalidBookmark(models.Model): - tags_ = GenericRelation('TaggedItem') + tags_ = GenericRelation("TaggedItem") - self.assertEqual(InvalidBookmark.tags_.field.check(), [ - checks.Error( - 'Field names must not end with an underscore.', - obj=InvalidBookmark.tags_.field, - id='fields.E001', - ) - ]) + self.assertEqual( + InvalidBookmark.tags_.field.check(), + [ + checks.Error( + "Field names must not end with an underscore.", + obj=InvalidBookmark.tags_.field, + id="fields.E001", + ) + ], + ) -@isolate_apps('contenttypes_tests', attr_name='apps') +@isolate_apps("contenttypes_tests", attr_name="apps") class ModelCheckTests(SimpleTestCase): def test_model_name_too_long(self): - model = type('A' * 101, (models.Model,), {'__module__': self.__module__}) - self.assertEqual(check_model_name_lengths(self.apps.get_app_configs()), [ - checks.Error( - 'Model names must be at most 100 characters (got 101).', - obj=model, - id='contenttypes.E005', - ) - ]) + model = type("A" * 101, (models.Model,), {"__module__": self.__module__}) + self.assertEqual( + check_model_name_lengths(self.apps.get_app_configs()), + [ + checks.Error( + "Model names must be at most 100 characters (got 101).", + obj=model, + id="contenttypes.E005", + ) + ], + ) def test_model_name_max_length(self): - type('A' * 100, (models.Model,), {'__module__': self.__module__}) + type("A" * 100, (models.Model,), {"__module__": self.__module__}) self.assertEqual(check_model_name_lengths(self.apps.get_app_configs()), []) diff --git a/tests/contenttypes_tests/test_fields.py b/tests/contenttypes_tests/test_fields.py index 5638846cc5..170b38d018 100644 --- a/tests/contenttypes_tests/test_fields.py +++ b/tests/contenttypes_tests/test_fields.py @@ -8,25 +8,31 @@ from django.test.utils import isolate_apps from .models import Answer, Post, Question -@isolate_apps('contenttypes_tests') +@isolate_apps("contenttypes_tests") class GenericForeignKeyTests(TestCase): - def test_str(self): class Model(models.Model): field = GenericForeignKey() - self.assertEqual(str(Model.field), 'contenttypes_tests.Model.field') + + self.assertEqual(str(Model.field), "contenttypes_tests.Model.field") def test_get_content_type_no_arguments(self): - with self.assertRaisesMessage(Exception, 'Impossible arguments to GFK.get_content_type!'): + with self.assertRaisesMessage( + Exception, "Impossible arguments to GFK.get_content_type!" + ): Answer.question.get_content_type() def test_incorrect_get_prefetch_queryset_arguments(self): - with self.assertRaisesMessage(ValueError, "Custom queryset can't be used for this lookup."): - Answer.question.get_prefetch_queryset(Answer.objects.all(), Answer.objects.all()) + with self.assertRaisesMessage( + ValueError, "Custom queryset can't be used for this lookup." + ): + Answer.question.get_prefetch_queryset( + Answer.objects.all(), Answer.objects.all() + ) def test_get_object_cache_respects_deleted_objects(self): - question = Question.objects.create(text='Who?') - post = Post.objects.create(title='Answer', parent=question) + question = Question.objects.create(text="Who?") + post = Post.objects.create(title="Answer", parent=question) question_pk = question.pk Question.objects.all().delete() @@ -39,9 +45,8 @@ class GenericForeignKeyTests(TestCase): class GenericRelationTests(TestCase): - def test_value_to_string(self): - question = Question.objects.create(text='test') + question = Question.objects.create(text="test") answer1 = Answer.objects.create(question=question) answer2 = Answer.objects.create(question=question) result = json.loads(Question.answer_set.field.value_to_string(question)) diff --git a/tests/contenttypes_tests/test_management.py b/tests/contenttypes_tests/test_management.py index 57d3757abe..d5e14c7df3 100644 --- a/tests/contenttypes_tests/test_management.py +++ b/tests/contenttypes_tests/test_management.py @@ -10,42 +10,44 @@ from django.test.utils import captured_stdout from .models import ModelWithNullFKToSite, Post -@modify_settings(INSTALLED_APPS={'append': ['empty_models', 'no_models']}) +@modify_settings(INSTALLED_APPS={"append": ["empty_models", "no_models"]}) class RemoveStaleContentTypesTests(TestCase): # Speed up tests by avoiding retrieving ContentTypes for all test apps. available_apps = [ - 'contenttypes_tests', - 'empty_models', - 'no_models', - 'django.contrib.contenttypes', + "contenttypes_tests", + "empty_models", + "no_models", + "django.contrib.contenttypes", ] @classmethod def setUpTestData(cls): cls.before_count = ContentType.objects.count() - cls.content_type = ContentType.objects.create(app_label='contenttypes_tests', model='Fake') + cls.content_type = ContentType.objects.create( + app_label="contenttypes_tests", model="Fake" + ) def setUp(self): - self.app_config = apps.get_app_config('contenttypes_tests') + self.app_config = apps.get_app_config("contenttypes_tests") def test_interactive_true_with_dependent_objects(self): """ interactive mode (the default) deletes stale content types and warns of dependent objects. """ - post = Post.objects.create(title='post', content_type=self.content_type) + post = Post.objects.create(title="post", content_type=self.content_type) # A related object is needed to show that a custom collector with # can_fast_delete=False is needed. ModelWithNullFKToSite.objects.create(post=post) - with mock.patch('builtins.input', return_value='yes'): + with mock.patch("builtins.input", return_value="yes"): with captured_stdout() as stdout: - call_command('remove_stale_contenttypes', verbosity=2, stdout=stdout) + call_command("remove_stale_contenttypes", verbosity=2, stdout=stdout) self.assertEqual(Post.objects.count(), 0) output = stdout.getvalue() - self.assertIn('- Content type for contenttypes_tests.Fake', output) - self.assertIn('- 1 contenttypes_tests.Post object(s)', output) - self.assertIn('- 1 contenttypes_tests.ModelWithNullFKToSite', output) - self.assertIn('Deleting stale content type', output) + self.assertIn("- Content type for contenttypes_tests.Fake", output) + self.assertIn("- 1 contenttypes_tests.Post object(s)", output) + self.assertIn("- 1 contenttypes_tests.ModelWithNullFKToSite", output) + self.assertIn("Deleting stale content type", output) self.assertEqual(ContentType.objects.count(), self.before_count) def test_interactive_true_without_dependent_objects(self): @@ -53,32 +55,36 @@ class RemoveStaleContentTypesTests(TestCase): interactive mode deletes stale content types even if there aren't any dependent objects. """ - with mock.patch('builtins.input', return_value='yes'): + with mock.patch("builtins.input", return_value="yes"): with captured_stdout() as stdout: - call_command('remove_stale_contenttypes', verbosity=2) + call_command("remove_stale_contenttypes", verbosity=2) self.assertIn("Deleting stale content type", stdout.getvalue()) self.assertEqual(ContentType.objects.count(), self.before_count) def test_interactive_false(self): """non-interactive mode deletes stale content types.""" with captured_stdout() as stdout: - call_command('remove_stale_contenttypes', interactive=False, verbosity=2) - self.assertIn('Deleting stale content type', stdout.getvalue()) + call_command("remove_stale_contenttypes", interactive=False, verbosity=2) + self.assertIn("Deleting stale content type", stdout.getvalue()) self.assertEqual(ContentType.objects.count(), self.before_count) def test_unavailable_content_type_model(self): """A ContentType isn't created if the model isn't available.""" apps = Apps() with self.assertNumQueries(0): - contenttypes_management.create_contenttypes(self.app_config, interactive=False, verbosity=0, apps=apps) + contenttypes_management.create_contenttypes( + self.app_config, interactive=False, verbosity=0, apps=apps + ) self.assertEqual(ContentType.objects.count(), self.before_count + 1) - @modify_settings(INSTALLED_APPS={'remove': ['empty_models']}) + @modify_settings(INSTALLED_APPS={"remove": ["empty_models"]}) def test_contenttypes_removed_in_installed_apps_without_models(self): - ContentType.objects.create(app_label='empty_models', model='Fake 1') - ContentType.objects.create(app_label='no_models', model='Fake 2') - with mock.patch('builtins.input', return_value='yes'), captured_stdout() as stdout: - call_command('remove_stale_contenttypes', verbosity=2) + ContentType.objects.create(app_label="empty_models", model="Fake 1") + ContentType.objects.create(app_label="no_models", model="Fake 2") + with mock.patch( + "builtins.input", return_value="yes" + ), captured_stdout() as stdout: + call_command("remove_stale_contenttypes", verbosity=2) self.assertNotIn( "Deleting stale content type 'empty_models | Fake 1'", stdout.getvalue(), @@ -89,12 +95,16 @@ class RemoveStaleContentTypesTests(TestCase): ) self.assertEqual(ContentType.objects.count(), self.before_count + 1) - @modify_settings(INSTALLED_APPS={'remove': ['empty_models']}) + @modify_settings(INSTALLED_APPS={"remove": ["empty_models"]}) def test_contenttypes_removed_for_apps_not_in_installed_apps(self): - ContentType.objects.create(app_label='empty_models', model='Fake 1') - ContentType.objects.create(app_label='no_models', model='Fake 2') - with mock.patch('builtins.input', return_value='yes'), captured_stdout() as stdout: - call_command('remove_stale_contenttypes', include_stale_apps=True, verbosity=2) + ContentType.objects.create(app_label="empty_models", model="Fake 1") + ContentType.objects.create(app_label="no_models", model="Fake 2") + with mock.patch( + "builtins.input", return_value="yes" + ), captured_stdout() as stdout: + call_command( + "remove_stale_contenttypes", include_stale_apps=True, verbosity=2 + ) self.assertIn( "Deleting stale content type 'empty_models | Fake 1'", stdout.getvalue(), diff --git a/tests/contenttypes_tests/test_models.py b/tests/contenttypes_tests/test_models.py index 0554d13184..e2fb7fe818 100644 --- a/tests/contenttypes_tests/test_models.py +++ b/tests/contenttypes_tests/test_models.py @@ -7,7 +7,6 @@ from .models import Author, ConcreteModel, FooWithUrl, ProxyModel class ContentTypesTests(TestCase): - def setUp(self): ContentType.objects.clear_cache() @@ -31,7 +30,7 @@ class ContentTypesTests(TestCase): with self.assertNumQueries(0): ContentType.objects.get_for_id(ct.id) with self.assertNumQueries(0): - ContentType.objects.get_by_natural_key('contenttypes', 'contenttype') + ContentType.objects.get_by_natural_key("contenttypes", "contenttype") # Once we clear the cache, another lookup will again hit the DB ContentType.objects.clear_cache() @@ -41,42 +40,55 @@ class ContentTypesTests(TestCase): # 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') + 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') + ContentType.objects.get_by_natural_key("contenttypes", "contenttype") def test_get_for_models_creation(self): ContentType.objects.all().delete() with self.assertNumQueries(4): - cts = ContentType.objects.get_for_models(ContentType, FooWithUrl, ProxyModel, ConcreteModel) - self.assertEqual(cts, { - ContentType: ContentType.objects.get_for_model(ContentType), - FooWithUrl: ContentType.objects.get_for_model(FooWithUrl), - ProxyModel: ContentType.objects.get_for_model(ProxyModel), - ConcreteModel: ContentType.objects.get_for_model(ConcreteModel), - }) + cts = ContentType.objects.get_for_models( + ContentType, FooWithUrl, ProxyModel, ConcreteModel + ) + self.assertEqual( + cts, + { + ContentType: ContentType.objects.get_for_model(ContentType), + FooWithUrl: ContentType.objects.get_for_model(FooWithUrl), + ProxyModel: ContentType.objects.get_for_model(ProxyModel), + ConcreteModel: ContentType.objects.get_for_model(ConcreteModel), + }, + ) def test_get_for_models_empty_cache(self): # Empty cache. with self.assertNumQueries(1): - cts = ContentType.objects.get_for_models(ContentType, FooWithUrl, ProxyModel, ConcreteModel) - self.assertEqual(cts, { - ContentType: ContentType.objects.get_for_model(ContentType), - FooWithUrl: ContentType.objects.get_for_model(FooWithUrl), - ProxyModel: ContentType.objects.get_for_model(ProxyModel), - ConcreteModel: ContentType.objects.get_for_model(ConcreteModel), - }) + cts = ContentType.objects.get_for_models( + ContentType, FooWithUrl, ProxyModel, ConcreteModel + ) + self.assertEqual( + cts, + { + ContentType: ContentType.objects.get_for_model(ContentType), + FooWithUrl: ContentType.objects.get_for_model(FooWithUrl), + ProxyModel: ContentType.objects.get_for_model(ProxyModel), + ConcreteModel: ContentType.objects.get_for_model(ConcreteModel), + }, + ) 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), - }) + 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 @@ -84,24 +96,28 @@ class ContentTypesTests(TestCase): 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), - }) + self.assertEqual( + cts, + { + ContentType: ContentType.objects.get_for_model(ContentType), + FooWithUrl: ContentType.objects.get_for_model(FooWithUrl), + }, + ) - @isolate_apps('contenttypes_tests') + @isolate_apps("contenttypes_tests") def test_get_for_model_create_contenttype(self): """ ContentTypeManager.get_for_model() creates the corresponding content type if it doesn't exist in the database. """ + class ModelCreatedOnTheFly(models.Model): name = models.CharField() ct = ContentType.objects.get_for_model(ModelCreatedOnTheFly) - self.assertEqual(ct.app_label, 'contenttypes_tests') - self.assertEqual(ct.model, 'modelcreatedonthefly') - self.assertEqual(str(ct), 'modelcreatedonthefly') + self.assertEqual(ct.app_label, "contenttypes_tests") + self.assertEqual(ct.model, "modelcreatedonthefly") + self.assertEqual(str(ct), "modelcreatedonthefly") def test_get_for_concrete_model(self): """ @@ -109,26 +125,41 @@ class ContentTypesTests(TestCase): 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)) + 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) + 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__ + 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) + ) self.assertEqual( concrete_model_ct, - ContentType.objects.get_for_model(DeferredConcreteModel, for_concrete_model=False) + ContentType.objects.get_for_model( + DeferredConcreteModel, for_concrete_model=False + ), + ) + self.assertEqual( + concrete_model_ct, ContentType.objects.get_for_model(DeferredProxyModel) ) - 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) + ContentType.objects.get_for_model( + DeferredProxyModel, for_concrete_model=False + ), ) def test_get_for_concrete_models(self): @@ -139,36 +170,54 @@ class ContentTypesTests(TestCase): 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, - }) + 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, - }) + 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__ + 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 + ) + 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, - }) + self.assertEqual( + cts, + { + DeferredConcreteModel: concrete_model_ct, + DeferredProxyModel: proxy_model_ct, + }, + ) def test_cache_not_shared_between_managers(self): with self.assertNumQueries(1): @@ -189,10 +238,10 @@ class ContentTypesTests(TestCase): anymore. """ ct = ContentType.objects.create( - app_label='contenttypes', - model='OldModel', + app_label="contenttypes", + model="OldModel", ) - self.assertEqual(str(ct), 'OldModel') + self.assertEqual(str(ct), "OldModel") self.assertIsNone(ct.model_class()) # Stale ContentTypes can be fetched like any other object. @@ -200,29 +249,29 @@ class ContentTypesTests(TestCase): self.assertIsNone(ct_fetched.model_class()) def test_str(self): - ct = ContentType.objects.get(app_label='contenttypes_tests', model='site') - self.assertEqual(str(ct), 'contenttypes_tests | site') + ct = ContentType.objects.get(app_label="contenttypes_tests", model="site") + self.assertEqual(str(ct), "contenttypes_tests | site") def test_app_labeled_name(self): - ct = ContentType.objects.get(app_label='contenttypes_tests', model='site') - self.assertEqual(ct.app_labeled_name, 'contenttypes_tests | site') + ct = ContentType.objects.get(app_label="contenttypes_tests", model="site") + self.assertEqual(ct.app_labeled_name, "contenttypes_tests | site") def test_app_labeled_name_unknown_model(self): - ct = ContentType(app_label='contenttypes_tests', model='unknown') - self.assertEqual(ct.app_labeled_name, 'unknown') + ct = ContentType(app_label="contenttypes_tests", model="unknown") + self.assertEqual(ct.app_labeled_name, "unknown") class TestRouter: def db_for_read(self, model, **hints): - return 'other' + return "other" def db_for_write(self, model, **hints): - return 'default' + return "default" @override_settings(DATABASE_ROUTERS=[TestRouter()]) class ContentTypesMultidbTests(TestCase): - databases = {'default', 'other'} + databases = {"default", "other"} def test_multidb(self): """ @@ -230,5 +279,7 @@ class ContentTypesMultidbTests(TestCase): db_for_read(). """ ContentType.objects.clear_cache() - with self.assertNumQueries(0, using='default'), self.assertNumQueries(1, using='other'): + with self.assertNumQueries(0, using="default"), self.assertNumQueries( + 1, using="other" + ): ContentType.objects.get_for_model(Author) diff --git a/tests/contenttypes_tests/test_operations.py b/tests/contenttypes_tests/test_operations.py index 3ec8b75e87..a2bff373a4 100644 --- a/tests/contenttypes_tests/test_operations.py +++ b/tests/contenttypes_tests/test_operations.py @@ -10,27 +10,31 @@ from django.test import TransactionTestCase, override_settings @override_settings( MIGRATION_MODULES=dict( settings.MIGRATION_MODULES, - contenttypes_tests='contenttypes_tests.operations_migrations', + contenttypes_tests="contenttypes_tests.operations_migrations", ), ) class ContentTypeOperationsTests(TransactionTestCase): - databases = {'default', 'other'} + databases = {"default", "other"} available_apps = [ - 'contenttypes_tests', - 'django.contrib.contenttypes', + "contenttypes_tests", + "django.contrib.contenttypes", ] class TestRouter: def db_for_write(self, model, **hints): - return 'default' + return "default" def setUp(self): - app_config = apps.get_app_config('contenttypes_tests') - models.signals.post_migrate.connect(self.assertOperationsInjected, sender=app_config) + 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) + 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: @@ -38,45 +42,151 @@ class ContentTypeOperationsTests(TransactionTestCase): for operation in operations: if isinstance(operation, migrations.RenameModel): next_operation = next(operations) - self.assertIsInstance(next_operation, contenttypes_management.RenameContentType) + 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') - 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()) - 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()) + ContentType.objects.create(app_label="contenttypes_tests", model="foo") + 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() + ) + 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() + ) @override_settings(DATABASE_ROUTERS=[TestRouter()]) def test_existing_content_type_rename_other_database(self): - ContentType.objects.using('other').create(app_label='contenttypes_tests', model='foo') - other_content_types = ContentType.objects.using('other').filter(app_label='contenttypes_tests') - call_command('migrate', 'contenttypes_tests', database='other', interactive=False, verbosity=0) - self.assertFalse(other_content_types.filter(model='foo').exists()) - self.assertTrue(other_content_types.filter(model='renamedfoo').exists()) - call_command('migrate', 'contenttypes_tests', 'zero', database='other', interactive=False, verbosity=0) - self.assertTrue(other_content_types.filter(model='foo').exists()) - self.assertFalse(other_content_types.filter(model='renamedfoo').exists()) + ContentType.objects.using("other").create( + app_label="contenttypes_tests", model="foo" + ) + other_content_types = ContentType.objects.using("other").filter( + app_label="contenttypes_tests" + ) + call_command( + "migrate", + "contenttypes_tests", + database="other", + interactive=False, + verbosity=0, + ) + self.assertFalse(other_content_types.filter(model="foo").exists()) + self.assertTrue(other_content_types.filter(model="renamedfoo").exists()) + call_command( + "migrate", + "contenttypes_tests", + "zero", + database="other", + interactive=False, + verbosity=0, + ) + self.assertTrue(other_content_types.filter(model="foo").exists()) + self.assertFalse(other_content_types.filter(model="renamedfoo").exists()) def test_missing_content_type_rename_ignore(self): - 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()) - 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()) + 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() + ) + 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') - 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()) - 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()) + ContentType.objects.create(app_label="contenttypes_tests", model="foo") + ContentType.objects.create(app_label="contenttypes_tests", model="renamedfoo") + 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() + ) + 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() + ) diff --git a/tests/contenttypes_tests/test_views.py b/tests/contenttypes_tests/test_views.py index e54e5ff925..4d85d15065 100644 --- a/tests/contenttypes_tests/test_views.py +++ b/tests/contenttypes_tests/test_views.py @@ -9,37 +9,54 @@ from django.http import Http404, HttpRequest from django.test import TestCase, override_settings from .models import ( - Article, Author, FooWithBrokenAbsoluteUrl, FooWithoutUrl, FooWithUrl, - ModelWithM2MToSite, ModelWithNullFKToSite, SchemeIncludedURL, - Site as MockSite, + Article, + Author, + FooWithBrokenAbsoluteUrl, + FooWithoutUrl, + FooWithUrl, + ModelWithM2MToSite, + ModelWithNullFKToSite, + SchemeIncludedURL, ) +from .models import Site as MockSite -@override_settings(ROOT_URLCONF='contenttypes_tests.urls') +@override_settings(ROOT_URLCONF="contenttypes_tests.urls") class ContentTypesViewsTests(TestCase): - @classmethod def setUpTestData(cls): # Don't use the manager to ensure the site exists with pk=1, regardless # of whether or not it already exists. - cls.site1 = Site(pk=1, domain='testserver', name='testserver') + cls.site1 = Site(pk=1, domain="testserver", name="testserver") cls.site1.save() - cls.author1 = Author.objects.create(name='Boris') + cls.author1 = Author.objects.create(name="Boris") cls.article1 = Article.objects.create( - title='Old Article', slug='old_article', author=cls.author1, + title="Old Article", + slug="old_article", + author=cls.author1, date_created=datetime.datetime(2001, 1, 1, 21, 22, 23), ) cls.article2 = Article.objects.create( - title='Current Article', slug='current_article', author=cls.author1, + title="Current Article", + slug="current_article", + author=cls.author1, date_created=datetime.datetime(2007, 9, 17, 21, 22, 23), ) cls.article3 = Article.objects.create( - title='Future Article', slug='future_article', author=cls.author1, + title="Future Article", + slug="future_article", + author=cls.author1, date_created=datetime.datetime(3000, 1, 1, 21, 22, 23), ) - cls.scheme1 = SchemeIncludedURL.objects.create(url='http://test_scheme_included_http/') - cls.scheme2 = SchemeIncludedURL.objects.create(url='https://test_scheme_included_https/') - cls.scheme3 = SchemeIncludedURL.objects.create(url='//test_default_scheme_kept/') + cls.scheme1 = SchemeIncludedURL.objects.create( + url="http://test_scheme_included_http/" + ) + cls.scheme2 = SchemeIncludedURL.objects.create( + url="https://test_scheme_included_https/" + ) + cls.scheme3 = SchemeIncludedURL.objects.create( + url="//test_default_scheme_kept/" + ) def setUp(self): Site.objects.clear_cache() @@ -48,9 +65,16 @@ class ContentTypesViewsTests(TestCase): "Can view a shortcut for an Author object that has a get_absolute_url method" for obj in Author.objects.all(): with self.subTest(obj=obj): - short_url = '/shortcut/%s/%s/' % (ContentType.objects.get_for_model(Author).id, obj.pk) + short_url = "/shortcut/%s/%s/" % ( + ContentType.objects.get_for_model(Author).id, + obj.pk, + ) response = self.client.get(short_url) - self.assertRedirects(response, 'http://testserver%s' % obj.get_absolute_url(), target_status_code=404) + self.assertRedirects( + response, + "http://testserver%s" % obj.get_absolute_url(), + target_status_code=404, + ) def test_shortcut_with_absolute_url_including_scheme(self): """ @@ -59,9 +83,14 @@ class ContentTypesViewsTests(TestCase): """ for obj in SchemeIncludedURL.objects.all(): with self.subTest(obj=obj): - short_url = '/shortcut/%s/%s/' % (ContentType.objects.get_for_model(SchemeIncludedURL).id, obj.pk) + short_url = "/shortcut/%s/%s/" % ( + ContentType.objects.get_for_model(SchemeIncludedURL).id, + obj.pk, + ) response = self.client.get(short_url) - self.assertRedirects(response, obj.get_absolute_url(), fetch_redirect_response=False) + self.assertRedirects( + response, obj.get_absolute_url(), fetch_redirect_response=False + ) def test_shortcut_no_absolute_url(self): """ @@ -70,88 +99,119 @@ class ContentTypesViewsTests(TestCase): """ for obj in Article.objects.all(): with self.subTest(obj=obj): - short_url = '/shortcut/%s/%s/' % (ContentType.objects.get_for_model(Article).id, obj.pk) + short_url = "/shortcut/%s/%s/" % ( + ContentType.objects.get_for_model(Article).id, + obj.pk, + ) response = self.client.get(short_url) self.assertEqual(response.status_code, 404) def test_wrong_type_pk(self): - short_url = '/shortcut/%s/%s/' % (ContentType.objects.get_for_model(Author).id, 'nobody/expects') + short_url = "/shortcut/%s/%s/" % ( + ContentType.objects.get_for_model(Author).id, + "nobody/expects", + ) response = self.client.get(short_url) self.assertEqual(response.status_code, 404) def test_shortcut_bad_pk(self): - short_url = '/shortcut/%s/%s/' % (ContentType.objects.get_for_model(Author).id, '42424242') + short_url = "/shortcut/%s/%s/" % ( + ContentType.objects.get_for_model(Author).id, + "42424242", + ) response = self.client.get(short_url) self.assertEqual(response.status_code, 404) def test_nonint_content_type(self): an_author = Author.objects.all()[0] - short_url = '/shortcut/%s/%s/' % ('spam', an_author.pk) + short_url = "/shortcut/%s/%s/" % ("spam", an_author.pk) response = self.client.get(short_url) self.assertEqual(response.status_code, 404) def test_bad_content_type(self): an_author = Author.objects.all()[0] - short_url = '/shortcut/%s/%s/' % (42424242, an_author.pk) + short_url = "/shortcut/%s/%s/" % (42424242, an_author.pk) response = self.client.get(short_url) self.assertEqual(response.status_code, 404) -@override_settings(ROOT_URLCONF='contenttypes_tests.urls') +@override_settings(ROOT_URLCONF="contenttypes_tests.urls") class ContentTypesViewsSiteRelTests(TestCase): - def setUp(self): Site.objects.clear_cache() @classmethod def setUpTestData(cls): - cls.site_2 = Site.objects.create(domain='example2.com', name='example2.com') - cls.site_3 = Site.objects.create(domain='example3.com', name='example3.com') + cls.site_2 = Site.objects.create(domain="example2.com", name="example2.com") + cls.site_3 = Site.objects.create(domain="example3.com", name="example3.com") - @mock.patch('django.apps.apps.get_model') + @mock.patch("django.apps.apps.get_model") def test_shortcut_view_with_null_site_fk(self, get_model): """ The shortcut view works if a model's ForeignKey to site is None. """ - get_model.side_effect = lambda *args, **kwargs: MockSite if args[0] == 'sites.Site' else ModelWithNullFKToSite + get_model.side_effect = ( + lambda *args, **kwargs: MockSite + if args[0] == "sites.Site" + else ModelWithNullFKToSite + ) - obj = ModelWithNullFKToSite.objects.create(title='title') - url = '/shortcut/%s/%s/' % (ContentType.objects.get_for_model(ModelWithNullFKToSite).id, obj.pk) + obj = ModelWithNullFKToSite.objects.create(title="title") + url = "/shortcut/%s/%s/" % ( + ContentType.objects.get_for_model(ModelWithNullFKToSite).id, + obj.pk, + ) response = self.client.get(url) - expected_url = 'http://example.com%s' % obj.get_absolute_url() + expected_url = "http://example.com%s" % obj.get_absolute_url() self.assertRedirects(response, expected_url, fetch_redirect_response=False) - @mock.patch('django.apps.apps.get_model') + @mock.patch("django.apps.apps.get_model") def test_shortcut_view_with_site_m2m(self, get_model): """ When the object has a ManyToManyField to Site, redirect to the current site if it's attached to the object or to the domain of the first site found in the m2m relationship. """ - get_model.side_effect = lambda *args, **kwargs: MockSite if args[0] == 'sites.Site' else ModelWithM2MToSite + get_model.side_effect = ( + lambda *args, **kwargs: MockSite + if args[0] == "sites.Site" + else ModelWithM2MToSite + ) # get_current_site() will lookup a Site object, so these must match the # domains in the MockSite model. - MockSite.objects.bulk_create([ - MockSite(pk=1, domain='example.com'), - MockSite(pk=self.site_2.pk, domain=self.site_2.domain), - MockSite(pk=self.site_3.pk, domain=self.site_3.domain), - ]) + MockSite.objects.bulk_create( + [ + MockSite(pk=1, domain="example.com"), + MockSite(pk=self.site_2.pk, domain=self.site_2.domain), + MockSite(pk=self.site_3.pk, domain=self.site_3.domain), + ] + ) ct = ContentType.objects.get_for_model(ModelWithM2MToSite) - site_3_obj = ModelWithM2MToSite.objects.create(title='Not Linked to Current Site') + site_3_obj = ModelWithM2MToSite.objects.create( + title="Not Linked to Current Site" + ) site_3_obj.sites.add(MockSite.objects.get(pk=self.site_3.pk)) - expected_url = 'http://%s%s' % (self.site_3.domain, site_3_obj.get_absolute_url()) + expected_url = "http://%s%s" % ( + self.site_3.domain, + site_3_obj.get_absolute_url(), + ) with self.settings(SITE_ID=self.site_2.pk): # Redirects to the domain of the first Site found in the m2m # relationship (ordering is arbitrary). - response = self.client.get('/shortcut/%s/%s/' % (ct.pk, site_3_obj.pk)) + response = self.client.get("/shortcut/%s/%s/" % (ct.pk, site_3_obj.pk)) self.assertRedirects(response, expected_url, fetch_redirect_response=False) - obj_with_sites = ModelWithM2MToSite.objects.create(title='Linked to Current Site') + obj_with_sites = ModelWithM2MToSite.objects.create( + title="Linked to Current Site" + ) obj_with_sites.sites.set(MockSite.objects.all()) - shortcut_url = '/shortcut/%s/%s/' % (ct.pk, obj_with_sites.pk) - expected_url = 'http://%s%s' % (self.site_2.domain, obj_with_sites.get_absolute_url()) + shortcut_url = "/shortcut/%s/%s/" % (ct.pk, obj_with_sites.pk) + expected_url = "http://%s%s" % ( + self.site_2.domain, + obj_with_sites.get_absolute_url(), + ) with self.settings(SITE_ID=self.site_2.pk): # Redirects to the domain of the Site matching the current site's @@ -167,33 +227,34 @@ class ContentTypesViewsSiteRelTests(TestCase): class ShortcutViewTests(TestCase): - def setUp(self): self.request = HttpRequest() - self.request.META = {'SERVER_NAME': 'Example.com', 'SERVER_PORT': '80'} + self.request.META = {"SERVER_NAME": "Example.com", "SERVER_PORT": "80"} - @override_settings(ALLOWED_HOSTS=['example.com']) + @override_settings(ALLOWED_HOSTS=["example.com"]) def test_not_dependent_on_sites_app(self): """ The view returns a complete URL regardless of whether the sites framework is installed. """ user_ct = ContentType.objects.get_for_model(FooWithUrl) - obj = FooWithUrl.objects.create(name='john') - with self.modify_settings(INSTALLED_APPS={'append': 'django.contrib.sites'}): + obj = FooWithUrl.objects.create(name="john") + with self.modify_settings(INSTALLED_APPS={"append": "django.contrib.sites"}): response = shortcut(self.request, user_ct.id, obj.id) self.assertEqual( - 'http://%s/users/john/' % get_current_site(self.request).domain, - response.headers.get('location') + "http://%s/users/john/" % get_current_site(self.request).domain, + response.headers.get("location"), ) - with self.modify_settings(INSTALLED_APPS={'remove': 'django.contrib.sites'}): + with self.modify_settings(INSTALLED_APPS={"remove": "django.contrib.sites"}): response = shortcut(self.request, user_ct.id, obj.id) - self.assertEqual('http://Example.com/users/john/', response.headers.get('location')) + self.assertEqual( + "http://Example.com/users/john/", response.headers.get("location") + ) def test_model_without_get_absolute_url(self): """The view returns 404 when Model.get_absolute_url() isn't defined.""" user_ct = ContentType.objects.get_for_model(FooWithoutUrl) - obj = FooWithoutUrl.objects.create(name='john') + obj = FooWithoutUrl.objects.create(name="john") with self.assertRaises(Http404): shortcut(self.request, user_ct.id, obj.id) @@ -203,6 +264,6 @@ class ShortcutViewTests(TestCase): Model.get_absolute_url() (#8997). """ user_ct = ContentType.objects.get_for_model(FooWithBrokenAbsoluteUrl) - obj = FooWithBrokenAbsoluteUrl.objects.create(name='john') + obj = FooWithBrokenAbsoluteUrl.objects.create(name="john") with self.assertRaises(AttributeError): shortcut(self.request, user_ct.id, obj.id) diff --git a/tests/contenttypes_tests/urls.py b/tests/contenttypes_tests/urls.py index 1403b00ac4..8f94d8a54c 100644 --- a/tests/contenttypes_tests/urls.py +++ b/tests/contenttypes_tests/urls.py @@ -2,5 +2,5 @@ from django.contrib.contenttypes import views from django.urls import re_path urlpatterns = [ - re_path(r'^shortcut/([0-9]+)/(.*)/$', views.shortcut), + re_path(r"^shortcut/([0-9]+)/(.*)/$", views.shortcut), ] |
