mirror of
				https://github.com/django/django.git
				synced 2025-10-30 17:16:10 +00:00 
			
		
		
		
	Thanks Carl Meyer for django-secure and for reviewing. Thanks also to Zach Borboa, Erik Romijn, Collin Anderson, and Jorge Carleitao for reviews.
		
			
				
	
	
		
			330 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			330 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # -*- coding: utf-8 -*-
 | |
| from __future__ import unicode_literals
 | |
| 
 | |
| from django.utils.six import StringIO
 | |
| import sys
 | |
| 
 | |
| from django.apps import apps
 | |
| from django.conf import settings
 | |
| from django.core import checks
 | |
| from django.core.checks import Error, Warning
 | |
| from django.core.checks.registry import CheckRegistry
 | |
| from django.core.checks.compatibility.django_1_6_0 import check_1_6_compatibility
 | |
| from django.core.checks.compatibility.django_1_7_0 import check_1_7_compatibility
 | |
| from django.core.management.base import CommandError
 | |
| from django.core.management import call_command
 | |
| from django.db.models.fields import NOT_PROVIDED
 | |
| from django.test import TestCase
 | |
| from django.test.utils import override_settings, override_system_checks
 | |
| from django.utils.encoding import force_text
 | |
| 
 | |
| from .models import SimpleModel, Book
 | |
| 
 | |
| 
 | |
| class DummyObj(object):
 | |
|     def __repr__(self):
 | |
|         return "obj"
 | |
| 
 | |
| 
 | |
| class SystemCheckFrameworkTests(TestCase):
 | |
| 
 | |
|     def test_register_and_run_checks(self):
 | |
|         calls = [0]
 | |
| 
 | |
|         registry = CheckRegistry()
 | |
| 
 | |
|         @registry.register()
 | |
|         def f(**kwargs):
 | |
|             calls[0] += 1
 | |
|             return [1, 2, 3]
 | |
|         errors = registry.run_checks()
 | |
|         self.assertEqual(errors, [1, 2, 3])
 | |
|         self.assertEqual(calls[0], 1)
 | |
| 
 | |
| 
 | |
| class MessageTests(TestCase):
 | |
| 
 | |
|     def test_printing(self):
 | |
|         e = Error("Message", hint="Hint", obj=DummyObj())
 | |
|         expected = "obj: Message\n\tHINT: Hint"
 | |
|         self.assertEqual(force_text(e), expected)
 | |
| 
 | |
|     def test_printing_no_hint(self):
 | |
|         e = Error("Message", hint=None, obj=DummyObj())
 | |
|         expected = "obj: Message"
 | |
|         self.assertEqual(force_text(e), expected)
 | |
| 
 | |
|     def test_printing_no_object(self):
 | |
|         e = Error("Message", hint="Hint", obj=None)
 | |
|         expected = "?: Message\n\tHINT: Hint"
 | |
|         self.assertEqual(force_text(e), expected)
 | |
| 
 | |
|     def test_printing_with_given_id(self):
 | |
|         e = Error("Message", hint="Hint", obj=DummyObj(), id="ID")
 | |
|         expected = "obj: (ID) Message\n\tHINT: Hint"
 | |
|         self.assertEqual(force_text(e), expected)
 | |
| 
 | |
|     def test_printing_field_error(self):
 | |
|         field = SimpleModel._meta.get_field('field')
 | |
|         e = Error("Error", hint=None, obj=field)
 | |
|         expected = "check_framework.SimpleModel.field: Error"
 | |
|         self.assertEqual(force_text(e), expected)
 | |
| 
 | |
|     def test_printing_model_error(self):
 | |
|         e = Error("Error", hint=None, obj=SimpleModel)
 | |
|         expected = "check_framework.SimpleModel: Error"
 | |
|         self.assertEqual(force_text(e), expected)
 | |
| 
 | |
|     def test_printing_manager_error(self):
 | |
|         manager = SimpleModel.manager
 | |
|         e = Error("Error", hint=None, obj=manager)
 | |
|         expected = "check_framework.SimpleModel.manager: Error"
 | |
|         self.assertEqual(force_text(e), expected)
 | |
| 
 | |
| 
 | |
| class Django_1_6_0_CompatibilityChecks(TestCase):
 | |
| 
 | |
