github.com/hashicorp/vault/sdk@v0.11.0/helper/template/funcs_test.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package template
     5  
     6  import (
     7  	"strconv"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  func TestUnixTimestamp(t *testing.T) {
    15  	now := time.Now().Unix()
    16  	for i := 0; i < 100; i++ {
    17  		str := unixTime()
    18  		actual, err := strconv.Atoi(str)
    19  		require.NoError(t, err)
    20  		// Make sure the value generated is from now (or later if the clock ticked over)
    21  		require.GreaterOrEqual(t, int64(actual), now)
    22  	}
    23  }
    24  
    25  func TestNowNano(t *testing.T) {
    26  	now := time.Now().UnixNano() / int64(time.Millisecond)
    27  	for i := 0; i < 100; i++ {
    28  		str := unixTimeMillis()
    29  		actual, err := strconv.ParseUint(str, 10, 64)
    30  		require.NoError(t, err)
    31  		// Make sure the value generated is from now (or later if the clock ticked over)
    32  		require.GreaterOrEqual(t, int64(actual), now)
    33  	}
    34  }
    35  
    36  func TestTruncate(t *testing.T) {
    37  	type testCase struct {
    38  		maxLen    int
    39  		input     string
    40  		expected  string
    41  		expectErr bool
    42  	}
    43  
    44  	tests := map[string]testCase{
    45  		"negative max length": {
    46  			maxLen:    -1,
    47  			input:     "foobarbaz",
    48  			expected:  "",
    49  			expectErr: true,
    50  		},
    51  		"zero max length": {
    52  			maxLen:    0,
    53  			input:     "foobarbaz",
    54  			expected:  "",
    55  			expectErr: true,
    56  		},
    57  		"one max length": {
    58  			maxLen:    1,
    59  			input:     "foobarbaz",
    60  			expected:  "f",
    61  			expectErr: false,
    62  		},
    63  		"half max length": {
    64  			maxLen:    5,
    65  			input:     "foobarbaz",
    66  			expected:  "fooba",
    67  			expectErr: false,
    68  		},
    69  		"max length one less than length": {
    70  			maxLen:    8,
    71  			input:     "foobarbaz",
    72  			expected:  "foobarba",
    73  			expectErr: false,
    74  		},
    75  		"max length equals string length": {
    76  			maxLen:    9,
    77  			input:     "foobarbaz",
    78  			expected:  "foobarbaz",
    79  			expectErr: false,
    80  		},
    81  		"max length greater than string length": {
    82  			maxLen:    10,
    83  			input:     "foobarbaz",
    84  			expected:  "foobarbaz",
    85  			expectErr: false,
    86  		},
    87  		"max length significantly greater than string length": {
    88  			maxLen:    100,
    89  			input:     "foobarbaz",
    90  			expected:  "foobarbaz",
    91  			expectErr: false,
    92  		},
    93  	}
    94  
    95  	for name, test := range tests {
    96  		t.Run(name, func(t *testing.T) {
    97  			actual, err := truncate(test.maxLen, test.input)
    98  			if test.expectErr && err == nil {
    99  				t.Fatalf("err expected, got nil")
   100  			}
   101  			if !test.expectErr && err != nil {
   102  				t.Fatalf("no error expected, got: %s", err)
   103  			}
   104  
   105  			require.Equal(t, test.expected, actual)
   106  		})
   107  	}
   108  }
   109  
   110  func TestTruncateSHA256(t *testing.T) {
   111  	type testCase struct {
   112  		maxLen    int
   113  		input     string
   114  		expected  string
   115  		expectErr bool
   116  	}
   117  
   118  	tests := map[string]testCase{
   119  		"negative max length": {
   120  			maxLen:    -1,
   121  			input:     "thisisareallylongstring",
   122  			expected:  "",
   123  			expectErr: true,
   124  		},
   125  		"zero max length": {
   126  			maxLen:    0,
   127  			input:     "thisisareallylongstring",
   128  			expected:  "",
   129  			expectErr: true,
   130  		},
   131  		"8 max length": {
   132  			maxLen:    8,
   133  			input:     "thisisareallylongstring",
   134  			expected:  "",
   135  			expectErr: true,
   136  		},
   137  		"nine max length": {
   138  			maxLen:    9,
   139  			input:     "thisisareallylongstring",
   140  			expected:  "t4bb25641",
   141  			expectErr: false,
   142  		},
   143  		"half max length": {
   144  			maxLen:    12,
   145  			input:     "thisisareallylongstring",
   146  			expected:  "this704cd12b",
   147  			expectErr: false,
   148  		},
   149  		"max length one less than length": {
   150  			maxLen:    22,
   151  			input:     "thisisareallylongstring",
   152  			expected:  "thisisareallyl7f978be6",
   153  			expectErr: false,
   154  		},
   155  		"max length equals string length": {
   156  			maxLen:    23,
   157  			input:     "thisisareallylongstring",
   158  			expected:  "thisisareallylongstring",
   159  			expectErr: false,
   160  		},
   161  		"max length greater than string length": {
   162  			maxLen:    24,
   163  			input:     "thisisareallylongstring",
   164  			expected:  "thisisareallylongstring",
   165  			expectErr: false,
   166  		},
   167  		"max length significantly greater than string length": {
   168  			maxLen:    100,
   169  			input:     "thisisareallylongstring",
   170  			expected:  "thisisareallylongstring",
   171  			expectErr: false,
   172  		},
   173  	}
   174  
   175  	for name, test := range tests {
   176  		t.Run(name, func(t *testing.T) {
   177  			actual, err := truncateSHA256(test.maxLen, test.input)
   178  			if test.expectErr && err == nil {
   179  				t.Fatalf("err expected, got nil")
   180  			}
   181  			if !test.expectErr && err != nil {
   182  				t.Fatalf("no error expected, got: %s", err)
   183  			}
   184  
   185  			require.Equal(t, test.expected, actual)
   186  		})
   187  	}
   188  }
   189  
   190  func TestSHA256(t *testing.T) {
   191  	type testCase struct {
   192  		input    string
   193  		expected string
   194  	}
   195  
   196  	tests := map[string]testCase{
   197  		"empty string": {
   198  			input:    "",
   199  			expected: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
   200  		},
   201  		"foobar": {
   202  			input:    "foobar",
   203  			expected: "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2",
   204  		},
   205  		"mystring": {
   206  			input:    "mystring",
   207  			expected: "bd3ff47540b31e62d4ca6b07794e5a886b0f655fc322730f26ecd65cc7dd5c90",
   208  		},
   209  		"very long string": {
   210  			input: "Nullam pharetra mattis laoreet. Mauris feugiat, tortor in malesuada convallis, " +
   211  				"eros nunc dapibus erat, eget malesuada purus leo id lorem. Morbi pharetra, libero at malesuada bibendum, " +
   212  				"dui quam tristique libero, bibendum cursus diam quam at sem. Vivamus vestibulum orci vel odio posuere, " +
   213  				"quis tincidunt ipsum lacinia. Donec elementum a orci quis lobortis. Etiam bibendum ullamcorper varius. " +
   214  				"Mauris tempor eros est, at porta erat rutrum ac. Aliquam erat volutpat. Sed sagittis leo non bibendum " +
   215  				"lacinia. Praesent id justo iaculis, mattis libero vel, feugiat dui. Morbi id diam non magna imperdiet " +
   216  				"imperdiet. Ut tortor arcu, mollis ac maximus ac, sagittis commodo augue. Ut semper, diam pulvinar porta " +
   217  				"dignissim, massa ex condimentum enim, sed euismod urna quam vitae ex. Sed id neque vitae magna sagittis " +
   218  				"pretium. Suspendisse potenti.",
   219  			expected: "3e2a996c20b7a02378204f0843507d335e1ba203df2c4ded8d839d44af24482f",
   220  		},
   221  	}
   222  
   223  	for name, test := range tests {
   224  		t.Run(name, func(t *testing.T) {
   225  			actual := hashSHA256(test.input)
   226  			require.Equal(t, test.expected, actual)
   227  		})
   228  	}
   229  }
   230  
   231  func TestUppercase(t *testing.T) {
   232  	type testCase struct {
   233  		input    string
   234  		expected string
   235  	}
   236  
   237  	tests := map[string]testCase{
   238  		"empty string": {
   239  			input:    "",
   240  			expected: "",
   241  		},
   242  		"lowercase": {
   243  			input:    "foobar",
   244  			expected: "FOOBAR",
   245  		},
   246  		"uppercase": {
   247  			input:    "FOOBAR",
   248  			expected: "FOOBAR",
   249  		},
   250  		"mixed case": {
   251  			input:    "fOoBaR",
   252  			expected: "FOOBAR",
   253  		},
   254  	}
   255  
   256  	for name, test := range tests {
   257  		t.Run(name, func(t *testing.T) {
   258  			actual := uppercase(test.input)
   259  			require.Equal(t, test.expected, actual)
   260  		})
   261  	}
   262  }
   263  
   264  func TestLowercase(t *testing.T) {
   265  	type testCase struct {
   266  		input    string
   267  		expected string
   268  	}
   269  
   270  	tests := map[string]testCase{
   271  		"empty string": {
   272  			input:    "",
   273  			expected: "",
   274  		},
   275  		"lowercase": {
   276  			input:    "foobar",
   277  			expected: "foobar",
   278  		},
   279  		"uppercase": {
   280  			input:    "FOOBAR",
   281  			expected: "foobar",
   282  		},
   283  		"mixed case": {
   284  			input:    "fOoBaR",
   285  			expected: "foobar",
   286  		},
   287  	}
   288  
   289  	for name, test := range tests {
   290  		t.Run(name, func(t *testing.T) {
   291  			actual := lowercase(test.input)
   292  			require.Equal(t, test.expected, actual)
   293  		})
   294  	}
   295  }
   296  
   297  func TestReplace(t *testing.T) {
   298  	type testCase struct {
   299  		input    string
   300  		find     string
   301  		replace  string
   302  		expected string
   303  	}
   304  
   305  	tests := map[string]testCase{
   306  		"empty string": {
   307  			input:    "",
   308  			find:     "",
   309  			replace:  "",
   310  			expected: "",
   311  		},
   312  		"search not found": {
   313  			input:    "foobar",
   314  			find:     ".",
   315  			replace:  "_",
   316  			expected: "foobar",
   317  		},
   318  		"single character found": {
   319  			input:    "foo.bar",
   320  			find:     ".",
   321  			replace:  "_",
   322  			expected: "foo_bar",
   323  		},
   324  		"multiple characters found": {
   325  			input:    "foo.bar.baz",
   326  			find:     ".",
   327  			replace:  "_",
   328  			expected: "foo_bar_baz",
   329  		},
   330  		"find and remove": {
   331  			input:    "foo.bar",
   332  			find:     ".",
   333  			replace:  "",
   334  			expected: "foobar",
   335  		},
   336  		"find full string": {
   337  			input:    "foobarbaz",
   338  			find:     "bar",
   339  			replace:  "_",
   340  			expected: "foo_baz",
   341  		},
   342  	}
   343  
   344  	for name, test := range tests {
   345  		t.Run(name, func(t *testing.T) {
   346  			actual := replace(test.find, test.replace, test.input)
   347  			require.Equal(t, test.expected, actual)
   348  		})
   349  	}
   350  }
   351  
   352  func TestUUID(t *testing.T) {
   353  	re := "^[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}$"
   354  	for i := 0; i < 100; i++ {
   355  		id, err := uuid()
   356  		require.NoError(t, err)
   357  		require.Regexp(t, re, id)
   358  	}
   359  }