github.com/hashicorp/vault/sdk@v0.11.0/helper/template/template_test.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package template 5 6 import ( 7 "fmt" 8 "testing" 9 10 "github.com/stretchr/testify/require" 11 ) 12 13 func TestGenerate(t *testing.T) { 14 type testCase struct { 15 template string 16 additionalOpts []Opt 17 data interface{} 18 19 expected string 20 expectErr bool 21 } 22 23 tests := map[string]testCase{ 24 "template without arguments": { 25 template: "this is a template", 26 data: nil, 27 expected: "this is a template", 28 expectErr: false, 29 }, 30 "template with arguments but no data": { 31 template: "this is a {{.String}}", 32 data: nil, 33 expected: "this is a <no value>", 34 expectErr: false, 35 }, 36 "template with arguments": { 37 template: "this is a {{.String}}", 38 data: struct { 39 String string 40 }{ 41 String: "foobar", 42 }, 43 expected: "this is a foobar", 44 expectErr: false, 45 }, 46 "template with builtin functions": { 47 template: `{{.String | truncate 10}} 48 {{.String | uppercase}} 49 {{.String | lowercase}} 50 {{.String | replace " " "."}} 51 {{.String | sha256}} 52 {{.String | base64}} 53 {{.String | truncate_sha256 20}}`, 54 data: struct { 55 String string 56 }{ 57 String: "Some string with Multiple Capitals LETTERS", 58 }, 59 expected: `Some strin 60 SOME STRING WITH MULTIPLE CAPITALS LETTERS 61 some string with multiple capitals letters 62 Some.string.with.Multiple.Capitals.LETTERS 63 da9872dd96609c72897defa11fe81017a62c3f44339d9d3b43fe37540ede3601 64 U29tZSBzdHJpbmcgd2l0aCBNdWx0aXBsZSBDYXBpdGFscyBMRVRURVJT 65 Some string 6841cf80`, 66 expectErr: false, 67 }, 68 "custom function": { 69 template: "{{foo}}", 70 additionalOpts: []Opt{ 71 Function("foo", func() string { 72 return "custom-foo" 73 }), 74 }, 75 expected: "custom-foo", 76 expectErr: false, 77 }, 78 } 79 80 for name, test := range tests { 81 t.Run(name, func(t *testing.T) { 82 opts := append(test.additionalOpts, Template(test.template)) 83 st, err := NewTemplate(opts...) 84 require.NoError(t, err) 85 86 actual, err := st.Generate(test.data) 87 if test.expectErr && err == nil { 88 t.Fatalf("err expected, got nil") 89 } 90 if !test.expectErr && err != nil { 91 t.Fatalf("no error expected, got: %s", err) 92 } 93 94 require.Equal(t, test.expected, actual) 95 }) 96 } 97 98 t.Run("random", func(t *testing.T) { 99 for i := 1; i < 100; i++ { 100 st, err := NewTemplate( 101 Template(fmt.Sprintf("{{random %d}}", i)), 102 ) 103 require.NoError(t, err) 104 105 actual, err := st.Generate(nil) 106 require.NoError(t, err) 107 108 require.Regexp(t, fmt.Sprintf("^[a-zA-Z0-9]{%d}$", i), actual) 109 } 110 }) 111 112 t.Run("unix_time", func(t *testing.T) { 113 for i := 0; i < 100; i++ { 114 st, err := NewTemplate( 115 Template("{{unix_time}}"), 116 ) 117 require.NoError(t, err) 118 119 actual, err := st.Generate(nil) 120 require.NoError(t, err) 121 122 require.Regexp(t, "^[0-9]+$", actual) 123 } 124 }) 125 126 t.Run("unix_time_millis", func(t *testing.T) { 127 for i := 0; i < 100; i++ { 128 st, err := NewTemplate( 129 Template("{{unix_time_millis}}"), 130 ) 131 require.NoError(t, err) 132 133 actual, err := st.Generate(nil) 134 require.NoError(t, err) 135 136 require.Regexp(t, "^[0-9]+$", actual) 137 } 138 }) 139 140 t.Run("timestamp", func(t *testing.T) { 141 for i := 0; i < 100; i++ { 142 st, err := NewTemplate( 143 Template(`{{timestamp "2006-01-02T15:04:05.000Z"}}`), 144 ) 145 require.NoError(t, err) 146 147 actual, err := st.Generate(nil) 148 require.NoError(t, err) 149 150 require.Regexp(t, `^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$`, actual) 151 } 152 }) 153 } 154 155 func TestBadConstructorArguments(t *testing.T) { 156 type testCase struct { 157 opts []Opt 158 } 159 160 tests := map[string]testCase{ 161 "missing template": { 162 opts: nil, 163 }, 164 "missing custom function name": { 165 opts: []Opt{ 166 Template("foo bar"), 167 Function("", func() string { 168 return "foo" 169 }), 170 }, 171 }, 172 "missing custom function": { 173 opts: []Opt{ 174 Template("foo bar"), 175 Function("foo", nil), 176 }, 177 }, 178 "bad template": { 179 opts: []Opt{ 180 Template("{{.String"), 181 }, 182 }, 183 } 184 185 for name, test := range tests { 186 t.Run(name, func(t *testing.T) { 187 st, err := NewTemplate(test.opts...) 188 require.Error(t, err) 189 190 str, err := st.Generate(nil) 191 require.Error(t, err) 192 require.Equal(t, "", str) 193 }) 194 } 195 196 t.Run("erroring custom function", func(t *testing.T) { 197 st, err := NewTemplate( 198 Template("{{foo}}"), 199 Function("foo", func() (string, error) { 200 return "", fmt.Errorf("an error!") 201 }), 202 ) 203 require.NoError(t, err) 204 205 str, err := st.Generate(nil) 206 require.Error(t, err) 207 require.Equal(t, "", str) 208 }) 209 }