|     @override_settings(TEST_RUNNER='django.test.runner.DiscoverRunner')
 | |
|     def test_test_runner_new_default(self):
 | |
|         errors = check_1_6_compatibility()
 | |
|         self.assertEqual(errors, [])
 | |
| 
 | |
|     @override_settings(TEST_RUNNER='myapp.test.CustomRunner')
 | |
|     def test_test_runner_overriden(self):
 | |
|         errors = check_1_6_compatibility()
 | |
|         self.assertEqual(errors, [])
 | |
| 
 | |
|     def test_test_runner_not_set_explicitly(self):
 | |
|         # If TEST_RUNNER was set explicitly, temporarily pretend it wasn't
 | |
|         test_runner_overridden = False
 | |
|         if 'TEST_RUNNER' in settings._wrapped._explicit_settings:
 | |
|             test_runner_overridden = True
 | |
|             settings._wrapped._explicit_settings.remove('TEST_RUNNER')
 | |
|         # We remove some settings to make this look like a project generated under Django 1.5.
 | |
|         settings._wrapped._explicit_settings.add('MANAGERS')
 | |
|         settings._wrapped._explicit_settings.add('ADMINS')
 | |
|         try:
 | |
|             errors = check_1_6_compatibility()
 | |
|             expected = [
 | |
|                 checks.Warning(
 | |
|                     "Some project unittests may not execute as expected.",
 | |
|                     hint=("Django 1.6 introduced a new default test runner. It looks like "
 | |
|                           "this project was generated using Django 1.5 or earlier. You should "
 | |
|                           "ensure your tests are all running & behaving as expected. See "
 | |
|                           "https://docs.djangoproject.com/en/dev/releases/1.6/#new-test-runner "
 | |
|                           "for more information."),
 | |
|                     obj=None,
 | |
|                     id='1_6.W001',
 | |
|                 )
 | |
|             ]
 | |
|             self.assertEqual(errors, expected)
 | |
|         finally:
 | |
|             # Restore settings value
 | |
|             if test_runner_overridden:
 | |
|                 settings._wrapped._explicit_settings.add('TEST_RUNNER')
 | |
|             settings._wrapped._explicit_settings.remove('MANAGERS')
 | |
|             settings._wrapped._explicit_settings.remove('ADMINS')
 | |
| 
 | |
|     def test_boolean_field_default_value(self):
 | |
|         with self.settings(TEST_RUNNER='myapp.test.CustomRunnner'):
 | |
|             # We patch the field's default value to trigger the warning
 | |
|             boolean_field = Book._meta.get_field('is_published')
 | |
|             old_default = boolean_field.default
 | |
|             try:
 | |
|                 boolean_field.default = NOT_PROVIDED
 | |
|                 errors = check_1_6_compatibility()
 | |
|                 expected = [
 | |
|                     checks.Warning(
 | |
|                         'BooleanField does not have a default value.',
 | |
|                         hint=('Django 1.6 changed the default value of BooleanField from False to None. '
 | |
|                               'See https://docs.djangoproject.com/en/1.6/ref/models/fields/#booleanfield '
 | |
|                               'for more information.'),
 | |
|                         obj=boolean_field,
 | |
|                         id='1_6.W002',
 | |
|                     )
 | |
|                 ]
 | |
|                 self.assertEqual(errors, expected)
 | |
|             finally:
 | |
|                 # Restore the ``default``
 | |
|                 boolean_field.default = old_default
 | |
| 
 | |
| 
 | |
| class Django_1_7_0_CompatibilityChecks(TestCase):
 | |
| 
 | |
|     @override_settings(MIDDLEWARE_CLASSES=('django.contrib.sessions.middleware.SessionMiddleware',))
 | |
|     def test_middleware_classes_overridden(self):
 | |
|         errors = check_1_7_compatibility()
 | |
|         self.assertEqual(errors, [])
 | |
| 
 | |
|     def test_middleware_classes_not_set_explicitly(self):
 | |
|         # If MIDDLEWARE_CLASSES was set explicitly, temporarily pretend it wasn't
 | |
|         middleware_classes_overridden = False
 | |
|         if 'MIDDLEWARE_CLASSES' in settings._wrapped._explicit_settings:
 | |
|             middleware_classes_overridden = True
 | |
