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  }