test_autoescape.py 6.3 KB

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