|             settings._wrapped._explicit_settings.remove('MIDDLEWARE_CLASSES')
 | |
|         try:
 | |
|             errors = check_1_7_compatibility()
 | |
|             expected = [
 | |
|                 checks.Warning(
 | |
|                     "MIDDLEWARE_CLASSES is not set.",
 | |
|                     hint=("Django 1.7 changed the global defaults for the MIDDLEWARE_CLASSES. "
 | |
|                           "django.contrib.sessions.middleware.SessionMiddleware, "
 | |
|                           "django.contrib.auth.middleware.AuthenticationMiddleware, and "
 | |
|                           "django.contrib.messages.middleware.MessageMiddleware were removed from the defaults. "
 | |
|                           "If your project needs these middleware then you should configure this setting."),
 | |
|                     obj=None,
 | |
|                     id='1_7.W001',
 | |
|                 )
 | |
|             ]
 | |
|             self.assertEqual(errors, expected)
 | |
|         finally:
 | |
|             # Restore settings value
 | |
|             if middleware_classes_overridden:
 | |
|                 settings._wrapped._explicit_settings.add('MIDDLEWARE_CLASSES')
 | |
| 
 | |
| 
 | |
| def simple_system_check(**kwargs):
 | |
|     simple_system_check.kwargs = kwargs
 | |
|     return []
 | |
| 
 | |
| 
 | |
| def tagged_system_check(**kwargs):
 | |
|     tagged_system_check.kwargs = kwargs
 | |
|     return []
 | |
| tagged_system_check.tags = ['simpletag']
 | |
| 
 | |
| 
 | |
| def deployment_system_check(**kwargs):
 | |
|     deployment_system_check.kwargs = kwargs
 | |
|     return [checks.Warning('Deployment Check')]
 | |
| deployment_system_check.tags = ['deploymenttag']
 | |
| 
 | |
| 
 | |
| class CheckCommandTests(TestCase):
 | |
| 
 | |
|     def setUp(self):
 | |
|         simple_system_check.kwargs = None
 | |
|         tagged_system_check.kwargs = None
 | |
|         self.old_stdout, self.old_stderr = sys.stdout, sys.stderr
 | |
|         sys.stdout, sys.stderr = StringIO(), StringIO()
 | |
| 
 | |
|     def tearDown(self):
 | |
|         sys.stdout, sys.stderr = self.old_stdout, self.old_stderr
 | |
| 
 | |
|     @override_system_checks([simple_system_check, tagged_system_check])
 | |
|     def test_simple_call(self):
 | |
|         call_command('check')
 | |
|         self.assertEqual(simple_system_check.kwargs, {'app_configs': None})
 | |
|         self.assertEqual(tagged_system_check.kwargs, {'app_configs': None})
 | |
| 
 | |
|     @override_system_checks([simple_system_check, tagged_system_check])
 | |
|     def test_given_app(self):
 | |
|         call_command('check', 'auth', 'admin')
 | |
|         auth_config = apps.get_app_config('auth')
 | |
|         admin_config = apps.get_app_config('admin')
 | |
|         self.assertEqual(simple_system_check.kwargs, {'app_configs': [auth_config, admin_config]})
 | |
|         self.assertEqual(tagged_system_check.kwargs, {'app_configs': [auth_config, admin_config]})
 | |
| 
 | |
|     @override_system_checks([simple_system_check, tagged_system_check])
 | |
|     def test_given_tag(self):
 | |
|         call_command('check', tags=['simpletag'])
 | |
|         self.assertEqual(simple_system_check.kwargs, None)
 | |
|         self.assertEqual(tagged_system_check.kwargs, {'app_configs': None})
 | |
| 
 | |
|     @override_system_checks([simple_system_check, tagged_system_check])
 | |
|     def test_invalid_tag(self):
 | |
|         self.assertRaises(CommandError, call_command, 'check', tags=['missingtag'])
 | |
| 
 | |
|     @override_system_checks([simple_system_check])
 | |
|     def test_list_tags_empty(self):
 | |
|         call_command('check', list_tags=True)
 | |
|         self.assertEqual('\n', sys.stdout.getvalue())
 | |
| 
 | |
|     @override_system_checks([tagged_system_check])
 | |
|     def test_list_tags(self):
 | |
