mirror of https://github.com/authelia/authelia.git
429 lines
11 KiB
Go
429 lines
11 KiB
Go
package utils
|
|
|
|
import (
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestIsStringAbsURL(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
have string
|
|
err string
|
|
}{
|
|
{
|
|
"ShouldBeAbs",
|
|
"https://google.com",
|
|
"",
|
|
},
|
|
{
|
|
"ShouldNotBeAbs",
|
|
"google.com",
|
|
"could not parse 'google.com' as a URL",
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
theError := IsStringAbsURL(tc.have)
|
|
|
|
if tc.err == "" {
|
|
assert.NoError(t, theError)
|
|
} else {
|
|
assert.EqualError(t, theError, tc.err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func FuzzIsStringAbsURL(f *testing.F) {
|
|
f.Add("https://google.com")
|
|
f.Add("https://example.com")
|
|
f.Add("https://abc.com")
|
|
f.Fuzz(func(t *testing.T, s string) {
|
|
assert.NoError(t, IsStringAbsURL(s))
|
|
})
|
|
}
|
|
|
|
func TestIsStringInSliceF(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
needle string
|
|
haystack []string
|
|
isEqual func(needle, item string) bool
|
|
expected bool
|
|
}{
|
|
{
|
|
"ShouldBePresent",
|
|
"good",
|
|
[]string{"good"},
|
|
func(needle, item string) bool {
|
|
return needle == item
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"ShouldNotBePresent",
|
|
"bad",
|
|
[]string{"good"},
|
|
func(needle, item string) bool {
|
|
return needle == item
|
|
},
|
|
false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
assert.Equal(t, tc.expected, IsStringInSliceF(tc.needle, tc.haystack, tc.isEqual))
|
|
})
|
|
}
|
|
}
|
|
|
|
func FuzzIsStringInSliceF(f *testing.F) {
|
|
a := func(needle, item string) bool {
|
|
return needle == item
|
|
}
|
|
|
|
f.Add("abc", "abc,123,456")
|
|
f.Add("abc", "123,abc,456")
|
|
f.Add("456", "123,abc,456")
|
|
f.Fuzz(func(t *testing.T, n, h string) {
|
|
haystack := strings.Split(h, ",")
|
|
assert.True(t, IsStringInSliceF(n, haystack, a))
|
|
assert.True(t, IsStringInSliceF(n, haystack, strings.EqualFold))
|
|
})
|
|
}
|
|
|
|
func TestStringHTMLEscape(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
have string
|
|
expected string
|
|
}{
|
|
{
|
|
"ShouldNotAlterAlphaNum",
|
|
"abc123",
|
|
"abc123",
|
|
},
|
|
{
|
|
"ShouldEscapeSpecial",
|
|
"abc123><@#@",
|
|
"abc123><@#@",
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
assert.Equal(t, tc.expected, StringHTMLEscape(tc.have))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestStringSplitDelimitedEscaped(t *testing.T) {
|
|
testCases := []struct {
|
|
desc, have string
|
|
delimiter rune
|
|
want []string
|
|
}{
|
|
{desc: "ShouldSplitNormalString", have: "abc,123,456", delimiter: ',', want: []string{"abc", "123", "456"}},
|
|
{desc: "ShouldSplitEscapedString", have: "a\\,bc,123,456", delimiter: ',', want: []string{"a,bc", "123", "456"}},
|
|
{desc: "ShouldSplitEscapedStringPipe", have: "a\\|bc|123|456", delimiter: '|', want: []string{"a|bc", "123", "456"}},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
actual := StringSplitDelimitedEscaped(tc.have, tc.delimiter)
|
|
|
|
assert.Equal(t, tc.want, actual)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestStringJoinDelimitedEscaped(t *testing.T) {
|
|
testCases := []struct {
|
|
desc, want string
|
|
delimiter rune
|
|
have []string
|
|
}{
|
|
{desc: "ShouldJoinNormalStringSlice", have: []string{"abc", "123", "456"}, delimiter: ',', want: "abc,123,456"},
|
|
{desc: "ShouldJoinEscapeNeededStringSlice", have: []string{"abc", "1,23", "456"}, delimiter: ',', want: "abc,1\\,23,456"},
|
|
{desc: "ShouldJoinEscapeNeededStringSlicePipe", have: []string{"abc", "1|23", "456"}, delimiter: '|', want: "abc|1\\|23|456"},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.desc, func(t *testing.T) {
|
|
actual := StringJoinDelimitedEscaped(tc.have, tc.delimiter)
|
|
|
|
assert.Equal(t, tc.want, actual)
|
|
|
|
// Ensure splitting again also works fine.
|
|
split := StringSplitDelimitedEscaped(actual, tc.delimiter)
|
|
|
|
assert.Equal(t, tc.have, split)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestShouldDetectAlphaNumericString(t *testing.T) {
|
|
assert.True(t, IsStringAlphaNumeric("abc"))
|
|
assert.True(t, IsStringAlphaNumeric("abc123"))
|
|
assert.False(t, IsStringAlphaNumeric("abc123@"))
|
|
}
|
|
|
|
func TestShouldSplitIntoEvenStringsOfFour(t *testing.T) {
|
|
input := testStringInput
|
|
|
|
arrayOfStrings := SliceString(input, 4)
|
|
|
|
assert.Equal(t, len(arrayOfStrings), 3)
|
|
assert.Equal(t, "abcd", arrayOfStrings[0])
|
|
assert.Equal(t, "efgh", arrayOfStrings[1])
|
|
assert.Equal(t, "ijkl", arrayOfStrings[2])
|
|
}
|
|
|
|
func TestShouldSplitIntoEvenStringsOfOne(t *testing.T) {
|
|
input := testStringInput
|
|
|
|
arrayOfStrings := SliceString(input, 1)
|
|
|
|
assert.Equal(t, 12, len(arrayOfStrings))
|
|
assert.Equal(t, "a", arrayOfStrings[0])
|
|
assert.Equal(t, "b", arrayOfStrings[1])
|
|
assert.Equal(t, "c", arrayOfStrings[2])
|
|
assert.Equal(t, "d", arrayOfStrings[3])
|
|
assert.Equal(t, "l", arrayOfStrings[11])
|
|
}
|
|
|
|
func TestShouldSplitIntoUnevenStringsOfFour(t *testing.T) {
|
|
input := testStringInput + "m"
|
|
|
|
arrayOfStrings := SliceString(input, 4)
|
|
|
|
assert.Equal(t, len(arrayOfStrings), 4)
|
|
assert.Equal(t, "abcd", arrayOfStrings[0])
|
|
assert.Equal(t, "efgh", arrayOfStrings[1])
|
|
assert.Equal(t, "ijkl", arrayOfStrings[2])
|
|
assert.Equal(t, "m", arrayOfStrings[3])
|
|
}
|
|
|
|
func TestShouldFindSliceDifferencesDelta(t *testing.T) {
|
|
before := []string{"abc", "onetwothree"}
|
|
after := []string{"abc", "xyz"}
|
|
|
|
added, removed := StringSlicesDelta(before, after)
|
|
|
|
require.Len(t, added, 1)
|
|
require.Len(t, removed, 1)
|
|
assert.Equal(t, "onetwothree", removed[0])
|
|
assert.Equal(t, "xyz", added[0])
|
|
}
|
|
|
|
func TestShouldNotFindSliceDifferencesDelta(t *testing.T) {
|
|
before := []string{"abc", "onetwothree"}
|
|
after := []string{"abc", "onetwothree"}
|
|
|
|
added, removed := StringSlicesDelta(before, after)
|
|
|
|
require.Len(t, added, 0)
|
|
require.Len(t, removed, 0)
|
|
}
|
|
|
|
func TestShouldFindSliceDifferences(t *testing.T) {
|
|
a := []string{"abc", "onetwothree"}
|
|
b := []string{"abc", "xyz"}
|
|
|
|
assert.True(t, IsStringSlicesDifferent(a, b))
|
|
assert.True(t, IsStringSlicesDifferentFold(a, b))
|
|
|
|
c := []string{"Abc", "xyz"}
|
|
|
|
assert.True(t, IsStringSlicesDifferent(b, c))
|
|
assert.False(t, IsStringSlicesDifferentFold(b, c))
|
|
}
|
|
|
|
func TestShouldNotFindSliceDifferences(t *testing.T) {
|
|
a := []string{"abc", "onetwothree"}
|
|
b := []string{"abc", "onetwothree"}
|
|
|
|
assert.False(t, IsStringSlicesDifferent(a, b))
|
|
assert.False(t, IsStringSlicesDifferentFold(a, b))
|
|
}
|
|
|
|
func TestShouldFindSliceDifferenceWhenDifferentLength(t *testing.T) {
|
|
a := []string{"abc", "onetwothree"}
|
|
b := []string{"abc", "onetwothree", "more"}
|
|
|
|
assert.True(t, IsStringSlicesDifferent(a, b))
|
|
assert.True(t, IsStringSlicesDifferentFold(a, b))
|
|
}
|
|
|
|
func TestShouldFindStringInSliceContains(t *testing.T) {
|
|
a := "abc"
|
|
slice := []string{"abc", "onetwothree"}
|
|
|
|
assert.True(t, IsStringInSliceContains(a, slice))
|
|
}
|
|
|
|
func TestShouldNotFindStringInSliceContains(t *testing.T) {
|
|
a := "xyz"
|
|
slice := []string{"abc", "onetwothree"}
|
|
|
|
assert.False(t, IsStringInSliceContains(a, slice))
|
|
}
|
|
|
|
func TestShouldFindStringInSliceFold(t *testing.T) {
|
|
a := "xYz"
|
|
b := "AbC"
|
|
slice := []string{"XYz", "abc"}
|
|
|
|
assert.True(t, IsStringInSliceFold(a, slice))
|
|
assert.True(t, IsStringInSliceFold(b, slice))
|
|
}
|
|
|
|
func TestShouldNotFindStringInSliceFold(t *testing.T) {
|
|
a := "xyZ"
|
|
b := "ABc"
|
|
slice := []string{"cba", "zyx"}
|
|
|
|
assert.False(t, IsStringInSliceFold(a, slice))
|
|
assert.False(t, IsStringInSliceFold(b, slice))
|
|
}
|
|
|
|
func TestIsStringSliceContainsAll(t *testing.T) {
|
|
needles := []string{"abc", "123", "xyz"}
|
|
haystackOne := []string{"abc", "tvu", "123", "456", "xyz"}
|
|
haystackTwo := []string{"tvu", "123", "456", "xyz"}
|
|
|
|
assert.True(t, IsStringSliceContainsAll(needles, haystackOne))
|
|
assert.False(t, IsStringSliceContainsAll(needles, haystackTwo))
|
|
}
|
|
|
|
func TestIsStringSliceContainsAny(t *testing.T) {
|
|
needles := []string{"abc", "123", "xyz"}
|
|
haystackOne := []string{"tvu", "456", "hij"}
|
|
haystackTwo := []string{"tvu", "123", "456", "xyz"}
|
|
|
|
assert.False(t, IsStringSliceContainsAny(needles, haystackOne))
|
|
assert.True(t, IsStringSliceContainsAny(needles, haystackTwo))
|
|
}
|
|
|
|
func TestStringSliceURLConversionFuncs(t *testing.T) {
|
|
urls := URLsFromStringSlice([]string{"https://google.com", "abc", "%*()@#$J(@*#$J@#($H"})
|
|
|
|
require.Len(t, urls, 2)
|
|
assert.Equal(t, "https://google.com", urls[0].String())
|
|
assert.Equal(t, "abc", urls[1].String())
|
|
|
|
strs := StringSliceFromURLs(urls)
|
|
|
|
require.Len(t, strs, 2)
|
|
assert.Equal(t, "https://google.com", strs[0])
|
|
assert.Equal(t, "abc", strs[1])
|
|
}
|
|
|
|
func TestOriginFromURL(t *testing.T) {
|
|
google, err := url.Parse("https://google.com/abc?a=123#five")
|
|
assert.NoError(t, err)
|
|
|
|
origin := OriginFromURL(google)
|
|
assert.Equal(t, "https://google.com", origin.String())
|
|
}
|
|
|
|
func TestJoinAndCanonicalizeHeaders(t *testing.T) {
|
|
result := JoinAndCanonicalizeHeaders([]byte(", "), "x-example-ONE", "X-EGG-Two")
|
|
|
|
assert.Equal(t, []byte("X-Example-One, X-Egg-Two"), result)
|
|
}
|
|
|
|
func TestBuildStringFuncsMissingTests(t *testing.T) {
|
|
assert.Equal(t, "", StringJoinBuild(".", ":", "'", nil))
|
|
assert.Equal(t, "'abc', '123'", StringJoinComma("", []string{"abc", "123"}))
|
|
}
|
|
|
|
func TestStringJoinOr(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
items []string
|
|
expected string
|
|
}{
|
|
{"Multiple items", []string{"apple", "banana", "cherry"}, "'apple', 'banana', or 'cherry'"},
|
|
{"Single item", []string{"apple"}, "'apple'"},
|
|
{"Empty slice", []string{}, ""},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
result := StringJoinOr(test.items)
|
|
assert.Equal(t, test.expected, result)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestStringJoinAnd(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
items []string
|
|
expected string
|
|
}{
|
|
{"Multiple items", []string{"apple", "banana", "cherry"}, "'apple', 'banana', and 'cherry'"},
|
|
{"Single item", []string{"apple"}, "'apple'"},
|
|
{"Empty slice", []string{}, ""},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
result := StringJoinAnd(test.items)
|
|
assert.Equal(t, test.expected, result)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestStringJoinComma(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
word string
|
|
items []string
|
|
expected string
|
|
}{
|
|
{"Multiple items with 'or'", "or", []string{"apple", "banana", "cherry"}, "'apple', 'banana', or 'cherry'"},
|
|
{"Multiple items with 'and'", "and", []string{"apple", "banana", "cherry"}, "'apple', 'banana', and 'cherry'"},
|
|
{"Single item", "", []string{"apple"}, "'apple'"},
|
|
{"Empty slice", "", []string{}, ""},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
result := StringJoinComma(test.word, test.items)
|
|
assert.Equal(t, test.expected, result)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestStringJoinBuild(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
sep string
|
|
sepFinal string
|
|
quote string
|
|
items []string
|
|
expected string
|
|
}{
|
|
{"Multiple items with comma", ",", "and", "'", []string{"apple", "banana", "cherry"}, "'apple', 'banana', and 'cherry'"},
|
|
{"Multiple items with semicolon", ";", "or", "\"", []string{"apple", "banana", "cherry"}, "\"apple\"; \"banana\"; or \"cherry\""},
|
|
{"Single item", ",", "", "'", []string{"apple"}, "'apple'"},
|
|
{"Empty slice", ",", "and", "'", []string{}, ""},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
result := StringJoinBuild(test.sep, test.sepFinal, test.quote, test.items)
|
|
assert.Equal(t, test.expected, result)
|
|
})
|
|
}
|
|
}
|