code.gitea.io/gitea@v1.22.3/modules/templates/scopedtmpl/scopedtmpl_test.go (about) 1 // Copyright 2023 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package scopedtmpl 5 6 import ( 7 "bytes" 8 "html/template" 9 "strings" 10 "sync" 11 "testing" 12 "time" 13 14 "github.com/stretchr/testify/assert" 15 ) 16 17 func TestScopedTemplateSetFuncMap(t *testing.T) { 18 all := template.New("") 19 20 all.Funcs(template.FuncMap{"CtxFunc": func(s string) string { 21 return "default" 22 }}) 23 24 _, err := all.New("base").Parse(`{{CtxFunc "base"}}`) 25 assert.NoError(t, err) 26 27 _, err = all.New("test").Parse(strings.TrimSpace(` 28 {{template "base"}} 29 {{CtxFunc "test"}} 30 {{template "base"}} 31 {{CtxFunc "test"}} 32 `)) 33 assert.NoError(t, err) 34 35 ts, err := newScopedTemplateSet(all, "test") 36 assert.NoError(t, err) 37 38 // try to use different CtxFunc to render concurrently 39 40 funcMap1 := template.FuncMap{ 41 "CtxFunc": func(s string) string { 42 time.Sleep(100 * time.Millisecond) 43 return s + "1" 44 }, 45 } 46 47 funcMap2 := template.FuncMap{ 48 "CtxFunc": func(s string) string { 49 time.Sleep(100 * time.Millisecond) 50 return s + "2" 51 }, 52 } 53 54 out1 := bytes.Buffer{} 55 out2 := bytes.Buffer{} 56 wg := sync.WaitGroup{} 57 wg.Add(2) 58 go func() { 59 err := ts.newExecutor(funcMap1).Execute(&out1, nil) 60 assert.NoError(t, err) 61 wg.Done() 62 }() 63 go func() { 64 err := ts.newExecutor(funcMap2).Execute(&out2, nil) 65 assert.NoError(t, err) 66 wg.Done() 67 }() 68 wg.Wait() 69 assert.Equal(t, "base1\ntest1\nbase1\ntest1", out1.String()) 70 assert.Equal(t, "base2\ntest2\nbase2\ntest2", out2.String()) 71 } 72 73 func TestScopedTemplateSetEscape(t *testing.T) { 74 all := template.New("") 75 _, err := all.New("base").Parse(`<a href="?q={{.param}}">{{.text}}</a>`) 76 assert.NoError(t, err) 77 78 _, err = all.New("test").Parse(`{{template "base" .}}<form action="?q={{.param}}">{{.text}}</form>`) 79 assert.NoError(t, err) 80 81 ts, err := newScopedTemplateSet(all, "test") 82 assert.NoError(t, err) 83 84 out := bytes.Buffer{} 85 err = ts.newExecutor(nil).Execute(&out, map[string]string{"param": "/", "text": "<"}) 86 assert.NoError(t, err) 87 88 assert.Equal(t, `<a href="?q=%2f"><</a><form action="?q=%2f"><</form>`, out.String()) 89 } 90 91 func TestScopedTemplateSetUnsafe(t *testing.T) { 92 all := template.New("") 93 _, err := all.New("test").Parse(`<a href="{{if true}}?{{end}}a={{.param}}"></a>`) 94 assert.NoError(t, err) 95 96 _, err = newScopedTemplateSet(all, "test") 97 assert.ErrorContains(t, err, "appears in an ambiguous context within a URL") 98 }