|         call_command('check', list_tags=True)
 | |
|         self.assertEqual('simpletag\n', sys.stdout.getvalue())
 | |
| 
 | |
|     @override_system_checks([tagged_system_check], deployment_checks=[deployment_system_check])
 | |
|     def test_list_deployment_check_omitted(self):
 | |
|         call_command('check', list_tags=True)
 | |
|         self.assertEqual('simpletag\n', sys.stdout.getvalue())
 | |
| 
 | |
|     @override_system_checks([tagged_system_check], deployment_checks=[deployment_system_check])
 | |
|     def test_list_deployment_check_included(self):
 | |
|         call_command('check', deploy=True, list_tags=True)
 | |
|         self.assertEqual('deploymenttag\nsimpletag\n', sys.stdout.getvalue())
 | |
| 
 | |
|     @override_system_checks([tagged_system_check], deployment_checks=[deployment_system_check])
 | |
|     def test_tags_deployment_check_omitted(self):
 | |
|         msg = 'There is no system check with the "deploymenttag" tag.'
 | |
|         with self.assertRaisesMessage(CommandError, msg):
 | |
|             call_command('check', tags=['deploymenttag'])
 | |
| 
 | |
|     @override_system_checks([tagged_system_check], deployment_checks=[deployment_system_check])
 | |
|     def test_tags_deployment_check_included(self):
 | |
|         call_command('check', deploy=True, tags=['deploymenttag'])
 | |
|         self.assertIn('Deployment Check', sys.stderr.getvalue())
 | |
| 
 | |
| 
 | |
| def custom_error_system_check(app_configs, **kwargs):
 | |
|     return [
 | |
|         Error(
 | |
|             'Error',
 | |
|             hint=None,
 | |
|             id='myerrorcheck.E001',
 | |
|         )
 | |
|     ]
 | |
| 
 | |
| 
 | |
| def custom_warning_system_check(app_configs, **kwargs):
 | |
|     return [
 | |
|         Warning(
 | |
|             'Warning',
 | |
|             hint=None,
 | |
|             id='mywarningcheck.E001',
 | |
|         )
 | |
|     ]
 | |
| 
 | |
| 
 | |
| class SilencingCheckTests(TestCase):
 | |
| 
 | |
|     def setUp(self):
 | |
|         self.old_stdout, self.old_stderr = sys.stdout, sys.stderr
 | |
|         self.stdout, self.stderr = StringIO(), StringIO()
 | |
|         sys.stdout, sys.stderr = self.stdout, self.stderr
 | |
| 
 | |
|     def tearDown(self):
 | |
|         sys.stdout, sys.stderr = self.old_stdout, self.old_stderr
 | |
| 
 | |
|     @override_settings(SILENCED_SYSTEM_CHECKS=['myerrorcheck.E001'])
 | |
|     @override_system_checks([custom_error_system_check])
 | |
|     def test_silenced_error(self):
 | |
|         out = StringIO()
 | |
|         err = StringIO()
 | |
|         try:
 | |
|             call_command('check', stdout=out, stderr=err)
 | |
|         except CommandError:
 | |
|             self.fail("The mycheck.E001 check should be silenced.")
 | |
|         self.assertEqual(out.getvalue(), '')
 | |
|         self.assertEqual(
 | |
|             err.getvalue(),
 | |
|             'System check identified some issues:\n\n'
 | |
|             'ERRORS:\n'
 | |
|             '?: (myerrorcheck.E001) Error\n\n'
 | |
|             'System check identified 1 issue (0 silenced).\n'
 | |
|         )
 | |
| 
 | |
|     @override_settings(SILENCED_SYSTEM_CHECKS=['mywarningcheck.E001'])
 | |
|     @override_system_checks([custom_warning_system_check])
 | |
|     def test_silenced_warning(self):
 | |
|         out = StringIO()
 | |
|         err = StringIO()
 | |
|         try:
 | |
|             call_command('check', stdout=out, stderr=err)
 | |
|         except CommandError:
 | |
|             self.fail("The mycheck.E001 check should be silenced.")
 | |
| 
 | |
|         self.assertEqual(out.getvalue(), 'System check identified no issues (1 silenced).\n')
 | |
|         self.assertEqual(err.getvalue(), '')
 |