1. from pathlib import Path
    
  2. from unittest import mock, skipIf
    
  3. 
    
  4. from django.template import TemplateSyntaxError
    
  5. from django.test import RequestFactory
    
  6. 
    
  7. from .test_dummy import TemplateStringsTests
    
  8. 
    
  9. try:
    
  10.     import jinja2
    
  11. except ImportError:
    
  12.     jinja2 = None
    
  13.     Jinja2 = None
    
  14. else:
    
  15.     from django.template.backends.jinja2 import Jinja2
    
  16. 
    
  17. 
    
  18. @skipIf(jinja2 is None, "this test requires jinja2")
    
  19. class Jinja2Tests(TemplateStringsTests):
    
  20.     engine_class = Jinja2
    
  21.     backend_name = "jinja2"
    
  22.     options = {
    
  23.         "keep_trailing_newline": True,
    
  24.         "context_processors": [
    
  25.             "django.template.context_processors.static",
    
  26.         ],
    
  27.     }
    
  28. 
    
  29.     def test_origin(self):
    
  30.         template = self.engine.get_template("template_backends/hello.html")
    
  31.         self.assertTrue(template.origin.name.endswith("hello.html"))
    
  32.         self.assertEqual(template.origin.template_name, "template_backends/hello.html")
    
  33. 
    
  34.     def test_origin_from_string(self):
    
  35.         template = self.engine.from_string("Hello!\n")
    
  36.         self.assertEqual(template.origin.name, "<template>")
    
  37.         self.assertIsNone(template.origin.template_name)
    
  38. 
    
  39.     def test_self_context(self):
    
  40.         """
    
  41.         Using 'self' in the context should not throw errors (#24538).
    
  42.         """
    
  43.         # self will be overridden to be a TemplateReference, so the self
    
  44.         # variable will not come through. Attempting to use one though should
    
  45.         # not throw an error.
    
  46.         template = self.engine.from_string("hello {{ foo }}!")
    
  47.         content = template.render(context={"self": "self", "foo": "world"})
    
  48.         self.assertEqual(content, "hello world!")
    
  49. 
    
  50.     def test_exception_debug_info_min_context(self):
    
  51.         with self.assertRaises(TemplateSyntaxError) as e:
    
  52.             self.engine.get_template("template_backends/syntax_error.html")
    
  53.         debug = e.exception.template_debug
    
  54.         self.assertEqual(debug["after"], "")
    
  55.         self.assertEqual(debug["before"], "")
    
  56.         self.assertEqual(debug["during"], "{% block %}")
    
  57.         self.assertEqual(debug["bottom"], 1)
    
  58.         self.assertEqual(debug["top"], 0)
    
  59.         self.assertEqual(debug["line"], 1)
    
  60.         self.assertEqual(debug["total"], 1)
    
  61.         self.assertEqual(len(debug["source_lines"]), 1)
    
  62.         self.assertTrue(debug["name"].endswith("syntax_error.html"))
    
  63.         self.assertIn("message", debug)
    
  64. 
    
  65.     def test_exception_debug_info_max_context(self):
    
  66.         with self.assertRaises(TemplateSyntaxError) as e:
    
  67.             self.engine.get_template("template_backends/syntax_error2.html")
    
  68.         debug = e.exception.template_debug
    
  69.         self.assertEqual(debug["after"], "")
    
  70.         self.assertEqual(debug["before"], "")
    
  71.         self.assertEqual(debug["during"], "{% block %}")
    
  72.         self.assertEqual(debug["bottom"], 26)
    
  73.         self.assertEqual(debug["top"], 5)
    
  74.         self.assertEqual(debug["line"], 16)
    
  75.         self.assertEqual(debug["total"], 31)
    
  76.         self.assertEqual(len(debug["source_lines"]), 21)
    
  77.         self.assertTrue(debug["name"].endswith("syntax_error2.html"))
    
  78.         self.assertIn("message", debug)
    
  79. 
    
  80.     def test_context_processors(self):
    
  81.         request = RequestFactory().get("/")
    
  82.         template = self.engine.from_string("Static URL: {{ STATIC_URL }}")
    
  83.         content = template.render(request=request)
    
  84.         self.assertEqual(content, "Static URL: /static/")
    
  85.         with self.settings(STATIC_URL="/s/"):
    
  86.             content = template.render(request=request)
    
  87.         self.assertEqual(content, "Static URL: /s/")
    
  88. 
    
  89.     def test_dirs_pathlib(self):
    
  90.         engine = Jinja2(
    
  91.             {
    
  92.                 "DIRS": [Path(__file__).parent / "templates" / "template_backends"],
    
  93.                 "APP_DIRS": False,
    
  94.                 "NAME": "jinja2",
    
  95.                 "OPTIONS": {},
    
  96.             }
    
  97.         )
    
  98.         template = engine.get_template("hello.html")
    
  99.         self.assertEqual(template.render({"name": "Joe"}), "Hello Joe!")
    
  100. 
    
  101.     def test_template_render_nested_error(self):
    
  102.         template = self.engine.get_template(
    
  103.             "template_backends/syntax_error_include.html"
    
  104.         )
    
  105.         with self.assertRaises(TemplateSyntaxError) as e:
    
  106.             template.render(context={})
    
  107.         debug = e.exception.template_debug
    
  108.         self.assertEqual(debug["after"], "")
    
  109.         self.assertEqual(debug["before"], "")
    
  110.         self.assertEqual(debug["during"], "{% block %}")
    
  111.         self.assertEqual(debug["bottom"], 1)
    
  112.         self.assertEqual(debug["top"], 0)
    
  113.         self.assertEqual(debug["line"], 1)
    
  114.         self.assertEqual(debug["total"], 1)
    
  115.         self.assertEqual(len(debug["source_lines"]), 1)
    
  116.         self.assertTrue(debug["name"].endswith("syntax_error.html"))
    
  117.         self.assertIn("message", debug)
    
  118. 
    
  119.     def test_template_render_error_nonexistent_source(self):
    
  120.         template = self.engine.get_template("template_backends/hello.html")
    
  121.         with mock.patch(
    
  122.             "jinja2.environment.Template.render",
    
  123.             side_effect=jinja2.TemplateSyntaxError("", 1, filename="nonexistent.html"),
    
  124.         ):
    
  125.             with self.assertRaises(TemplateSyntaxError) as e:
    
  126.                 template.render(context={})
    
  127.         debug = e.exception.template_debug
    
  128.         self.assertEqual(debug["after"], "")
    
  129.         self.assertEqual(debug["before"], "")
    
  130.         self.assertEqual(debug["during"], "")
    
  131.         self.assertEqual(debug["bottom"], 0)
    
  132.         self.assertEqual(debug["top"], 0)
    
  133.         self.assertEqual(debug["line"], 1)
    
  134.         self.assertEqual(debug["total"], 0)
    
  135.         self.assertEqual(len(debug["source_lines"]), 0)
    
  136.         self.assertTrue(debug["name"].endswith("nonexistent.html"))
    
  137.         self.assertIn("message", debug)