from django.template import TemplateSyntaxError
from django.test import SimpleTestCase
from django.utils.safestring import mark_safe
from ..utils import SafeClass, UnsafeClass, setup
class AutoescapeTagTests(SimpleTestCase):
@setup({"autoescape-tag01": "{% autoescape off %}hello{% endautoescape %}"})
def test_autoescape_tag01(self):
output = self.engine.render_to_string("autoescape-tag01")
self.assertEqual(output, "hello")
@setup({"autoescape-tag02": "{% autoescape off %}{{ first }}{% endautoescape %}"})
def test_autoescape_tag02(self):
output = self.engine.render_to_string(
"autoescape-tag02", {"first": "hello"}
)
self.assertEqual(output, "hello")
@setup({"autoescape-tag03": "{% autoescape on %}{{ first }}{% endautoescape %}"})
def test_autoescape_tag03(self):
output = self.engine.render_to_string(
"autoescape-tag03", {"first": "hello"}
)
self.assertEqual(output, "<b>hello</b>")
# Autoescape disabling and enabling nest in a predictable way.
@setup(
{
"autoescape-tag04": (
"{% autoescape off %}{{ first }} {% autoescape on %}{{ first }}"
"{% endautoescape %}{% endautoescape %}"
)
}
)
def test_autoescape_tag04(self):
output = self.engine.render_to_string("autoescape-tag04", {"first": ""})
self.assertEqual(output, " <a>")
@setup({"autoescape-tag05": "{% autoescape on %}{{ first }}{% endautoescape %}"})
def test_autoescape_tag05(self):
output = self.engine.render_to_string(
"autoescape-tag05", {"first": "first"}
)
self.assertEqual(output, "<b>first</b>")
# Strings (ASCII or Unicode) already marked as "safe" are not
# auto-escaped
@setup({"autoescape-tag06": "{{ first }}"})
def test_autoescape_tag06(self):
output = self.engine.render_to_string(
"autoescape-tag06", {"first": mark_safe("first")}
)
self.assertEqual(output, "first")
@setup({"autoescape-tag07": "{% autoescape on %}{{ first }}{% endautoescape %}"})
def test_autoescape_tag07(self):
output = self.engine.render_to_string(
"autoescape-tag07", {"first": mark_safe("Apple")}
)
self.assertEqual(output, "Apple")
@setup(
{
"autoescape-tag08": (
r'{% autoescape on %}{{ var|default_if_none:" endquote\" hah" }}'
r"{% endautoescape %}"
)
}
)
def test_autoescape_tag08(self):
"""
Literal string arguments to filters, if used in the result, are safe.
"""
output = self.engine.render_to_string("autoescape-tag08", {"var": None})
self.assertEqual(output, ' endquote" hah')
# Objects which return safe strings as their __str__ method
# won't get double-escaped.
@setup({"autoescape-tag09": r"{{ unsafe }}"})
def test_autoescape_tag09(self):
output = self.engine.render_to_string(
"autoescape-tag09", {"unsafe": UnsafeClass()}
)
self.assertEqual(output, "you & me")
@setup({"autoescape-tag10": r"{{ safe }}"})
def test_autoescape_tag10(self):
output = self.engine.render_to_string("autoescape-tag10", {"safe": SafeClass()})
self.assertEqual(output, "you > me")
@setup(
{
"autoescape-filtertag01": (
"{{ first }}{% filter safe %}{{ first }} x"})
# Arguments to filters are 'safe' and manipulate their input unescaped.
@setup({"autoescape-filters01": '{{ var|cut:"&" }}'})
def test_autoescape_filters01(self):
output = self.engine.render_to_string(
"autoescape-filters01", {"var": "this & that"}
)
self.assertEqual(output, "this that")
@setup({"autoescape-filters02": '{{ var|join:" & " }}'})
def test_autoescape_filters02(self):
output = self.engine.render_to_string(
"autoescape-filters02", {"var": ("Tom", "Dick", "Harry")}
)
self.assertEqual(output, "Tom & Dick & Harry")
@setup({"autoescape-literals01": '{{ "this & that" }}'})
def test_autoescape_literals01(self):
"""
Literal strings are safe.
"""
output = self.engine.render_to_string("autoescape-literals01")
self.assertEqual(output, "this & that")
@setup({"autoescape-stringiterations01": "{% for l in var %}{{ l }},{% endfor %}"})
def test_autoescape_stringiterations01(self):
"""
Iterating over strings outputs safe characters.
"""
output = self.engine.render_to_string(
"autoescape-stringiterations01", {"var": "K&R"}
)
self.assertEqual(output, "K,&,R,")
@setup({"autoescape-lookup01": "{{ var.key }}"})
def test_autoescape_lookup01(self):
"""
Escape requirement survives lookup.
"""
output = self.engine.render_to_string(
"autoescape-lookup01", {"var": {"key": "this & that"}}
)
self.assertEqual(output, "this & that")
@setup(
{
"autoescape-incorrect-arg": (
"{% autoescape true %}{{ var.key }}{% endautoescape %}"
)
}
)
def test_invalid_arg(self):
msg = "'autoescape' argument should be 'on' or 'off'"
with self.assertRaisesMessage(TemplateSyntaxError, msg):
self.engine.render_to_string(
"autoescape-incorrect-arg", {"var": {"key": "this & that"}}
)
@setup(
{"autoescape-incorrect-arg": "{% autoescape %}{{ var.key }}{% endautoescape %}"}
)
def test_no_arg(self):
msg = "'autoescape' tag requires exactly one argument."
with self.assertRaisesMessage(TemplateSyntaxError, msg):
self.engine.render_to_string(
"autoescape-incorrect-arg", {"var": {"key": "this & that"}}
)