1. from pathlib import Path
    
  2. 
    
  3. from template_tests.test_response import test_processor_name
    
  4. 
    
  5. from django.template import Context, EngineHandler, RequestContext
    
  6. from django.template.backends.django import DjangoTemplates
    
  7. from django.template.library import InvalidTemplateLibrary
    
  8. from django.test import RequestFactory, override_settings
    
  9. 
    
  10. from .test_dummy import TemplateStringsTests
    
  11. 
    
  12. 
    
  13. class DjangoTemplatesTests(TemplateStringsTests):
    
  14.     engine_class = DjangoTemplates
    
  15.     backend_name = "django"
    
  16.     request_factory = RequestFactory()
    
  17. 
    
  18.     def test_context_has_priority_over_template_context_processors(self):
    
  19.         # See ticket #23789.
    
  20.         engine = DjangoTemplates(
    
  21.             {
    
  22.                 "DIRS": [],
    
  23.                 "APP_DIRS": False,
    
  24.                 "NAME": "django",
    
  25.                 "OPTIONS": {
    
  26.                     "context_processors": [test_processor_name],
    
  27.                 },
    
  28.             }
    
  29.         )
    
  30. 
    
  31.         template = engine.from_string("{{ processors }}")
    
  32.         request = self.request_factory.get("/")
    
  33. 
    
  34.         # Context processors run
    
  35.         content = template.render({}, request)
    
  36.         self.assertEqual(content, "yes")
    
  37. 
    
  38.         # Context overrides context processors
    
  39.         content = template.render({"processors": "no"}, request)
    
  40.         self.assertEqual(content, "no")
    
  41. 
    
  42.     def test_render_requires_dict(self):
    
  43.         """django.Template.render() requires a dict."""
    
  44.         engine = DjangoTemplates(
    
  45.             {
    
  46.                 "DIRS": [],
    
  47.                 "APP_DIRS": False,
    
  48.                 "NAME": "django",
    
  49.                 "OPTIONS": {},
    
  50.             }
    
  51.         )
    
  52.         template = engine.from_string("")
    
  53.         context = Context()
    
  54.         request_context = RequestContext(self.request_factory.get("/"), {})
    
  55.         msg = "context must be a dict rather than Context."
    
  56.         with self.assertRaisesMessage(TypeError, msg):
    
  57.             template.render(context)
    
  58.         msg = "context must be a dict rather than RequestContext."
    
  59.         with self.assertRaisesMessage(TypeError, msg):
    
  60.             template.render(request_context)
    
  61. 
    
  62.     @override_settings(INSTALLED_APPS=["template_backends.apps.good"])
    
  63.     def test_templatetag_discovery(self):
    
  64.         engine = DjangoTemplates(
    
  65.             {
    
  66.                 "DIRS": [],
    
  67.                 "APP_DIRS": False,
    
  68.                 "NAME": "django",
    
  69.                 "OPTIONS": {
    
  70.                     "libraries": {
    
  71.                         "alternate": (
    
  72.                             "template_backends.apps.good.templatetags.good_tags"
    
  73.                         ),
    
  74.                         "override": (
    
  75.                             "template_backends.apps.good.templatetags.good_tags"
    
  76.                         ),
    
  77.                     },
    
  78.                 },
    
  79.             }
    
  80.         )
    
  81. 
    
  82.         # libraries are discovered from installed applications
    
  83.         self.assertEqual(
    
  84.             engine.engine.libraries["good_tags"],
    
  85.             "template_backends.apps.good.templatetags.good_tags",
    
  86.         )
    
  87.         self.assertEqual(
    
  88.             engine.engine.libraries["subpackage.tags"],
    
  89.             "template_backends.apps.good.templatetags.subpackage.tags",
    
  90.         )
    
  91.         # libraries are discovered from django.templatetags
    
  92.         self.assertEqual(
    
  93.             engine.engine.libraries["static"],
    
  94.             "django.templatetags.static",
    
  95.         )
    
  96.         # libraries passed in OPTIONS are registered
    
  97.         self.assertEqual(
    
  98.             engine.engine.libraries["alternate"],
    
  99.             "template_backends.apps.good.templatetags.good_tags",
    
  100.         )
    
  101.         # libraries passed in OPTIONS take precedence over discovered ones
    
  102.         self.assertEqual(
    
  103.             engine.engine.libraries["override"],
    
  104.             "template_backends.apps.good.templatetags.good_tags",
    
  105.         )
    
  106. 
    
  107.     @override_settings(INSTALLED_APPS=["template_backends.apps.importerror"])
    
  108.     def test_templatetag_discovery_import_error(self):
    
  109.         """
    
  110.         Import errors in tag modules should be reraised with a helpful message.
    
  111.         """
    
  112.         with self.assertRaisesMessage(
    
  113.             InvalidTemplateLibrary,
    
  114.             "ImportError raised when trying to load "
    
  115.             "'template_backends.apps.importerror.templatetags.broken_tags'",
    
  116.         ) as cm:
    
  117.             DjangoTemplates(
    
  118.                 {
    
  119.                     "DIRS": [],
    
  120.                     "APP_DIRS": False,
    
  121.                     "NAME": "django",
    
  122.                     "OPTIONS": {},
    
  123.                 }
    
  124.             )
    
  125.         self.assertIsInstance(cm.exception.__cause__, ImportError)
    
  126. 
    
  127.     def test_builtins_discovery(self):
    
  128.         engine = DjangoTemplates(
    
  129.             {
    
  130.                 "DIRS": [],
    
  131.                 "APP_DIRS": False,
    
  132.                 "NAME": "django",
    
  133.                 "OPTIONS": {
    
  134.                     "builtins": ["template_backends.apps.good.templatetags.good_tags"],
    
  135.                 },
    
  136.             }
    
  137.         )
    
  138. 
    
  139.         self.assertEqual(
    
  140.             engine.engine.builtins,
    
  141.             [
    
  142.                 "django.template.defaulttags",
    
  143.                 "django.template.defaultfilters",
    
  144.                 "django.template.loader_tags",
    
  145.                 "template_backends.apps.good.templatetags.good_tags",
    
  146.             ],
    
  147.         )
    
  148. 
    
  149.     def test_autoescape_off(self):
    
  150.         templates = [
    
  151.             {
    
  152.                 "BACKEND": "django.template.backends.django.DjangoTemplates",
    
  153.                 "OPTIONS": {"autoescape": False},
    
  154.             }
    
  155.         ]
    
  156.         engines = EngineHandler(templates=templates)
    
  157.         self.assertEqual(
    
  158.             engines["django"]
    
  159.             .from_string("Hello, {{ name }}")
    
  160.             .render({"name": "Bob & Jim"}),
    
  161.             "Hello, Bob & Jim",
    
  162.         )
    
  163. 
    
  164.     def test_autoescape_default(self):
    
  165.         templates = [
    
  166.             {
    
  167.                 "BACKEND": "django.template.backends.django.DjangoTemplates",
    
  168.             }
    
  169.         ]
    
  170.         engines = EngineHandler(templates=templates)
    
  171.         self.assertEqual(
    
  172.             engines["django"]
    
  173.             .from_string("Hello, {{ name }}")
    
  174.             .render({"name": "Bob & Jim"}),
    
  175.             "Hello, Bob & Jim",
    
  176.         )
    
  177. 
    
  178.     def test_default_template_loaders(self):
    
  179.         """The cached template loader is always enabled by default."""
    
  180.         for debug in (True, False):
    
  181.             with self.subTest(DEBUG=debug), self.settings(DEBUG=debug):
    
  182.                 engine = DjangoTemplates(
    
  183.                     {"DIRS": [], "APP_DIRS": True, "NAME": "django", "OPTIONS": {}}
    
  184.                 )
    
  185.                 self.assertEqual(
    
  186.                     engine.engine.loaders,
    
  187.                     [
    
  188.                         (
    
  189.                             "django.template.loaders.cached.Loader",
    
  190.                             [
    
  191.                                 "django.template.loaders.filesystem.Loader",
    
  192.                                 "django.template.loaders.app_directories.Loader",
    
  193.                             ],
    
  194.                         )
    
  195.                     ],
    
  196.                 )
    
  197. 
    
  198.     def test_dirs_pathlib(self):
    
  199.         engine = DjangoTemplates(
    
  200.             {
    
  201.                 "DIRS": [Path(__file__).parent / "templates" / "template_backends"],
    
  202.                 "APP_DIRS": False,
    
  203.                 "NAME": "django",
    
  204.                 "OPTIONS": {},
    
  205.             }
    
  206.         )
    
  207.         template = engine.get_template("hello.html")
    
  208.         self.assertEqual(template.render({"name": "Joe"}), "Hello Joe!\n")