[1.8.x] Cleaned up template loader tests.
Backport of 1827aa9024
from master
This commit is contained in:
parent
3e0df285fd
commit
210bf24ddb
|
@ -0,0 +1 @@
|
|||
index
|
|
@ -0,0 +1,125 @@
|
|||
import os
|
||||
|
||||
from django.template import Context
|
||||
from django.template.engine import Engine
|
||||
from django.test import SimpleTestCase, ignore_warnings
|
||||
from django.utils.deprecation import RemovedInDjango20Warning
|
||||
|
||||
from .utils import ROOT, TEMPLATE_DIR
|
||||
|
||||
OTHER_DIR = os.path.join(ROOT, 'other_templates')
|
||||
|
||||
|
||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
||||
class DeprecatedRenderToStringTest(SimpleTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.engine = Engine(dirs=[TEMPLATE_DIR])
|
||||
|
||||
def test_basic_context(self):
|
||||
self.assertEqual(
|
||||
self.engine.render_to_string('test_context.html', {'obj': 'test'}),
|
||||
'obj:test\n',
|
||||
)
|
||||
|
||||
def test_existing_context_kept_clean(self):
|
||||
context = Context({'obj': 'before'})
|
||||
output = self.engine.render_to_string(
|
||||
'test_context.html', {'obj': 'after'}, context_instance=context,
|
||||
)
|
||||
self.assertEqual(output, 'obj:after\n')
|
||||
self.assertEqual(context['obj'], 'before')
|
||||
|
||||
def test_no_empty_dict_pushed_to_stack(self):
|
||||
"""
|
||||
#21741 -- An empty dict should not be pushed to the context stack when
|
||||
render_to_string is called without a context argument.
|
||||
"""
|
||||
|
||||
# The stack should have a length of 1, corresponding to the builtins
|
||||
self.assertEqual(
|
||||
'1',
|
||||
self.engine.render_to_string('test_context_stack.html').strip(),
|
||||
)
|
||||
self.assertEqual(
|
||||
'1',
|
||||
self.engine.render_to_string(
|
||||
'test_context_stack.html',
|
||||
context_instance=Context()
|
||||
).strip(),
|
||||
)
|
||||
|
||||
|
||||
class LoaderTests(SimpleTestCase):
|
||||
|
||||
def test_debug_nodelist_name(self):
|
||||
engine = Engine(dirs=[TEMPLATE_DIR], debug=True)
|
||||
template_name = 'index.html'
|
||||
template = engine.get_template(template_name)
|
||||
name = template.nodelist[0].source[0].name
|
||||
self.assertTrue(name.endswith(template_name))
|
||||
|
||||
def test_origin(self):
|
||||
engine = Engine(dirs=[TEMPLATE_DIR], debug=True)
|
||||
template = engine.get_template('index.html')
|
||||
self.assertEqual(template.origin.loadname, 'index.html')
|
||||
|
||||
def test_origin_debug_false(self):
|
||||
engine = Engine(dirs=[TEMPLATE_DIR], debug=False)
|
||||
template = engine.get_template('index.html')
|
||||
self.assertEqual(template.origin, None)
|
||||
|
||||
def test_loader_priority(self):
|
||||
"""
|
||||
#21460 -- Check that the order of template loader works.
|
||||
"""
|
||||
loaders = [
|
||||
'django.template.loaders.filesystem.Loader',
|
||||
'django.template.loaders.app_directories.Loader',
|
||||
]
|
||||
engine = Engine(dirs=[OTHER_DIR, TEMPLATE_DIR], loaders=loaders)
|
||||
template = engine.get_template('priority/foo.html')
|
||||
self.assertEqual(template.render(Context()), 'priority\n')
|
||||
|
||||
def test_cached_loader_priority(self):
|
||||
"""
|
||||
Check that the order of template loader works. Refs #21460.
|
||||
"""
|
||||
loaders = [
|
||||
('django.template.loaders.cached.Loader', [
|
||||
'django.template.loaders.filesystem.Loader',
|
||||
'django.template.loaders.app_directories.Loader',
|
||||
]),
|
||||
]
|
||||
engine = Engine(dirs=[OTHER_DIR, TEMPLATE_DIR], loaders=loaders)
|
||||
|
||||
template = engine.get_template('priority/foo.html')
|
||||
self.assertEqual(template.render(Context()), 'priority\n')
|
||||
|
||||
template = engine.get_template('priority/foo.html')
|
||||
self.assertEqual(template.render(Context()), 'priority\n')
|
||||
|
||||
|
||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
||||
class TemplateDirsOverrideTests(SimpleTestCase):
|
||||
DIRS = ((OTHER_DIR, ), [OTHER_DIR])
|
||||
|
||||
def setUp(self):
|
||||
self.engine = Engine()
|
||||
|
||||
def test_render_to_string(self):
|
||||
for dirs in self.DIRS:
|
||||
self.assertEqual(
|
||||
self.engine.render_to_string('test_dirs.html', dirs=dirs),
|
||||
'spam eggs\n',
|
||||
)
|
||||
|
||||
def test_get_template(self):
|
||||
for dirs in self.DIRS:
|
||||
template = self.engine.get_template('test_dirs.html', dirs=dirs)
|
||||
self.assertEqual(template.render(Context()), 'spam eggs\n')
|
||||
|
||||
def test_select_template(self):
|
||||
for dirs in self.DIRS:
|
||||
template = self.engine.select_template(['test_dirs.html'], dirs=dirs)
|
||||
self.assertEqual(template.render(Context()), 'spam eggs\n')
|
|
@ -1,22 +1,18 @@
|
|||
"""
|
||||
Test cases for the template loaders
|
||||
|
||||
Note: This test requires setuptools!
|
||||
"""
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os.path
|
||||
import sys
|
||||
import types
|
||||
import unittest
|
||||
from contextlib import contextmanager
|
||||
|
||||
from django.template import Context, TemplateDoesNotExist, loader
|
||||
from django.template import Context, TemplateDoesNotExist
|
||||
from django.template.engine import Engine
|
||||
from django.template.loaders import cached, eggs
|
||||
from django.test import SimpleTestCase, ignore_warnings, override_settings
|
||||
from django.test import SimpleTestCase, override_settings
|
||||
from django.utils import six
|
||||
from django.utils._os import upath
|
||||
from django.utils.deprecation import RemovedInDjango20Warning
|
||||
from django.utils.six import StringIO
|
||||
|
||||
from .utils import TEMPLATE_DIR
|
||||
|
||||
try:
|
||||
import pkg_resources
|
||||
|
@ -24,38 +20,86 @@ except ImportError:
|
|||
pkg_resources = None
|
||||
|
||||
|
||||
TEMPLATES_DIR = os.path.join(os.path.dirname(upath(__file__)), 'templates')
|
||||
class CachedLoaderTests(SimpleTestCase):
|
||||
|
||||
GLOBAL_TEMPLATES_DIR = os.path.join(os.path.dirname(os.path.dirname(upath(__file__))), 'templates')
|
||||
def create_engine(self, **kwargs):
|
||||
return Engine(
|
||||
loaders=[
|
||||
('django.template.loaders.cached.Loader', [
|
||||
'django.template.loaders.filesystem.Loader',
|
||||
]),
|
||||
],
|
||||
)
|
||||
|
||||
def test_templatedir_caching(self):
|
||||
"""
|
||||
#13573 -- Template directories should be part of the cache key.
|
||||
"""
|
||||
engine = self.create_engine()
|
||||
|
||||
# Mock classes and objects for pkg_resources functions.
|
||||
class MockLoader(object):
|
||||
pass
|
||||
# Retrieve a template specifying a template directory to check
|
||||
t1, name = engine.find_template('test.html', (os.path.join(TEMPLATE_DIR, 'first'),))
|
||||
# Now retrieve the same template name, but from a different directory
|
||||
t2, name = engine.find_template('test.html', (os.path.join(TEMPLATE_DIR, 'second'),))
|
||||
|
||||
# The two templates should not have the same content
|
||||
self.assertNotEqual(t1.render(Context({})), t2.render(Context({})))
|
||||
|
||||
def create_egg(name, resources):
|
||||
"""
|
||||
Creates a mock egg with a list of resources.
|
||||
def test_missing_template_is_cached(self):
|
||||
"""
|
||||
#19949 -- TemplateDoesNotExist exceptions should be cached.
|
||||
"""
|
||||
engine = self.create_engine()
|
||||
loader = engine.template_loaders[0]
|
||||
|
||||
name: The name of the module.
|
||||
resources: A dictionary of resources. Keys are the names and values the data.
|
||||
"""
|
||||
egg = types.ModuleType(name)
|
||||
egg.__loader__ = MockLoader()
|
||||
egg.__path__ = ['/some/bogus/path/']
|
||||
egg.__file__ = '/some/bogus/path/__init__.pyc'
|
||||
egg._resources = resources
|
||||
sys.modules[name] = egg
|
||||
self.assertFalse('missing.html' in loader.template_cache)
|
||||
|
||||
with self.assertRaises(TemplateDoesNotExist):
|
||||
loader.load_template("missing.html")
|
||||
|
||||
self.assertEqual(
|
||||
loader.template_cache["missing.html"],
|
||||
TemplateDoesNotExist,
|
||||
"Cached loader failed to cache the TemplateDoesNotExist exception",
|
||||
)
|
||||
|
||||
def test_debug_nodelist_name(self):
|
||||
template_name = 'index.html'
|
||||
engine = Engine(dirs=[TEMPLATE_DIR], debug=True)
|
||||
|
||||
template = engine.get_template(template_name)
|
||||
name = template.nodelist[0].source[0].name
|
||||
self.assertTrue(
|
||||
name.endswith(template_name),
|
||||
'Template loaded through cached loader has incorrect name for debug page: %s' % template_name,
|
||||
)
|
||||
|
||||
template = engine.get_template(template_name)
|
||||
name = template.nodelist[0].source[0].name
|
||||
self.assertTrue(
|
||||
name.endswith(template_name),
|
||||
'Cached template loaded through cached loader has incorrect name for debug page: %s' % template_name,
|
||||
)
|
||||
|
||||
|
||||
@unittest.skipUnless(pkg_resources, 'setuptools is not installed')
|
||||
class EggLoaderTest(SimpleTestCase):
|
||||
class EggLoaderTests(SimpleTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.loader = eggs.Loader(Engine.get_default())
|
||||
@contextmanager
|
||||
def create_egg(self, name, resources):
|
||||
"""
|
||||
Creates a mock egg with a list of resources.
|
||||
|
||||
name: The name of the module.
|
||||
resources: A dictionary of template names mapped to file-like objects.
|
||||
"""
|
||||
|
||||
if six.PY2:
|
||||
name = name.encode('utf-8')
|
||||
|
||||
class MockLoader(object):
|
||||
pass
|
||||
|
||||
# Defined here b/c at module scope we may not have pkg_resources
|
||||
class MockProvider(pkg_resources.NullProvider):
|
||||
def __init__(self, module):
|
||||
pkg_resources.NullProvider.__init__(self, module)
|
||||
|
@ -76,181 +120,123 @@ class EggLoaderTest(SimpleTestCase):
|
|||
def _fn(self, base, resource_name):
|
||||
return os.path.normcase(resource_name)
|
||||
|
||||
egg = types.ModuleType(name)
|
||||
egg.__loader__ = MockLoader()
|
||||
egg.__path__ = ['/some/bogus/path/']
|
||||
egg.__file__ = '/some/bogus/path/__init__.pyc'
|
||||
egg._resources = resources
|
||||
sys.modules[name] = egg
|
||||
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("y"),
|
||||
os.path.normcase('templates/x.txt'): StringIO("x"),
|
||||
})
|
||||
|
||||
@override_settings(INSTALLED_APPS=['egg_empty'])
|
||||
def test_empty(self):
|
||||
"Loading any template on an empty egg should fail"
|
||||
with self.assertRaises(TemplateDoesNotExist):
|
||||
self.loader.load_template_source("not-existing.html")
|
||||
|
||||
@override_settings(INSTALLED_APPS=['egg_1'])
|
||||
def test_non_existing(self):
|
||||
"Template loading fails if the template is not in the egg"
|
||||
with self.assertRaises(TemplateDoesNotExist):
|
||||
self.loader.load_template_source("not-existing.html")
|
||||
|
||||
@override_settings(INSTALLED_APPS=['egg_1'])
|
||||
def test_existing(self):
|
||||
"A template can be loaded from an egg"
|
||||
contents, template_name = self.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 any app should fail"
|
||||
with self.assertRaises(TemplateDoesNotExist):
|
||||
self.loader.load_template_source("y.html")
|
||||
|
||||
|
||||
class CachedLoader(SimpleTestCase):
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
del sys.modules[name]
|
||||
del pkg_resources._provider_factories[MockLoader]
|
||||
|
||||
def setUp(self):
|
||||
self.loader = cached.Loader(Engine.get_default(), [
|
||||
'django.template.loaders.filesystem.Loader',
|
||||
engine = Engine(loaders=[
|
||||
'django.template.loaders.eggs.Loader',
|
||||
])
|
||||
self.loader = engine.template_loaders[0]
|
||||
|
||||
def test_templatedir_caching(self):
|
||||
"Check that the template directories form part of the template cache key. Refs #13573"
|
||||
# Retrieve a template specifying a template directory to check
|
||||
t1, name = self.loader.find_template('test.html', (os.path.join(TEMPLATES_DIR, 'first'),))
|
||||
# Now retrieve the same template name, but from a different directory
|
||||
t2, name = self.loader.find_template('test.html', (os.path.join(TEMPLATES_DIR, 'second'),))
|
||||
def test_existing(self):
|
||||
templates = {
|
||||
os.path.normcase('templates/y.html'): six.StringIO("y"),
|
||||
}
|
||||
|
||||
# The two templates should not have the same content
|
||||
self.assertNotEqual(t1.render(Context({})), t2.render(Context({})))
|
||||
with self.create_egg('egg', templates):
|
||||
with override_settings(INSTALLED_APPS=['egg']):
|
||||
contents, template_name = self.loader.load_template_source("y.html")
|
||||
self.assertEqual(contents, "y")
|
||||
self.assertEqual(template_name, "egg:egg:templates/y.html")
|
||||
|
||||
def test_missing_template_is_cached(self):
|
||||
"#19949 -- Check that the missing template is cached."
|
||||
# Check that 'missing.html' isn't already in cache before 'missing.html' is loaded
|
||||
with self.assertRaises(KeyError):
|
||||
self.loader.template_cache["missing.html"]
|
||||
# Try to load it, it should fail
|
||||
with self.assertRaises(TemplateDoesNotExist):
|
||||
self.loader.load_template("missing.html")
|
||||
# Verify that the fact that the missing template, which hasn't been found, has actually
|
||||
# been cached:
|
||||
cached_miss = self.loader.template_cache["missing.html"]
|
||||
self.assertEqual(cached_miss, TemplateDoesNotExist,
|
||||
"Cached template loader doesn't cache file lookup misses. It should.")
|
||||
|
||||
|
||||
@override_settings(TEMPLATES=[{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [TEMPLATES_DIR],
|
||||
}])
|
||||
class RenderToStringTest(SimpleTestCase):
|
||||
def test_basic(self):
|
||||
self.assertEqual(loader.render_to_string('test_context.html'), 'obj:\n')
|
||||
|
||||
def test_basic_context(self):
|
||||
self.assertEqual(loader.render_to_string('test_context.html',
|
||||
{'obj': 'test'}), 'obj:test\n')
|
||||
|
||||
def test_empty_list(self):
|
||||
six.assertRaisesRegex(self, TemplateDoesNotExist,
|
||||
'No template names provided$',
|
||||
loader.render_to_string, [])
|
||||
|
||||
def test_select_templates_from_empty_list(self):
|
||||
six.assertRaisesRegex(self, TemplateDoesNotExist,
|
||||
'No template names provided$',
|
||||
loader.select_template, [])
|
||||
|
||||
|
||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
||||
@override_settings(TEMPLATES=[{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [TEMPLATES_DIR],
|
||||
}])
|
||||
class DeprecatedRenderToStringTest(SimpleTestCase):
|
||||
|
||||
def test_existing_context_kept_clean(self):
|
||||
context = Context({'obj': 'before'})
|
||||
output = loader.render_to_string('test_context.html', {'obj': 'after'},
|
||||
context_instance=context)
|
||||
self.assertEqual(output, 'obj:after\n')
|
||||
self.assertEqual(context['obj'], 'before')
|
||||
|
||||
def test_no_empty_dict_pushed_to_stack(self):
|
||||
def test_non_existing(self):
|
||||
"""
|
||||
No empty dict should be pushed to the context stack when render_to_string
|
||||
is called without any argument (#21741).
|
||||
Template loading fails if the template is not in the egg.
|
||||
"""
|
||||
with self.create_egg('egg', {}):
|
||||
with override_settings(INSTALLED_APPS=['egg']):
|
||||
with self.assertRaises(TemplateDoesNotExist):
|
||||
self.loader.load_template_source("not-existing.html")
|
||||
|
||||
# The stack should have a length of 1, corresponding to the builtins
|
||||
self.assertEqual('1',
|
||||
loader.render_to_string('test_context_stack.html').strip())
|
||||
self.assertEqual('1',
|
||||
loader.render_to_string('test_context_stack.html', context_instance=Context()).strip())
|
||||
|
||||
|
||||
@ignore_warnings(category=RemovedInDjango20Warning)
|
||||
@override_settings(TEMPLATES=[{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
}])
|
||||
class TemplateDirsOverrideTest(SimpleTestCase):
|
||||
|
||||
dirs_tuple = (os.path.join(os.path.dirname(upath(__file__)), 'other_templates'),)
|
||||
dirs_list = list(dirs_tuple)
|
||||
dirs_iter = (dirs_tuple, dirs_list)
|
||||
|
||||
def test_render_to_string(self):
|
||||
for dirs in self.dirs_iter:
|
||||
self.assertEqual(loader.render_to_string('test_dirs.html', dirs=dirs), 'spam eggs\n')
|
||||
|
||||
def test_get_template(self):
|
||||
for dirs in self.dirs_iter:
|
||||
template = loader.get_template('test_dirs.html', dirs=dirs)
|
||||
self.assertEqual(template.render(), 'spam eggs\n')
|
||||
|
||||
def test_select_template(self):
|
||||
for dirs in self.dirs_iter:
|
||||
template = loader.select_template(['test_dirs.html'], dirs=dirs)
|
||||
self.assertEqual(template.render(), 'spam eggs\n')
|
||||
|
||||
|
||||
@override_settings(TEMPLATES=[{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [GLOBAL_TEMPLATES_DIR],
|
||||
'OPTIONS': {
|
||||
'loaders': [
|
||||
('django.template.loaders.cached.Loader', [
|
||||
'django.template.loaders.filesystem.Loader',
|
||||
'django.template.loaders.app_directories.Loader',
|
||||
]),
|
||||
],
|
||||
},
|
||||
}])
|
||||
class PriorityCacheLoader(SimpleTestCase):
|
||||
def test_basic(self):
|
||||
def test_not_installed(self):
|
||||
"""
|
||||
Check that the order of template loader works. Refs #21460.
|
||||
Template loading fails if the egg is not in INSTALLED_APPS.
|
||||
"""
|
||||
t1 = loader.get_template('priority/foo.html')
|
||||
self.assertEqual(t1.render(), 'priority\n')
|
||||
templates = {
|
||||
os.path.normcase('templates/y.html'): six.StringIO("y"),
|
||||
}
|
||||
|
||||
with self.create_egg('egg', templates):
|
||||
with self.assertRaises(TemplateDoesNotExist):
|
||||
self.loader.load_template_source("y.html")
|
||||
|
||||
|
||||
@override_settings(TEMPLATES=[{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [GLOBAL_TEMPLATES_DIR],
|
||||
'OPTIONS': {
|
||||
'loaders': [
|
||||
'django.template.loaders.filesystem.Loader',
|
||||
'django.template.loaders.app_directories.Loader',
|
||||
],
|
||||
},
|
||||
}])
|
||||
class PriorityLoader(SimpleTestCase):
|
||||
def test_basic(self):
|
||||
class FileSystemLoaderTests(SimpleTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.engine = Engine()
|
||||
|
||||
@contextmanager
|
||||
def source_checker(self, dirs):
|
||||
loader = self.engine.template_loaders[0]
|
||||
|
||||
def check_sources(path, expected_sources):
|
||||
expected_sources = [os.path.abspath(s) for s in expected_sources]
|
||||
self.assertEqual(
|
||||
list(loader.get_template_sources(path, dirs)),
|
||||
expected_sources,
|
||||
)
|
||||
|
||||
yield check_sources
|
||||
|
||||
def test_directory_security(self):
|
||||
with self.source_checker(['/dir1', '/dir2']) as check_sources:
|
||||
check_sources('index.html', ['/dir1/index.html', '/dir2/index.html'])
|
||||
check_sources('/etc/passwd', [])
|
||||
check_sources('etc/passwd', ['/dir1/etc/passwd', '/dir2/etc/passwd'])
|
||||
check_sources('../etc/passwd', [])
|
||||
check_sources('../../../etc/passwd', [])
|
||||
check_sources('/dir1/index.html', ['/dir1/index.html'])
|
||||
check_sources('../dir2/index.html', ['/dir2/index.html'])
|
||||
check_sources('/dir1blah', [])
|
||||
check_sources('../dir1blah', [])
|
||||
|
||||
def test_unicode_template_name(self):
|
||||
with self.source_checker(['/dir1', '/dir2']) as check_sources:
|
||||
# UTF-8 bytestrings are permitted.
|
||||
check_sources(b'\xc3\x85ngstr\xc3\xb6m', ['/dir1/Ångström', '/dir2/Ångström'])
|
||||
# Unicode strings are permitted.
|
||||
check_sources('Ångström', ['/dir1/Ångström', '/dir2/Ångström'])
|
||||
|
||||
def test_utf8_bytestring(self):
|
||||
"""
|
||||
Check that the order of template loader works. Refs #21460.
|
||||
Invalid UTF-8 encoding in bytestrings should raise a useful error
|
||||
"""
|
||||
t1 = loader.get_template('priority/foo.html')
|
||||
self.assertEqual(t1.render(), 'priority\n')
|
||||
engine = Engine()
|
||||
loader = engine.template_loaders[0]
|
||||
with self.assertRaises(UnicodeDecodeError):
|
||||
list(loader.get_template_sources(b'\xc3\xc3', ['/dir1']))
|
||||
|
||||
def test_unicode_dir_name(self):
|
||||
with self.source_checker([b'/Stra\xc3\x9fe']) as check_sources:
|
||||
check_sources('Ångström', ['/Straße/Ångström'])
|
||||
check_sources(b'\xc3\x85ngstr\xc3\xb6m', ['/Straße/Ångström'])
|
||||
|
||||
@unittest.skipUnless(
|
||||
os.path.normcase('/TEST') == os.path.normpath('/test'),
|
||||
"This test only runs on case-sensitive file systems.",
|
||||
)
|
||||
def test_case_sensitivity(self):
|
||||
with self.source_checker(['/dir1', '/DIR2']) as check_sources:
|
||||
check_sources('index.html', ['/dir1/index.html', '/DIR2/index.html'])
|
||||
check_sources('/DIR1/index.HTML', ['/DIR1/index.HTML'])
|
||||
|
||||
|
||||
class AppDirectoriesLoaderTest(FileSystemLoaderTests):
|
||||
|
||||
def setUp(self):
|
||||
self.engine = Engine(
|
||||
loaders=['django.template.loaders.app_directories.Loader'],
|
||||
)
|
||||
|
|
|
@ -13,7 +13,6 @@ from django.template import (
|
|||
base as template_base, engines, loader,
|
||||
)
|
||||
from django.template.engine import Engine
|
||||
from django.template.loaders import app_directories, filesystem
|
||||
from django.test import RequestFactory, SimpleTestCase
|
||||
from django.test.utils import (
|
||||
extend_sys_path, ignore_warnings, override_settings,
|
||||
|
@ -21,126 +20,18 @@ from django.test.utils import (
|
|||
from django.utils._os import upath
|
||||
from django.utils.deprecation import RemovedInDjango20Warning
|
||||
|
||||
TESTS_DIR = os.path.dirname(os.path.dirname(os.path.abspath(upath(__file__))))
|
||||
|
||||
TEMPLATES_DIR = os.path.join(TESTS_DIR, 'templates')
|
||||
TEMPLATES_DIR = os.path.join(os.path.dirname(upath(__file__)), 'templates')
|
||||
|
||||
|
||||
class TemplateLoaderTests(SimpleTestCase):
|
||||
|
||||
def test_loaders_security(self):
|
||||
ad_loader = app_directories.Loader(Engine.get_default())
|
||||
fs_loader = filesystem.Loader(Engine.get_default())
|
||||
|
||||
def test_template_sources(path, template_dirs, expected_sources):
|
||||
if isinstance(expected_sources, list):
|
||||
# Fix expected sources so they are abspathed
|
||||
expected_sources = [os.path.abspath(s) for s in expected_sources]
|
||||
# Test the two loaders (app_directores and filesystem).
|
||||
func1 = lambda p, t: list(ad_loader.get_template_sources(p, t))
|
||||
func2 = lambda p, t: list(fs_loader.get_template_sources(p, t))
|
||||
for func in (func1, func2):
|
||||
if isinstance(expected_sources, list):
|
||||
self.assertEqual(func(path, template_dirs), expected_sources)
|
||||
else:
|
||||
self.assertRaises(expected_sources, func, path, template_dirs)
|
||||
|
||||
template_dirs = ['/dir1', '/dir2']
|
||||
test_template_sources('index.html', template_dirs,
|
||||
['/dir1/index.html', '/dir2/index.html'])
|
||||
test_template_sources('/etc/passwd', template_dirs, [])
|
||||
test_template_sources('etc/passwd', template_dirs,
|
||||
['/dir1/etc/passwd', '/dir2/etc/passwd'])
|
||||
test_template_sources('../etc/passwd', template_dirs, [])
|
||||
test_template_sources('../../../etc/passwd', template_dirs, [])
|
||||
test_template_sources('/dir1/index.html', template_dirs,
|
||||
['/dir1/index.html'])
|
||||
test_template_sources('../dir2/index.html', template_dirs,
|
||||
['/dir2/index.html'])
|
||||
test_template_sources('/dir1blah', template_dirs, [])
|
||||
test_template_sources('../dir1blah', template_dirs, [])
|
||||
|
||||
# UTF-8 bytestrings are permitted.
|
||||
test_template_sources(b'\xc3\x85ngstr\xc3\xb6m', template_dirs,
|
||||
['/dir1/Ångström', '/dir2/Ångström'])
|
||||
# Unicode strings are permitted.
|
||||
test_template_sources('Ångström', template_dirs,
|
||||
['/dir1/Ångström', '/dir2/Ångström'])
|
||||
test_template_sources('Ångström', [b'/Stra\xc3\x9fe'], ['/Straße/Ångström'])
|
||||
test_template_sources(b'\xc3\x85ngstr\xc3\xb6m', [b'/Stra\xc3\x9fe'],
|
||||
['/Straße/Ångström'])
|
||||
# Invalid UTF-8 encoding in bytestrings is not. Should raise a
|
||||
# semi-useful error message.
|
||||
test_template_sources(b'\xc3\xc3', template_dirs, UnicodeDecodeError)
|
||||
|
||||
# Case insensitive tests (for win32). Not run unless we're on
|
||||
# a case insensitive operating system.
|
||||
if os.path.normcase('/TEST') == os.path.normpath('/test'):
|
||||
template_dirs = ['/dir1', '/DIR2']
|
||||
test_template_sources('index.html', template_dirs,
|
||||
['/dir1/index.html', '/DIR2/index.html'])
|
||||
test_template_sources('/DIR1/index.HTML', template_dirs,
|
||||
['/DIR1/index.HTML'])
|
||||
|
||||
@override_settings(TEMPLATES=[{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [TEMPLATES_DIR],
|
||||
'OPTIONS': {
|
||||
# Turn DEBUG on, so that the origin file name will be kept with
|
||||
# the compiled templates.
|
||||
'debug': True,
|
||||
}
|
||||
}])
|
||||
def test_loader_debug_origin(self):
|
||||
load_name = 'login.html'
|
||||
|
||||
# We rely on the fact the file system and app directories loaders both
|
||||
# inherit the load_template method from the base Loader class, so we
|
||||
# only need to test one of them.
|
||||
template = loader.get_template(load_name).template
|
||||
template_name = template.nodelist[0].source[0].name
|
||||
self.assertTrue(template_name.endswith(load_name),
|
||||
'Template loaded by filesystem loader has incorrect name for debug page: %s' % template_name)
|
||||
|
||||
@override_settings(TEMPLATES=[{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [TEMPLATES_DIR],
|
||||
'OPTIONS': {
|
||||
'debug': True,
|
||||
'loaders': [
|
||||
('django.template.loaders.cached.Loader', [
|
||||
'django.template.loaders.filesystem.Loader',
|
||||
]),
|
||||
],
|
||||
},
|
||||
}])
|
||||
def test_cached_loader_debug_origin(self):
|
||||
load_name = 'login.html'
|
||||
|
||||
# Test the cached loader separately since it overrides load_template.
|
||||
template = loader.get_template(load_name).template
|
||||
template_name = template.nodelist[0].source[0].name
|
||||
self.assertTrue(template_name.endswith(load_name),
|
||||
'Template loaded through cached loader has incorrect name for debug page: %s' % template_name)
|
||||
|
||||
template = loader.get_template(load_name).template
|
||||
template_name = template.nodelist[0].source[0].name
|
||||
self.assertTrue(template_name.endswith(load_name),
|
||||
'Cached template loaded through cached loader has incorrect name for debug page: %s' % template_name)
|
||||
|
||||
@override_settings(DEBUG=True)
|
||||
def test_loader_origin(self):
|
||||
template = loader.get_template('login.html')
|
||||
self.assertEqual(template.origin.loadname, 'login.html')
|
||||
class TemplateTests(SimpleTestCase):
|
||||
|
||||
@override_settings(DEBUG=True)
|
||||
def test_string_origin(self):
|
||||
template = Template('string template')
|
||||
self.assertEqual(template.origin.source, 'string template')
|
||||
|
||||
def test_debug_false_origin(self):
|
||||
template = loader.get_template('login.html')
|
||||
self.assertEqual(template.origin, None)
|
||||
|
||||
class IncludeTests(SimpleTestCase):
|
||||
|
||||
# Test the base loader class via the app loader. load_template
|
||||
# from base is used by all shipped loaders excepting cached,
|
||||
|
|
|
@ -15,6 +15,7 @@ from django.utils.encoding import python_2_unicode_compatible
|
|||
from django.utils.safestring import mark_safe
|
||||
|
||||
ROOT = os.path.dirname(os.path.abspath(upath(__file__)))
|
||||
TEMPLATE_DIR = os.path.join(ROOT, 'templates')
|
||||
|
||||
|
||||
def setup(templates, *args, **kwargs):
|
||||
|
|
Loading…
Reference in New Issue