diff options
Diffstat (limited to 'modules/validation')
-rw-r--r-- | modules/validation/binding_test.go | 2 | ||||
-rw-r--r-- | modules/validation/glob_pattern_test.go | 56 | ||||
-rw-r--r-- | modules/validation/helpers.go | 35 | ||||
-rw-r--r-- | modules/validation/helpers_test.go | 5 | ||||
-rw-r--r-- | modules/validation/refname_test.go | 419 | ||||
-rw-r--r-- | modules/validation/regex_pattern_test.go | 56 | ||||
-rw-r--r-- | modules/validation/validurl_test.go | 158 | ||||
-rw-r--r-- | modules/validation/validurllist_test.go | 238 |
8 files changed, 487 insertions, 482 deletions
diff --git a/modules/validation/binding_test.go b/modules/validation/binding_test.go index 28d0f57b5c..0cd328f312 100644 --- a/modules/validation/binding_test.go +++ b/modules/validation/binding_test.go @@ -47,7 +47,7 @@ func performValidationTest(t *testing.T, testCase validationTestCase) { assert.Equal(t, testCase.expectedErrors, actual) }) - req, err := http.NewRequest("POST", testRoute, nil) + req, err := http.NewRequest(http.MethodPost, testRoute, nil) if err != nil { panic(err) } diff --git a/modules/validation/glob_pattern_test.go b/modules/validation/glob_pattern_test.go index 1bf622e61d..7f3e609acf 100644 --- a/modules/validation/glob_pattern_test.go +++ b/modules/validation/glob_pattern_test.go @@ -19,39 +19,39 @@ func getGlobPatternErrorString(pattern string) string { return "" } -var globValidationTestCases = []validationTestCase{ - { - description: "Empty glob pattern", - data: TestForm{ - GlobPattern: "", - }, - expectedErrors: binding.Errors{}, - }, - { - description: "Valid glob", - data: TestForm{ - GlobPattern: "{master,release*}", - }, - expectedErrors: binding.Errors{}, - }, +func Test_GlobPatternValidation(t *testing.T) { + AddBindingRules() - { - description: "Invalid glob", - data: TestForm{ - GlobPattern: "[a-", + globValidationTestCases := []validationTestCase{ + { + description: "Empty glob pattern", + data: TestForm{ + GlobPattern: "", + }, + expectedErrors: binding.Errors{}, }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"GlobPattern"}, - Classification: ErrGlobPattern, - Message: getGlobPatternErrorString("[a-"), + { + description: "Valid glob", + data: TestForm{ + GlobPattern: "{master,release*}", }, + expectedErrors: binding.Errors{}, }, - }, -} -func Test_GlobPatternValidation(t *testing.T) { - AddBindingRules() + { + description: "Invalid glob", + data: TestForm{ + GlobPattern: "[a-", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"GlobPattern"}, + Classification: ErrGlobPattern, + Message: getGlobPatternErrorString("[a-"), + }, + }, + }, + } for _, testCase := range globValidationTestCases { t.Run(testCase.description, func(t *testing.T) { diff --git a/modules/validation/helpers.go b/modules/validation/helpers.go index f6e00f3887..ba383ba195 100644 --- a/modules/validation/helpers.go +++ b/modules/validation/helpers.go @@ -7,14 +7,28 @@ import ( "net" "net/url" "regexp" + "slices" "strings" + "sync" "code.gitea.io/gitea/modules/setting" "github.com/gobwas/glob" ) -var externalTrackerRegex = regexp.MustCompile(`({?)(?:user|repo|index)+?(}?)`) +type globalVarsStruct struct { + externalTrackerRegex *regexp.Regexp + validUsernamePattern *regexp.Regexp + invalidUsernamePattern *regexp.Regexp +} + +var globalVars = sync.OnceValue(func() *globalVarsStruct { + return &globalVarsStruct{ + externalTrackerRegex: regexp.MustCompile(`({?)(?:user|repo|index)+?(}?)`), + validUsernamePattern: regexp.MustCompile(`^[\da-zA-Z][-.\w]*$`), + invalidUsernamePattern: regexp.MustCompile(`[-._]{2,}|[-._]$`), // No consecutive or trailing non-alphanumeric chars + } +}) func isLoopbackIP(ip string) bool { return net.ParseIP(ip).IsLoopback() @@ -42,12 +56,7 @@ func IsValidSiteURL(uri string) bool { return false } - for _, scheme := range setting.Service.ValidSiteURLSchemes { - if scheme == u.Scheme { - return true - } - } - return false + return slices.Contains(setting.Service.ValidSiteURLSchemes, u.Scheme) } // IsEmailDomainListed checks whether the domain of an email address @@ -105,9 +114,9 @@ func IsValidExternalTrackerURLFormat(uri string) bool { if !IsValidExternalURL(uri) { return false } - + vars := globalVars() // check for typoed variables like /{index/ or /[repo} - for _, match := range externalTrackerRegex.FindAllStringSubmatch(uri, -1) { + for _, match := range vars.externalTrackerRegex.FindAllStringSubmatch(uri, -1) { if (match[1] == "{" || match[2] == "}") && (match[1] != "{" || match[2] != "}") { return false } @@ -116,14 +125,10 @@ func IsValidExternalTrackerURLFormat(uri string) bool { return true } -var ( - validUsernamePattern = regexp.MustCompile(`^[\da-zA-Z][-.\w]*$`) - invalidUsernamePattern = regexp.MustCompile(`[-._]{2,}|[-._]$`) // No consecutive or trailing non-alphanumeric chars -) - // IsValidUsername checks if username is valid func IsValidUsername(name string) bool { // It is difficult to find a single pattern that is both readable and effective, // but it's easier to use positive and negative checks. - return validUsernamePattern.MatchString(name) && !invalidUsernamePattern.MatchString(name) + vars := globalVars() + return vars.validUsernamePattern.MatchString(name) && !vars.invalidUsernamePattern.MatchString(name) } diff --git a/modules/validation/helpers_test.go b/modules/validation/helpers_test.go index 52f383f698..6a982965f6 100644 --- a/modules/validation/helpers_test.go +++ b/modules/validation/helpers_test.go @@ -7,6 +7,7 @@ import ( "testing" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/test" "github.com/stretchr/testify/assert" ) @@ -47,7 +48,7 @@ func Test_IsValidURL(t *testing.T) { } func Test_IsValidExternalURL(t *testing.T) { - setting.AppURL = "https://try.gitea.io/" + defer test.MockVariableValue(&setting.AppURL, "https://try.gitea.io/")() cases := []struct { description string @@ -89,7 +90,7 @@ func Test_IsValidExternalURL(t *testing.T) { } func Test_IsValidExternalTrackerURLFormat(t *testing.T) { - setting.AppURL = "https://try.gitea.io/" + defer test.MockVariableValue(&setting.AppURL, "https://try.gitea.io/")() cases := []struct { description string diff --git a/modules/validation/refname_test.go b/modules/validation/refname_test.go index 3af7387c47..93703761cf 100644 --- a/modules/validation/refname_test.go +++ b/modules/validation/refname_test.go @@ -9,253 +9,252 @@ import ( "gitea.com/go-chi/binding" ) -var gitRefNameValidationTestCases = []validationTestCase{ - { - description: "Reference name contains only characters", - data: TestForm{ - BranchName: "test", - }, - expectedErrors: binding.Errors{}, - }, - { - description: "Reference name contains single slash", - data: TestForm{ - BranchName: "feature/test", - }, - expectedErrors: binding.Errors{}, - }, - { - description: "Reference name has allowed special characters", - data: TestForm{ - BranchName: "debian/1%1.6.0-2", - }, - expectedErrors: binding.Errors{}, - }, - { - description: "Reference name contains backslash", - data: TestForm{ - BranchName: "feature\\test", - }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"BranchName"}, - Classification: ErrGitRefName, - Message: "GitRefName", +func Test_GitRefNameValidation(t *testing.T) { + AddBindingRules() + gitRefNameValidationTestCases := []validationTestCase{ + { + description: "Reference name contains only characters", + data: TestForm{ + BranchName: "test", }, + expectedErrors: binding.Errors{}, }, - }, - { - description: "Reference name starts with dot", - data: TestForm{ - BranchName: ".test", - }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"BranchName"}, - Classification: ErrGitRefName, - Message: "GitRefName", + { + description: "Reference name contains single slash", + data: TestForm{ + BranchName: "feature/test", }, + expectedErrors: binding.Errors{}, }, - }, - { - description: "Reference name ends with dot", - data: TestForm{ - BranchName: "test.", - }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"BranchName"}, - Classification: ErrGitRefName, - Message: "GitRefName", + { + description: "Reference name has allowed special characters", + data: TestForm{ + BranchName: "debian/1%1.6.0-2", }, + expectedErrors: binding.Errors{}, }, - }, - { - description: "Reference name starts with slash", - data: TestForm{ - BranchName: "/test", - }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"BranchName"}, - Classification: ErrGitRefName, - Message: "GitRefName", + { + description: "Reference name contains backslash", + data: TestForm{ + BranchName: "feature\\test", }, - }, - }, - { - description: "Reference name ends with slash", - data: TestForm{ - BranchName: "test/", - }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"BranchName"}, - Classification: ErrGitRefName, - Message: "GitRefName", + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"BranchName"}, + Classification: ErrGitRefName, + Message: "GitRefName", + }, }, }, - }, - { - description: "Reference name ends with .lock", - data: TestForm{ - BranchName: "test.lock", - }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"BranchName"}, - Classification: ErrGitRefName, - Message: "GitRefName", + { + description: "Reference name starts with dot", + data: TestForm{ + BranchName: ".test", }, - }, - }, - { - description: "Reference name contains multiple consecutive dots", - data: TestForm{ - BranchName: "te..st", - }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"BranchName"}, - Classification: ErrGitRefName, - Message: "GitRefName", + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"BranchName"}, + Classification: ErrGitRefName, + Message: "GitRefName", + }, }, }, - }, - { - description: "Reference name contains multiple consecutive slashes", - data: TestForm{ - BranchName: "te//st", - }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"BranchName"}, - Classification: ErrGitRefName, - Message: "GitRefName", + { + description: "Reference name ends with dot", + data: TestForm{ + BranchName: "test.", }, - }, - }, - { - description: "Reference name is single @", - data: TestForm{ - BranchName: "@", - }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"BranchName"}, - Classification: ErrGitRefName, - Message: "GitRefName", + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"BranchName"}, + Classification: ErrGitRefName, + Message: "GitRefName", + }, }, }, - }, - { - description: "Reference name has @{", - data: TestForm{ - BranchName: "branch@{", - }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"BranchName"}, - Classification: ErrGitRefName, - Message: "GitRefName", + { + description: "Reference name starts with slash", + data: TestForm{ + BranchName: "/test", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"BranchName"}, + Classification: ErrGitRefName, + Message: "GitRefName", + }, }, }, - }, - { - description: "Reference name has unallowed special character ~", - data: TestForm{ - BranchName: "~debian/1%1.6.0-2", - }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"BranchName"}, - Classification: ErrGitRefName, - Message: "GitRefName", + { + description: "Reference name ends with slash", + data: TestForm{ + BranchName: "test/", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"BranchName"}, + Classification: ErrGitRefName, + Message: "GitRefName", + }, }, }, - }, - { - description: "Reference name has unallowed special character *", - data: TestForm{ - BranchName: "*debian/1%1.6.0-2", + { + description: "Reference name ends with .lock", + data: TestForm{ + BranchName: "test.lock", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"BranchName"}, + Classification: ErrGitRefName, + Message: "GitRefName", + }, + }, }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"BranchName"}, - Classification: ErrGitRefName, - Message: "GitRefName", + { + description: "Reference name contains multiple consecutive dots", + data: TestForm{ + BranchName: "te..st", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"BranchName"}, + Classification: ErrGitRefName, + Message: "GitRefName", + }, }, }, - }, - { - description: "Reference name has unallowed special character ?", - data: TestForm{ - BranchName: "?debian/1%1.6.0-2", + { + description: "Reference name contains multiple consecutive slashes", + data: TestForm{ + BranchName: "te//st", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"BranchName"}, + Classification: ErrGitRefName, + Message: "GitRefName", + }, + }, }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"BranchName"}, - Classification: ErrGitRefName, - Message: "GitRefName", + { + description: "Reference name is single @", + data: TestForm{ + BranchName: "@", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"BranchName"}, + Classification: ErrGitRefName, + Message: "GitRefName", + }, }, }, - }, - { - description: "Reference name has unallowed special character ^", - data: TestForm{ - BranchName: "^debian/1%1.6.0-2", + { + description: "Reference name has @{", + data: TestForm{ + BranchName: "branch@{", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"BranchName"}, + Classification: ErrGitRefName, + Message: "GitRefName", + }, + }, }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"BranchName"}, - Classification: ErrGitRefName, - Message: "GitRefName", + { + description: "Reference name has unallowed special character ~", + data: TestForm{ + BranchName: "~debian/1%1.6.0-2", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"BranchName"}, + Classification: ErrGitRefName, + Message: "GitRefName", + }, }, }, - }, - { - description: "Reference name has unallowed special character :", - data: TestForm{ - BranchName: "debian:jessie", + { + description: "Reference name has unallowed special character *", + data: TestForm{ + BranchName: "*debian/1%1.6.0-2", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"BranchName"}, + Classification: ErrGitRefName, + Message: "GitRefName", + }, + }, }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"BranchName"}, - Classification: ErrGitRefName, - Message: "GitRefName", + { + description: "Reference name has unallowed special character ?", + data: TestForm{ + BranchName: "?debian/1%1.6.0-2", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"BranchName"}, + Classification: ErrGitRefName, + Message: "GitRefName", + }, }, }, - }, - { - description: "Reference name has unallowed special character (whitespace)", - data: TestForm{ - BranchName: "debian jessie", + { + description: "Reference name has unallowed special character ^", + data: TestForm{ + BranchName: "^debian/1%1.6.0-2", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"BranchName"}, + Classification: ErrGitRefName, + Message: "GitRefName", + }, + }, }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"BranchName"}, - Classification: ErrGitRefName, - Message: "GitRefName", + { + description: "Reference name has unallowed special character :", + data: TestForm{ + BranchName: "debian:jessie", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"BranchName"}, + Classification: ErrGitRefName, + Message: "GitRefName", + }, }, }, - }, - { - description: "Reference name has unallowed special character [", - data: TestForm{ - BranchName: "debian[jessie", + { + description: "Reference name has unallowed special character (whitespace)", + data: TestForm{ + BranchName: "debian jessie", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"BranchName"}, + Classification: ErrGitRefName, + Message: "GitRefName", + }, + }, }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"BranchName"}, - Classification: ErrGitRefName, - Message: "GitRefName", + { + description: "Reference name has unallowed special character [", + data: TestForm{ + BranchName: "debian[jessie", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"BranchName"}, + Classification: ErrGitRefName, + Message: "GitRefName", + }, }, }, - }, -} - -func Test_GitRefNameValidation(t *testing.T) { - AddBindingRules() + } for _, testCase := range gitRefNameValidationTestCases { t.Run(testCase.description, func(t *testing.T) { diff --git a/modules/validation/regex_pattern_test.go b/modules/validation/regex_pattern_test.go index efcb276734..80790a23b1 100644 --- a/modules/validation/regex_pattern_test.go +++ b/modules/validation/regex_pattern_test.go @@ -17,39 +17,39 @@ func getRegexPatternErrorString(pattern string) string { return "" } -var regexValidationTestCases = []validationTestCase{ - { - description: "Empty regex pattern", - data: TestForm{ - RegexPattern: "", - }, - expectedErrors: binding.Errors{}, - }, - { - description: "Valid regex", - data: TestForm{ - RegexPattern: `(\d{1,3})+`, - }, - expectedErrors: binding.Errors{}, - }, +func Test_RegexPatternValidation(t *testing.T) { + AddBindingRules() - { - description: "Invalid regex", - data: TestForm{ - RegexPattern: "[a-", + regexValidationTestCases := []validationTestCase{ + { + description: "Empty regex pattern", + data: TestForm{ + RegexPattern: "", + }, + expectedErrors: binding.Errors{}, }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"RegexPattern"}, - Classification: ErrRegexPattern, - Message: getRegexPatternErrorString("[a-"), + { + description: "Valid regex", + data: TestForm{ + RegexPattern: `(\d{1,3})+`, }, + expectedErrors: binding.Errors{}, }, - }, -} -func Test_RegexPatternValidation(t *testing.T) { - AddBindingRules() + { + description: "Invalid regex", + data: TestForm{ + RegexPattern: "[a-", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"RegexPattern"}, + Classification: ErrRegexPattern, + Message: getRegexPatternErrorString("[a-"), + }, + }, + }, + } for _, testCase := range regexValidationTestCases { t.Run(testCase.description, func(t *testing.T) { diff --git a/modules/validation/validurl_test.go b/modules/validation/validurl_test.go index 39f7fa5d65..ce4898b271 100644 --- a/modules/validation/validurl_test.go +++ b/modules/validation/validurl_test.go @@ -9,98 +9,98 @@ import ( "gitea.com/go-chi/binding" ) -var urlValidationTestCases = []validationTestCase{ - { - description: "Empty URL", - data: TestForm{ - URL: "", - }, - expectedErrors: binding.Errors{}, - }, - { - description: "URL without port", - data: TestForm{ - URL: "http://test.lan/", - }, - expectedErrors: binding.Errors{}, - }, - { - description: "URL with port", - data: TestForm{ - URL: "http://test.lan:3000/", - }, - expectedErrors: binding.Errors{}, - }, - { - description: "URL with IPv6 address without port", - data: TestForm{ - URL: "http://[::1]/", - }, - expectedErrors: binding.Errors{}, - }, - { - description: "URL with IPv6 address with port", - data: TestForm{ - URL: "http://[::1]:3000/", +func Test_ValidURLValidation(t *testing.T) { + AddBindingRules() + + urlValidationTestCases := []validationTestCase{ + { + description: "Empty URL", + data: TestForm{ + URL: "", + }, + expectedErrors: binding.Errors{}, }, - expectedErrors: binding.Errors{}, - }, - { - description: "Invalid URL", - data: TestForm{ - URL: "http//test.lan/", + { + description: "URL without port", + data: TestForm{ + URL: "http://test.lan/", + }, + expectedErrors: binding.Errors{}, }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"URL"}, - Classification: binding.ERR_URL, - Message: "Url", + { + description: "URL with port", + data: TestForm{ + URL: "http://test.lan:3000/", }, + expectedErrors: binding.Errors{}, }, - }, - { - description: "Invalid schema", - data: TestForm{ - URL: "ftp://test.lan/", + { + description: "URL with IPv6 address without port", + data: TestForm{ + URL: "http://[::1]/", + }, + expectedErrors: binding.Errors{}, }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"URL"}, - Classification: binding.ERR_URL, - Message: "Url", + { + description: "URL with IPv6 address with port", + data: TestForm{ + URL: "http://[::1]:3000/", }, + expectedErrors: binding.Errors{}, }, - }, - { - description: "Invalid port", - data: TestForm{ - URL: "http://test.lan:3x4/", + { + description: "Invalid URL", + data: TestForm{ + URL: "http//test.lan/", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"URL"}, + Classification: binding.ERR_URL, + Message: "Url", + }, + }, }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"URL"}, - Classification: binding.ERR_URL, - Message: "Url", + { + description: "Invalid schema", + data: TestForm{ + URL: "ftp://test.lan/", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"URL"}, + Classification: binding.ERR_URL, + Message: "Url", + }, }, }, - }, - { - description: "Invalid port with IPv6 address", - data: TestForm{ - URL: "http://[::1]:3x4/", + { + description: "Invalid port", + data: TestForm{ + URL: "http://test.lan:3x4/", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"URL"}, + Classification: binding.ERR_URL, + Message: "Url", + }, + }, }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"URL"}, - Classification: binding.ERR_URL, - Message: "Url", + { + description: "Invalid port with IPv6 address", + data: TestForm{ + URL: "http://[::1]:3x4/", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"URL"}, + Classification: binding.ERR_URL, + Message: "Url", + }, }, }, - }, -} - -func Test_ValidURLValidation(t *testing.T) { - AddBindingRules() + } for _, testCase := range urlValidationTestCases { t.Run(testCase.description, func(t *testing.T) { diff --git a/modules/validation/validurllist_test.go b/modules/validation/validurllist_test.go index c6f862a962..cccc570a1a 100644 --- a/modules/validation/validurllist_test.go +++ b/modules/validation/validurllist_test.go @@ -9,145 +9,145 @@ import ( "gitea.com/go-chi/binding" ) -// This is a copy of all the URL tests cases, plus additional ones to -// account for multiple URLs -var urlListValidationTestCases = []validationTestCase{ - { - description: "Empty URL", - data: TestForm{ - URLs: "", - }, - expectedErrors: binding.Errors{}, - }, - { - description: "URL without port", - data: TestForm{ - URLs: "http://test.lan/", - }, - expectedErrors: binding.Errors{}, - }, - { - description: "URL with port", - data: TestForm{ - URLs: "http://test.lan:3000/", - }, - expectedErrors: binding.Errors{}, - }, - { - description: "URL with IPv6 address without port", - data: TestForm{ - URLs: "http://[::1]/", - }, - expectedErrors: binding.Errors{}, - }, - { - description: "URL with IPv6 address with port", - data: TestForm{ - URLs: "http://[::1]:3000/", - }, - expectedErrors: binding.Errors{}, - }, - { - description: "Invalid URL", - data: TestForm{ - URLs: "http//test.lan/", - }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"URLs"}, - Classification: binding.ERR_URL, - Message: "http//test.lan/", +func Test_ValidURLListValidation(t *testing.T) { + AddBindingRules() + + // This is a copy of all the URL tests cases, plus additional ones to + // account for multiple URLs + urlListValidationTestCases := []validationTestCase{ + { + description: "Empty URL", + data: TestForm{ + URLs: "", }, + expectedErrors: binding.Errors{}, }, - }, - { - description: "Invalid schema", - data: TestForm{ - URLs: "ftp://test.lan/", + { + description: "URL without port", + data: TestForm{ + URLs: "http://test.lan/", + }, + expectedErrors: binding.Errors{}, }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"URLs"}, - Classification: binding.ERR_URL, - Message: "ftp://test.lan/", + { + description: "URL with port", + data: TestForm{ + URLs: "http://test.lan:3000/", }, + expectedErrors: binding.Errors{}, }, - }, - { - description: "Invalid port", - data: TestForm{ - URLs: "http://test.lan:3x4/", + { + description: "URL with IPv6 address without port", + data: TestForm{ + URLs: "http://[::1]/", + }, + expectedErrors: binding.Errors{}, }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"URLs"}, - Classification: binding.ERR_URL, - Message: "http://test.lan:3x4/", + { + description: "URL with IPv6 address with port", + data: TestForm{ + URLs: "http://[::1]:3000/", }, + expectedErrors: binding.Errors{}, }, - }, - { - description: "Invalid port with IPv6 address", - data: TestForm{ - URLs: "http://[::1]:3x4/", + { + description: "Invalid URL", + data: TestForm{ + URLs: "http//test.lan/", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"URLs"}, + Classification: binding.ERR_URL, + Message: "http//test.lan/", + }, + }, }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"URLs"}, - Classification: binding.ERR_URL, - Message: "http://[::1]:3x4/", + { + description: "Invalid schema", + data: TestForm{ + URLs: "ftp://test.lan/", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"URLs"}, + Classification: binding.ERR_URL, + Message: "ftp://test.lan/", + }, }, }, - }, - { - description: "Multi URLs", - data: TestForm{ - URLs: "http://test.lan:3000/\nhttp://test.local/", + { + description: "Invalid port", + data: TestForm{ + URLs: "http://test.lan:3x4/", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"URLs"}, + Classification: binding.ERR_URL, + Message: "http://test.lan:3x4/", + }, + }, }, - expectedErrors: binding.Errors{}, - }, - { - description: "Multi URLs with newline", - data: TestForm{ - URLs: "http://test.lan:3000/\nhttp://test.local/\n", + { + description: "Invalid port with IPv6 address", + data: TestForm{ + URLs: "http://[::1]:3x4/", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"URLs"}, + Classification: binding.ERR_URL, + Message: "http://[::1]:3x4/", + }, + }, }, - expectedErrors: binding.Errors{}, - }, - { - description: "List with invalid entry", - data: TestForm{ - URLs: "http://test.lan:3000/\nhttp://[::1]:3x4/", + { + description: "Multi URLs", + data: TestForm{ + URLs: "http://test.lan:3000/\nhttp://test.local/", + }, + expectedErrors: binding.Errors{}, }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"URLs"}, - Classification: binding.ERR_URL, - Message: "http://[::1]:3x4/", + { + description: "Multi URLs with newline", + data: TestForm{ + URLs: "http://test.lan:3000/\nhttp://test.local/\n", }, + expectedErrors: binding.Errors{}, }, - }, - { - description: "List with two invalid entries", - data: TestForm{ - URLs: "ftp://test.lan:3000/\nhttp://[::1]:3x4/\n", + { + description: "List with invalid entry", + data: TestForm{ + URLs: "http://test.lan:3000/\nhttp://[::1]:3x4/", + }, + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"URLs"}, + Classification: binding.ERR_URL, + Message: "http://[::1]:3x4/", + }, + }, }, - expectedErrors: binding.Errors{ - binding.Error{ - FieldNames: []string{"URLs"}, - Classification: binding.ERR_URL, - Message: "ftp://test.lan:3000/", + { + description: "List with two invalid entries", + data: TestForm{ + URLs: "ftp://test.lan:3000/\nhttp://[::1]:3x4/\n", }, - binding.Error{ - FieldNames: []string{"URLs"}, - Classification: binding.ERR_URL, - Message: "http://[::1]:3x4/", + expectedErrors: binding.Errors{ + binding.Error{ + FieldNames: []string{"URLs"}, + Classification: binding.ERR_URL, + Message: "ftp://test.lan:3000/", + }, + binding.Error{ + FieldNames: []string{"URLs"}, + Classification: binding.ERR_URL, + Message: "http://[::1]:3x4/", + }, }, }, - }, -} - -func Test_ValidURLListValidation(t *testing.T) { - AddBindingRules() + } for _, testCase := range urlListValidationTestCases { t.Run(testCase.description, func(t *testing.T) { |