1import os
2import tempfile
3
4from mako import exceptions
5from mako import lookup
6from mako import runtime
7from mako.template import Template
8from mako.testing.assertions import assert_raises_message
9from mako.testing.assertions import assert_raises_with_given_cause
10from mako.testing.config import config
11from mako.testing.helpers import file_with_template_code
12from mako.testing.helpers import replace_file_with_dir
13from mako.testing.helpers import result_lines
14from mako.testing.helpers import rewind_compile_time
15from mako.util import FastEncodingBuffer
16
17tl = lookup.TemplateLookup(directories=[config.template_base])
18
19
20class LookupTest:
21    def test_basic(self):
22        t = tl.get_template("index.html")
23        assert result_lines(t.render()) == ["this is index"]
24
25    def test_subdir(self):
26        t = tl.get_template("/subdir/index.html")
27        assert result_lines(t.render()) == [
28            "this is sub index",
29            "this is include 2",
30        ]
31
32        assert (
33            tl.get_template("/subdir/index.html").module_id
34            == "_subdir_index_html"
35        )
36
37    def test_updir(self):
38        t = tl.get_template("/subdir/foo/../bar/../index.html")
39        assert result_lines(t.render()) == [
40            "this is sub index",
41            "this is include 2",
42        ]
43
44    def test_directory_lookup(self):
45        """test that hitting an existent directory still raises
46        LookupError."""
47
48        assert_raises_with_given_cause(
49            exceptions.TopLevelLookupException,
50            KeyError,
51            tl.get_template,
52            "/subdir",
53        )
54
55    def test_no_lookup(self):
56        t = Template("hi <%include file='foo.html'/>")
57
58        assert_raises_message(
59            exceptions.TemplateLookupException,
60            "Template 'memory:%s' has no TemplateLookup associated"
61            % hex(id(t)),
62            t.render,
63        )
64
65    def test_uri_adjust(self):
66        tl = lookup.TemplateLookup(directories=["/foo/bar"])
67        assert (
68            tl.filename_to_uri("/foo/bar/etc/lala/index.html")
69            == "/etc/lala/index.html"
70        )
71
72        tl = lookup.TemplateLookup(directories=["./foo/bar"])
73        assert (
74            tl.filename_to_uri("./foo/bar/etc/index.html") == "/etc/index.html"
75        )
76
77    def test_uri_cache(self):
78        """test that the _uri_cache dictionary is available"""
79        tl._uri_cache[("foo", "bar")] = "/some/path"
80        assert tl._uri_cache[("foo", "bar")] == "/some/path"
81
82    def test_check_not_found(self):
83        tl = lookup.TemplateLookup()
84        tl.put_string("foo", "this is a template")
85        f = tl.get_template("foo")
86        assert f.uri in tl._collection
87        f.filename = "nonexistent"
88        assert_raises_with_given_cause(
89            exceptions.TemplateLookupException,
90            FileNotFoundError,
91            tl.get_template,
92            "foo",
93        )
94        assert f.uri not in tl._collection
95
96    def test_dont_accept_relative_outside_of_root(self):
97        """test the mechanics of an include where
98        the include goes outside of the path"""
99        tl = lookup.TemplateLookup(
100            directories=[os.path.join(config.template_base, "subdir")]
101        )
102        index = tl.get_template("index.html")
103
104        ctx = runtime.Context(FastEncodingBuffer())
105        ctx._with_template = index
106
107        assert_raises_message(
108            exceptions.TemplateLookupException,
109            'Template uri "../index.html" is invalid - it '
110            "cannot be relative outside of the root path",
111            runtime._lookup_template,
112            ctx,
113            "../index.html",
114            index.uri,
115        )
116
117        assert_raises_message(
118            exceptions.TemplateLookupException,
119            'Template uri "../othersubdir/foo.html" is invalid - it '
120            "cannot be relative outside of the root path",
121            runtime._lookup_template,
122            ctx,
123            "../othersubdir/foo.html",
124            index.uri,
125        )
126
127        # this is OK since the .. cancels out
128        runtime._lookup_template(ctx, "foo/../index.html", index.uri)
129
130    def test_checking_against_bad_filetype(self):
131        with tempfile.TemporaryDirectory() as tempdir:
132            tl = lookup.TemplateLookup(directories=[tempdir])
133            index_file = file_with_template_code(
134                os.path.join(tempdir, "index.html")
135            )
136
137            with rewind_compile_time():
138                tmpl = Template(filename=index_file)
139
140            tl.put_template("index.html", tmpl)
141
142            replace_file_with_dir(index_file)
143
144            assert_raises_with_given_cause(
145                exceptions.TemplateLookupException,
146                OSError,
147                tl._check,
148                "index.html",
149                tl._collection["index.html"],
150            )
151