see ticket 23789 context processors run context overrides context processors django template render requires a dict engine djangotemplates dirs appdirs false name django options template engine fromstring context context requestcontext requestcontextself requestfactory get msg context must be a dict rather than context with self assertraisesmessagetypeerror msg template rendercontext msg context must be a dict rather than requestcontext with self assertraisesmessagetypeerror msg template renderrequestcontext overridesettingsinstalledappstemplatebackends apps good def testtemplatetagdiscoveryself engine djangotemplates dirs appdirs false name django options libraries alternate templatebackends apps good templatetags goodtags override templatebackends apps good templatetags goodtags libraries are discovered from installed applications self assertequal engine engine librariesgoodtags templatebackends apps good templatetags goodtags self assertequal engine engine librariessubpackage tags templatebackends apps good templatetags subpackage tags libraries are discovered from django templatetags self assertequal engine engine librariesstatic django templatetags static libraries passed in options are registered self assertequal engine engine librariesalternate templatebackends apps good templatetags goodtags libraries passed in options take precedence over discovered ones self assertequal engine engine librariesoverride templatebackends apps good templatetags goodtags overridesettingsinstalledappstemplatebackends apps importerror def testtemplatetagdiscoveryimporterrorself with self assertraisesmessage invalidtemplatelibrary importerror raised when trying to load templatebackends apps importerror templatetags brokentags as cm djangotemplates dirs appdirs false name django options self assertisinstancecm exception cause importerror def testbuiltinsdiscoveryself engine djangotemplates dirs appdirs false name django options builtins templatebackends apps good templatetags goodtags self assertequal engine engine builtins django template defaulttags django template defaultfilters django template loadertags templatebackends apps good templatetags goodtags def testautoescapeoffself templates backend django template backends django djangotemplates options autoescape false engines enginehandlertemplatestemplates self assertequal enginesdjango fromstringhello name rendername bob jim hello bob jim def testautoescapedefaultself templates backend django template backends django djangotemplates engines enginehandlertemplatestemplates self assertequal enginesdjango fromstringhello name rendername bob jim hello bob amp jim def testdefaulttemplateloadersself see ticket 23789 context processors run context overrides context processors django template render requires a dict libraries are discovered from installed applications libraries are discovered from django templatetags libraries passed in options are registered libraries passed in options take precedence over discovered ones import errors in tag modules should be reraised with a helpful message the cached template loader is always enabled by default
from pathlib import Path

from template_tests.test_response import test_processor_name

from django.template import Context, EngineHandler, RequestContext
from django.template.backends.django import DjangoTemplates
from django.template.library import InvalidTemplateLibrary
from django.test import RequestFactory, override_settings

from .test_dummy import TemplateStringsTests


