1. from django.template import TemplateSyntaxError
    
  2. from django.test import SimpleTestCase
    
  3. from django.utils.safestring import mark_safe
    
  4. 
    
  5. from ..utils import SafeClass, UnsafeClass, setup
    
  6. 
    
  7. 
    
  8. class AutoescapeTagTests(SimpleTestCase):
    
  9.     @setup({"autoescape-tag01": "{% autoescape off %}hello{% endautoescape %}"})
    
  10.     def test_autoescape_tag01(self):
    
  11.         output = self.engine.render_to_string("autoescape-tag01")
    
  12.         self.assertEqual(output, "hello")
    
  13. 
    
  14.     @setup({"autoescape-tag02": "{% autoescape off %}{{ first }}{% endautoescape %}"})
    
  15.     def test_autoescape_tag02(self):
    
  16.         output = self.engine.render_to_string(
    
  17.             "autoescape-tag02", {"first": "<b>hello</b>"}
    
  18.         )
    
  19.         self.assertEqual(output, "<b>hello</b>")
    
  20. 
    
  21.     @setup({"autoescape-tag03": "{% autoescape on %}{{ first }}{% endautoescape %}"})
    
  22.     def test_autoescape_tag03(self):
    
  23.         output = self.engine.render_to_string(
    
  24.             "autoescape-tag03", {"first": "<b>hello</b>"}
    
  25.         )
    
  26.         self.assertEqual(output, "&lt;b&gt;hello&lt;/b&gt;")
    
  27. 
    
  28.     # Autoescape disabling and enabling nest in a predictable way.
    
  29.     @setup(
    
  30.         {
    
  31.             "autoescape-tag04": (
    
  32.                 "{% autoescape off %}{{ first }} {% autoescape on %}{{ first }}"
    
  33.                 "{% endautoescape %}{% endautoescape %}"
    
  34.             )
    
  35.         }
    
  36.     )
    
  37.     def test_autoescape_tag04(self):
    
  38.         output = self.engine.render_to_string("autoescape-tag04", {"first": "<a>"})
    
  39.         self.assertEqual(output, "<a> &lt;a&gt;")
    
  40. 
    
  41.     @setup({"autoescape-tag05": "{% autoescape on %}{{ first }}{% endautoescape %}"})
    
  42.     def test_autoescape_tag05(self):
    
  43.         output = self.engine.render_to_string(
    
  44.             "autoescape-tag05", {"first": "<b>first</b>"}
    
  45.         )
    
  46.         self.assertEqual(output, "&lt;b&gt;first&lt;/b&gt;")
    
  47. 
    
  48.     # Strings (ASCII or Unicode) already marked as "safe" are not
    
  49.     # auto-escaped
    
  50.     @setup({"autoescape-tag06": "{{ first }}"})
    
  51.     def test_autoescape_tag06(self):
    
  52.         output = self.engine.render_to_string(
    
  53.             "autoescape-tag06", {"first": mark_safe("<b>first</b>")}
    
  54.         )
    
  55.         self.assertEqual(output, "<b>first</b>")
    
  56. 
    
  57.     @setup({"autoescape-tag07": "{% autoescape on %}{{ first }}{% endautoescape %}"})
    
  58.     def test_autoescape_tag07(self):
    
  59.         output = self.engine.render_to_string(
    
  60.             "autoescape-tag07", {"first": mark_safe("<b>Apple</b>")}
    
  61.         )
    
  62.         self.assertEqual(output, "<b>Apple</b>")
    
  63. 
    
  64.     @setup(
    
  65.         {
    
  66.             "autoescape-tag08": (
    
  67.                 r'{% autoescape on %}{{ var|default_if_none:" endquote\" hah" }}'
    
  68.                 r"{% endautoescape %}"
    
  69.             )
    
  70.         }
    
  71.     )
    
  72.     def test_autoescape_tag08(self):
    
  73.         """
    
  74.         Literal string arguments to filters, if used in the result, are safe.
    
  75.         """
    
  76.         output = self.engine.render_to_string("autoescape-tag08", {"var": None})
    
  77.         self.assertEqual(output, ' endquote" hah')
    
  78. 
    
  79.     # Objects which return safe strings as their __str__ method
    
  80.     # won't get double-escaped.
    
  81.     @setup({"autoescape-tag09": r"{{ unsafe }}"})
    
  82.     def test_autoescape_tag09(self):
    
  83.         output = self.engine.render_to_string(
    
  84.             "autoescape-tag09", {"unsafe": UnsafeClass()}
    
  85.         )
    
  86.         self.assertEqual(output, "you &amp; me")
    
  87. 
    
  88.     @setup({"autoescape-tag10": r"{{ safe }}"})
    
  89.     def test_autoescape_tag10(self):
    
  90.         output = self.engine.render_to_string("autoescape-tag10", {"safe": SafeClass()})
    
  91.         self.assertEqual(output, "you &gt; me")
    
  92. 
    
  93.     @setup(
    
  94.         {
    
  95.             "autoescape-filtertag01": (
    
  96.                 "{{ first }}{% filter safe %}{{ first }} x<y{% endfilter %}"
    
  97.             )
    
  98.         }
    
  99.     )
    
  100.     def test_autoescape_filtertag01(self):
    
  101.         """
    
  102.         The "safe" and "escape" filters cannot work due to internal
    
  103.         implementation details (fortunately, the (no)autoescape block
    
  104.         tags can be used in those cases)
    
  105.         """
    
  106.         with self.assertRaises(TemplateSyntaxError):
    
  107.             self.engine.render_to_string("autoescape-filtertag01", {"first": "<a>"})
    
  108. 
    
  109.     # Arguments to filters are 'safe' and manipulate their input unescaped.
    
  110.     @setup({"autoescape-filters01": '{{ var|cut:"&" }}'})
    
  111.     def test_autoescape_filters01(self):
    
  112.         output = self.engine.render_to_string(
    
  113.             "autoescape-filters01", {"var": "this & that"}
    
  114.         )
    
  115.         self.assertEqual(output, "this  that")
    
  116. 
    
  117.     @setup({"autoescape-filters02": '{{ var|join:" & " }}'})
    
  118.     def test_autoescape_filters02(self):
    
  119.         output = self.engine.render_to_string(
    
  120.             "autoescape-filters02", {"var": ("Tom", "Dick", "Harry")}
    
  121.         )
    
  122.         self.assertEqual(output, "Tom & Dick & Harry")
    
  123. 
    
  124.     @setup({"autoescape-literals01": '{{ "this & that" }}'})
    
  125.     def test_autoescape_literals01(self):
    
  126.         """
    
  127.         Literal strings are safe.
    
  128.         """
    
  129.         output = self.engine.render_to_string("autoescape-literals01")
    
  130.         self.assertEqual(output, "this & that")
    
  131. 
    
  132.     @setup({"autoescape-stringiterations01": "{% for l in var %}{{ l }},{% endfor %}"})
    
  133.     def test_autoescape_stringiterations01(self):
    
  134.         """
    
  135.         Iterating over strings outputs safe characters.
    
  136.         """
    
  137.         output = self.engine.render_to_string(
    
  138.             "autoescape-stringiterations01", {"var": "K&R"}
    
  139.         )
    
  140.         self.assertEqual(output, "K,&amp;,R,")
    
  141. 
    
  142.     @setup({"autoescape-lookup01": "{{ var.key }}"})
    
  143.     def test_autoescape_lookup01(self):
    
  144.         """
    
  145.         Escape requirement survives lookup.
    
  146.         """
    
  147.         output = self.engine.render_to_string(
    
  148.             "autoescape-lookup01", {"var": {"key": "this & that"}}
    
  149.         )
    
  150.         self.assertEqual(output, "this &amp; that")
    
  151. 
    
  152.     @setup(
    
  153.         {
    
  154.             "autoescape-incorrect-arg": (
    
  155.                 "{% autoescape true %}{{ var.key }}{% endautoescape %}"
    
  156.             )
    
  157.         }
    
  158.     )
    
  159.     def test_invalid_arg(self):
    
  160.         msg = "'autoescape' argument should be 'on' or 'off'"
    
  161.         with self.assertRaisesMessage(TemplateSyntaxError, msg):
    
  162.             self.engine.render_to_string(
    
  163.                 "autoescape-incorrect-arg", {"var": {"key": "this & that"}}
    
  164.             )
    
  165. 
    
  166.     @setup(
    
  167.         {"autoescape-incorrect-arg": "{% autoescape %}{{ var.key }}{% endautoescape %}"}
    
  168.     )
    
  169.     def test_no_arg(self):
    
  170.         msg = "'autoescape' tag requires exactly one argument."
    
  171.         with self.assertRaisesMessage(TemplateSyntaxError, msg):
    
  172.             self.engine.render_to_string(
    
  173.                 "autoescape-incorrect-arg", {"var": {"key": "this & that"}}
    
  174.             )