1. from pathlib import Path
    
  2. from unittest import mock
    
  3. 
    
  4. from django.template import autoreload
    
  5. from django.test import SimpleTestCase, override_settings
    
  6. from django.test.utils import require_jinja2
    
  7. 
    
  8. ROOT = Path(__file__).parent.absolute()
    
  9. EXTRA_TEMPLATES_DIR = ROOT / "templates_extra"
    
  10. 
    
  11. 
    
  12. @override_settings(
    
  13.     INSTALLED_APPS=["template_tests"],
    
  14.     TEMPLATES=[
    
  15.         {
    
  16.             "BACKEND": "django.template.backends.dummy.TemplateStrings",
    
  17.             "APP_DIRS": True,
    
  18.         },
    
  19.         {
    
  20.             "BACKEND": "django.template.backends.django.DjangoTemplates",
    
  21.             "DIRS": [EXTRA_TEMPLATES_DIR],
    
  22.             "OPTIONS": {
    
  23.                 "context_processors": [
    
  24.                     "django.template.context_processors.request",
    
  25.                 ],
    
  26.                 "loaders": [
    
  27.                     "django.template.loaders.filesystem.Loader",
    
  28.                     "django.template.loaders.app_directories.Loader",
    
  29.                 ],
    
  30.             },
    
  31.         },
    
  32.     ],
    
  33. )
    
  34. class TemplateReloadTests(SimpleTestCase):
    
  35.     @mock.patch("django.template.autoreload.reset_loaders")
    
  36.     def test_template_changed(self, mock_reset):
    
  37.         template_path = Path(__file__).parent / "templates" / "index.html"
    
  38.         self.assertTrue(autoreload.template_changed(None, template_path))
    
  39.         mock_reset.assert_called_once()
    
  40. 
    
  41.     @mock.patch("django.template.autoreload.reset_loaders")
    
  42.     def test_non_template_changed(self, mock_reset):
    
  43.         self.assertIsNone(autoreload.template_changed(None, Path(__file__)))
    
  44.         mock_reset.assert_not_called()
    
  45. 
    
  46.     @override_settings(
    
  47.         TEMPLATES=[
    
  48.             {
    
  49.                 "DIRS": [ROOT],
    
  50.                 "BACKEND": "django.template.backends.django.DjangoTemplates",
    
  51.             }
    
  52.         ]
    
  53.     )
    
  54.     @mock.patch("django.template.autoreload.reset_loaders")
    
  55.     def test_non_template_changed_in_template_directory(self, mock_reset):
    
  56.         self.assertIsNone(autoreload.template_changed(None, Path(__file__)))
    
  57.         mock_reset.assert_not_called()
    
  58. 
    
  59.     def test_watch_for_template_changes(self):
    
  60.         mock_reloader = mock.MagicMock()
    
  61.         autoreload.watch_for_template_changes(mock_reloader)
    
  62.         self.assertSequenceEqual(
    
  63.             sorted(mock_reloader.watch_dir.call_args_list),
    
  64.             [
    
  65.                 mock.call(ROOT / "templates", "**/*"),
    
  66.                 mock.call(ROOT / "templates_extra", "**/*"),
    
  67.             ],
    
  68.         )
    
  69. 
    
  70.     def test_get_template_directories(self):
    
  71.         self.assertSetEqual(
    
  72.             autoreload.get_template_directories(),
    
  73.             {
    
  74.                 ROOT / "templates_extra",
    
  75.                 ROOT / "templates",
    
  76.             },
    
  77.         )
    
  78. 
    
  79.     @mock.patch("django.template.loaders.base.Loader.reset")
    
  80.     def test_reset_all_loaders(self, mock_reset):
    
  81.         autoreload.reset_loaders()
    
  82.         self.assertEqual(mock_reset.call_count, 2)
    
  83. 
    
  84.     @override_settings(
    
  85.         TEMPLATES=[
    
  86.             {
    
  87.                 "DIRS": [""],
    
  88.                 "BACKEND": "django.template.backends.django.DjangoTemplates",
    
  89.             }
    
  90.         ]
    
  91.     )
    
  92.     def test_template_dirs_ignore_empty_path(self):
    
  93.         self.assertEqual(autoreload.get_template_directories(), set())
    
  94. 
    
  95.     @override_settings(
    
  96.         TEMPLATES=[
    
  97.             {
    
  98.                 "DIRS": [
    
  99.                     str(ROOT) + "/absolute_str",
    
  100.                     "template_tests/relative_str",
    
  101.                     Path("template_tests/relative_path"),
    
  102.                 ],
    
  103.                 "BACKEND": "django.template.backends.django.DjangoTemplates",
    
  104.             }
    
  105.         ]
    
  106.     )
    
  107.     def test_template_dirs_normalized_to_paths(self):
    
  108.         self.assertSetEqual(
    
  109.             autoreload.get_template_directories(),
    
  110.             {
    
  111.                 ROOT / "absolute_str",
    
  112.                 Path.cwd() / "template_tests/relative_str",
    
  113.                 Path.cwd() / "template_tests/relative_path",
    
  114.             },
    
  115.         )
    
  116. 
    
  117. 
    
  118. @require_jinja2
    
  119. @override_settings(INSTALLED_APPS=["template_tests"])
    
  120. class Jinja2TemplateReloadTests(SimpleTestCase):
    
  121.     def test_watch_for_template_changes(self):
    
  122.         mock_reloader = mock.MagicMock()
    
  123.         autoreload.watch_for_template_changes(mock_reloader)
    
  124.         self.assertSequenceEqual(
    
  125.             sorted(mock_reloader.watch_dir.call_args_list),
    
  126.             [
    
  127.                 mock.call(ROOT / "templates", "**/*"),
    
  128.             ],
    
  129.         )
    
  130. 
    
  131.     def test_get_template_directories(self):
    
  132.         self.assertSetEqual(
    
  133.             autoreload.get_template_directories(),
    
  134.             {
    
  135.                 ROOT / "templates",
    
  136.             },
    
  137.         )
    
  138. 
    
  139.     @mock.patch("django.template.loaders.base.Loader.reset")
    
  140.     def test_reset_all_loaders(self, mock_reset):
    
  141.         autoreload.reset_loaders()
    
  142.         self.assertEqual(mock_reset.call_count, 0)