class DjangoTemplatesTests(TemplateStringsTests):
    engine_class = DjangoTemplates
    backend_name = "django"
    request_factory = RequestFactory()

    def test_context_has_priority_over_template_context_processors(self):
        
        engine = DjangoTemplates(
            {
                "DIRS": [],
                "APP_DIRS": False,
                "NAME": "django",
                "OPTIONS": {
                    "context_processors": [test_processor_name],
                },
            }
        )

        template = engine.from_string("{{ processors }}")
        request = self.request_factory.get("/")

        
        content = template.render({}, request)
        self.assertEqual(content, "yes")

        
        content = template.render({"processors": "no"}, request)
        self.assertEqual(content, "no")

    def test_render_requires_dict(self):
        
        engine = DjangoTemplates(
            {
                "DIRS": [],
                "APP_DIRS": False,
                "NAME": "django",
                "OPTIONS": {},
            }
        )
        template = engine.from_string("")
        context = Context()
        request_context = RequestContext(self.request_factory.get("/"), {})
        msg = "context must be a dict rather than Context."
        with self.assertRaisesMessage(TypeError, msg):
            template.render(context)
        msg = "context must be a dict rather than RequestContext."
        with self.assertRaisesMessage(TypeError, msg):
            template.render(request_context)

    @override_settings(INSTALLED_APPS=["template_backends.apps.good"])
    def test_templatetag_discovery(self):
        engine = DjangoTemplates(
            {
                "DIRS": [],
                "APP_DIRS": False,
                "NAME": "django",
                "OPTIONS": {
                    "libraries": {
                        "alternate": (
                            "template_backends.apps.good.templatetags.good_tags"
                        ),
                        "override": (
                            "template_backends.apps.good.templatetags.good_tags"
                        ),
                    },
                },
            }
        )

        
        self.assertEqual(
            engine.engine.libraries["good_tags"],
            "template_backends.apps.good.templatetags.good_tags",
        )
        self.assertEqual(
            engine.engine.libraries["subpackage.tags"],
            "template_backends.apps.good.templatetags.subpackage.tags",
        )
        
        self.assertEqual(
            engine.engine.libraries["static"],
            "django.templatetags.static",
        )
        
        self.assertEqual(
            engine.engine.libraries["alternate"],
            "template_backends.apps.good.templatetags.good_tags",
        )
        
        self.assertEqual(
            engine.engine.libraries["override"],
            "template_backends.apps.good.templatetags.good_tags",
        )

    @override_settings(INSTALLED_APPS=["template_backends.apps.importerror"])
    def test_templatetag_discovery_import_error(self):
        
        with self.assertRaisesMessage(
            InvalidTemplateLibrary,
            "ImportError raised when trying to load "
            "'template_backends.apps.importerror.templatetags.broken_tags'",
        ) as cm:
            DjangoTemplates(
                {
                    "DIRS": [],
                    "APP_DIRS": False,
                    "NAME": "django",
                    "OPTIONS": {},
                }
            )
        self.assertIsInstance(cm.exception.__cause__, ImportError)

    def test_builtins_discovery(self):
        engine = DjangoTemplates(
            {
                "DIRS": [],
                "APP_DIRS": False,
                "NAME": "django",
                "OPTIONS": {
                    "builtins": ["template_backends.apps.good.templatetags.good_tags"],
                },
            }
        )

        self.assertEqual(
            engine.engine.builtins,
            [
                "django.template.defaulttags",
                "django.template.defaultfilters",
                "django.template.loader_tags",
                "template_backends.apps.good.templatetags.good_tags",
            ],
        )

    def test_autoescape_off(self):
        templates = [
            {
                "BACKEND": "django.template.backends.django.DjangoTemplates",
                "OPTIONS": {"autoescape": False},
            }
        ]
        engines = EngineHandler(templates=templates)
        self.assertEqual(
            engines["django"]
            .from_string("Hello, {{ name }}")
            .render({"name": "Bob & Jim"}),
            "Hello, Bob & Jim",
        )

    def test_autoescape_default(self):
        templates = [
            {
                "BACKEND": "django.template.backends.django.DjangoTemplates",
            }
        ]
        engines = EngineHandler(templates=templates)
        self.assertEqual(
            engines["django"]
            .from_string("Hello, {{ name }}")
            .render({"name": "Bob & Jim"}),
            "Hello, Bob &amp; Jim",
        )

    def test_default_template_loaders(self):
        
        for debug in (True, False):
            with self.subTest(DEBUG=debug), self.settings(DEBUG=debug):
                engine = DjangoTemplates(
                    {"DIRS": [], "APP_DIRS": True, "NAME": "django", "OPTIONS": {}}
                )
                self.assertEqual(
                    engine.engine.loaders,
                    [
                        (
                            "django.template.loaders.cached.Loader",
                            [
                                "django.template.loaders.filesystem.Loader",
                                "django.template.loaders.app_directories.Loader",
                            ],
                        )
                    ],
                )

    def test_dirs_pathlib(self):
        engine = DjangoTemplates(
            {
                "DIRS": [Path(__file__).parent / "templates" / "template_backends"],
                "APP_DIRS": False,
                "NAME": "django",
                "OPTIONS": {},
            }
        )
        template = engine.get_template("hello.html")
        self.assertEqual(template.render({"name": "Joe"}), "Hello Joe!\n")