1. """
    
  2. A series of tests to establish that the command-line management tools work as
    
  3. advertised - especially with regards to the handling of the
    
  4. DJANGO_SETTINGS_MODULE and default settings.py files.
    
  5. """
    
  6. import os
    
  7. import re
    
  8. import shutil
    
  9. import socket
    
  10. import stat
    
  11. import subprocess
    
  12. import sys
    
  13. import tempfile
    
  14. import unittest
    
  15. from io import StringIO
    
  16. from unittest import mock
    
  17. 
    
  18. from django import conf, get_version
    
  19. from django.conf import settings
    
  20. from django.core.management import (
    
  21.     BaseCommand,
    
  22.     CommandError,
    
  23.     call_command,
    
  24.     color,
    
  25.     execute_from_command_line,
    
  26. )
    
  27. from django.core.management.commands.loaddata import Command as LoaddataCommand
    
  28. from django.core.management.commands.runserver import Command as RunserverCommand
    
  29. from django.core.management.commands.testserver import Command as TestserverCommand
    
  30. from django.db import ConnectionHandler, connection
    
  31. from django.db.migrations.recorder import MigrationRecorder
    
  32. from django.test import LiveServerTestCase, SimpleTestCase, TestCase, override_settings
    
  33. from django.test.utils import captured_stderr, captured_stdout
    
  34. from django.urls import path
    
  35. from django.utils.version import PY39
    
  36. from django.views.static import serve
    
  37. 
    
  38. from . import urls
    
  39. 
    
  40. custom_templates_dir = os.path.join(os.path.dirname(__file__), "custom_templates")
    
  41. 
    
  42. SYSTEM_CHECK_MSG = "System check identified no issues"
    
  43. 
    
  44. HAS_BLACK = shutil.which("black")
    
  45. 
    
  46. 
    
  47. class AdminScriptTestCase(SimpleTestCase):
    
  48.     def setUp(self):
    
  49.         tmpdir = tempfile.TemporaryDirectory()
    
  50.         self.addCleanup(tmpdir.cleanup)
    
  51.         # os.path.realpath() is required for temporary directories on macOS,
    
  52.         # where `/var` is a symlink to `/private/var`.
    
  53.         self.test_dir = os.path.realpath(os.path.join(tmpdir.name, "test_project"))
    
  54.         os.mkdir(self.test_dir)
    
  55. 
    
  56.     def write_settings(self, filename, apps=None, is_dir=False, sdict=None, extra=None):
    
  57.         if is_dir:
    
  58.             settings_dir = os.path.join(self.test_dir, filename)
    
  59.             os.mkdir(settings_dir)
    
  60.             settings_file_path = os.path.join(settings_dir, "__init__.py")
    
  61.         else:
    
  62.             settings_file_path = os.path.join(self.test_dir, filename)
    
  63. 
    
  64.         with open(settings_file_path, "w") as settings_file:
    
  65.             settings_file.write(
    
  66.                 "# Settings file automatically generated by admin_scripts test case\n"
    
  67.             )
    
  68.             if extra:
    
  69.                 settings_file.write("%s\n" % extra)
    
  70.             exports = [
    
  71.                 "DATABASES",
    
  72.                 "DEFAULT_AUTO_FIELD",
    
  73.                 "ROOT_URLCONF",
    
  74.                 "SECRET_KEY",
    
  75.                 "USE_TZ",
    
  76.             ]
    
  77.             for s in exports:
    
  78.                 if hasattr(settings, s):
    
  79.                     o = getattr(settings, s)
    
  80.                     if not isinstance(o, (dict, tuple, list)):
    
  81.                         o = "'%s'" % o
    
  82.                     settings_file.write("%s = %s\n" % (s, o))
    
  83. 
    
  84.             if apps is None:
    
  85.                 apps = [
    
  86.                     "django.contrib.auth",
    
  87.                     "django.contrib.contenttypes",
    
  88.                     "admin_scripts",
    
  89.                 ]
    
  90. 
    
  91.             settings_file.write("INSTALLED_APPS = %s\n" % apps)
    
  92. 
    
  93.             if sdict:
    
  94.                 for k, v in sdict.items():
    
  95.                     settings_file.write("%s = %s\n" % (k, v))
    
  96. 
    
  97.     def _ext_backend_paths(self):
    
  98.         """
    
  99.         Returns the paths for any external backend packages.
    
  100.         """
    
  101.         paths = []
    
  102.         for backend in settings.DATABASES.values():
    
  103.             package = backend["ENGINE"].split(".")[0]
    
  104.             if package != "django":
    
  105.                 backend_pkg = __import__(package)
    
  106.                 backend_dir = os.path.dirname(backend_pkg.__file__)
    
  107.                 paths.append(os.path.dirname(backend_dir))
    
  108.         return paths
    
  109. 
    
  110.     def run_test(self, args, settings_file=None, apps=None, umask=None):
    
  111.         base_dir = os.path.dirname(self.test_dir)
    
  112.         # The base dir for Django's tests is one level up.
    
  113.         tests_dir = os.path.dirname(os.path.dirname(__file__))
    
  114.         # The base dir for Django is one level above the test dir. We don't use
    
  115.         # `import django` to figure that out, so we don't pick up a Django
    
  116.         # from site-packages or similar.
    
  117.         django_dir = os.path.dirname(tests_dir)
    
  118.         ext_backend_base_dirs = self._ext_backend_paths()
    
  119. 
    
  120.         # Define a temporary environment for the subprocess
    
  121.         test_environ = os.environ.copy()
    
  122. 
    
  123.         # Set the test environment
    
  124.         if settings_file:
    
  125.             test_environ["DJANGO_SETTINGS_MODULE"] = settings_file
    
  126.         elif "DJANGO_SETTINGS_MODULE" in test_environ:
    
  127.             del test_environ["DJANGO_SETTINGS_MODULE"]
    
  128.         python_path = [base_dir, django_dir, tests_dir]
    
  129.         python_path.extend(ext_backend_base_dirs)
    
  130.         test_environ["PYTHONPATH"] = os.pathsep.join(python_path)
    
  131.         test_environ["PYTHONWARNINGS"] = ""
    
  132. 
    
  133.         p = subprocess.run(
    
  134.             [sys.executable, *args],
    
  135.             capture_output=True,
    
  136.             cwd=self.test_dir,
    
  137.             env=test_environ,
    
  138.             text=True,
    
  139.             # subprocess.run()'s umask was added in Python 3.9.
    
  140.             **({"umask": umask} if umask and PY39 else {}),
    
  141.         )
    
  142.         return p.stdout, p.stderr
    
  143. 
    
  144.     def run_django_admin(self, args, settings_file=None, umask=None):
    
  145.         return self.run_test(["-m", "django", *args], settings_file, umask=umask)
    
  146. 
    
  147.     def run_manage(self, args, settings_file=None, manage_py=None):
    
  148.         template_manage_py = (
    
  149.             os.path.join(os.path.dirname(__file__), manage_py)
    
  150.             if manage_py
    
  151.             else os.path.join(
    
  152.                 os.path.dirname(conf.__file__), "project_template", "manage.py-tpl"
    
  153.             )
    
  154.         )
    
  155.         test_manage_py = os.path.join(self.test_dir, "manage.py")
    
  156.         shutil.copyfile(template_manage_py, test_manage_py)
    
  157. 
    
  158.         with open(test_manage_py) as fp:
    
  159.             manage_py_contents = fp.read()
    
  160.         manage_py_contents = manage_py_contents.replace(
    
  161.             "{{ project_name }}", "test_project"
    
  162.         )
    
  163.         with open(test_manage_py, "w") as fp:
    
  164.             fp.write(manage_py_contents)
    
  165. 
    
  166.         return self.run_test(["./manage.py", *args], settings_file)
    
  167. 
    
  168.     def assertNoOutput(self, stream):
    
  169.         "Utility assertion: assert that the given stream is empty"
    
  170.         self.assertEqual(
    
  171.             len(stream), 0, "Stream should be empty: actually contains '%s'" % stream
    
  172.         )
    
  173. 
    
  174.     def assertOutput(self, stream, msg, regex=False):
    
  175.         "Utility assertion: assert that the given message exists in the output"
    
  176.         if regex:
    
  177.             self.assertIsNotNone(
    
  178.                 re.search(msg, stream),
    
  179.                 "'%s' does not match actual output text '%s'" % (msg, stream),
    
  180.             )
    
  181.         else:
    
  182.             self.assertIn(
    
  183.                 msg,
    
  184.                 stream,
    
  185.                 "'%s' does not match actual output text '%s'" % (msg, stream),
    
  186.             )
    
  187. 
    
  188.     def assertNotInOutput(self, stream, msg):
    
  189.         "Utility assertion: assert that the given message doesn't exist in the output"
    
  190.         self.assertNotIn(
    
  191.             msg, stream, "'%s' matches actual output text '%s'" % (msg, stream)
    
  192.         )
    
  193. 
    
  194. 
    
  195. ##########################################################################
    
  196. # DJANGO ADMIN TESTS
    
  197. # This first series of test classes checks the environment processing
    
  198. # of the django-admin.
    
  199. ##########################################################################
    
  200. 
    
  201. 
    
  202. class DjangoAdminNoSettings(AdminScriptTestCase):
    
  203.     "A series of tests for django-admin when there is no settings.py file."
    
  204. 
    
  205.     def test_builtin_command(self):
    
  206.         """
    
  207.         no settings: django-admin builtin commands fail with an error when no
    
  208.         settings provided.
    
  209.         """
    
  210.         args = ["check", "admin_scripts"]
    
  211.         out, err = self.run_django_admin(args)
    
  212.         self.assertNoOutput(out)
    
  213.         self.assertOutput(err, "settings are not configured")
    
  214. 
    
  215.     def test_builtin_with_bad_settings(self):
    
  216.         """
    
  217.         no settings: django-admin builtin commands fail if settings file (from
    
  218.         argument) doesn't exist.
    
  219.         """
    
  220.         args = ["check", "--settings=bad_settings", "admin_scripts"]
    
  221.         out, err = self.run_django_admin(args)
    
  222.         self.assertNoOutput(out)
    
  223.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  224. 
    
  225.     def test_builtin_with_bad_environment(self):
    
  226.         """
    
  227.         no settings: django-admin builtin commands fail if settings file (from
    
  228.         environment) doesn't exist.
    
  229.         """
    
  230.         args = ["check", "admin_scripts"]
    
  231.         out, err = self.run_django_admin(args, "bad_settings")
    
  232.         self.assertNoOutput(out)
    
  233.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  234. 
    
  235.     def test_commands_with_invalid_settings(self):
    
  236.         """
    
  237.         Commands that don't require settings succeed if the settings file
    
  238.         doesn't exist.
    
  239.         """
    
  240.         args = ["startproject"]
    
  241.         out, err = self.run_django_admin(args, settings_file="bad_settings")
    
  242.         self.assertNoOutput(out)
    
  243.         self.assertOutput(err, "You must provide a project name", regex=True)
    
  244. 
    
  245. 
    
  246. class DjangoAdminDefaultSettings(AdminScriptTestCase):
    
  247.     """
    
  248.     A series of tests for django-admin when using a settings.py file that
    
  249.     contains the test application.
    
  250.     """
    
  251. 
    
  252.     def setUp(self):
    
  253.         super().setUp()
    
  254.         self.write_settings("settings.py")
    
  255. 
    
  256.     def test_builtin_command(self):
    
  257.         """
    
  258.         default: django-admin builtin commands fail with an error when no
    
  259.         settings provided.
    
  260.         """
    
  261.         args = ["check", "admin_scripts"]
    
  262.         out, err = self.run_django_admin(args)
    
  263.         self.assertNoOutput(out)
    
  264.         self.assertOutput(err, "settings are not configured")
    
  265. 
    
  266.     def test_builtin_with_settings(self):
    
  267.         """
    
  268.         default: django-admin builtin commands succeed if settings are provided
    
  269.         as argument.
    
  270.         """
    
  271.         args = ["check", "--settings=test_project.settings", "admin_scripts"]
    
  272.         out, err = self.run_django_admin(args)
    
  273.         self.assertNoOutput(err)
    
  274.         self.assertOutput(out, SYSTEM_CHECK_MSG)
    
  275. 
    
  276.     def test_builtin_with_environment(self):
    
  277.         """
    
  278.         default: django-admin builtin commands succeed if settings are provided
    
  279.         in the environment.
    
  280.         """
    
  281.         args = ["check", "admin_scripts"]
    
  282.         out, err = self.run_django_admin(args, "test_project.settings")
    
  283.         self.assertNoOutput(err)
    
  284.         self.assertOutput(out, SYSTEM_CHECK_MSG)
    
  285. 
    
  286.     def test_builtin_with_bad_settings(self):
    
  287.         """
    
  288.         default: django-admin builtin commands fail if settings file (from
    
  289.         argument) doesn't exist.
    
  290.         """
    
  291.         args = ["check", "--settings=bad_settings", "admin_scripts"]
    
  292.         out, err = self.run_django_admin(args)
    
  293.         self.assertNoOutput(out)
    
  294.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  295. 
    
  296.     def test_builtin_with_bad_environment(self):
    
  297.         """
    
  298.         default: django-admin builtin commands fail if settings file (from
    
  299.         environment) doesn't exist.
    
  300.         """
    
  301.         args = ["check", "admin_scripts"]
    
  302.         out, err = self.run_django_admin(args, "bad_settings")
    
  303.         self.assertNoOutput(out)
    
  304.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  305. 
    
  306.     def test_custom_command(self):
    
  307.         """
    
  308.         default: django-admin can't execute user commands if it isn't provided
    
  309.         settings.
    
  310.         """
    
  311.         args = ["noargs_command"]
    
  312.         out, err = self.run_django_admin(args)
    
  313.         self.assertNoOutput(out)
    
  314.         self.assertOutput(err, "No Django settings specified")
    
  315.         self.assertOutput(err, "Unknown command: 'noargs_command'")
    
  316. 
    
  317.     def test_custom_command_with_settings(self):
    
  318.         """
    
  319.         default: django-admin can execute user commands if settings are
    
  320.         provided as argument.
    
  321.         """
    
  322.         args = ["noargs_command", "--settings=test_project.settings"]
    
  323.         out, err = self.run_django_admin(args)
    
  324.         self.assertNoOutput(err)
    
  325.         self.assertOutput(out, "EXECUTE: noargs_command")
    
  326. 
    
  327.     def test_custom_command_with_environment(self):
    
  328.         """
    
  329.         default: django-admin can execute user commands if settings are
    
  330.         provided in environment.
    
  331.         """
    
  332.         args = ["noargs_command"]
    
  333.         out, err = self.run_django_admin(args, "test_project.settings")
    
  334.         self.assertNoOutput(err)
    
  335.         self.assertOutput(out, "EXECUTE: noargs_command")
    
  336. 
    
  337. 
    
  338. class DjangoAdminFullPathDefaultSettings(AdminScriptTestCase):
    
  339.     """
    
  340.     A series of tests for django-admin when using a settings.py file that
    
  341.     contains the test application specified using a full path.
    
  342.     """
    
  343. 
    
  344.     def setUp(self):
    
  345.         super().setUp()
    
  346.         self.write_settings(
    
  347.             "settings.py",
    
  348.             [
    
  349.                 "django.contrib.auth",
    
  350.                 "django.contrib.contenttypes",
    
  351.                 "admin_scripts",
    
  352.                 "admin_scripts.complex_app",
    
  353.             ],
    
  354.         )
    
  355. 
    
  356.     def test_builtin_command(self):
    
  357.         """
    
  358.         fulldefault: django-admin builtin commands fail with an error when no
    
  359.         settings provided.
    
  360.         """
    
  361.         args = ["check", "admin_scripts"]
    
  362.         out, err = self.run_django_admin(args)
    
  363.         self.assertNoOutput(out)
    
  364.         self.assertOutput(err, "settings are not configured")
    
  365. 
    
  366.     def test_builtin_with_settings(self):
    
  367.         """
    
  368.         fulldefault: django-admin builtin commands succeed if a settings file
    
  369.         is provided.
    
  370.         """
    
  371.         args = ["check", "--settings=test_project.settings", "admin_scripts"]
    
  372.         out, err = self.run_django_admin(args)
    
  373.         self.assertNoOutput(err)
    
  374.         self.assertOutput(out, SYSTEM_CHECK_MSG)
    
  375. 
    
  376.     def test_builtin_with_environment(self):
    
  377.         """
    
  378.         fulldefault: django-admin builtin commands succeed if the environment
    
  379.         contains settings.
    
  380.         """
    
  381.         args = ["check", "admin_scripts"]
    
  382.         out, err = self.run_django_admin(args, "test_project.settings")
    
  383.         self.assertNoOutput(err)
    
  384.         self.assertOutput(out, SYSTEM_CHECK_MSG)
    
  385. 
    
  386.     def test_builtin_with_bad_settings(self):
    
  387.         """
    
  388.         fulldefault: django-admin builtin commands fail if settings file (from
    
  389.         argument) doesn't exist.
    
  390.         """
    
  391.         args = ["check", "--settings=bad_settings", "admin_scripts"]
    
  392.         out, err = self.run_django_admin(args)
    
  393.         self.assertNoOutput(out)
    
  394.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  395. 
    
  396.     def test_builtin_with_bad_environment(self):
    
  397.         """
    
  398.         fulldefault: django-admin builtin commands fail if settings file (from
    
  399.         environment) doesn't exist.
    
  400.         """
    
  401.         args = ["check", "admin_scripts"]
    
  402.         out, err = self.run_django_admin(args, "bad_settings")
    
  403.         self.assertNoOutput(out)
    
  404.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  405. 
    
  406.     def test_custom_command(self):
    
  407.         """
    
  408.         fulldefault: django-admin can't execute user commands unless settings
    
  409.         are provided.
    
  410.         """
    
  411.         args = ["noargs_command"]
    
  412.         out, err = self.run_django_admin(args)
    
  413.         self.assertNoOutput(out)
    
  414.         self.assertOutput(err, "No Django settings specified")
    
  415.         self.assertOutput(err, "Unknown command: 'noargs_command'")
    
  416. 
    
  417.     def test_custom_command_with_settings(self):
    
  418.         """
    
  419.         fulldefault: django-admin can execute user commands if settings are
    
  420.         provided as argument.
    
  421.         """
    
  422.         args = ["noargs_command", "--settings=test_project.settings"]
    
  423.         out, err = self.run_django_admin(args)
    
  424.         self.assertNoOutput(err)
    
  425.         self.assertOutput(out, "EXECUTE: noargs_command")
    
  426. 
    
  427.     def test_custom_command_with_environment(self):
    
  428.         """
    
  429.         fulldefault: django-admin can execute user commands if settings are
    
  430.         provided in environment.
    
  431.         """
    
  432.         args = ["noargs_command"]
    
  433.         out, err = self.run_django_admin(args, "test_project.settings")
    
  434.         self.assertNoOutput(err)
    
  435.         self.assertOutput(out, "EXECUTE: noargs_command")
    
  436. 
    
  437. 
    
  438. class DjangoAdminMinimalSettings(AdminScriptTestCase):
    
  439.     """
    
  440.     A series of tests for django-admin when using a settings.py file that
    
  441.     doesn't contain the test application.
    
  442.     """
    
  443. 
    
  444.     def setUp(self):
    
  445.         super().setUp()
    
  446.         self.write_settings(
    
  447.             "settings.py", apps=["django.contrib.auth", "django.contrib.contenttypes"]
    
  448.         )
    
  449. 
    
  450.     def test_builtin_command(self):
    
  451.         """
    
  452.         minimal: django-admin builtin commands fail with an error when no
    
  453.         settings provided.
    
  454.         """
    
  455.         args = ["check", "admin_scripts"]
    
  456.         out, err = self.run_django_admin(args)
    
  457.         self.assertNoOutput(out)
    
  458.         self.assertOutput(err, "settings are not configured")
    
  459. 
    
  460.     def test_builtin_with_settings(self):
    
  461.         """
    
  462.         minimal: django-admin builtin commands fail if settings are provided as
    
  463.         argument.
    
  464.         """
    
  465.         args = ["check", "--settings=test_project.settings", "admin_scripts"]
    
  466.         out, err = self.run_django_admin(args)
    
  467.         self.assertNoOutput(out)
    
  468.         self.assertOutput(err, "No installed app with label 'admin_scripts'.")
    
  469. 
    
  470.     def test_builtin_with_environment(self):
    
  471.         """
    
  472.         minimal: django-admin builtin commands fail if settings are provided in
    
  473.         the environment.
    
  474.         """
    
  475.         args = ["check", "admin_scripts"]
    
  476.         out, err = self.run_django_admin(args, "test_project.settings")
    
  477.         self.assertNoOutput(out)
    
  478.         self.assertOutput(err, "No installed app with label 'admin_scripts'.")
    
  479. 
    
  480.     def test_builtin_with_bad_settings(self):
    
  481.         """
    
  482.         minimal: django-admin builtin commands fail if settings file (from
    
  483.         argument) doesn't exist.
    
  484.         """
    
  485.         args = ["check", "--settings=bad_settings", "admin_scripts"]
    
  486.         out, err = self.run_django_admin(args)
    
  487.         self.assertNoOutput(out)
    
  488.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  489. 
    
  490.     def test_builtin_with_bad_environment(self):
    
  491.         """
    
  492.         minimal: django-admin builtin commands fail if settings file (from
    
  493.         environment) doesn't exist.
    
  494.         """
    
  495.         args = ["check", "admin_scripts"]
    
  496.         out, err = self.run_django_admin(args, "bad_settings")
    
  497.         self.assertNoOutput(out)
    
  498.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  499. 
    
  500.     def test_custom_command(self):
    
  501.         "minimal: django-admin can't execute user commands unless settings are provided"
    
  502.         args = ["noargs_command"]
    
  503.         out, err = self.run_django_admin(args)
    
  504.         self.assertNoOutput(out)
    
  505.         self.assertOutput(err, "No Django settings specified")
    
  506.         self.assertOutput(err, "Unknown command: 'noargs_command'")
    
  507. 
    
  508.     def test_custom_command_with_settings(self):
    
  509.         """
    
  510.         minimal: django-admin can't execute user commands, even if settings are
    
  511.         provided as argument.
    
  512.         """
    
  513.         args = ["noargs_command", "--settings=test_project.settings"]
    
  514.         out, err = self.run_django_admin(args)
    
  515.         self.assertNoOutput(out)
    
  516.         self.assertOutput(err, "Unknown command: 'noargs_command'")
    
  517. 
    
  518.     def test_custom_command_with_environment(self):
    
  519.         """
    
  520.         minimal: django-admin can't execute user commands, even if settings are
    
  521.         provided in environment.
    
  522.         """
    
  523.         args = ["noargs_command"]
    
  524.         out, err = self.run_django_admin(args, "test_project.settings")
    
  525.         self.assertNoOutput(out)
    
  526.         self.assertOutput(err, "Unknown command: 'noargs_command'")
    
  527. 
    
  528. 
    
  529. class DjangoAdminAlternateSettings(AdminScriptTestCase):
    
  530.     """
    
  531.     A series of tests for django-admin when using a settings file with a name
    
  532.     other than 'settings.py'.
    
  533.     """
    
  534. 
    
  535.     def setUp(self):
    
  536.         super().setUp()
    
  537.         self.write_settings("alternate_settings.py")
    
  538. 
    
  539.     def test_builtin_command(self):
    
  540.         """
    
  541.         alternate: django-admin builtin commands fail with an error when no
    
  542.         settings provided.
    
  543.         """
    
  544.         args = ["check", "admin_scripts"]
    
  545.         out, err = self.run_django_admin(args)
    
  546.         self.assertNoOutput(out)
    
  547.         self.assertOutput(err, "settings are not configured")
    
  548. 
    
  549.     def test_builtin_with_settings(self):
    
  550.         """
    
  551.         alternate: django-admin builtin commands succeed if settings are
    
  552.         provided as argument.
    
  553.         """
    
  554.         args = ["check", "--settings=test_project.alternate_settings", "admin_scripts"]
    
  555.         out, err = self.run_django_admin(args)
    
  556.         self.assertNoOutput(err)
    
  557.         self.assertOutput(out, SYSTEM_CHECK_MSG)
    
  558. 
    
  559.     def test_builtin_with_environment(self):
    
  560.         """
    
  561.         alternate: django-admin builtin commands succeed if settings are
    
  562.         provided in the environment.
    
  563.         """
    
  564.         args = ["check", "admin_scripts"]
    
  565.         out, err = self.run_django_admin(args, "test_project.alternate_settings")
    
  566.         self.assertNoOutput(err)
    
  567.         self.assertOutput(out, SYSTEM_CHECK_MSG)
    
  568. 
    
  569.     def test_builtin_with_bad_settings(self):
    
  570.         """
    
  571.         alternate: django-admin builtin commands fail if settings file (from
    
  572.         argument) doesn't exist.
    
  573.         """
    
  574.         args = ["check", "--settings=bad_settings", "admin_scripts"]
    
  575.         out, err = self.run_django_admin(args)
    
  576.         self.assertNoOutput(out)
    
  577.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  578. 
    
  579.     def test_builtin_with_bad_environment(self):
    
  580.         """
    
  581.         alternate: django-admin builtin commands fail if settings file (from
    
  582.         environment) doesn't exist.
    
  583.         """
    
  584.         args = ["check", "admin_scripts"]
    
  585.         out, err = self.run_django_admin(args, "bad_settings")
    
  586.         self.assertNoOutput(out)
    
  587.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  588. 
    
  589.     def test_custom_command(self):
    
  590.         """
    
  591.         alternate: django-admin can't execute user commands unless settings
    
  592.         are provided.
    
  593.         """
    
  594.         args = ["noargs_command"]
    
  595.         out, err = self.run_django_admin(args)
    
  596.         self.assertNoOutput(out)
    
  597.         self.assertOutput(err, "No Django settings specified")
    
  598.         self.assertOutput(err, "Unknown command: 'noargs_command'")
    
  599. 
    
  600.     def test_custom_command_with_settings(self):
    
  601.         """
    
  602.         alternate: django-admin can execute user commands if settings are
    
  603.         provided as argument.
    
  604.         """
    
  605.         args = ["noargs_command", "--settings=test_project.alternate_settings"]
    
  606.         out, err = self.run_django_admin(args)
    
  607.         self.assertNoOutput(err)
    
  608.         self.assertOutput(out, "EXECUTE: noargs_command")
    
  609. 
    
  610.     def test_custom_command_with_environment(self):
    
  611.         """
    
  612.         alternate: django-admin can execute user commands if settings are
    
  613.         provided in environment.
    
  614.         """
    
  615.         args = ["noargs_command"]
    
  616.         out, err = self.run_django_admin(args, "test_project.alternate_settings")
    
  617.         self.assertNoOutput(err)
    
  618.         self.assertOutput(out, "EXECUTE: noargs_command")
    
  619. 
    
  620. 
    
  621. class DjangoAdminMultipleSettings(AdminScriptTestCase):
    
  622.     """
    
  623.     A series of tests for django-admin when multiple settings files
    
  624.     (including the default 'settings.py') are available. The default settings
    
  625.     file is insufficient for performing the operations described, so the
    
  626.     alternate settings must be used by the running script.
    
  627.     """
    
  628. 
    
  629.     def setUp(self):
    
  630.         super().setUp()
    
  631.         self.write_settings(
    
  632.             "settings.py", apps=["django.contrib.auth", "django.contrib.contenttypes"]
    
  633.         )
    
  634.         self.write_settings("alternate_settings.py")
    
  635. 
    
  636.     def test_builtin_command(self):
    
  637.         """
    
  638.         alternate: django-admin builtin commands fail with an error when no
    
  639.         settings provided.
    
  640.         """
    
  641.         args = ["check", "admin_scripts"]
    
  642.         out, err = self.run_django_admin(args)
    
  643.         self.assertNoOutput(out)
    
  644.         self.assertOutput(err, "settings are not configured")
    
  645. 
    
  646.     def test_builtin_with_settings(self):
    
  647.         """
    
  648.         alternate: django-admin builtin commands succeed if settings are
    
  649.         provided as argument.
    
  650.         """
    
  651.         args = ["check", "--settings=test_project.alternate_settings", "admin_scripts"]
    
  652.         out, err = self.run_django_admin(args)
    
  653.         self.assertNoOutput(err)
    
  654.         self.assertOutput(out, SYSTEM_CHECK_MSG)
    
  655. 
    
  656.     def test_builtin_with_environment(self):
    
  657.         """
    
  658.         alternate: django-admin builtin commands succeed if settings are
    
  659.         provided in the environment.
    
  660.         """
    
  661.         args = ["check", "admin_scripts"]
    
  662.         out, err = self.run_django_admin(args, "test_project.alternate_settings")
    
  663.         self.assertNoOutput(err)
    
  664.         self.assertOutput(out, SYSTEM_CHECK_MSG)
    
  665. 
    
  666.     def test_builtin_with_bad_settings(self):
    
  667.         """
    
  668.         alternate: django-admin builtin commands fail if settings file (from
    
  669.         argument) doesn't exist.
    
  670.         """
    
  671.         args = ["check", "--settings=bad_settings", "admin_scripts"]
    
  672.         out, err = self.run_django_admin(args)
    
  673.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  674. 
    
  675.     def test_builtin_with_bad_environment(self):
    
  676.         """
    
  677.         alternate: django-admin builtin commands fail if settings file (from
    
  678.         environment) doesn't exist.
    
  679.         """
    
  680.         args = ["check", "admin_scripts"]
    
  681.         out, err = self.run_django_admin(args, "bad_settings")
    
  682.         self.assertNoOutput(out)
    
  683.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  684. 
    
  685.     def test_custom_command(self):
    
  686.         """
    
  687.         alternate: django-admin can't execute user commands unless settings are
    
  688.         provided.
    
  689.         """
    
  690.         args = ["noargs_command"]
    
  691.         out, err = self.run_django_admin(args)
    
  692.         self.assertNoOutput(out)
    
  693.         self.assertOutput(err, "No Django settings specified")
    
  694.         self.assertOutput(err, "Unknown command: 'noargs_command'")
    
  695. 
    
  696.     def test_custom_command_with_settings(self):
    
  697.         """
    
  698.         alternate: django-admin can execute user commands if settings are
    
  699.         provided as argument.
    
  700.         """
    
  701.         args = ["noargs_command", "--settings=test_project.alternate_settings"]
    
  702.         out, err = self.run_django_admin(args)
    
  703.         self.assertNoOutput(err)
    
  704.         self.assertOutput(out, "EXECUTE: noargs_command")
    
  705. 
    
  706.     def test_custom_command_with_environment(self):
    
  707.         """
    
  708.         alternate: django-admin can execute user commands if settings are
    
  709.         provided in environment.
    
  710.         """
    
  711.         args = ["noargs_command"]
    
  712.         out, err = self.run_django_admin(args, "test_project.alternate_settings")
    
  713.         self.assertNoOutput(err)
    
  714.         self.assertOutput(out, "EXECUTE: noargs_command")
    
  715. 
    
  716. 
    
  717. class DjangoAdminSettingsDirectory(AdminScriptTestCase):
    
  718.     """
    
  719.     A series of tests for django-admin when the settings file is in a
    
  720.     directory. (see #9751).
    
  721.     """
    
  722. 
    
  723.     def setUp(self):
    
  724.         super().setUp()
    
  725.         self.write_settings("settings", is_dir=True)
    
  726. 
    
  727.     def test_setup_environ(self):
    
  728.         "directory: startapp creates the correct directory"
    
  729.         args = ["startapp", "settings_test"]
    
  730.         app_path = os.path.join(self.test_dir, "settings_test")
    
  731.         out, err = self.run_django_admin(args, "test_project.settings")
    
  732.         self.assertNoOutput(err)
    
  733.         self.assertTrue(os.path.exists(app_path))
    
  734.         with open(os.path.join(app_path, "apps.py")) as f:
    
  735.             content = f.read()
    
  736.             self.assertIn("class SettingsTestConfig(AppConfig)", content)
    
  737.             self.assertIn(
    
  738.                 'name = "settings_test"' if HAS_BLACK else "name = 'settings_test'",
    
  739.                 content,
    
  740.             )
    
  741. 
    
  742.     def test_setup_environ_custom_template(self):
    
  743.         "directory: startapp creates the correct directory with a custom template"
    
  744.         template_path = os.path.join(custom_templates_dir, "app_template")
    
  745.         args = ["startapp", "--template", template_path, "custom_settings_test"]
    
  746.         app_path = os.path.join(self.test_dir, "custom_settings_test")
    
  747.         out, err = self.run_django_admin(args, "test_project.settings")
    
  748.         self.assertNoOutput(err)
    
  749.         self.assertTrue(os.path.exists(app_path))
    
  750.         self.assertTrue(os.path.exists(os.path.join(app_path, "api.py")))
    
  751. 
    
  752.     def test_startapp_unicode_name(self):
    
  753.         """startapp creates the correct directory with Unicode characters."""
    
  754.         args = ["startapp", "こんにちは"]
    
  755.         app_path = os.path.join(self.test_dir, "こんにちは")
    
  756.         out, err = self.run_django_admin(args, "test_project.settings")
    
  757.         self.assertNoOutput(err)
    
  758.         self.assertTrue(os.path.exists(app_path))
    
  759.         with open(os.path.join(app_path, "apps.py"), encoding="utf8") as f:
    
  760.             content = f.read()
    
  761.             self.assertIn("class こんにちはConfig(AppConfig)", content)
    
  762.             self.assertIn('name = "こんにちは"' if HAS_BLACK else "name = 'こんにちは'", content)
    
  763. 
    
  764.     def test_builtin_command(self):
    
  765.         """
    
  766.         directory: django-admin builtin commands fail with an error when no
    
  767.         settings provided.
    
  768.         """
    
  769.         args = ["check", "admin_scripts"]
    
  770.         out, err = self.run_django_admin(args)
    
  771.         self.assertNoOutput(out)
    
  772.         self.assertOutput(err, "settings are not configured")
    
  773. 
    
  774.     def test_builtin_with_bad_settings(self):
    
  775.         """
    
  776.         directory: django-admin builtin commands fail if settings file (from
    
  777.         argument) doesn't exist.
    
  778.         """
    
  779.         args = ["check", "--settings=bad_settings", "admin_scripts"]
    
  780.         out, err = self.run_django_admin(args)
    
  781.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  782. 
    
  783.     def test_builtin_with_bad_environment(self):
    
  784.         """
    
  785.         directory: django-admin builtin commands fail if settings file (from
    
  786.         environment) doesn't exist.
    
  787.         """
    
  788.         args = ["check", "admin_scripts"]
    
  789.         out, err = self.run_django_admin(args, "bad_settings")
    
  790.         self.assertNoOutput(out)
    
  791.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  792. 
    
  793.     def test_custom_command(self):
    
  794.         """
    
  795.         directory: django-admin can't execute user commands unless settings are
    
  796.         provided.
    
  797.         """
    
  798.         args = ["noargs_command"]
    
  799.         out, err = self.run_django_admin(args)
    
  800.         self.assertNoOutput(out)
    
  801.         self.assertOutput(err, "No Django settings specified")
    
  802.         self.assertOutput(err, "Unknown command: 'noargs_command'")
    
  803. 
    
  804.     def test_builtin_with_settings(self):
    
  805.         """
    
  806.         directory: django-admin builtin commands succeed if settings are
    
  807.         provided as argument.
    
  808.         """
    
  809.         args = ["check", "--settings=test_project.settings", "admin_scripts"]
    
  810.         out, err = self.run_django_admin(args)
    
  811.         self.assertNoOutput(err)
    
  812.         self.assertOutput(out, SYSTEM_CHECK_MSG)
    
  813. 
    
  814.     def test_builtin_with_environment(self):
    
  815.         """
    
  816.         directory: django-admin builtin commands succeed if settings are
    
  817.         provided in the environment.
    
  818.         """
    
  819.         args = ["check", "admin_scripts"]
    
  820.         out, err = self.run_django_admin(args, "test_project.settings")
    
  821.         self.assertNoOutput(err)
    
  822.         self.assertOutput(out, SYSTEM_CHECK_MSG)
    
  823. 
    
  824. 
    
  825. ##########################################################################
    
  826. # MANAGE.PY TESTS
    
  827. # This next series of test classes checks the environment processing
    
  828. # of the generated manage.py script
    
  829. ##########################################################################
    
  830. 
    
  831. 
    
  832. class ManageManuallyConfiguredSettings(AdminScriptTestCase):
    
  833.     """Customized manage.py calling settings.configure()."""
    
  834. 
    
  835.     def test_non_existent_command_output(self):
    
  836.         out, err = self.run_manage(
    
  837.             ["invalid_command"], manage_py="configured_settings_manage.py"
    
  838.         )
    
  839.         self.assertNoOutput(out)
    
  840.         self.assertOutput(err, "Unknown command: 'invalid_command'")
    
  841.         self.assertNotInOutput(err, "No Django settings specified")
    
  842. 
    
  843. 
    
  844. class ManageNoSettings(AdminScriptTestCase):
    
  845.     "A series of tests for manage.py when there is no settings.py file."
    
  846. 
    
  847.     def test_builtin_command(self):
    
  848.         """
    
  849.         no settings: manage.py builtin commands fail with an error when no
    
  850.         settings provided.
    
  851.         """
    
  852.         args = ["check", "admin_scripts"]
    
  853.         out, err = self.run_manage(args)
    
  854.         self.assertNoOutput(out)
    
  855.         self.assertOutput(
    
  856.             err, r"No module named '?(test_project\.)?settings'?", regex=True
    
  857.         )
    
  858. 
    
  859.     def test_builtin_with_bad_settings(self):
    
  860.         """
    
  861.         no settings: manage.py builtin commands fail if settings file (from
    
  862.         argument) doesn't exist.
    
  863.         """
    
  864.         args = ["check", "--settings=bad_settings", "admin_scripts"]
    
  865.         out, err = self.run_manage(args)
    
  866.         self.assertNoOutput(out)
    
  867.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  868. 
    
  869.     def test_builtin_with_bad_environment(self):
    
  870.         """
    
  871.         no settings: manage.py builtin commands fail if settings file (from
    
  872.         environment) doesn't exist.
    
  873.         """
    
  874.         args = ["check", "admin_scripts"]
    
  875.         out, err = self.run_manage(args, "bad_settings")
    
  876.         self.assertNoOutput(out)
    
  877.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  878. 
    
  879. 
    
  880. class ManageDefaultSettings(AdminScriptTestCase):
    
  881.     """A series of tests for manage.py when using a settings.py file that
    
  882.     contains the test application.
    
  883.     """
    
  884. 
    
  885.     def setUp(self):
    
  886.         super().setUp()
    
  887.         self.write_settings("settings.py")
    
  888. 
    
  889.     def test_builtin_command(self):
    
  890.         """
    
  891.         default: manage.py builtin commands succeed when default settings are
    
  892.         appropriate.
    
  893.         """
    
  894.         args = ["check", "admin_scripts"]
    
  895.         out, err = self.run_manage(args)
    
  896.         self.assertNoOutput(err)
    
  897.         self.assertOutput(out, SYSTEM_CHECK_MSG)
    
  898. 
    
  899.     def test_builtin_with_settings(self):
    
  900.         """
    
  901.         default: manage.py builtin commands succeed if settings are provided as
    
  902.         argument.
    
  903.         """
    
  904.         args = ["check", "--settings=test_project.settings", "admin_scripts"]
    
  905.         out, err = self.run_manage(args)
    
  906.         self.assertNoOutput(err)
    
  907.         self.assertOutput(out, SYSTEM_CHECK_MSG)
    
  908. 
    
  909.     def test_builtin_with_environment(self):
    
  910.         """
    
  911.         default: manage.py builtin commands succeed if settings are provided in
    
  912.         the environment.
    
  913.         """
    
  914.         args = ["check", "admin_scripts"]
    
  915.         out, err = self.run_manage(args, "test_project.settings")
    
  916.         self.assertNoOutput(err)
    
  917.         self.assertOutput(out, SYSTEM_CHECK_MSG)
    
  918. 
    
  919.     def test_builtin_with_bad_settings(self):
    
  920.         """
    
  921.         default: manage.py builtin commands succeed if settings file (from
    
  922.         argument) doesn't exist.
    
  923.         """
    
  924.         args = ["check", "--settings=bad_settings", "admin_scripts"]
    
  925.         out, err = self.run_manage(args)
    
  926.         self.assertNoOutput(out)
    
  927.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  928. 
    
  929.     def test_builtin_with_bad_environment(self):
    
  930.         """
    
  931.         default: manage.py builtin commands fail if settings file (from
    
  932.         environment) doesn't exist.
    
  933.         """
    
  934.         args = ["check", "admin_scripts"]
    
  935.         out, err = self.run_manage(args, "bad_settings")
    
  936.         self.assertNoOutput(out)
    
  937.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  938. 
    
  939.     def test_custom_command(self):
    
  940.         """
    
  941.         default: manage.py can execute user commands when default settings are
    
  942.         appropriate.
    
  943.         """
    
  944.         args = ["noargs_command"]
    
  945.         out, err = self.run_manage(args)
    
  946.         self.assertNoOutput(err)
    
  947.         self.assertOutput(out, "EXECUTE: noargs_command")
    
  948. 
    
  949.     def test_custom_command_with_settings(self):
    
  950.         """
    
  951.         default: manage.py can execute user commands when settings are provided
    
  952.         as argument.
    
  953.         """
    
  954.         args = ["noargs_command", "--settings=test_project.settings"]
    
  955.         out, err = self.run_manage(args)
    
  956.         self.assertNoOutput(err)
    
  957.         self.assertOutput(out, "EXECUTE: noargs_command")
    
  958. 
    
  959.     def test_custom_command_with_environment(self):
    
  960.         """
    
  961.         default: manage.py can execute user commands when settings are provided
    
  962.         in environment.
    
  963.         """
    
  964.         args = ["noargs_command"]
    
  965.         out, err = self.run_manage(args, "test_project.settings")
    
  966.         self.assertNoOutput(err)
    
  967.         self.assertOutput(out, "EXECUTE: noargs_command")
    
  968. 
    
  969. 
    
  970. class ManageFullPathDefaultSettings(AdminScriptTestCase):
    
  971.     """A series of tests for manage.py when using a settings.py file that
    
  972.     contains the test application specified using a full path.
    
  973.     """
    
  974. 
    
  975.     def setUp(self):
    
  976.         super().setUp()
    
  977.         self.write_settings(
    
  978.             "settings.py",
    
  979.             ["django.contrib.auth", "django.contrib.contenttypes", "admin_scripts"],
    
  980.         )
    
  981. 
    
  982.     def test_builtin_command(self):
    
  983.         """
    
  984.         fulldefault: manage.py builtin commands succeed when default settings
    
  985.         are appropriate.
    
  986.         """
    
  987.         args = ["check", "admin_scripts"]
    
  988.         out, err = self.run_manage(args)
    
  989.         self.assertNoOutput(err)
    
  990.         self.assertOutput(out, SYSTEM_CHECK_MSG)
    
  991. 
    
  992.     def test_builtin_with_settings(self):
    
  993.         """
    
  994.         fulldefault: manage.py builtin commands succeed if settings are
    
  995.         provided as argument.
    
  996.         """
    
  997.         args = ["check", "--settings=test_project.settings", "admin_scripts"]
    
  998.         out, err = self.run_manage(args)
    
  999.         self.assertNoOutput(err)
    
  1000.         self.assertOutput(out, SYSTEM_CHECK_MSG)
    
  1001. 
    
  1002.     def test_builtin_with_environment(self):
    
  1003.         """
    
  1004.         fulldefault: manage.py builtin commands succeed if settings are
    
  1005.         provided in the environment.
    
  1006.         """
    
  1007.         args = ["check", "admin_scripts"]
    
  1008.         out, err = self.run_manage(args, "test_project.settings")
    
  1009.         self.assertNoOutput(err)
    
  1010.         self.assertOutput(out, SYSTEM_CHECK_MSG)
    
  1011. 
    
  1012.     def test_builtin_with_bad_settings(self):
    
  1013.         """
    
  1014.         fulldefault: manage.py builtin commands succeed if settings file (from
    
  1015.         argument) doesn't exist.
    
  1016.         """
    
  1017.         args = ["check", "--settings=bad_settings", "admin_scripts"]
    
  1018.         out, err = self.run_manage(args)
    
  1019.         self.assertNoOutput(out)
    
  1020.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  1021. 
    
  1022.     def test_builtin_with_bad_environment(self):
    
  1023.         """
    
  1024.         fulldefault: manage.py builtin commands fail if settings file (from
    
  1025.         environment) doesn't exist.
    
  1026.         """
    
  1027.         args = ["check", "admin_scripts"]
    
  1028.         out, err = self.run_manage(args, "bad_settings")
    
  1029.         self.assertNoOutput(out)
    
  1030.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  1031. 
    
  1032.     def test_custom_command(self):
    
  1033.         """
    
  1034.         fulldefault: manage.py can execute user commands when default settings
    
  1035.         are appropriate.
    
  1036.         """
    
  1037.         args = ["noargs_command"]
    
  1038.         out, err = self.run_manage(args)
    
  1039.         self.assertNoOutput(err)
    
  1040.         self.assertOutput(out, "EXECUTE: noargs_command")
    
  1041. 
    
  1042.     def test_custom_command_with_settings(self):
    
  1043.         """
    
  1044.         fulldefault: manage.py can execute user commands when settings are
    
  1045.         provided as argument.
    
  1046.         """
    
  1047.         args = ["noargs_command", "--settings=test_project.settings"]
    
  1048.         out, err = self.run_manage(args)
    
  1049.         self.assertNoOutput(err)
    
  1050.         self.assertOutput(out, "EXECUTE: noargs_command")
    
  1051. 
    
  1052.     def test_custom_command_with_environment(self):
    
  1053.         """
    
  1054.         fulldefault: manage.py can execute user commands when settings are
    
  1055.         provided in environment.
    
  1056.         """
    
  1057.         args = ["noargs_command"]
    
  1058.         out, err = self.run_manage(args, "test_project.settings")
    
  1059.         self.assertNoOutput(err)
    
  1060.         self.assertOutput(out, "EXECUTE: noargs_command")
    
  1061. 
    
  1062. 
    
  1063. class ManageMinimalSettings(AdminScriptTestCase):
    
  1064.     """A series of tests for manage.py when using a settings.py file that
    
  1065.     doesn't contain the test application.
    
  1066.     """
    
  1067. 
    
  1068.     def setUp(self):
    
  1069.         super().setUp()
    
  1070.         self.write_settings(
    
  1071.             "settings.py", apps=["django.contrib.auth", "django.contrib.contenttypes"]
    
  1072.         )
    
  1073. 
    
  1074.     def test_builtin_command(self):
    
  1075.         """
    
  1076.         minimal: manage.py builtin commands fail with an error when no settings
    
  1077.         provided.
    
  1078.         """
    
  1079.         args = ["check", "admin_scripts"]
    
  1080.         out, err = self.run_manage(args)
    
  1081.         self.assertNoOutput(out)
    
  1082.         self.assertOutput(err, "No installed app with label 'admin_scripts'.")
    
  1083. 
    
  1084.     def test_builtin_with_settings(self):
    
  1085.         "minimal: manage.py builtin commands fail if settings are provided as argument"
    
  1086.         args = ["check", "--settings=test_project.settings", "admin_scripts"]
    
  1087.         out, err = self.run_manage(args)
    
  1088.         self.assertNoOutput(out)
    
  1089.         self.assertOutput(err, "No installed app with label 'admin_scripts'.")
    
  1090. 
    
  1091.     def test_builtin_with_environment(self):
    
  1092.         """
    
  1093.         minimal: manage.py builtin commands fail if settings are provided in
    
  1094.         the environment.
    
  1095.         """
    
  1096.         args = ["check", "admin_scripts"]
    
  1097.         out, err = self.run_manage(args, "test_project.settings")
    
  1098.         self.assertNoOutput(out)
    
  1099.         self.assertOutput(err, "No installed app with label 'admin_scripts'.")
    
  1100. 
    
  1101.     def test_builtin_with_bad_settings(self):
    
  1102.         """
    
  1103.         minimal: manage.py builtin commands fail if settings file (from
    
  1104.         argument) doesn't exist.
    
  1105.         """
    
  1106.         args = ["check", "--settings=bad_settings", "admin_scripts"]
    
  1107.         out, err = self.run_manage(args)
    
  1108.         self.assertNoOutput(out)
    
  1109.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  1110. 
    
  1111.     def test_builtin_with_bad_environment(self):
    
  1112.         """
    
  1113.         minimal: manage.py builtin commands fail if settings file (from
    
  1114.         environment) doesn't exist.
    
  1115.         """
    
  1116.         args = ["check", "admin_scripts"]
    
  1117.         out, err = self.run_manage(args, "bad_settings")
    
  1118.         self.assertNoOutput(out)
    
  1119.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  1120. 
    
  1121.     def test_custom_command(self):
    
  1122.         "minimal: manage.py can't execute user commands without appropriate settings"
    
  1123.         args = ["noargs_command"]
    
  1124.         out, err = self.run_manage(args)
    
  1125.         self.assertNoOutput(out)
    
  1126.         self.assertOutput(err, "Unknown command: 'noargs_command'")
    
  1127. 
    
  1128.     def test_custom_command_with_settings(self):
    
  1129.         """
    
  1130.         minimal: manage.py can't execute user commands, even if settings are
    
  1131.         provided as argument.
    
  1132.         """
    
  1133.         args = ["noargs_command", "--settings=test_project.settings"]
    
  1134.         out, err = self.run_manage(args)
    
  1135.         self.assertNoOutput(out)
    
  1136.         self.assertOutput(err, "Unknown command: 'noargs_command'")
    
  1137. 
    
  1138.     def test_custom_command_with_environment(self):
    
  1139.         """
    
  1140.         minimal: manage.py can't execute user commands, even if settings are
    
  1141.         provided in environment.
    
  1142.         """
    
  1143.         args = ["noargs_command"]
    
  1144.         out, err = self.run_manage(args, "test_project.settings")
    
  1145.         self.assertNoOutput(out)
    
  1146.         self.assertOutput(err, "Unknown command: 'noargs_command'")
    
  1147. 
    
  1148. 
    
  1149. class ManageAlternateSettings(AdminScriptTestCase):
    
  1150.     """A series of tests for manage.py when using a settings file
    
  1151.     with a name other than 'settings.py'.
    
  1152.     """
    
  1153. 
    
  1154.     def setUp(self):
    
  1155.         super().setUp()
    
  1156.         self.write_settings("alternate_settings.py")
    
  1157. 
    
  1158.     def test_builtin_command(self):
    
  1159.         """
    
  1160.         alternate: manage.py builtin commands fail with an error when no
    
  1161.         default settings provided.
    
  1162.         """
    
  1163.         args = ["check", "admin_scripts"]
    
  1164.         out, err = self.run_manage(args)
    
  1165.         self.assertNoOutput(out)
    
  1166.         self.assertOutput(
    
  1167.             err, r"No module named '?(test_project\.)?settings'?", regex=True
    
  1168.         )
    
  1169. 
    
  1170.     def test_builtin_with_settings(self):
    
  1171.         "alternate: manage.py builtin commands work with settings provided as argument"
    
  1172.         args = ["check", "--settings=alternate_settings", "admin_scripts"]
    
  1173.         out, err = self.run_manage(args)
    
  1174.         self.assertOutput(out, SYSTEM_CHECK_MSG)
    
  1175.         self.assertNoOutput(err)
    
  1176. 
    
  1177.     def test_builtin_with_environment(self):
    
  1178.         """
    
  1179.         alternate: manage.py builtin commands work if settings are provided in
    
  1180.         the environment
    
  1181.         """
    
  1182.         args = ["check", "admin_scripts"]
    
  1183.         out, err = self.run_manage(args, "alternate_settings")
    
  1184.         self.assertOutput(out, SYSTEM_CHECK_MSG)
    
  1185.         self.assertNoOutput(err)
    
  1186. 
    
  1187.     def test_builtin_with_bad_settings(self):
    
  1188.         """
    
  1189.         alternate: manage.py builtin commands fail if settings file (from
    
  1190.         argument) doesn't exist.
    
  1191.         """
    
  1192.         args = ["check", "--settings=bad_settings", "admin_scripts"]
    
  1193.         out, err = self.run_manage(args)
    
  1194.         self.assertNoOutput(out)
    
  1195.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  1196. 
    
  1197.     def test_builtin_with_bad_environment(self):
    
  1198.         """
    
  1199.         alternate: manage.py builtin commands fail if settings file (from
    
  1200.         environment) doesn't exist
    
  1201.         """
    
  1202.         args = ["check", "admin_scripts"]
    
  1203.         out, err = self.run_manage(args, "bad_settings")
    
  1204.         self.assertNoOutput(out)
    
  1205.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  1206. 
    
  1207.     def test_custom_command(self):
    
  1208.         "alternate: manage.py can't execute user commands without settings"
    
  1209.         args = ["noargs_command"]
    
  1210.         out, err = self.run_manage(args)
    
  1211.         self.assertNoOutput(out)
    
  1212.         self.assertOutput(
    
  1213.             err, r"No module named '?(test_project\.)?settings'?", regex=True
    
  1214.         )
    
  1215. 
    
  1216.     def test_custom_command_with_settings(self):
    
  1217.         """
    
  1218.         alternate: manage.py can execute user commands if settings are provided
    
  1219.         as argument
    
  1220.         """
    
  1221.         args = ["noargs_command", "--settings=alternate_settings"]
    
  1222.         out, err = self.run_manage(args)
    
  1223.         self.assertOutput(
    
  1224.             out,
    
  1225.             "EXECUTE: noargs_command options=[('force_color', False), "
    
  1226.             "('no_color', False), ('pythonpath', None), ('settings', "
    
  1227.             "'alternate_settings'), ('traceback', False), ('verbosity', 1)]",
    
  1228.         )
    
  1229.         self.assertNoOutput(err)
    
  1230. 
    
  1231.     def test_custom_command_with_environment(self):
    
  1232.         """
    
  1233.         alternate: manage.py can execute user commands if settings are provided
    
  1234.         in environment.
    
  1235.         """
    
  1236.         args = ["noargs_command"]
    
  1237.         out, err = self.run_manage(args, "alternate_settings")
    
  1238.         self.assertOutput(
    
  1239.             out,
    
  1240.             "EXECUTE: noargs_command options=[('force_color', False), "
    
  1241.             "('no_color', False), ('pythonpath', None), ('settings', None), "
    
  1242.             "('traceback', False), ('verbosity', 1)]",
    
  1243.         )
    
  1244.         self.assertNoOutput(err)
    
  1245. 
    
  1246.     def test_custom_command_output_color(self):
    
  1247.         """
    
  1248.         alternate: manage.py output syntax color can be deactivated with the
    
  1249.         `--no-color` option.
    
  1250.         """
    
  1251.         args = ["noargs_command", "--no-color", "--settings=alternate_settings"]
    
  1252.         out, err = self.run_manage(args)
    
  1253.         self.assertOutput(
    
  1254.             out,
    
  1255.             "EXECUTE: noargs_command options=[('force_color', False), "
    
  1256.             "('no_color', True), ('pythonpath', None), ('settings', "
    
  1257.             "'alternate_settings'), ('traceback', False), ('verbosity', 1)]",
    
  1258.         )
    
  1259.         self.assertNoOutput(err)
    
  1260. 
    
  1261. 
    
  1262. class ManageMultipleSettings(AdminScriptTestCase):
    
  1263.     """A series of tests for manage.py when multiple settings files
    
  1264.     (including the default 'settings.py') are available. The default settings
    
  1265.     file is insufficient for performing the operations described, so the
    
  1266.     alternate settings must be used by the running script.
    
  1267.     """
    
  1268. 
    
  1269.     def setUp(self):
    
  1270.         super().setUp()
    
  1271.         self.write_settings(
    
  1272.             "settings.py", apps=["django.contrib.auth", "django.contrib.contenttypes"]
    
  1273.         )
    
  1274.         self.write_settings("alternate_settings.py")
    
  1275. 
    
  1276.     def test_builtin_command(self):
    
  1277.         """
    
  1278.         multiple: manage.py builtin commands fail with an error when no
    
  1279.         settings provided.
    
  1280.         """
    
  1281.         args = ["check", "admin_scripts"]
    
  1282.         out, err = self.run_manage(args)
    
  1283.         self.assertNoOutput(out)
    
  1284.         self.assertOutput(err, "No installed app with label 'admin_scripts'.")
    
  1285. 
    
  1286.     def test_builtin_with_settings(self):
    
  1287.         """
    
  1288.         multiple: manage.py builtin commands succeed if settings are provided
    
  1289.         as argument.
    
  1290.         """
    
  1291.         args = ["check", "--settings=alternate_settings", "admin_scripts"]
    
  1292.         out, err = self.run_manage(args)
    
  1293.         self.assertNoOutput(err)
    
  1294.         self.assertOutput(out, SYSTEM_CHECK_MSG)
    
  1295. 
    
  1296.     def test_builtin_with_environment(self):
    
  1297.         """
    
  1298.         multiple: manage.py can execute builtin commands if settings are
    
  1299.         provided in the environment.
    
  1300.         """
    
  1301.         args = ["check", "admin_scripts"]
    
  1302.         out, err = self.run_manage(args, "alternate_settings")
    
  1303.         self.assertNoOutput(err)
    
  1304.         self.assertOutput(out, SYSTEM_CHECK_MSG)
    
  1305. 
    
  1306.     def test_builtin_with_bad_settings(self):
    
  1307.         """
    
  1308.         multiple: manage.py builtin commands fail if settings file (from
    
  1309.         argument) doesn't exist.
    
  1310.         """
    
  1311.         args = ["check", "--settings=bad_settings", "admin_scripts"]
    
  1312.         out, err = self.run_manage(args)
    
  1313.         self.assertNoOutput(out)
    
  1314.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  1315. 
    
  1316.     def test_builtin_with_bad_environment(self):
    
  1317.         """
    
  1318.         multiple: manage.py builtin commands fail if settings file (from
    
  1319.         environment) doesn't exist.
    
  1320.         """
    
  1321.         args = ["check", "admin_scripts"]
    
  1322.         out, err = self.run_manage(args, "bad_settings")
    
  1323.         self.assertNoOutput(out)
    
  1324.         self.assertOutput(err, "No module named '?bad_settings'?", regex=True)
    
  1325. 
    
  1326.     def test_custom_command(self):
    
  1327.         "multiple: manage.py can't execute user commands using default settings"
    
  1328.         args = ["noargs_command"]
    
  1329.         out, err = self.run_manage(args)
    
  1330.         self.assertNoOutput(out)
    
  1331.         self.assertOutput(err, "Unknown command: 'noargs_command'")
    
  1332. 
    
  1333.     def test_custom_command_with_settings(self):
    
  1334.         """
    
  1335.         multiple: manage.py can execute user commands if settings are provided
    
  1336.         as argument.
    
  1337.         """
    
  1338.         args = ["noargs_command", "--settings=alternate_settings"]
    
  1339.         out, err = self.run_manage(args)
    
  1340.         self.assertNoOutput(err)
    
  1341.         self.assertOutput(out, "EXECUTE: noargs_command")
    
  1342. 
    
  1343.     def test_custom_command_with_environment(self):
    
  1344.         """
    
  1345.         multiple: manage.py can execute user commands if settings are provided
    
  1346.         in environment.
    
  1347.         """
    
  1348.         args = ["noargs_command"]
    
  1349.         out, err = self.run_manage(args, "alternate_settings")
    
  1350.         self.assertNoOutput(err)
    
  1351.         self.assertOutput(out, "EXECUTE: noargs_command")
    
  1352. 
    
  1353. 
    
  1354. class ManageSettingsWithSettingsErrors(AdminScriptTestCase):
    
  1355.     """
    
  1356.     Tests for manage.py when using the default settings.py file containing
    
  1357.     runtime errors.
    
  1358.     """
    
  1359. 
    
  1360.     def write_settings_with_import_error(self, filename):
    
  1361.         settings_file_path = os.path.join(self.test_dir, filename)
    
  1362.         with open(settings_file_path, "w") as settings_file:
    
  1363.             settings_file.write(
    
  1364.                 "# Settings file automatically generated by admin_scripts test case\n"
    
  1365.             )
    
  1366.             settings_file.write(
    
  1367.                 "# The next line will cause an import error:\nimport foo42bar\n"
    
  1368.             )
    
  1369. 
    
  1370.     def test_import_error(self):
    
  1371.         """
    
  1372.         import error: manage.py builtin commands shows useful diagnostic info
    
  1373.         when settings with import errors is provided (#14130).
    
  1374.         """
    
  1375.         self.write_settings_with_import_error("settings.py")
    
  1376.         args = ["check", "admin_scripts"]
    
  1377.         out, err = self.run_manage(args)
    
  1378.         self.assertNoOutput(out)
    
  1379.         self.assertOutput(err, "No module named")
    
  1380.         self.assertOutput(err, "foo42bar")
    
  1381. 
    
  1382.     def test_attribute_error(self):
    
  1383.         """
    
  1384.         manage.py builtin commands does not swallow attribute error due to bad
    
  1385.         settings (#18845).
    
  1386.         """
    
  1387.         self.write_settings("settings.py", sdict={"BAD_VAR": "INSTALLED_APPS.crash"})
    
  1388.         args = ["collectstatic", "admin_scripts"]
    
  1389.         out, err = self.run_manage(args)
    
  1390.         self.assertNoOutput(out)
    
  1391.         self.assertOutput(err, "AttributeError: 'list' object has no attribute 'crash'")
    
  1392. 
    
  1393.     def test_key_error(self):
    
  1394.         self.write_settings("settings.py", sdict={"BAD_VAR": 'DATABASES["blah"]'})
    
  1395.         args = ["collectstatic", "admin_scripts"]
    
  1396.         out, err = self.run_manage(args)
    
  1397.         self.assertNoOutput(out)
    
  1398.         self.assertOutput(err, "KeyError: 'blah'")
    
  1399. 
    
  1400.     def test_help(self):
    
  1401.         """
    
  1402.         Test listing available commands output note when only core commands are
    
  1403.         available.
    
  1404.         """
    
  1405.         self.write_settings(
    
  1406.             "settings.py",
    
  1407.             extra="from django.core.exceptions import ImproperlyConfigured\n"
    
  1408.             "raise ImproperlyConfigured()",
    
  1409.         )
    
  1410.         args = ["help"]
    
  1411.         out, err = self.run_manage(args)
    
  1412.         self.assertOutput(out, "only Django core commands are listed")
    
  1413.         self.assertNoOutput(err)
    
  1414. 
    
  1415. 
    
  1416. class ManageCheck(AdminScriptTestCase):
    
  1417.     def test_nonexistent_app(self):
    
  1418.         """check reports an error on a nonexistent app in INSTALLED_APPS."""
    
  1419.         self.write_settings(
    
  1420.             "settings.py",
    
  1421.             apps=["admin_scriptz.broken_app"],
    
  1422.             sdict={"USE_I18N": False},
    
  1423.         )
    
  1424.         args = ["check"]
    
  1425.         out, err = self.run_manage(args)
    
  1426.         self.assertNoOutput(out)
    
  1427.         self.assertOutput(err, "ModuleNotFoundError")
    
  1428.         self.assertOutput(err, "No module named")
    
  1429.         self.assertOutput(err, "admin_scriptz")
    
  1430. 
    
  1431.     def test_broken_app(self):
    
  1432.         """manage.py check reports an ImportError if an app's models.py
    
  1433.         raises one on import"""
    
  1434. 
    
  1435.         self.write_settings("settings.py", apps=["admin_scripts.broken_app"])
    
  1436.         args = ["check"]
    
  1437.         out, err = self.run_manage(args)
    
  1438.         self.assertNoOutput(out)
    
  1439.         self.assertOutput(err, "ImportError")
    
  1440. 
    
  1441.     def test_complex_app(self):
    
  1442.         """manage.py check does not raise an ImportError validating a
    
  1443.         complex app with nested calls to load_app"""
    
  1444. 
    
  1445.         self.write_settings(
    
  1446.             "settings.py",
    
  1447.             apps=[
    
  1448.                 "admin_scripts.complex_app",
    
  1449.                 "admin_scripts.simple_app",
    
  1450.                 "django.contrib.admin.apps.SimpleAdminConfig",
    
  1451.                 "django.contrib.auth",
    
  1452.                 "django.contrib.contenttypes",
    
  1453.                 "django.contrib.messages",
    
  1454.             ],
    
  1455.             sdict={
    
  1456.                 "DEBUG": True,
    
  1457.                 "MIDDLEWARE": [
    
  1458.                     "django.contrib.messages.middleware.MessageMiddleware",
    
  1459.                     "django.contrib.auth.middleware.AuthenticationMiddleware",
    
  1460.                     "django.contrib.sessions.middleware.SessionMiddleware",
    
  1461.                 ],
    
  1462.                 "TEMPLATES": [
    
  1463.                     {
    
  1464.                         "BACKEND": "django.template.backends.django.DjangoTemplates",
    
  1465.                         "DIRS": [],
    
  1466.                         "APP_DIRS": True,
    
  1467.                         "OPTIONS": {
    
  1468.                             "context_processors": [
    
  1469.                                 "django.template.context_processors.request",
    
  1470.                                 "django.contrib.auth.context_processors.auth",
    
  1471.                                 "django.contrib.messages.context_processors.messages",
    
  1472.                             ],
    
  1473.                         },
    
  1474.                     },
    
  1475.                 ],
    
  1476.             },
    
  1477.         )
    
  1478.         args = ["check"]
    
  1479.         out, err = self.run_manage(args)
    
  1480.         self.assertNoOutput(err)
    
  1481.         self.assertEqual(out, "System check identified no issues (0 silenced).\n")
    
  1482. 
    
  1483.     def test_app_with_import(self):
    
  1484.         """manage.py check does not raise errors when an app imports a base
    
  1485.         class that itself has an abstract base."""
    
  1486. 
    
  1487.         self.write_settings(
    
  1488.             "settings.py",
    
  1489.             apps=[
    
  1490.                 "admin_scripts.app_with_import",
    
  1491.                 "django.contrib.auth",
    
  1492.                 "django.contrib.contenttypes",
    
  1493.                 "django.contrib.sites",
    
  1494.             ],
    
  1495.             sdict={"DEBUG": True},
    
  1496.         )
    
  1497.         args = ["check"]
    
  1498.         out, err = self.run_manage(args)
    
  1499.         self.assertNoOutput(err)
    
  1500.         self.assertEqual(out, "System check identified no issues (0 silenced).\n")
    
  1501. 
    
  1502.     def test_output_format(self):
    
  1503.         """All errors/warnings should be sorted by level and by message."""
    
  1504. 
    
  1505.         self.write_settings(
    
  1506.             "settings.py",
    
  1507.             apps=[
    
  1508.                 "admin_scripts.app_raising_messages",
    
  1509.                 "django.contrib.auth",
    
  1510.                 "django.contrib.contenttypes",
    
  1511.             ],
    
  1512.             sdict={"DEBUG": True},
    
  1513.         )
    
  1514.         args = ["check"]
    
  1515.         out, err = self.run_manage(args)
    
  1516.         expected_err = (
    
  1517.             "SystemCheckError: System check identified some issues:\n"
    
  1518.             "\n"
    
  1519.             "ERRORS:\n"
    
  1520.             "?: An error\n"
    
  1521.             "\tHINT: Error hint\n"
    
  1522.             "\n"
    
  1523.             "WARNINGS:\n"
    
  1524.             "a: Second warning\n"
    
  1525.             "obj: First warning\n"
    
  1526.             "\tHINT: Hint\n"
    
  1527.             "\n"
    
  1528.             "System check identified 3 issues (0 silenced).\n"
    
  1529.         )
    
  1530.         self.assertEqual(err, expected_err)
    
  1531.         self.assertNoOutput(out)
    
  1532. 
    
  1533.     def test_warning_does_not_halt(self):
    
  1534.         """
    
  1535.         When there are only warnings or less serious messages, then Django
    
  1536.         should not prevent user from launching their project, so `check`
    
  1537.         command should not raise `CommandError` exception.
    
  1538. 
    
  1539.         In this test we also test output format.
    
  1540.         """
    
  1541. 
    
  1542.         self.write_settings(
    
  1543.             "settings.py",
    
  1544.             apps=[
    
  1545.                 "admin_scripts.app_raising_warning",
    
  1546.                 "django.contrib.auth",
    
  1547.                 "django.contrib.contenttypes",
    
  1548.             ],
    
  1549.             sdict={"DEBUG": True},
    
  1550.         )
    
  1551.         args = ["check"]
    
  1552.         out, err = self.run_manage(args)
    
  1553.         expected_err = (
    
  1554.             "System check identified some issues:\n"  # No "CommandError: " part
    
  1555.             "\n"
    
  1556.             "WARNINGS:\n"
    
  1557.             "?: A warning\n"
    
  1558.             "\n"
    
  1559.             "System check identified 1 issue (0 silenced).\n"
    
  1560.         )
    
  1561.         self.assertEqual(err, expected_err)
    
  1562.         self.assertNoOutput(out)
    
  1563. 
    
  1564. 
    
  1565. class ManageRunserver(SimpleTestCase):
    
  1566.     def setUp(self):
    
  1567.         def monkey_run(*args, **options):
    
  1568.             return
    
  1569. 
    
  1570.         self.output = StringIO()
    
  1571.         self.cmd = RunserverCommand(stdout=self.output)
    
  1572.         self.cmd.run = monkey_run
    
  1573. 
    
  1574.     def assertServerSettings(self, addr, port, ipv6=False, raw_ipv6=False):
    
  1575.         self.assertEqual(self.cmd.addr, addr)
    
  1576.         self.assertEqual(self.cmd.port, port)
    
  1577.         self.assertEqual(self.cmd.use_ipv6, ipv6)
    
  1578.         self.assertEqual(self.cmd._raw_ipv6, raw_ipv6)
    
  1579. 
    
  1580.     def test_runserver_addrport(self):
    
  1581.         call_command(self.cmd)
    
  1582.         self.assertServerSettings("127.0.0.1", "8000")
    
  1583. 
    
  1584.         call_command(self.cmd, addrport="1.2.3.4:8000")
    
  1585.         self.assertServerSettings("1.2.3.4", "8000")
    
  1586. 
    
  1587.         call_command(self.cmd, addrport="7000")
    
  1588.         self.assertServerSettings("127.0.0.1", "7000")
    
  1589. 
    
  1590.     @unittest.skipUnless(socket.has_ipv6, "platform doesn't support IPv6")
    
  1591.     def test_runner_addrport_ipv6(self):
    
  1592.         call_command(self.cmd, addrport="", use_ipv6=True)
    
  1593.         self.assertServerSettings("::1", "8000", ipv6=True, raw_ipv6=True)
    
  1594. 
    
  1595.         call_command(self.cmd, addrport="7000", use_ipv6=True)
    
  1596.         self.assertServerSettings("::1", "7000", ipv6=True, raw_ipv6=True)
    
  1597. 
    
  1598.         call_command(self.cmd, addrport="[2001:0db8:1234:5678::9]:7000")
    
  1599.         self.assertServerSettings(
    
  1600.             "2001:0db8:1234:5678::9", "7000", ipv6=True, raw_ipv6=True
    
  1601.         )
    
  1602. 
    
  1603.     def test_runner_hostname(self):
    
  1604.         call_command(self.cmd, addrport="localhost:8000")
    
  1605.         self.assertServerSettings("localhost", "8000")
    
  1606. 
    
  1607.         call_command(self.cmd, addrport="test.domain.local:7000")
    
  1608.         self.assertServerSettings("test.domain.local", "7000")
    
  1609. 
    
  1610.     @unittest.skipUnless(socket.has_ipv6, "platform doesn't support IPv6")
    
  1611.     def test_runner_hostname_ipv6(self):
    
  1612.         call_command(self.cmd, addrport="test.domain.local:7000", use_ipv6=True)
    
  1613.         self.assertServerSettings("test.domain.local", "7000", ipv6=True)
    
  1614. 
    
  1615.     def test_runner_custom_defaults(self):
    
  1616.         self.cmd.default_addr = "0.0.0.0"
    
  1617.         self.cmd.default_port = "5000"
    
  1618.         call_command(self.cmd)
    
  1619.         self.assertServerSettings("0.0.0.0", "5000")
    
  1620. 
    
  1621.     @unittest.skipUnless(socket.has_ipv6, "platform doesn't support IPv6")
    
  1622.     def test_runner_custom_defaults_ipv6(self):
    
  1623.         self.cmd.default_addr_ipv6 = "::"
    
  1624.         call_command(self.cmd, use_ipv6=True)
    
  1625.         self.assertServerSettings("::", "8000", ipv6=True, raw_ipv6=True)
    
  1626. 
    
  1627.     def test_runner_ambiguous(self):
    
  1628.         # Only 4 characters, all of which could be in an ipv6 address
    
  1629.         call_command(self.cmd, addrport="beef:7654")
    
  1630.         self.assertServerSettings("beef", "7654")
    
  1631. 
    
  1632.         # Uses only characters that could be in an ipv6 address
    
  1633.         call_command(self.cmd, addrport="deadbeef:7654")
    
  1634.         self.assertServerSettings("deadbeef", "7654")
    
  1635. 
    
  1636.     def test_no_database(self):
    
  1637.         """
    
  1638.         Ensure runserver.check_migrations doesn't choke on empty DATABASES.
    
  1639.         """
    
  1640.         tested_connections = ConnectionHandler({})
    
  1641.         with mock.patch(
    
  1642.             "django.core.management.base.connections", new=tested_connections
    
  1643.         ):
    
  1644.             self.cmd.check_migrations()
    
  1645. 
    
  1646.     def test_readonly_database(self):
    
  1647.         """
    
  1648.         runserver.check_migrations() doesn't choke when a database is read-only.
    
  1649.         """
    
  1650.         with mock.patch.object(MigrationRecorder, "has_table", return_value=False):
    
  1651.             self.cmd.check_migrations()
    
  1652.         # You have # ...
    
  1653.         self.assertIn("unapplied migration(s)", self.output.getvalue())
    
  1654. 
    
  1655.     @mock.patch("django.core.management.commands.runserver.run")
    
  1656.     @mock.patch("django.core.management.base.BaseCommand.check_migrations")
    
  1657.     @mock.patch("django.core.management.base.BaseCommand.check")
    
  1658.     def test_skip_checks(self, mocked_check, *mocked_objects):
    
  1659.         call_command(
    
  1660.             "runserver",
    
  1661.             use_reloader=False,
    
  1662.             skip_checks=True,
    
  1663.             stdout=self.output,
    
  1664.         )
    
  1665.         self.assertNotIn("Performing system checks...", self.output.getvalue())
    
  1666.         mocked_check.assert_not_called()
    
  1667. 
    
  1668.         self.output.truncate(0)
    
  1669.         call_command(
    
  1670.             "runserver",
    
  1671.             use_reloader=False,
    
  1672.             skip_checks=False,
    
  1673.             stdout=self.output,
    
  1674.         )
    
  1675.         self.assertIn("Performing system checks...", self.output.getvalue())
    
  1676.         mocked_check.assert_called()
    
  1677. 
    
  1678. 
    
  1679. class ManageRunserverMigrationWarning(TestCase):
    
  1680.     def setUp(self):
    
  1681.         self.stdout = StringIO()
    
  1682.         self.runserver_command = RunserverCommand(stdout=self.stdout)
    
  1683. 
    
  1684.     @override_settings(INSTALLED_APPS=["admin_scripts.app_waiting_migration"])
    
  1685.     def test_migration_warning_one_app(self):
    
  1686.         self.runserver_command.check_migrations()
    
  1687.         output = self.stdout.getvalue()
    
  1688.         self.assertIn("You have 1 unapplied migration(s)", output)
    
  1689.         self.assertIn("apply the migrations for app(s): app_waiting_migration.", output)
    
  1690. 
    
  1691.     @override_settings(
    
  1692.         INSTALLED_APPS=[
    
  1693.             "admin_scripts.app_waiting_migration",
    
  1694.             "admin_scripts.another_app_waiting_migration",
    
  1695.         ],
    
  1696.     )
    
  1697.     def test_migration_warning_multiple_apps(self):
    
  1698.         self.runserver_command.check_migrations()
    
  1699.         output = self.stdout.getvalue()
    
  1700.         self.assertIn("You have 2 unapplied migration(s)", output)
    
  1701.         self.assertIn(
    
  1702.             "apply the migrations for app(s): another_app_waiting_migration, "
    
  1703.             "app_waiting_migration.",
    
  1704.             output,
    
  1705.         )
    
  1706. 
    
  1707. 
    
  1708. class ManageRunserverEmptyAllowedHosts(AdminScriptTestCase):
    
  1709.     def setUp(self):
    
  1710.         super().setUp()
    
  1711.         self.write_settings(
    
  1712.             "settings.py",
    
  1713.             sdict={
    
  1714.                 "ALLOWED_HOSTS": [],
    
  1715.                 "DEBUG": False,
    
  1716.             },
    
  1717.         )
    
  1718. 
    
  1719.     def test_empty_allowed_hosts_error(self):
    
  1720.         out, err = self.run_manage(["runserver"])
    
  1721.         self.assertNoOutput(out)
    
  1722.         self.assertOutput(
    
  1723.             err, "CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False."
    
  1724.         )
    
  1725. 
    
  1726. 
    
  1727. class ManageRunserverHelpOutput(AdminScriptTestCase):
    
  1728.     def test_suppressed_options(self):
    
  1729.         """runserver doesn't support --verbosity and --trackback options."""
    
  1730.         out, err = self.run_manage(["runserver", "--help"])
    
  1731.         self.assertNotInOutput(out, "--verbosity")
    
  1732.         self.assertNotInOutput(out, "--trackback")
    
  1733.         self.assertOutput(out, "--settings")
    
  1734. 
    
  1735. 
    
  1736. class ManageTestserver(SimpleTestCase):
    
  1737.     @mock.patch.object(TestserverCommand, "handle", return_value="")
    
  1738.     def test_testserver_handle_params(self, mock_handle):
    
  1739.         out = StringIO()
    
  1740.         call_command("testserver", "blah.json", stdout=out)
    
  1741.         mock_handle.assert_called_with(
    
  1742.             "blah.json",
    
  1743.             stdout=out,
    
  1744.             settings=None,
    
  1745.             pythonpath=None,
    
  1746.             verbosity=1,
    
  1747.             traceback=False,
    
  1748.             addrport="",
    
  1749.             no_color=False,
    
  1750.             use_ipv6=False,
    
  1751.             skip_checks=True,
    
  1752.             interactive=True,
    
  1753.             force_color=False,
    
  1754.         )
    
  1755. 
    
  1756.     @mock.patch("django.db.connection.creation.create_test_db", return_value="test_db")
    
  1757.     @mock.patch.object(LoaddataCommand, "handle", return_value="")
    
  1758.     @mock.patch.object(RunserverCommand, "handle", return_value="")
    
  1759.     def test_params_to_runserver(
    
  1760.         self, mock_runserver_handle, mock_loaddata_handle, mock_create_test_db
    
  1761.     ):
    
  1762.         call_command("testserver", "blah.json")
    
  1763.         mock_runserver_handle.assert_called_with(
    
  1764.             addrport="",
    
  1765.             force_color=False,
    
  1766.             insecure_serving=False,
    
  1767.             no_color=False,
    
  1768.             pythonpath=None,
    
  1769.             settings=None,
    
  1770.             shutdown_message=(
    
  1771.                 "\nServer stopped.\nNote that the test database, 'test_db', "
    
  1772.                 "has not been deleted. You can explore it on your own."
    
  1773.             ),
    
  1774.             skip_checks=True,
    
  1775.             traceback=False,
    
  1776.             use_ipv6=False,
    
  1777.             use_reloader=False,
    
  1778.             use_static_handler=True,
    
  1779.             use_threading=connection.features.test_db_allows_multiple_connections,
    
  1780.             verbosity=1,
    
  1781.         )
    
  1782. 
    
  1783. 
    
  1784. ##########################################################################
    
  1785. # COMMAND PROCESSING TESTS
    
  1786. # user-space commands are correctly handled - in particular, arguments to
    
  1787. # the commands are correctly parsed and processed.
    
  1788. ##########################################################################
    
  1789. class ColorCommand(BaseCommand):
    
  1790.     requires_system_checks = []
    
  1791. 
    
  1792.     def handle(self, *args, **options):
    
  1793.         self.stdout.write("Hello, world!", self.style.ERROR)
    
  1794.         self.stderr.write("Hello, world!", self.style.ERROR)
    
  1795. 
    
  1796. 
    
  1797. class CommandTypes(AdminScriptTestCase):
    
  1798.     "Tests for the various types of base command types that can be defined."
    
  1799. 
    
  1800.     def setUp(self):
    
  1801.         super().setUp()
    
  1802.         self.write_settings("settings.py")
    
  1803. 
    
  1804.     def test_version(self):
    
  1805.         "version is handled as a special case"
    
  1806.         args = ["version"]
    
  1807.         out, err = self.run_manage(args)
    
  1808.         self.assertNoOutput(err)
    
  1809.         self.assertOutput(out, get_version())
    
  1810. 
    
  1811.     def test_version_alternative(self):
    
  1812.         "--version is equivalent to version"
    
  1813.         args1, args2 = ["version"], ["--version"]
    
  1814.         # It's possible one outputs on stderr and the other on stdout, hence the set
    
  1815.         self.assertEqual(set(self.run_manage(args1)), set(self.run_manage(args2)))
    
  1816. 
    
  1817.     def test_help(self):
    
  1818.         "help is handled as a special case"
    
  1819.         args = ["help"]
    
  1820.         out, err = self.run_manage(args)
    
  1821.         self.assertOutput(
    
  1822.             out, "Type 'manage.py help <subcommand>' for help on a specific subcommand."
    
  1823.         )
    
  1824.         self.assertOutput(out, "[django]")
    
  1825.         self.assertOutput(out, "startapp")
    
  1826.         self.assertOutput(out, "startproject")
    
  1827. 
    
  1828.     def test_help_commands(self):
    
  1829.         "help --commands shows the list of all available commands"
    
  1830.         args = ["help", "--commands"]
    
  1831.         out, err = self.run_manage(args)
    
  1832.         self.assertNotInOutput(out, "usage:")
    
  1833.         self.assertNotInOutput(out, "Options:")
    
  1834.         self.assertNotInOutput(out, "[django]")
    
  1835.         self.assertOutput(out, "startapp")
    
  1836.         self.assertOutput(out, "startproject")
    
  1837.         self.assertNotInOutput(out, "\n\n")
    
  1838. 
    
  1839.     def test_help_alternative(self):
    
  1840.         "--help is equivalent to help"
    
  1841.         args1, args2 = ["help"], ["--help"]
    
  1842.         self.assertEqual(self.run_manage(args1), self.run_manage(args2))
    
  1843. 
    
  1844.     def test_help_short_altert(self):
    
  1845.         "-h is handled as a short form of --help"
    
  1846.         args1, args2 = ["--help"], ["-h"]
    
  1847.         self.assertEqual(self.run_manage(args1), self.run_manage(args2))
    
  1848. 
    
  1849.     def test_specific_help(self):
    
  1850.         "--help can be used on a specific command"
    
  1851.         args = ["check", "--help"]
    
  1852.         out, err = self.run_manage(args)
    
  1853.         self.assertNoOutput(err)
    
  1854.         # Command-specific options like --tag appear before options common to
    
  1855.         # all commands like --version.
    
  1856.         tag_location = out.find("--tag")
    
  1857.         version_location = out.find("--version")
    
  1858.         self.assertNotEqual(tag_location, -1)
    
  1859.         self.assertNotEqual(version_location, -1)
    
  1860.         self.assertLess(tag_location, version_location)
    
  1861.         self.assertOutput(
    
  1862.             out, "Checks the entire Django project for potential problems."
    
  1863.         )
    
  1864. 
    
  1865.     def test_help_default_options_with_custom_arguments(self):
    
  1866.         args = ["base_command", "--help"]
    
  1867.         out, err = self.run_manage(args)
    
  1868.         self.assertNoOutput(err)
    
  1869.         expected_options = [
    
  1870.             "-h",
    
  1871.             "--option_a OPTION_A",
    
  1872.             "--option_b OPTION_B",
    
  1873.             "--option_c OPTION_C",
    
  1874.             "--version",
    
  1875.             "-v {0,1,2,3}",
    
  1876.             "--settings SETTINGS",
    
  1877.             "--pythonpath PYTHONPATH",
    
  1878.             "--traceback",
    
  1879.             "--no-color",
    
  1880.             "--force-color",
    
  1881.             "args ...",
    
  1882.         ]
    
  1883.         for option in expected_options:
    
  1884.             self.assertOutput(out, f"[{option}]")
    
  1885.         self.assertOutput(out, "--option_a OPTION_A, -a OPTION_A")
    
  1886.         self.assertOutput(out, "--option_b OPTION_B, -b OPTION_B")
    
  1887.         self.assertOutput(out, "--option_c OPTION_C, -c OPTION_C")
    
  1888.         self.assertOutput(out, "-v {0,1,2,3}, --verbosity {0,1,2,3}")
    
  1889. 
    
  1890.     def test_color_style(self):
    
  1891.         style = color.no_style()
    
  1892.         self.assertEqual(style.ERROR("Hello, world!"), "Hello, world!")
    
  1893. 
    
  1894.         style = color.make_style("nocolor")
    
  1895.         self.assertEqual(style.ERROR("Hello, world!"), "Hello, world!")
    
  1896. 
    
  1897.         style = color.make_style("dark")
    
  1898.         self.assertIn("Hello, world!", style.ERROR("Hello, world!"))
    
  1899.         self.assertNotEqual(style.ERROR("Hello, world!"), "Hello, world!")
    
  1900. 
    
  1901.         # Default palette has color.
    
  1902.         style = color.make_style("")
    
  1903.         self.assertIn("Hello, world!", style.ERROR("Hello, world!"))
    
  1904.         self.assertNotEqual(style.ERROR("Hello, world!"), "Hello, world!")
    
  1905. 
    
  1906.     def test_command_color(self):
    
  1907.         out = StringIO()
    
  1908.         err = StringIO()
    
  1909.         command = ColorCommand(stdout=out, stderr=err)
    
  1910.         call_command(command)
    
  1911.         if color.supports_color():
    
  1912.             self.assertIn("Hello, world!\n", out.getvalue())
    
  1913.             self.assertIn("Hello, world!\n", err.getvalue())
    
  1914.             self.assertNotEqual(out.getvalue(), "Hello, world!\n")
    
  1915.             self.assertNotEqual(err.getvalue(), "Hello, world!\n")
    
  1916.         else:
    
  1917.             self.assertEqual(out.getvalue(), "Hello, world!\n")
    
  1918.             self.assertEqual(err.getvalue(), "Hello, world!\n")
    
  1919. 
    
  1920.     def test_command_no_color(self):
    
  1921.         "--no-color prevent colorization of the output"
    
  1922.         out = StringIO()
    
  1923.         err = StringIO()
    
  1924.         command = ColorCommand(stdout=out, stderr=err, no_color=True)
    
  1925.         call_command(command)
    
  1926.         self.assertEqual(out.getvalue(), "Hello, world!\n")
    
  1927.         self.assertEqual(err.getvalue(), "Hello, world!\n")
    
  1928. 
    
  1929.         out = StringIO()
    
  1930.         err = StringIO()
    
  1931.         command = ColorCommand(stdout=out, stderr=err)
    
  1932.         call_command(command, no_color=True)
    
  1933.         self.assertEqual(out.getvalue(), "Hello, world!\n")
    
  1934.         self.assertEqual(err.getvalue(), "Hello, world!\n")
    
  1935. 
    
  1936.     def test_force_color_execute(self):
    
  1937.         out = StringIO()
    
  1938.         err = StringIO()
    
  1939.         with mock.patch.object(sys.stdout, "isatty", lambda: False):
    
  1940.             command = ColorCommand(stdout=out, stderr=err)
    
  1941.             call_command(command, force_color=True)
    
  1942.         self.assertEqual(out.getvalue(), "\x1b[31;1mHello, world!\n\x1b[0m")
    
  1943.         self.assertEqual(err.getvalue(), "\x1b[31;1mHello, world!\n\x1b[0m")
    
  1944. 
    
  1945.     def test_force_color_command_init(self):
    
  1946.         out = StringIO()
    
  1947.         err = StringIO()
    
  1948.         with mock.patch.object(sys.stdout, "isatty", lambda: False):
    
  1949.             command = ColorCommand(stdout=out, stderr=err, force_color=True)
    
  1950.             call_command(command)
    
  1951.         self.assertEqual(out.getvalue(), "\x1b[31;1mHello, world!\n\x1b[0m")
    
  1952.         self.assertEqual(err.getvalue(), "\x1b[31;1mHello, world!\n\x1b[0m")
    
  1953. 
    
  1954.     def test_no_color_force_color_mutually_exclusive_execute(self):
    
  1955.         msg = "The --no-color and --force-color options can't be used together."
    
  1956.         with self.assertRaisesMessage(CommandError, msg):
    
  1957.             call_command(BaseCommand(), no_color=True, force_color=True)
    
  1958. 
    
  1959.     def test_no_color_force_color_mutually_exclusive_command_init(self):
    
  1960.         msg = "'no_color' and 'force_color' can't be used together."
    
  1961.         with self.assertRaisesMessage(CommandError, msg):
    
  1962.             call_command(BaseCommand(no_color=True, force_color=True))
    
  1963. 
    
  1964.     def test_custom_stdout(self):
    
  1965.         class Command(BaseCommand):
    
  1966.             requires_system_checks = []
    
  1967. 
    
  1968.             def handle(self, *args, **options):
    
  1969.                 self.stdout.write("Hello, World!")
    
  1970. 
    
  1971.         out = StringIO()
    
  1972.         command = Command(stdout=out)
    
  1973.         call_command(command)
    
  1974.         self.assertEqual(out.getvalue(), "Hello, World!\n")
    
  1975.         out.truncate(0)
    
  1976.         new_out = StringIO()
    
  1977.         call_command(command, stdout=new_out)
    
  1978.         self.assertEqual(out.getvalue(), "")
    
  1979.         self.assertEqual(new_out.getvalue(), "Hello, World!\n")
    
  1980. 
    
  1981.     def test_custom_stderr(self):
    
  1982.         class Command(BaseCommand):
    
  1983.             requires_system_checks = []
    
  1984. 
    
  1985.             def handle(self, *args, **options):
    
  1986.                 self.stderr.write("Hello, World!")
    
  1987. 
    
  1988.         err = StringIO()
    
  1989.         command = Command(stderr=err)
    
  1990.         call_command(command)
    
  1991.         self.assertEqual(err.getvalue(), "Hello, World!\n")
    
  1992.         err.truncate(0)
    
  1993.         new_err = StringIO()
    
  1994.         call_command(command, stderr=new_err)
    
  1995.         self.assertEqual(err.getvalue(), "")
    
  1996.         self.assertEqual(new_err.getvalue(), "Hello, World!\n")
    
  1997. 
    
  1998.     def test_base_command(self):
    
  1999.         "User BaseCommands can execute when a label is provided"
    
  2000.         args = ["base_command", "testlabel"]
    
  2001.         expected_labels = "('testlabel',)"
    
  2002.         self._test_base_command(args, expected_labels)
    
  2003. 
    
  2004.     def test_base_command_no_label(self):
    
  2005.         "User BaseCommands can execute when no labels are provided"
    
  2006.         args = ["base_command"]
    
  2007.         expected_labels = "()"
    
  2008.         self._test_base_command(args, expected_labels)
    
  2009. 
    
  2010.     def test_base_command_multiple_label(self):
    
  2011.         "User BaseCommands can execute when no labels are provided"
    
  2012.         args = ["base_command", "testlabel", "anotherlabel"]
    
  2013.         expected_labels = "('testlabel', 'anotherlabel')"
    
  2014.         self._test_base_command(args, expected_labels)
    
  2015. 
    
  2016.     def test_base_command_with_option(self):
    
  2017.         "User BaseCommands can execute with options when a label is provided"
    
  2018.         args = ["base_command", "testlabel", "--option_a=x"]
    
  2019.         expected_labels = "('testlabel',)"
    
  2020.         self._test_base_command(args, expected_labels, option_a="'x'")
    
  2021. 
    
  2022.     def test_base_command_with_options(self):
    
  2023.         "User BaseCommands can execute with multiple options when a label is provided"
    
  2024.         args = ["base_command", "testlabel", "-a", "x", "--option_b=y"]
    
  2025.         expected_labels = "('testlabel',)"
    
  2026.         self._test_base_command(args, expected_labels, option_a="'x'", option_b="'y'")
    
  2027. 
    
  2028.     def test_base_command_with_wrong_option(self):
    
  2029.         "User BaseCommands outputs command usage when wrong option is specified"
    
  2030.         args = ["base_command", "--invalid"]
    
  2031.         out, err = self.run_manage(args)
    
  2032.         self.assertNoOutput(out)
    
  2033.         self.assertOutput(err, "usage: manage.py base_command")
    
  2034.         self.assertOutput(err, "error: unrecognized arguments: --invalid")
    
  2035. 
    
  2036.     def _test_base_command(self, args, labels, option_a="'1'", option_b="'2'"):
    
  2037.         out, err = self.run_manage(args)
    
  2038. 
    
  2039.         expected_out = (
    
  2040.             "EXECUTE:BaseCommand labels=%s, "
    
  2041.             "options=[('force_color', False), ('no_color', False), "
    
  2042.             "('option_a', %s), ('option_b', %s), ('option_c', '3'), "
    
  2043.             "('pythonpath', None), ('settings', None), ('traceback', False), "
    
  2044.             "('verbosity', 1)]"
    
  2045.         ) % (labels, option_a, option_b)
    
  2046.         self.assertNoOutput(err)
    
  2047.         self.assertOutput(out, expected_out)
    
  2048. 
    
  2049.     def test_base_run_from_argv(self):
    
  2050.         """
    
  2051.         Test run_from_argv properly terminates even with custom execute() (#19665)
    
  2052.         Also test proper traceback display.
    
  2053.         """
    
  2054.         err = StringIO()
    
  2055.         command = BaseCommand(stderr=err)
    
  2056. 
    
  2057.         def raise_command_error(*args, **kwargs):
    
  2058.             raise CommandError("Custom error")
    
  2059. 
    
  2060.         command.execute = lambda args: args  # This will trigger TypeError
    
  2061. 
    
  2062.         # If the Exception is not CommandError it should always
    
  2063.         # raise the original exception.
    
  2064.         with self.assertRaises(TypeError):
    
  2065.             command.run_from_argv(["", ""])
    
  2066. 
    
  2067.         # If the Exception is CommandError and --traceback is not present
    
  2068.         # this command should raise a SystemExit and don't print any
    
  2069.         # traceback to the stderr.
    
  2070.         command.execute = raise_command_error
    
  2071.         err.truncate(0)
    
  2072.         with self.assertRaises(SystemExit):
    
  2073.             command.run_from_argv(["", ""])
    
  2074.         err_message = err.getvalue()
    
  2075.         self.assertNotIn("Traceback", err_message)
    
  2076.         self.assertIn("CommandError", err_message)
    
  2077. 
    
  2078.         # If the Exception is CommandError and --traceback is present
    
  2079.         # this command should raise the original CommandError as if it
    
  2080.         # were not a CommandError.
    
  2081.         err.truncate(0)
    
  2082.         with self.assertRaises(CommandError):
    
  2083.             command.run_from_argv(["", "", "--traceback"])
    
  2084. 
    
  2085.     def test_run_from_argv_non_ascii_error(self):
    
  2086.         """
    
  2087.         Non-ASCII message of CommandError does not raise any
    
  2088.         UnicodeDecodeError in run_from_argv.
    
  2089.         """
    
  2090. 
    
  2091.         def raise_command_error(*args, **kwargs):
    
  2092.             raise CommandError("Erreur personnalisée")
    
  2093. 
    
  2094.         command = BaseCommand(stderr=StringIO())
    
  2095.         command.execute = raise_command_error
    
  2096. 
    
  2097.         with self.assertRaises(SystemExit):
    
  2098.             command.run_from_argv(["", ""])
    
  2099. 
    
  2100.     def test_run_from_argv_closes_connections(self):
    
  2101.         """
    
  2102.         A command called from the command line should close connections after
    
  2103.         being executed (#21255).
    
  2104.         """
    
  2105.         command = BaseCommand()
    
  2106.         command.check = lambda: []
    
  2107.         command.handle = lambda *args, **kwargs: args
    
  2108.         with mock.patch("django.core.management.base.connections") as mock_connections:
    
  2109.             command.run_from_argv(["", ""])
    
  2110.         # Test connections have been closed
    
  2111.         self.assertTrue(mock_connections.close_all.called)
    
  2112. 
    
  2113.     def test_noargs(self):
    
  2114.         "NoArg Commands can be executed"
    
  2115.         args = ["noargs_command"]
    
  2116.         out, err = self.run_manage(args)
    
  2117.         self.assertNoOutput(err)
    
  2118.         self.assertOutput(
    
  2119.             out,
    
  2120.             "EXECUTE: noargs_command options=[('force_color', False), "
    
  2121.             "('no_color', False), ('pythonpath', None), ('settings', None), "
    
  2122.             "('traceback', False), ('verbosity', 1)]",
    
  2123.         )
    
  2124. 
    
  2125.     def test_noargs_with_args(self):
    
  2126.         "NoArg Commands raise an error if an argument is provided"
    
  2127.         args = ["noargs_command", "argument"]
    
  2128.         out, err = self.run_manage(args)
    
  2129.         self.assertOutput(err, "error: unrecognized arguments: argument")
    
  2130. 
    
  2131.     def test_app_command(self):
    
  2132.         "User AppCommands can execute when a single app name is provided"
    
  2133.         args = ["app_command", "auth"]
    
  2134.         out, err = self.run_manage(args)
    
  2135.         self.assertNoOutput(err)
    
  2136.         self.assertOutput(out, "EXECUTE:AppCommand name=django.contrib.auth, options=")
    
  2137.         self.assertOutput(
    
  2138.             out,
    
  2139.             ", options=[('force_color', False), ('no_color', False), "
    
  2140.             "('pythonpath', None), ('settings', None), ('traceback', False), "
    
  2141.             "('verbosity', 1)]",
    
  2142.         )
    
  2143. 
    
  2144.     def test_app_command_no_apps(self):
    
  2145.         "User AppCommands raise an error when no app name is provided"
    
  2146.         args = ["app_command"]
    
  2147.         out, err = self.run_manage(args)
    
  2148.         self.assertOutput(err, "error: Enter at least one application label.")
    
  2149. 
    
  2150.     def test_app_command_multiple_apps(self):
    
  2151.         "User AppCommands raise an error when multiple app names are provided"
    
  2152.         args = ["app_command", "auth", "contenttypes"]
    
  2153.         out, err = self.run_manage(args)
    
  2154.         self.assertNoOutput(err)
    
  2155.         self.assertOutput(out, "EXECUTE:AppCommand name=django.contrib.auth, options=")
    
  2156.         self.assertOutput(
    
  2157.             out,
    
  2158.             ", options=[('force_color', False), ('no_color', False), "
    
  2159.             "('pythonpath', None), ('settings', None), ('traceback', False), "
    
  2160.             "('verbosity', 1)]",
    
  2161.         )
    
  2162.         self.assertOutput(
    
  2163.             out, "EXECUTE:AppCommand name=django.contrib.contenttypes, options="
    
  2164.         )
    
  2165.         self.assertOutput(
    
  2166.             out,
    
  2167.             ", options=[('force_color', False), ('no_color', False), "
    
  2168.             "('pythonpath', None), ('settings', None), ('traceback', False), "
    
  2169.             "('verbosity', 1)]",
    
  2170.         )
    
  2171. 
    
  2172.     def test_app_command_invalid_app_label(self):
    
  2173.         "User AppCommands can execute when a single app name is provided"
    
  2174.         args = ["app_command", "NOT_AN_APP"]
    
  2175.         out, err = self.run_manage(args)
    
  2176.         self.assertOutput(err, "No installed app with label 'NOT_AN_APP'.")
    
  2177. 
    
  2178.     def test_app_command_some_invalid_app_labels(self):
    
  2179.         "User AppCommands can execute when some of the provided app names are invalid"
    
  2180.         args = ["app_command", "auth", "NOT_AN_APP"]
    
  2181.         out, err = self.run_manage(args)
    
  2182.         self.assertOutput(err, "No installed app with label 'NOT_AN_APP'.")
    
  2183. 
    
  2184.     def test_label_command(self):
    
  2185.         "User LabelCommands can execute when a label is provided"
    
  2186.         args = ["label_command", "testlabel"]
    
  2187.         out, err = self.run_manage(args)
    
  2188.         self.assertNoOutput(err)
    
  2189.         self.assertOutput(
    
  2190.             out,
    
  2191.             "EXECUTE:LabelCommand label=testlabel, options=[('force_color', "
    
  2192.             "False), ('no_color', False), ('pythonpath', None), ('settings', "
    
  2193.             "None), ('traceback', False), ('verbosity', 1)]",
    
  2194.         )
    
  2195. 
    
  2196.     def test_label_command_no_label(self):
    
  2197.         "User LabelCommands raise an error if no label is provided"
    
  2198.         args = ["label_command"]
    
  2199.         out, err = self.run_manage(args)
    
  2200.         self.assertOutput(err, "Enter at least one label")
    
  2201. 
    
  2202.     def test_label_command_multiple_label(self):
    
  2203.         "User LabelCommands are executed multiple times if multiple labels are provided"
    
  2204.         args = ["label_command", "testlabel", "anotherlabel"]
    
  2205.         out, err = self.run_manage(args)
    
  2206.         self.assertNoOutput(err)
    
  2207.         self.assertOutput(
    
  2208.             out,
    
  2209.             "EXECUTE:LabelCommand label=testlabel, options=[('force_color', "
    
  2210.             "False), ('no_color', False), ('pythonpath', None), "
    
  2211.             "('settings', None), ('traceback', False), ('verbosity', 1)]",
    
  2212.         )
    
  2213.         self.assertOutput(
    
  2214.             out,
    
  2215.             "EXECUTE:LabelCommand label=anotherlabel, options=[('force_color', "
    
  2216.             "False), ('no_color', False), ('pythonpath', None), "
    
  2217.             "('settings', None), ('traceback', False), ('verbosity', 1)]",
    
  2218.         )
    
  2219. 
    
  2220.     def test_suppress_base_options_command_help(self):
    
  2221.         args = ["suppress_base_options_command", "--help"]
    
  2222.         out, err = self.run_manage(args)
    
  2223.         self.assertNoOutput(err)
    
  2224.         self.assertOutput(out, "Test suppress base options command.")
    
  2225.         self.assertNotInOutput(out, "input file")
    
  2226.         self.assertOutput(out, "-h, --help")
    
  2227.         self.assertNotInOutput(out, "--version")
    
  2228.         self.assertNotInOutput(out, "--verbosity")
    
  2229.         self.assertNotInOutput(out, "-v {0,1,2,3}")
    
  2230.         self.assertNotInOutput(out, "--settings")
    
  2231.         self.assertNotInOutput(out, "--pythonpath")
    
  2232.         self.assertNotInOutput(out, "--traceback")
    
  2233.         self.assertNotInOutput(out, "--no-color")
    
  2234.         self.assertNotInOutput(out, "--force-color")
    
  2235. 
    
  2236.     def test_suppress_base_options_command_defaults(self):
    
  2237.         args = ["suppress_base_options_command"]
    
  2238.         out, err = self.run_manage(args)
    
  2239.         self.assertNoOutput(err)
    
  2240.         self.assertOutput(
    
  2241.             out,
    
  2242.             "EXECUTE:SuppressBaseOptionsCommand options=[('file', None), "
    
  2243.             "('force_color', False), ('no_color', False), "
    
  2244.             "('pythonpath', None), ('settings', None), "
    
  2245.             "('traceback', False), ('verbosity', 1)]",
    
  2246.         )
    
  2247. 
    
  2248. 
    
  2249. class Discovery(SimpleTestCase):
    
  2250.     def test_precedence(self):
    
  2251.         """
    
  2252.         Apps listed first in INSTALLED_APPS have precedence.
    
  2253.         """
    
  2254.         with self.settings(
    
  2255.             INSTALLED_APPS=[
    
  2256.                 "admin_scripts.complex_app",
    
  2257.                 "admin_scripts.simple_app",
    
  2258.                 "django.contrib.auth",
    
  2259.                 "django.contrib.contenttypes",
    
  2260.             ]
    
  2261.         ):
    
  2262.             out = StringIO()
    
  2263.             call_command("duplicate", stdout=out)
    
  2264.             self.assertEqual(out.getvalue().strip(), "complex_app")
    
  2265.         with self.settings(
    
  2266.             INSTALLED_APPS=[
    
  2267.                 "admin_scripts.simple_app",
    
  2268.                 "admin_scripts.complex_app",
    
  2269.                 "django.contrib.auth",
    
  2270.                 "django.contrib.contenttypes",
    
  2271.             ]
    
  2272.         ):
    
  2273.             out = StringIO()
    
  2274.             call_command("duplicate", stdout=out)
    
  2275.             self.assertEqual(out.getvalue().strip(), "simple_app")
    
  2276. 
    
  2277. 
    
  2278. class ArgumentOrder(AdminScriptTestCase):
    
  2279.     """Tests for 2-stage argument parsing scheme.
    
  2280. 
    
  2281.     django-admin command arguments are parsed in 2 parts; the core arguments
    
  2282.     (--settings, --traceback and --pythonpath) are parsed using a basic parser,
    
  2283.     ignoring any unknown options. Then the full settings are
    
  2284.     passed to the command parser, which extracts commands of interest to the
    
  2285.     individual command.
    
  2286.     """
    
  2287. 
    
  2288.     def setUp(self):
    
  2289.         super().setUp()
    
  2290.         self.write_settings(
    
  2291.             "settings.py", apps=["django.contrib.auth", "django.contrib.contenttypes"]
    
  2292.         )
    
  2293.         self.write_settings("alternate_settings.py")
    
  2294. 
    
  2295.     def test_setting_then_option(self):
    
  2296.         """Options passed after settings are correctly handled."""
    
  2297.         args = [
    
  2298.             "base_command",
    
  2299.             "testlabel",
    
  2300.             "--settings=alternate_settings",
    
  2301.             "--option_a=x",
    
  2302.         ]
    
  2303.         self._test(args)
    
  2304. 
    
  2305.     def test_setting_then_short_option(self):
    
  2306.         """Short options passed after settings are correctly handled."""
    
  2307.         args = ["base_command", "testlabel", "--settings=alternate_settings", "-a", "x"]
    
  2308.         self._test(args)
    
  2309. 
    
  2310.     def test_option_then_setting(self):
    
  2311.         """Options passed before settings are correctly handled."""
    
  2312.         args = [
    
  2313.             "base_command",
    
  2314.             "testlabel",
    
  2315.             "--option_a=x",
    
  2316.             "--settings=alternate_settings",
    
  2317.         ]
    
  2318.         self._test(args)
    
  2319. 
    
  2320.     def test_short_option_then_setting(self):
    
  2321.         """Short options passed before settings are correctly handled."""
    
  2322.         args = ["base_command", "testlabel", "-a", "x", "--settings=alternate_settings"]
    
  2323.         self._test(args)
    
  2324. 
    
  2325.     def test_option_then_setting_then_option(self):
    
  2326.         """Options are correctly handled when they are passed before and after
    
  2327.         a setting."""
    
  2328.         args = [
    
  2329.             "base_command",
    
  2330.             "testlabel",
    
  2331.             "--option_a=x",
    
  2332.             "--settings=alternate_settings",
    
  2333.             "--option_b=y",
    
  2334.         ]
    
  2335.         self._test(args, option_b="'y'")
    
  2336. 
    
  2337.     def _test(self, args, option_b="'2'"):
    
  2338.         out, err = self.run_manage(args)
    
  2339.         self.assertNoOutput(err)
    
  2340.         self.assertOutput(
    
  2341.             out,
    
  2342.             "EXECUTE:BaseCommand labels=('testlabel',), options=["
    
  2343.             "('force_color', False), ('no_color', False), ('option_a', 'x'), "
    
  2344.             "('option_b', %s), ('option_c', '3'), ('pythonpath', None), "
    
  2345.             "('settings', 'alternate_settings'), ('traceback', False), "
    
  2346.             "('verbosity', 1)]" % option_b,
    
  2347.         )
    
  2348. 
    
  2349. 
    
  2350. class ExecuteFromCommandLine(SimpleTestCase):
    
  2351.     def test_program_name_from_argv(self):
    
  2352.         """
    
  2353.         Program name is computed from the execute_from_command_line()'s argv
    
  2354.         argument, not sys.argv.
    
  2355.         """
    
  2356.         args = ["help", "shell"]
    
  2357.         with captured_stdout() as out, captured_stderr() as err:
    
  2358.             with mock.patch("sys.argv", [None] + args):
    
  2359.                 execute_from_command_line(["django-admin"] + args)
    
  2360.         self.assertIn("usage: django-admin shell", out.getvalue())
    
  2361.         self.assertEqual(err.getvalue(), "")
    
  2362. 
    
  2363. 
    
  2364. @override_settings(ROOT_URLCONF="admin_scripts.urls")
    
  2365. class StartProject(LiveServerTestCase, AdminScriptTestCase):
    
  2366.     available_apps = [
    
  2367.         "admin_scripts",
    
  2368.         "django.contrib.auth",
    
  2369.         "django.contrib.contenttypes",
    
  2370.         "django.contrib.sessions",
    
  2371.     ]
    
  2372. 
    
  2373.     def test_wrong_args(self):
    
  2374.         """
    
  2375.         Passing the wrong kinds of arguments outputs an error and prints usage.
    
  2376.         """
    
  2377.         out, err = self.run_django_admin(["startproject"])
    
  2378.         self.assertNoOutput(out)
    
  2379.         self.assertOutput(err, "usage:")
    
  2380.         self.assertOutput(err, "You must provide a project name.")
    
  2381. 
    
  2382.     def test_simple_project(self):
    
  2383.         "Make sure the startproject management command creates a project"
    
  2384.         args = ["startproject", "testproject"]
    
  2385.         testproject_dir = os.path.join(self.test_dir, "testproject")
    
  2386. 
    
  2387.         out, err = self.run_django_admin(args)
    
  2388.         self.assertNoOutput(err)
    
  2389.         self.assertTrue(os.path.isdir(testproject_dir))
    
  2390. 
    
  2391.         # running again..
    
  2392.         out, err = self.run_django_admin(args)
    
  2393.         self.assertNoOutput(out)
    
  2394.         self.assertOutput(
    
  2395.             err,
    
  2396.             "CommandError: 'testproject' conflicts with the name of an "
    
  2397.             "existing Python module and cannot be used as a project name. "
    
  2398.             "Please try another name.",
    
  2399.         )
    
  2400. 
    
  2401.     def test_invalid_project_name(self):
    
  2402.         "Make sure the startproject management command validates a project name"
    
  2403.         for bad_name in ("7testproject", "../testproject"):
    
  2404.             with self.subTest(project_name=bad_name):
    
  2405.                 args = ["startproject", bad_name]
    
  2406.                 testproject_dir = os.path.join(self.test_dir, bad_name)
    
  2407. 
    
  2408.                 out, err = self.run_django_admin(args)
    
  2409.                 self.assertOutput(
    
  2410.                     err,
    
  2411.                     "Error: '%s' is not a valid project name. Please make "
    
  2412.                     "sure the name is a valid identifier." % bad_name,
    
  2413.                 )
    
  2414.                 self.assertFalse(os.path.exists(testproject_dir))
    
  2415. 
    
  2416.     def test_importable_project_name(self):
    
  2417.         """
    
  2418.         startproject validates that project name doesn't clash with existing
    
  2419.         Python modules.
    
  2420.         """
    
  2421.         bad_name = "os"
    
  2422.         args = ["startproject", bad_name]
    
  2423.         testproject_dir = os.path.join(self.test_dir, bad_name)
    
  2424. 
    
  2425.         out, err = self.run_django_admin(args)
    
  2426.         self.assertOutput(
    
  2427.             err,
    
  2428.             "CommandError: 'os' conflicts with the name of an existing "
    
  2429.             "Python module and cannot be used as a project name. Please try "
    
  2430.             "another name.",
    
  2431.         )
    
  2432.         self.assertFalse(os.path.exists(testproject_dir))
    
  2433. 
    
  2434.     def test_simple_project_different_directory(self):
    
  2435.         """
    
  2436.         The startproject management command creates a project in a specific
    
  2437.         directory.
    
  2438.         """
    
  2439.         args = ["startproject", "testproject", "othertestproject"]
    
  2440.         testproject_dir = os.path.join(self.test_dir, "othertestproject")
    
  2441.         os.mkdir(testproject_dir)
    
  2442. 
    
  2443.         out, err = self.run_django_admin(args)
    
  2444.         self.assertNoOutput(err)
    
  2445.         self.assertTrue(os.path.exists(os.path.join(testproject_dir, "manage.py")))
    
  2446. 
    
  2447.         # running again..
    
  2448.         out, err = self.run_django_admin(args)
    
  2449.         self.assertNoOutput(out)
    
  2450.         self.assertOutput(
    
  2451.             err,
    
  2452.             "already exists. Overlaying a project into an existing directory "
    
  2453.             "won't replace conflicting files.",
    
  2454.         )
    
  2455. 
    
  2456.     def test_custom_project_template(self):
    
  2457.         """
    
  2458.         The startproject management command is able to use a different project
    
  2459.         template.
    
  2460.         """
    
  2461.         template_path = os.path.join(custom_templates_dir, "project_template")
    
  2462.         args = ["startproject", "--template", template_path, "customtestproject"]
    
  2463.         testproject_dir = os.path.join(self.test_dir, "customtestproject")
    
  2464. 
    
  2465.         out, err = self.run_django_admin(args)
    
  2466.         self.assertNoOutput(err)
    
  2467.         self.assertTrue(os.path.isdir(testproject_dir))
    
  2468.         self.assertTrue(os.path.exists(os.path.join(testproject_dir, "additional_dir")))
    
  2469. 
    
  2470.     def test_custom_project_template_non_python_files_not_formatted(self):
    
  2471.         template_path = os.path.join(custom_templates_dir, "project_template")
    
  2472.         args = ["startproject", "--template", template_path, "customtestproject"]
    
  2473.         testproject_dir = os.path.join(self.test_dir, "customtestproject")
    
  2474. 
    
  2475.         _, err = self.run_django_admin(args)
    
  2476.         self.assertNoOutput(err)
    
  2477.         with open(
    
  2478.             os.path.join(template_path, "additional_dir", "requirements.in")
    
  2479.         ) as f:
    
  2480.             expected = f.read()
    
  2481.         with open(
    
  2482.             os.path.join(testproject_dir, "additional_dir", "requirements.in")
    
  2483.         ) as f:
    
  2484.             result = f.read()
    
  2485.         self.assertEqual(expected, result)
    
  2486. 
    
  2487.     def test_template_dir_with_trailing_slash(self):
    
  2488.         "Ticket 17475: Template dir passed has a trailing path separator"
    
  2489.         template_path = os.path.join(custom_templates_dir, "project_template" + os.sep)
    
  2490.         args = ["startproject", "--template", template_path, "customtestproject"]
    
  2491.         testproject_dir = os.path.join(self.test_dir, "customtestproject")
    
  2492. 
    
  2493.         out, err = self.run_django_admin(args)
    
  2494.         self.assertNoOutput(err)
    
  2495.         self.assertTrue(os.path.isdir(testproject_dir))
    
  2496.         self.assertTrue(os.path.exists(os.path.join(testproject_dir, "additional_dir")))
    
  2497. 
    
  2498.     def test_custom_project_template_from_tarball_by_path(self):
    
  2499.         """
    
  2500.         The startproject management command is able to use a different project
    
  2501.         template from a tarball.
    
  2502.         """
    
  2503.         template_path = os.path.join(custom_templates_dir, "project_template.tgz")
    
  2504.         args = ["startproject", "--template", template_path, "tarballtestproject"]
    
  2505.         testproject_dir = os.path.join(self.test_dir, "tarballtestproject")
    
  2506. 
    
  2507.         out, err = self.run_django_admin(args)
    
  2508.         self.assertNoOutput(err)
    
  2509.         self.assertTrue(os.path.isdir(testproject_dir))
    
  2510.         self.assertTrue(os.path.exists(os.path.join(testproject_dir, "run.py")))
    
  2511. 
    
  2512.     def test_custom_project_template_from_tarball_to_alternative_location(self):
    
  2513.         """
    
  2514.         Startproject can use a project template from a tarball and create it in
    
  2515.         a specified location.
    
  2516.         """
    
  2517.         template_path = os.path.join(custom_templates_dir, "project_template.tgz")
    
  2518.         args = [
    
  2519.             "startproject",
    
  2520.             "--template",
    
  2521.             template_path,
    
  2522.             "tarballtestproject",
    
  2523.             "altlocation",
    
  2524.         ]
    
  2525.         testproject_dir = os.path.join(self.test_dir, "altlocation")
    
  2526.         os.mkdir(testproject_dir)
    
  2527. 
    
  2528.         out, err = self.run_django_admin(args)
    
  2529.         self.assertNoOutput(err)
    
  2530.         self.assertTrue(os.path.isdir(testproject_dir))
    
  2531.         self.assertTrue(os.path.exists(os.path.join(testproject_dir, "run.py")))
    
  2532. 
    
  2533.     def test_custom_project_template_from_tarball_by_url(self):
    
  2534.         """
    
  2535.         The startproject management command is able to use a different project
    
  2536.         template from a tarball via a URL.
    
  2537.         """
    
  2538.         template_url = "%s/custom_templates/project_template.tgz" % self.live_server_url
    
  2539. 
    
  2540.         args = ["startproject", "--template", template_url, "urltestproject"]
    
  2541.         testproject_dir = os.path.join(self.test_dir, "urltestproject")
    
  2542. 
    
  2543.         out, err = self.run_django_admin(args)
    
  2544.         self.assertNoOutput(err)
    
  2545.         self.assertTrue(os.path.isdir(testproject_dir))
    
  2546.         self.assertTrue(os.path.exists(os.path.join(testproject_dir, "run.py")))
    
  2547. 
    
  2548.     def test_custom_project_template_from_tarball_by_url_django_user_agent(self):
    
  2549.         user_agent = None
    
  2550. 
    
  2551.         def serve_template(request, *args, **kwargs):
    
  2552.             nonlocal user_agent
    
  2553.             user_agent = request.headers["User-Agent"]
    
  2554.             return serve(request, *args, **kwargs)
    
  2555. 
    
  2556.         old_urlpatterns = urls.urlpatterns[:]
    
  2557.         try:
    
  2558.             urls.urlpatterns += [
    
  2559.                 path(
    
  2560.                     "user_agent_check/<path:path>",
    
  2561.                     serve_template,
    
  2562.                     {"document_root": os.path.join(urls.here, "custom_templates")},
    
  2563.                 ),
    
  2564.             ]
    
  2565. 
    
  2566.             template_url = (
    
  2567.                 f"{self.live_server_url}/user_agent_check/project_template.tgz"
    
  2568.             )
    
  2569.             args = ["startproject", "--template", template_url, "urltestproject"]
    
  2570.             _, err = self.run_django_admin(args)
    
  2571. 
    
  2572.             self.assertNoOutput(err)
    
  2573.             self.assertIn("Django/%s" % get_version(), user_agent)
    
  2574.         finally:
    
  2575.             urls.urlpatterns = old_urlpatterns
    
  2576. 
    
  2577.     def test_project_template_tarball_url(self):
    
  2578.         """ "
    
  2579.         Startproject management command handles project template tar/zip balls
    
  2580.         from non-canonical urls.
    
  2581.         """
    
  2582.         template_url = (
    
  2583.             "%s/custom_templates/project_template.tgz/" % self.live_server_url
    
  2584.         )
    
  2585. 
    
  2586.         args = ["startproject", "--template", template_url, "urltestproject"]
    
  2587.         testproject_dir = os.path.join(self.test_dir, "urltestproject")
    
  2588. 
    
  2589.         out, err = self.run_django_admin(args)
    
  2590.         self.assertNoOutput(err)
    
  2591.         self.assertTrue(os.path.isdir(testproject_dir))
    
  2592.         self.assertTrue(os.path.exists(os.path.join(testproject_dir, "run.py")))
    
  2593. 
    
  2594.     def test_file_without_extension(self):
    
  2595.         "Make sure the startproject management command is able to render custom files"
    
  2596.         template_path = os.path.join(custom_templates_dir, "project_template")
    
  2597.         args = [
    
  2598.             "startproject",
    
  2599.             "--template",
    
  2600.             template_path,
    
  2601.             "customtestproject",
    
  2602.             "-e",
    
  2603.             "txt",
    
  2604.             "-n",
    
  2605.             "Procfile",
    
  2606.         ]
    
  2607.         testproject_dir = os.path.join(self.test_dir, "customtestproject")
    
  2608. 
    
  2609.         out, err = self.run_django_admin(args)
    
  2610.         self.assertNoOutput(err)
    
  2611.         self.assertTrue(os.path.isdir(testproject_dir))
    
  2612.         self.assertTrue(os.path.exists(os.path.join(testproject_dir, "additional_dir")))
    
  2613.         base_path = os.path.join(testproject_dir, "additional_dir")
    
  2614.         for f in ("Procfile", "additional_file.py", "requirements.txt"):
    
  2615.             self.assertTrue(os.path.exists(os.path.join(base_path, f)))
    
  2616.             with open(os.path.join(base_path, f)) as fh:
    
  2617.                 self.assertEqual(
    
  2618.                     fh.read().strip(), "# some file for customtestproject test project"
    
  2619.                 )
    
  2620. 
    
  2621.     def test_custom_project_template_context_variables(self):
    
  2622.         "Make sure template context variables are rendered with proper values"
    
  2623.         template_path = os.path.join(custom_templates_dir, "project_template")
    
  2624.         args = [
    
  2625.             "startproject",
    
  2626.             "--template",
    
  2627.             template_path,
    
  2628.             "another_project",
    
  2629.             "project_dir",
    
  2630.         ]
    
  2631.         testproject_dir = os.path.join(self.test_dir, "project_dir")
    
  2632.         os.mkdir(testproject_dir)
    
  2633.         out, err = self.run_django_admin(args)
    
  2634.         self.assertNoOutput(err)
    
  2635.         test_manage_py = os.path.join(testproject_dir, "manage.py")
    
  2636.         with open(test_manage_py) as fp:
    
  2637.             content = fp.read()
    
  2638.             self.assertIn('project_name = "another_project"', content)
    
  2639.             self.assertIn('project_directory = "%s"' % testproject_dir, content)
    
  2640. 
    
  2641.     def test_no_escaping_of_project_variables(self):
    
  2642.         "Make sure template context variables are not html escaped"
    
  2643.         # We're using a custom command so we need the alternate settings
    
  2644.         self.write_settings("alternate_settings.py")
    
  2645.         template_path = os.path.join(custom_templates_dir, "project_template")
    
  2646.         args = [
    
  2647.             "custom_startproject",
    
  2648.             "--template",
    
  2649.             template_path,
    
  2650.             "another_project",
    
  2651.             "project_dir",
    
  2652.             "--extra",
    
  2653.             "<&>",
    
  2654.             "--settings=alternate_settings",
    
  2655.         ]
    
  2656.         testproject_dir = os.path.join(self.test_dir, "project_dir")
    
  2657.         os.mkdir(testproject_dir)
    
  2658.         out, err = self.run_manage(args)
    
  2659.         self.assertNoOutput(err)
    
  2660.         test_manage_py = os.path.join(testproject_dir, "additional_dir", "extra.py")
    
  2661.         with open(test_manage_py) as fp:
    
  2662.             content = fp.read()
    
  2663.             self.assertIn("<&>", content)
    
  2664. 
    
  2665.     def test_custom_project_destination_missing(self):
    
  2666.         """
    
  2667.         Make sure an exception is raised when the provided
    
  2668.         destination directory doesn't exist
    
  2669.         """
    
  2670.         template_path = os.path.join(custom_templates_dir, "project_template")
    
  2671.         args = [
    
  2672.             "startproject",
    
  2673.             "--template",
    
  2674.             template_path,
    
  2675.             "yet_another_project",
    
  2676.             "project_dir2",
    
  2677.         ]
    
  2678.         testproject_dir = os.path.join(self.test_dir, "project_dir2")
    
  2679.         out, err = self.run_django_admin(args)
    
  2680.         self.assertNoOutput(out)
    
  2681.         self.assertOutput(
    
  2682.             err,
    
  2683.             "Destination directory '%s' does not exist, please create it first."
    
  2684.             % testproject_dir,
    
  2685.         )
    
  2686.         self.assertFalse(os.path.exists(testproject_dir))
    
  2687. 
    
  2688.     def test_custom_project_template_with_non_ascii_templates(self):
    
  2689.         """
    
  2690.         The startproject management command is able to render templates with
    
  2691.         non-ASCII content.
    
  2692.         """
    
  2693.         template_path = os.path.join(custom_templates_dir, "project_template")
    
  2694.         args = [
    
  2695.             "startproject",
    
  2696.             "--template",
    
  2697.             template_path,
    
  2698.             "--extension=txt",
    
  2699.             "customtestproject",
    
  2700.         ]
    
  2701.         testproject_dir = os.path.join(self.test_dir, "customtestproject")
    
  2702. 
    
  2703.         out, err = self.run_django_admin(args)
    
  2704.         self.assertNoOutput(err)
    
  2705.         self.assertTrue(os.path.isdir(testproject_dir))
    
  2706.         path = os.path.join(testproject_dir, "ticket-18091-non-ascii-template.txt")
    
  2707.         with open(path, encoding="utf-8") as f:
    
  2708.             self.assertEqual(
    
  2709.                 f.read().splitlines(False),
    
  2710.                 ["Some non-ASCII text for testing ticket #18091:", "üäö €"],
    
  2711.             )
    
  2712. 
    
  2713.     def test_custom_project_template_hidden_directory_default_excluded(self):
    
  2714.         """Hidden directories are excluded by default."""
    
  2715.         template_path = os.path.join(custom_templates_dir, "project_template")
    
  2716.         args = [
    
  2717.             "startproject",
    
  2718.             "--template",
    
  2719.             template_path,
    
  2720.             "custom_project_template_hidden_directories",
    
  2721.             "project_dir",
    
  2722.         ]
    
  2723.         testproject_dir = os.path.join(self.test_dir, "project_dir")
    
  2724.         os.mkdir(testproject_dir)
    
  2725. 
    
  2726.         _, err = self.run_django_admin(args)
    
  2727.         self.assertNoOutput(err)
    
  2728.         hidden_dir = os.path.join(testproject_dir, ".hidden")
    
  2729.         self.assertIs(os.path.exists(hidden_dir), False)
    
  2730. 
    
  2731.     def test_custom_project_template_hidden_directory_included(self):
    
  2732.         """
    
  2733.         Template context variables in hidden directories are rendered, if not
    
  2734.         excluded.
    
  2735.         """
    
  2736.         template_path = os.path.join(custom_templates_dir, "project_template")
    
  2737.         project_name = "custom_project_template_hidden_directories_included"
    
  2738.         args = [
    
  2739.             "startproject",
    
  2740.             "--template",
    
  2741.             template_path,
    
  2742.             project_name,
    
  2743.             "project_dir",
    
  2744.             "--exclude",
    
  2745.         ]
    
  2746.         testproject_dir = os.path.join(self.test_dir, "project_dir")
    
  2747.         os.mkdir(testproject_dir)
    
  2748. 
    
  2749.         _, err = self.run_django_admin(args)
    
  2750.         self.assertNoOutput(err)
    
  2751.         render_py_path = os.path.join(testproject_dir, ".hidden", "render.py")
    
  2752.         with open(render_py_path) as fp:
    
  2753.             self.assertIn(
    
  2754.                 f"# The {project_name} should be rendered.",
    
  2755.                 fp.read(),
    
  2756.             )
    
  2757. 
    
  2758.     def test_custom_project_template_exclude_directory(self):
    
  2759.         """
    
  2760.         Excluded directories (in addition to .git and __pycache__) are not
    
  2761.         included in the project.
    
  2762.         """
    
  2763.         template_path = os.path.join(custom_templates_dir, "project_template")
    
  2764.         project_name = "custom_project_with_excluded_directories"
    
  2765.         args = [
    
  2766.             "startproject",
    
  2767.             "--template",
    
  2768.             template_path,
    
  2769.             project_name,
    
  2770.             "project_dir",
    
  2771.             "--exclude",
    
  2772.             "additional_dir",
    
  2773.             "-x",
    
  2774.             ".hidden",
    
  2775.         ]
    
  2776.         testproject_dir = os.path.join(self.test_dir, "project_dir")
    
  2777.         os.mkdir(testproject_dir)
    
  2778. 
    
  2779.         _, err = self.run_django_admin(args)
    
  2780.         self.assertNoOutput(err)
    
  2781.         excluded_directories = [
    
  2782.             ".hidden",
    
  2783.             "additional_dir",
    
  2784.             ".git",
    
  2785.             "__pycache__",
    
  2786.         ]
    
  2787.         for directory in excluded_directories:
    
  2788.             self.assertIs(
    
  2789.                 os.path.exists(os.path.join(testproject_dir, directory)),
    
  2790.                 False,
    
  2791.             )
    
  2792.         not_excluded = os.path.join(testproject_dir, project_name)
    
  2793.         self.assertIs(os.path.exists(not_excluded), True)
    
  2794. 
    
  2795.     @unittest.skipIf(
    
  2796.         sys.platform == "win32",
    
  2797.         "Windows only partially supports umasks and chmod.",
    
  2798.     )
    
  2799.     @unittest.skipUnless(PY39, "subprocess.run()'s umask was added in Python 3.9.")
    
  2800.     def test_honor_umask(self):
    
  2801.         _, err = self.run_django_admin(["startproject", "testproject"], umask=0o077)
    
  2802.         self.assertNoOutput(err)
    
  2803.         testproject_dir = os.path.join(self.test_dir, "testproject")
    
  2804.         self.assertIs(os.path.isdir(testproject_dir), True)
    
  2805.         tests = [
    
  2806.             (["manage.py"], 0o700),
    
  2807.             (["testproject"], 0o700),
    
  2808.             (["testproject", "settings.py"], 0o600),
    
  2809.         ]
    
  2810.         for paths, expected_mode in tests:
    
  2811.             file_path = os.path.join(testproject_dir, *paths)
    
  2812.             with self.subTest(paths[-1]):
    
  2813.                 self.assertEqual(
    
  2814.                     stat.S_IMODE(os.stat(file_path).st_mode),
    
  2815.                     expected_mode,
    
  2816.                 )
    
  2817. 
    
  2818. 
    
  2819. class StartApp(AdminScriptTestCase):
    
  2820.     def test_invalid_name(self):
    
  2821.         """startapp validates that app name is a valid Python identifier."""
    
  2822.         for bad_name in ("7testproject", "../testproject"):
    
  2823.             with self.subTest(app_name=bad_name):
    
  2824.                 args = ["startapp", bad_name]
    
  2825.                 testproject_dir = os.path.join(self.test_dir, bad_name)
    
  2826. 
    
  2827.                 out, err = self.run_django_admin(args)
    
  2828.                 self.assertOutput(
    
  2829.                     err,
    
  2830.                     "CommandError: '{}' is not a valid app name. Please make "
    
  2831.                     "sure the name is a valid identifier.".format(bad_name),
    
  2832.                 )
    
  2833.                 self.assertFalse(os.path.exists(testproject_dir))
    
  2834. 
    
  2835.     def test_importable_name(self):
    
  2836.         """
    
  2837.         startapp validates that app name doesn't clash with existing Python
    
  2838.         modules.
    
  2839.         """
    
  2840.         bad_name = "os"
    
  2841.         args = ["startapp", bad_name]
    
  2842.         testproject_dir = os.path.join(self.test_dir, bad_name)
    
  2843. 
    
  2844.         out, err = self.run_django_admin(args)
    
  2845.         self.assertOutput(
    
  2846.             err,
    
  2847.             "CommandError: 'os' conflicts with the name of an existing "
    
  2848.             "Python module and cannot be used as an app name. Please try "
    
  2849.             "another name.",
    
  2850.         )
    
  2851.         self.assertFalse(os.path.exists(testproject_dir))
    
  2852. 
    
  2853.     def test_invalid_target_name(self):
    
  2854.         for bad_target in (
    
  2855.             "invalid.dir_name",
    
  2856.             "7invalid_dir_name",
    
  2857.             ".invalid_dir_name",
    
  2858.         ):
    
  2859.             with self.subTest(bad_target):
    
  2860.                 _, err = self.run_django_admin(["startapp", "app", bad_target])
    
  2861.                 self.assertOutput(
    
  2862.                     err,
    
  2863.                     "CommandError: '%s' is not a valid app directory. Please "
    
  2864.                     "make sure the directory is a valid identifier." % bad_target,
    
  2865.                 )
    
  2866. 
    
  2867.     def test_importable_target_name(self):
    
  2868.         _, err = self.run_django_admin(["startapp", "app", "os"])
    
  2869.         self.assertOutput(
    
  2870.             err,
    
  2871.             "CommandError: 'os' conflicts with the name of an existing Python "
    
  2872.             "module and cannot be used as an app directory. Please try "
    
  2873.             "another directory.",
    
  2874.         )
    
  2875. 
    
  2876.     def test_trailing_slash_in_target_app_directory_name(self):
    
  2877.         app_dir = os.path.join(self.test_dir, "apps", "app1")
    
  2878.         os.makedirs(app_dir)
    
  2879.         _, err = self.run_django_admin(
    
  2880.             ["startapp", "app", os.path.join("apps", "app1", "")]
    
  2881.         )
    
  2882.         self.assertNoOutput(err)
    
  2883.         self.assertIs(os.path.exists(os.path.join(app_dir, "apps.py")), True)
    
  2884. 
    
  2885.     def test_overlaying_app(self):
    
  2886.         # Use a subdirectory so it is outside the PYTHONPATH.
    
  2887.         os.makedirs(os.path.join(self.test_dir, "apps/app1"))
    
  2888.         self.run_django_admin(["startapp", "app1", "apps/app1"])
    
  2889.         out, err = self.run_django_admin(["startapp", "app2", "apps/app1"])
    
  2890.         self.assertOutput(
    
  2891.             err,
    
  2892.             "already exists. Overlaying an app into an existing directory "
    
  2893.             "won't replace conflicting files.",
    
  2894.         )
    
  2895. 
    
  2896.     def test_template(self):
    
  2897.         out, err = self.run_django_admin(["startapp", "new_app"])
    
  2898.         self.assertNoOutput(err)
    
  2899.         app_path = os.path.join(self.test_dir, "new_app")
    
  2900.         self.assertIs(os.path.exists(app_path), True)
    
  2901.         with open(os.path.join(app_path, "apps.py")) as f:
    
  2902.             content = f.read()
    
  2903.             self.assertIn("class NewAppConfig(AppConfig)", content)
    
  2904.             if HAS_BLACK:
    
  2905.                 test_str = 'default_auto_field = "django.db.models.BigAutoField"'
    
  2906.             else:
    
  2907.                 test_str = "default_auto_field = 'django.db.models.BigAutoField'"
    
  2908.             self.assertIn(test_str, content)
    
  2909.             self.assertIn(
    
  2910.                 'name = "new_app"' if HAS_BLACK else "name = 'new_app'",
    
  2911.                 content,
    
  2912.             )
    
  2913. 
    
  2914. 
    
  2915. class DiffSettings(AdminScriptTestCase):
    
  2916.     """Tests for diffsettings management command."""
    
  2917. 
    
  2918.     def test_basic(self):
    
  2919.         """Runs without error and emits settings diff."""
    
  2920.         self.write_settings("settings_to_diff.py", sdict={"FOO": '"bar"'})
    
  2921.         args = ["diffsettings", "--settings=settings_to_diff"]
    
  2922.         out, err = self.run_manage(args)
    
  2923.         self.assertNoOutput(err)
    
  2924.         self.assertOutput(out, "FOO = 'bar'  ###")
    
  2925.         # Attributes from django.conf.Settings don't appear.
    
  2926.         self.assertNotInOutput(out, "is_overridden = ")
    
  2927. 
    
  2928.     def test_settings_configured(self):
    
  2929.         out, err = self.run_manage(
    
  2930.             ["diffsettings"], manage_py="configured_settings_manage.py"
    
  2931.         )
    
  2932.         self.assertNoOutput(err)
    
  2933.         self.assertOutput(out, "CUSTOM = 1  ###\nDEBUG = True")
    
  2934.         # Attributes from django.conf.UserSettingsHolder don't appear.
    
  2935.         self.assertNotInOutput(out, "default_settings = ")
    
  2936. 
    
  2937.     def test_dynamic_settings_configured(self):
    
  2938.         # Custom default settings appear.
    
  2939.         out, err = self.run_manage(
    
  2940.             ["diffsettings"], manage_py="configured_dynamic_settings_manage.py"
    
  2941.         )
    
  2942.         self.assertNoOutput(err)
    
  2943.         self.assertOutput(out, "FOO = 'bar'  ###")
    
  2944. 
    
  2945.     def test_all(self):
    
  2946.         """The all option also shows settings with the default value."""
    
  2947.         self.write_settings("settings_to_diff.py", sdict={"STATIC_URL": "None"})
    
  2948.         args = ["diffsettings", "--settings=settings_to_diff", "--all"]
    
  2949.         out, err = self.run_manage(args)
    
  2950.         self.assertNoOutput(err)
    
  2951.         self.assertOutput(out, "### STATIC_URL = None")
    
  2952. 
    
  2953.     def test_custom_default(self):
    
  2954.         """
    
  2955.         The --default option specifies an alternate settings module for
    
  2956.         comparison.
    
  2957.         """
    
  2958.         self.write_settings(
    
  2959.             "settings_default.py", sdict={"FOO": '"foo"', "BAR": '"bar1"'}
    
  2960.         )
    
  2961.         self.write_settings(
    
  2962.             "settings_to_diff.py", sdict={"FOO": '"foo"', "BAR": '"bar2"'}
    
  2963.         )
    
  2964.         out, err = self.run_manage(
    
  2965.             [
    
  2966.                 "diffsettings",
    
  2967.                 "--settings=settings_to_diff",
    
  2968.                 "--default=settings_default",
    
  2969.             ]
    
  2970.         )
    
  2971.         self.assertNoOutput(err)
    
  2972.         self.assertNotInOutput(out, "FOO")
    
  2973.         self.assertOutput(out, "BAR = 'bar2'")
    
  2974. 
    
  2975.     def test_unified(self):
    
  2976.         """--output=unified emits settings diff in unified mode."""
    
  2977.         self.write_settings("settings_to_diff.py", sdict={"FOO": '"bar"'})
    
  2978.         args = ["diffsettings", "--settings=settings_to_diff", "--output=unified"]
    
  2979.         out, err = self.run_manage(args)
    
  2980.         self.assertNoOutput(err)
    
  2981.         self.assertOutput(out, "+ FOO = 'bar'")
    
  2982.         self.assertOutput(out, "- SECRET_KEY = ''")
    
  2983.         self.assertOutput(out, "+ SECRET_KEY = 'django_tests_secret_key'")
    
  2984.         self.assertNotInOutput(out, "  APPEND_SLASH = True")
    
  2985. 
    
  2986.     def test_unified_all(self):
    
  2987.         """
    
  2988.         --output=unified --all emits settings diff in unified mode and includes
    
  2989.         settings with the default value.
    
  2990.         """
    
  2991.         self.write_settings("settings_to_diff.py", sdict={"FOO": '"bar"'})
    
  2992.         args = [
    
  2993.             "diffsettings",
    
  2994.             "--settings=settings_to_diff",
    
  2995.             "--output=unified",
    
  2996.             "--all",
    
  2997.         ]
    
  2998.         out, err = self.run_manage(args)
    
  2999.         self.assertNoOutput(err)
    
  3000.         self.assertOutput(out, "  APPEND_SLASH = True")
    
  3001.         self.assertOutput(out, "+ FOO = 'bar'")
    
  3002.         self.assertOutput(out, "- SECRET_KEY = ''")
    
  3003. 
    
  3004. 
    
  3005. class Dumpdata(AdminScriptTestCase):
    
  3006.     """Tests for dumpdata management command."""
    
  3007. 
    
  3008.     def setUp(self):
    
  3009.         super().setUp()
    
  3010.         self.write_settings("settings.py")
    
  3011. 
    
  3012.     def test_pks_parsing(self):
    
  3013.         """Regression for #20509
    
  3014. 
    
  3015.         Test would raise an exception rather than printing an error message.
    
  3016.         """
    
  3017.         args = ["dumpdata", "--pks=1"]
    
  3018.         out, err = self.run_manage(args)
    
  3019.         self.assertOutput(err, "You can only use --pks option with one model")
    
  3020.         self.assertNoOutput(out)
    
  3021. 
    
  3022. 
    
  3023. class MainModule(AdminScriptTestCase):
    
  3024.     """python -m django works like django-admin."""
    
  3025. 
    
  3026.     def test_program_name_in_help(self):
    
  3027.         out, err = self.run_test(["-m", "django", "help"])
    
  3028.         self.assertOutput(
    
  3029.             out,
    
  3030.             "Type 'python -m django help <subcommand>' for help on a specific "
    
  3031.             "subcommand.",
    
  3032.         )
    
  3033. 
    
  3034. 
    
  3035. class DjangoAdminSuggestions(AdminScriptTestCase):
    
  3036.     def setUp(self):
    
  3037.         super().setUp()
    
  3038.         self.write_settings("settings.py")
    
  3039. 
    
  3040.     def test_suggestions(self):
    
  3041.         args = ["rnserver", "--settings=test_project.settings"]
    
  3042.         out, err = self.run_django_admin(args)
    
  3043.         self.assertNoOutput(out)
    
  3044.         self.assertOutput(err, "Unknown command: 'rnserver'. Did you mean runserver?")
    
  3045. 
    
  3046.     def test_no_suggestions(self):
    
  3047.         args = ["abcdef", "--settings=test_project.settings"]
    
  3048.         out, err = self.run_django_admin(args)
    
  3049.         self.assertNoOutput(out)
    
  3050.         self.assertNotInOutput(err, "Did you mean")