code.gitea.io/gitea@v1.22.3/modules/templates/helper_test.go (about) 1 // Copyright 2019 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package templates 5 6 import ( 7 "html/template" 8 "strings" 9 "testing" 10 11 "code.gitea.io/gitea/modules/util" 12 13 "github.com/stretchr/testify/assert" 14 ) 15 16 func TestSubjectBodySeparator(t *testing.T) { 17 test := func(input, subject, body string) { 18 loc := mailSubjectSplit.FindIndex([]byte(input)) 19 if loc == nil { 20 assert.Empty(t, subject, "no subject found, but one expected") 21 assert.Equal(t, body, input) 22 } else { 23 assert.Equal(t, subject, input[0:loc[0]]) 24 assert.Equal(t, body, input[loc[1]:]) 25 } 26 } 27 28 test("Simple\n---------------\nCase", 29 "Simple\n", 30 "\nCase") 31 test("Only\nBody", 32 "", 33 "Only\nBody") 34 test("Minimal\n---\nseparator", 35 "Minimal\n", 36 "\nseparator") 37 test("False --- separator", 38 "", 39 "False --- separator") 40 test("False\n--- separator", 41 "", 42 "False\n--- separator") 43 test("False ---\nseparator", 44 "", 45 "False ---\nseparator") 46 test("With extra spaces\n----- \t \nBody", 47 "With extra spaces\n", 48 "\nBody") 49 test("With leading spaces\n -------\nOnly body", 50 "", 51 "With leading spaces\n -------\nOnly body") 52 test("Multiple\n---\n-------\n---\nSeparators", 53 "Multiple\n", 54 "\n-------\n---\nSeparators") 55 test("Insufficient\n--\nSeparators", 56 "", 57 "Insufficient\n--\nSeparators") 58 } 59 60 func TestJSEscapeSafe(t *testing.T) { 61 assert.EqualValues(t, `\u0026\u003C\u003E\'\"`, JSEscapeSafe(`&<>'"`)) 62 } 63 64 func TestHTMLFormat(t *testing.T) { 65 assert.Equal(t, template.HTML("<a>< < 1</a>"), HTMLFormat("<a>%s %s %d</a>", "<", template.HTML("<"), 1)) 66 } 67 68 func TestSanitizeHTML(t *testing.T) { 69 assert.Equal(t, template.HTML(`<a href="/" rel="nofollow">link</a> xss <div>inline</div>`), SanitizeHTML(`<a href="/">link</a> <a href="javascript:">xss</a> <div style="dangerous">inline</div>`)) 70 } 71 72 func TestTemplateTruthy(t *testing.T) { 73 tmpl := template.New("test") 74 tmpl.Funcs(template.FuncMap{"Iif": Iif}) 75 template.Must(tmpl.Parse(`{{if .Value}}true{{else}}false{{end}}:{{Iif .Value "true" "false"}}`)) 76 77 cases := []any{ 78 nil, false, true, "", "string", 0, 1, 79 byte(0), byte(1), int64(0), int64(1), float64(0), float64(1), 80 complex(0, 0), complex(1, 0), 81 (chan int)(nil), make(chan int), 82 (func())(nil), func() {}, 83 util.ToPointer(0), util.ToPointer(util.ToPointer(0)), 84 util.ToPointer(1), util.ToPointer(util.ToPointer(1)), 85 [0]int{}, 86 [1]int{0}, 87 []int(nil), 88 []int{}, 89 []int{0}, 90 map[any]any(nil), 91 map[any]any{}, 92 map[any]any{"k": "v"}, 93 (*struct{})(nil), 94 struct{}{}, 95 util.ToPointer(struct{}{}), 96 } 97 w := &strings.Builder{} 98 truthyCount := 0 99 for i, v := range cases { 100 w.Reset() 101 assert.NoError(t, tmpl.Execute(w, struct{ Value any }{v}), "case %d (%T) %#v fails", i, v, v) 102 out := w.String() 103 truthyCount += util.Iif(out == "true:true", 1, 0) 104 truthyMatches := out == "true:true" || out == "false:false" 105 assert.True(t, truthyMatches, "case %d (%T) %#v fail: %s", i, v, v, out) 106 } 107 assert.True(t, truthyCount != 0 && truthyCount != len(cases)) 108 }