summaryrefslogtreecommitdiff
path: root/tests/regressiontests/templates
diff options
context:
space:
mode:
Diffstat (limited to 'tests/regressiontests/templates')
-rw-r--r--tests/regressiontests/templates/filters.py9
-rw-r--r--tests/regressiontests/templates/loaders.py42
-rw-r--r--tests/regressiontests/templates/tests.py34
3 files changed, 76 insertions, 9 deletions
diff --git a/tests/regressiontests/templates/filters.py b/tests/regressiontests/templates/filters.py
index 3d6284e881..af34c58a9f 100644
--- a/tests/regressiontests/templates/filters.py
+++ b/tests/regressiontests/templates/filters.py
@@ -328,7 +328,12 @@ def get_filter_tests():
'join03': (r'{{ a|join:" & " }}', {'a': ['alpha', 'beta & me']}, 'alpha & beta & me'),
'join04': (r'{% autoescape off %}{{ a|join:" & " }}{% endautoescape %}', {'a': ['alpha', 'beta & me']}, 'alpha & beta & me'),
-
+ # Test that joining with unsafe joiners don't result in unsafe strings (#11377)
+ 'join05': (r'{{ a|join:var }}', {'a': ['alpha', 'beta & me'], 'var': ' & '}, 'alpha & beta & me'),
+ 'join06': (r'{{ a|join:var }}', {'a': ['alpha', 'beta & me'], 'var': mark_safe(' & ')}, 'alpha & beta & me'),
+ 'join07': (r'{{ a|join:var|lower }}', {'a': ['Alpha', 'Beta & me'], 'var': ' & ' }, 'alpha & beta & me'),
+ 'join08': (r'{{ a|join:var|lower }}', {'a': ['Alpha', 'Beta & me'], 'var': mark_safe(' & ')}, 'alpha & beta & me'),
+
'date01': (r'{{ d|date:"m" }}', {'d': datetime(2008, 1, 1)}, '01'),
'date02': (r'{{ d|date }}', {'d': datetime(2008, 1, 1)}, 'Jan. 1, 2008'),
#Ticket 9520: Make sure |date doesn't blow up on non-dates
@@ -341,5 +346,5 @@ def get_filter_tests():
'add04': (r'{{ i|add:"16" }}', {'i': 'not_an_int'}, 'not_an_int16'),
'add05': (r'{{ l1|add:l2 }}', {'l1': [1, 2], 'l2': [3, 4]}, '[1, 2, 3, 4]'),
'add06': (r'{{ t1|add:t2 }}', {'t1': (3, 4), 't2': (1, 2)}, '(3, 4, 1, 2)'),
- 'add07': (r'{{ d|add:t }}', {'d': date(2000, 1, 1), 't': timedelta(10)}, '2000-01-11'),
+ 'add07': (r'{{ d|add:t }}', {'d': date(2000, 1, 1), 't': timedelta(10)}, 'Jan. 11, 2000'),
}
diff --git a/tests/regressiontests/templates/loaders.py b/tests/regressiontests/templates/loaders.py
index 64a0dc6505..caa3faa6bc 100644
--- a/tests/regressiontests/templates/loaders.py
+++ b/tests/regressiontests/templates/loaders.py
@@ -15,9 +15,11 @@ import pkg_resources
import imp
import StringIO
import os.path
+import warnings
from django.template import TemplateDoesNotExist, Context
from django.template.loaders.eggs import load_template_source as lts_egg
+from django.template.loaders.eggs import Loader as EggLoader
from django.template import loader
# Mock classes and objects for pkg_resources functions.
@@ -53,7 +55,33 @@ def create_egg(name, resources):
egg._resources = resources
sys.modules[name] = egg
-class EggLoader(unittest.TestCase):
+class DeprecatedEggLoaderTest(unittest.TestCase):
+ "Test the deprecated load_template_source interface to the egg loader"
+ def setUp(self):
+ pkg_resources._provider_factories[MockLoader] = MockProvider
+
+ self.empty_egg = create_egg("egg_empty", {})
+ self.egg_1 = create_egg("egg_1", {
+ os.path.normcase('templates/y.html') : StringIO.StringIO("y"),
+ os.path.normcase('templates/x.txt') : StringIO.StringIO("x"),
+ })
+ self._old_installed_apps = settings.INSTALLED_APPS
+ settings.INSTALLED_APPS = []
+ warnings.simplefilter("ignore", PendingDeprecationWarning)
+
+ def tearDown(self):
+ settings.INSTALLED_APPS = self._old_installed_apps
+ warnings.resetwarnings()
+
+ def test_existing(self):
+ "A template can be loaded from an egg"
+ settings.INSTALLED_APPS = ['egg_1']
+ contents, template_name = lts_egg("y.html")
+ self.assertEqual(contents, "y")
+ self.assertEqual(template_name, "egg:egg_1:templates/y.html")
+
+
+class EggLoaderTest(unittest.TestCase):
def setUp(self):
pkg_resources._provider_factories[MockLoader] = MockProvider
@@ -71,24 +99,28 @@ class EggLoader(unittest.TestCase):
def test_empty(self):
"Loading any template on an empty egg should fail"
settings.INSTALLED_APPS = ['egg_empty']
- self.assertRaises(TemplateDoesNotExist, lts_egg, "not-existing.html")
+ egg_loader = EggLoader()
+ self.assertRaises(TemplateDoesNotExist, egg_loader.load_template_source, "not-existing.html")
def test_non_existing(self):
"Template loading fails if the template is not in the egg"
settings.INSTALLED_APPS = ['egg_1']
- self.assertRaises(TemplateDoesNotExist, lts_egg, "not-existing.html")
+ egg_loader = EggLoader()
+ self.assertRaises(TemplateDoesNotExist, egg_loader.load_template_source, "not-existing.html")
def test_existing(self):
"A template can be loaded from an egg"
settings.INSTALLED_APPS = ['egg_1']
- contents, template_name = lts_egg("y.html")
+ egg_loader = EggLoader()
+ contents, template_name = egg_loader.load_template_source("y.html")
self.assertEqual(contents, "y")
self.assertEqual(template_name, "egg:egg_1:templates/y.html")
def test_not_installed(self):
"Loading an existent template from an egg not included in INSTALLED_APPS should fail"
settings.INSTALLED_APPS = []
- self.assertRaises(TemplateDoesNotExist, lts_egg, "y.html")
+ egg_loader = EggLoader()
+ self.assertRaises(TemplateDoesNotExist, egg_loader.load_template_source, "y.html")
class CachedLoader(unittest.TestCase):
def setUp(self):
diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
index 5902e8d5e7..bbbcae30eb 100644
--- a/tests/regressiontests/templates/tests.py
+++ b/tests/regressiontests/templates/tests.py
@@ -506,6 +506,17 @@ class Templates(unittest.TestCase):
'basic-syntax28': ("{{ a.b }}", {'a': SilentGetItemClass()}, ('', 'INVALID')),
'basic-syntax29': ("{{ a.b }}", {'a': SilentAttrClass()}, ('', 'INVALID')),
+ # Something that starts like a number but has an extra lookup works as a lookup.
+ 'basic-syntax30': ("{{ 1.2.3 }}", {"1": {"2": {"3": "d"}}}, "d"),
+ 'basic-syntax31': ("{{ 1.2.3 }}", {"1": {"2": ("a", "b", "c", "d")}}, "d"),
+ 'basic-syntax32': ("{{ 1.2.3 }}", {"1": (("x", "x", "x", "x"), ("y", "y", "y", "y"), ("a", "b", "c", "d"))}, "d"),
+ 'basic-syntax33': ("{{ 1.2.3 }}", {"1": ("xxxx", "yyyy", "abcd")}, "d"),
+ 'basic-syntax34': ("{{ 1.2.3 }}", {"1": ({"x": "x"}, {"y": "y"}, {"z": "z", "3": "d"})}, "d"),
+
+ # Numbers are numbers even if their digits are in the context.
+ 'basic-syntax35': ("{{ 1 }}", {"1": "abc"}, "1"),
+ 'basic-syntax36': ("{{ 1.2 }}", {"1": "abc"}, "1.2"),
+
# List-index syntax allows a template to access a certain item of a subscriptable object.
'list-index01': ("{{ var.1 }}", {"var": ["first item", "second item"]}, "second item"),
@@ -592,7 +603,7 @@ class Templates(unittest.TestCase):
#filters should accept empty string constants
'filter-syntax20': ('{{ ""|default_if_none:"was none" }}', {}, ""),
-
+
### COMMENT SYNTAX ########################################################
'comment-syntax01': ("{# this is hidden #}hello", {}, "hello"),
'comment-syntax02': ("{# this is hidden #}hello{# foo #}", {}, "hello"),
@@ -690,6 +701,7 @@ class Templates(unittest.TestCase):
'for-tag-unpack11': ("{% for x,y,z in items %}{{ x }}:{{ y }},{{ z }}/{% endfor %}", {"items": (('one', 1), ('two', 2))}, ("one:1,/two:2,/", "one:1,INVALID/two:2,INVALID/")),
'for-tag-unpack12': ("{% for x,y,z in items %}{{ x }}:{{ y }},{{ z }}/{% endfor %}", {"items": (('one', 1, 'carrot'), ('two', 2))}, ("one:1,carrot/two:2,/", "one:1,carrot/two:2,INVALID/")),
'for-tag-unpack13': ("{% for x,y,z in items %}{{ x }}:{{ y }},{{ z }}/{% endfor %}", {"items": (('one', 1, 'carrot'), ('two', 2, 'cheese'))}, ("one:1,carrot/two:2,cheese/", "one:1,carrot/two:2,cheese/")),
+ 'for-tag-unpack14': ("{% for x,y in items %}{{ x }}:{{ y }}/{% endfor %}", {"items": (1, 2)}, (":/:/", "INVALID:INVALID/INVALID:INVALID/")),
'for-tag-empty01': ("{% for val in values %}{{ val }}{% empty %}empty text{% endfor %}", {"values": [1, 2, 3]}, "123"),
'for-tag-empty02': ("{% for val in values %}{{ val }}{% empty %}values array empty{% endfor %}", {"values": []}, "values array empty"),
'for-tag-empty03': ("{% for val in values %}{{ val }}{% empty %}values array not found{% endfor %}", {}, "values array not found"),
@@ -1285,7 +1297,8 @@ class Templates(unittest.TestCase):
# Regression test for #11270.
'cache17': ('{% load cache %}{% cache 10 long_cache_key poem %}Some Content{% endcache %}', {'poem': 'Oh freddled gruntbuggly/Thy micturations are to me/As plurdled gabbleblotchits/On a lurgid bee/That mordiously hath bitled out/Its earted jurtles/Into a rancid festering/Or else I shall rend thee in the gobberwarts with my blurglecruncheon/See if I dont.'}, 'Some Content'),
-
+
+
### AUTOESCAPE TAG ##############################################
'autoescape-tag01': ("{% autoescape off %}hello{% endautoescape %}", {}, "hello"),
'autoescape-tag02': ("{% autoescape off %}{{ first }}{% endautoescape %}", {"first": "<b>hello</b>"}, "<b>hello</b>"),
@@ -1314,6 +1327,23 @@ class Templates(unittest.TestCase):
# implementation details (fortunately, the (no)autoescape block
# tags can be used in those cases)
'autoescape-filtertag01': ("{{ first }}{% filter safe %}{{ first }} x<y{% endfilter %}", {"first": "<a>"}, template.TemplateSyntaxError),
+
+ # ifqeual compares unescaped vales.
+ 'autoescape-ifequal01': ('{% ifequal var "this & that" %}yes{% endifequal %}', { "var": "this & that" }, "yes" ),
+
+ # Arguments to filters are 'safe' and manipulate their input unescaped.
+ 'autoescape-filters01': ('{{ var|cut:"&" }}', { "var": "this & that" }, "this that" ),
+ 'autoescape-filters02': ('{{ var|join:" & \" }}', { "var": ("Tom", "Dick", "Harry") }, "Tom & Dick & Harry" ),
+
+ # Literal strings are safe.
+ 'autoescape-literals01': ('{{ "this & that" }}',{}, "this & that" ),
+
+ # Iterating over strings outputs safe characters.
+ 'autoescape-stringiterations01': ('{% for l in var %}{{ l }},{% endfor %}', {'var': 'K&R'}, "K,&amp;,R," ),
+
+ # Escape requirement survives lookup.
+ 'autoescape-lookup01': ('{{ var.key }}', { "var": {"key": "this & that" }}, "this &amp; that" ),
+
}