[AI assisted] MM-62927: add comprehensive whitespace validation tests for FileSettings paths (#31087)

https://mattermost.atlassian.net/browse/MM-62927

```release-note
NONE
```
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
Agniva De Sarker
2025-05-27 10:03:12 +05:30
коммит произвёл GitHub
родитель 649b939e6a
Коммит 3d5cf06237
3 изменённых файлов: 109 добавлений и 0 удалений

Просмотреть файл

@@ -9152,6 +9152,10 @@
"id": "model.config.is_valid.directory.app_error",
"translation": "Invalid Local Storage Directory. Must be a non-empty string."
},
{
"id": "model.config.is_valid.directory_whitespace.app_error",
"translation": "Leading or trailing whitespace detected for {{.Setting}}. Found \"{{.Value}}\"."
},
{
"id": "model.config.is_valid.display.custom_url_schemes.app_error",
"translation": "The custom URL scheme {{.Scheme}} is invalid. Custom URL schemes must start with a letter and contain only letters, numbers, plus (+), period (.) and hyphen (-)."

Просмотреть файл

@@ -4129,6 +4129,11 @@ func (s *FileSettings) isValid() *AppError {
return NewAppError("Config.IsValid", "model.config.is_valid.directory.app_error", nil, "", http.StatusBadRequest)
}
// Check for leading/trailing whitespace in directory path
if strings.TrimSpace(*s.Directory) != *s.Directory {
return NewAppError("Config.IsValid", "model.config.is_valid.directory_whitespace.app_error", map[string]any{"Setting": "FileSettings.Directory", "Value": *s.Directory}, "", http.StatusBadRequest)
}
if *s.MaxImageDecoderConcurrency < -1 || *s.MaxImageDecoderConcurrency == 0 {
return NewAppError("Config.IsValid", "model.config.is_valid.image_decoder_concurrency.app_error", map[string]any{"Value": *s.MaxImageDecoderConcurrency}, "", http.StatusBadRequest)
}
@@ -4141,10 +4146,22 @@ func (s *FileSettings) isValid() *AppError {
return NewAppError("Config.IsValid", "model.config.is_valid.storage_class.app_error", map[string]any{"Value": *s.AmazonS3StorageClass}, "", http.StatusBadRequest)
}
if strings.TrimSpace(*s.AmazonS3PathPrefix) != *s.AmazonS3PathPrefix {
return NewAppError("Config.IsValid", "model.config.is_valid.directory_whitespace.app_error", map[string]any{"Setting": "FileSettings.AmazonS3PathPrefix", "Value": *s.AmazonS3PathPrefix}, "", http.StatusBadRequest)
}
if *s.ExportAmazonS3StorageClass != "" && !slices.Contains([]string{StorageClassStandard, StorageClassReducedRedundancy, StorageClassStandardIA, StorageClassOnezoneIA, StorageClassIntelligentTiering, StorageClassGlacier, StorageClassDeepArchive, StorageClassOutposts, StorageClassGlacierIR, StorageClassSnow, StorageClassExpressOnezone}, *s.ExportAmazonS3StorageClass) {
return NewAppError("Config.IsValid", "model.config.is_valid.storage_class.app_error", map[string]any{"Value": *s.ExportAmazonS3StorageClass}, "", http.StatusBadRequest)
}
if strings.TrimSpace(*s.ExportAmazonS3PathPrefix) != *s.ExportAmazonS3PathPrefix {
return NewAppError("Config.IsValid", "model.config.is_valid.directory_whitespace.app_error", map[string]any{"Setting": "FileSettings.ExportAmazonS3PathPrefix", "Value": *s.ExportAmazonS3PathPrefix}, "", http.StatusBadRequest)
}
if strings.TrimSpace(*s.ExportDirectory) != *s.ExportDirectory {
return NewAppError("Config.IsValid", "model.config.is_valid.directory_whitespace.app_error", map[string]any{"Setting": "FileSettings.ExportDirectory", "Value": *s.ExportDirectory}, "", http.StatusBadRequest)
}
return nil
}

Просмотреть файл

@@ -207,6 +207,94 @@ func TestConfigDefaultFileSettingsS3SSE(t *testing.T) {
require.False(t, *c1.FileSettings.AmazonS3SSE)
}
func TestFileSettingsDirectoryWhitespaceValidation(t *testing.T) {
// Define Unicode whitespace characters to test
unicodeWhitespaces := []struct {
name string
char string
}{
{"Regular Space", " "},
{"Standard Space (U+0020)", "\u0020"},
{"No-Break Space (U+00A0)", "\u00A0"},
{"En Space (U+2002)", "\u2002"},
}
// Define all FileSettings path fields to test
pathSettings := []struct {
name string
validValue string
configSetter func(*Config, *string)
}{
{
"Directory",
"/path/to/directory",
func(cfg *Config, value *string) { cfg.FileSettings.Directory = value },
},
{
"AmazonS3PathPrefix",
"files/",
func(cfg *Config, value *string) { cfg.FileSettings.AmazonS3PathPrefix = value },
},
{
"ExportAmazonS3PathPrefix",
"exports/",
func(cfg *Config, value *string) { cfg.FileSettings.ExportAmazonS3PathPrefix = value },
},
{
"ExportDirectory",
"/path/to/exports",
func(cfg *Config, value *string) { cfg.FileSettings.ExportDirectory = value },
},
}
// Test valid paths first
for _, setting := range pathSettings {
t.Run(fmt.Sprintf("Valid %s", setting.name), func(t *testing.T) {
cfg := &Config{}
cfg.SetDefaults()
setting.configSetter(cfg, NewPointer(setting.validValue))
err := cfg.FileSettings.isValid()
require.Nil(t, err, "Expected no error but got: %v", err)
})
}
// Test path with space in the middle (should be valid)
t.Run("Directory with space in the middle (valid)", func(t *testing.T) {
cfg := &Config{}
cfg.SetDefaults()
cfg.FileSettings.Directory = NewPointer("/path/to/my directory")
err := cfg.FileSettings.isValid()
require.Nil(t, err, "Expected no error but got: %v", err)
})
// Test all combinations of settings, whitespace characters, and positions
for _, setting := range pathSettings {
for _, ws := range unicodeWhitespaces {
for _, position := range []string{"leading", "trailing"} {
t.Run(fmt.Sprintf("%s with %s %s whitespace", setting.name, position, ws.name), func(t *testing.T) {
cfg := &Config{}
cfg.SetDefaults()
var testValue string
if position == "leading" {
testValue = ws.char + setting.validValue
} else {
testValue = setting.validValue + ws.char
}
setting.configSetter(cfg, NewPointer(testValue))
err := cfg.FileSettings.isValid()
require.NotNil(t, err, "Expected an error but got none")
assert.Equal(t, "model.config.is_valid.directory_whitespace.app_error", err.Id)
})
}
}
}
}
func TestConfigDefaultSignatureAlgorithm(t *testing.T) {
c1 := Config{}
c1.SetDefaults()