File: test_management.py

package info (click to toggle)
python-django 3%3A3.2.19-1%2Bdeb12u2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 56,696 kB
  • sloc: python: 264,418; javascript: 18,362; xml: 193; makefile: 178; sh: 43
file content (106 lines) | stat: -rw-r--r-- 4,987 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
from unittest import mock

from django.apps.registry import Apps, apps
from django.contrib.contenttypes import management as contenttypes_management
from django.contrib.contenttypes.models import ContentType
from django.core.management import call_command
from django.test import TestCase, modify_settings
from django.test.utils import captured_stdout

from .models import ModelWithNullFKToSite, Post


@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',
    ]

    @classmethod
    def setUpTestData(cls):
        cls.before_count = ContentType.objects.count()
        cls.content_type = ContentType.objects.create(app_label='contenttypes_tests', model='Fake')

    def setUp(self):
        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)
        # 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 captured_stdout() as 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.assertEqual(ContentType.objects.count(), self.before_count)

    def test_interactive_true_without_dependent_objects(self):
        """
        interactive mode deletes stale content types even if there aren't any
        dependent objects.
        """
        with mock.patch('builtins.input', return_value='yes'):
            with captured_stdout() as stdout:
                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())
        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)
        self.assertEqual(ContentType.objects.count(), self.before_count + 1)

    @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)
        self.assertNotIn(
            "Deleting stale content type 'empty_models | Fake 1'",
            stdout.getvalue(),
        )
        self.assertIn(
            "Deleting stale content type 'no_models | Fake 2'",
            stdout.getvalue(),
        )
        self.assertEqual(ContentType.objects.count(), self.before_count + 1)

    @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)
        self.assertIn(
            "Deleting stale content type 'empty_models | Fake 1'",
            stdout.getvalue(),
        )
        self.assertIn(
            "Deleting stale content type 'no_models | Fake 2'",
            stdout.getvalue(),
        )
        self.assertEqual(ContentType.objects.count(), self.before_count)