Merge branch 'master' into MM-45118_my_top_dms

Этот коммит содержится в:
Mattermod
2022-08-18 20:42:32 +03:00
коммит произвёл GitHub
родитель 582812f1fc 9de6ce5275
Коммит e87a2bbe19
134 изменённых файлов: 2203 добавлений и 2141 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@@ -140,20 +140,21 @@ type PaymentMethod struct {
// Subscription model represents a subscription on the system.
type Subscription struct {
ID string `json:"id"`
CustomerID string `json:"customer_id"`
ProductID string `json:"product_id"`
AddOns []string `json:"add_ons"`
StartAt int64 `json:"start_at"`
EndAt int64 `json:"end_at"`
CreateAt int64 `json:"create_at"`
Seats int `json:"seats"`
Status string `json:"status"`
DNS string `json:"dns"`
IsPaidTier string `json:"is_paid_tier"`
LastInvoice *Invoice `json:"last_invoice"`
IsFreeTrial string `json:"is_free_trial"`
TrialEndAt int64 `json:"trial_end_at"`
ID string `json:"id"`
CustomerID string `json:"customer_id"`
ProductID string `json:"product_id"`
AddOns []string `json:"add_ons"`
StartAt int64 `json:"start_at"`
EndAt int64 `json:"end_at"`
CreateAt int64 `json:"create_at"`
Seats int `json:"seats"`
Status string `json:"status"`
DNS string `json:"dns"`
IsPaidTier string `json:"is_paid_tier"`
LastInvoice *Invoice `json:"last_invoice"`
IsFreeTrial string `json:"is_free_trial"`
TrialEndAt int64 `json:"trial_end_at"`
DelinquentSince *int64 `json:"delinquent_since"`
}
// GetWorkSpaceNameFromDNS returns the work space name. For example from test.mattermost.cloud.com, it returns test

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

@@ -122,7 +122,7 @@ func (o *Command) IsValid() *AppError {
if o.AutocompleteData != nil {
if err := o.AutocompleteData.IsValid(); err != nil {
return NewAppError("Command.IsValid", "model.command.is_valid.autocomplete_data.app_error", nil, err.Error(), http.StatusBadRequest)
return NewAppError("Command.IsValid", "model.command.is_valid.autocomplete_data.app_error", nil, "", http.StatusBadRequest).Wrap(err)
}
}

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

@@ -46,13 +46,13 @@ func TestCommandWebhookIsValid(t *testing.T) {
} {
tmp := h
test.Transform()
err := h.IsValid()
appErr := h.IsValid()
if test.ExpectedError == "" {
assert.Nil(t, err, "hook should be valid")
assert.Nil(t, appErr, "hook should be valid")
} else {
require.NotNil(t, err)
assert.Equal(t, test.ExpectedError, err.Id, "expected "+test.ExpectedError+" error")
require.NotNil(t, appErr)
assert.Equal(t, test.ExpectedError, appErr.Id, "expected "+test.ExpectedError+" error")
}
h = tmp

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

@@ -3078,19 +3078,20 @@ const ConfigAccessTagAnySysConsoleRead = "*_read"
// environment with ExperimentalSettings.RestrictedSystemAdmin set to true.
//
// Example:
// type HairSettings struct {
// // Colour is writeable with either PermissionSysconsoleWriteReporting or PermissionSysconsoleWriteUserManagementGroups.
// // It is readable by PermissionSysconsoleReadReporting and PermissionSysconsoleReadUserManagementGroups permissions.
// // PermissionManageSystem grants read and write access.
// Colour string `access:"reporting,user_management_groups"`
//
// // Length is only readable and writable via PermissionManageSystem.
// Length string
// type HairSettings struct {
// // Colour is writeable with either PermissionSysconsoleWriteReporting or PermissionSysconsoleWriteUserManagementGroups.
// // It is readable by PermissionSysconsoleReadReporting and PermissionSysconsoleReadUserManagementGroups permissions.
// // PermissionManageSystem grants read and write access.
// Colour string `access:"reporting,user_management_groups"`
//
// // Product is only writeable by PermissionManageSystem if ExperimentalSettings.RestrictSystemAdmin is false.
// // PermissionManageSystem can always read the value.
// Product bool `access:write_restrictable`
// }
// // Length is only readable and writable via PermissionManageSystem.
// Length string
//
// // Product is only writeable by PermissionManageSystem if ExperimentalSettings.RestrictSystemAdmin is false.
// // PermissionManageSystem can always read the value.
// Product bool `access:write_restrictable`
// }
type Config struct {
ServiceSettings ServiceSettings
TeamSettings TeamSettings
@@ -3262,72 +3263,72 @@ func (o *Config) IsValid() *AppError {
return NewAppError("Config.IsValid", "model.config.is_valid.allow_cookies_for_subdomains.app_error", nil, "", http.StatusBadRequest)
}
if err := o.TeamSettings.isValid(); err != nil {
return err
if appErr := o.TeamSettings.isValid(); appErr != nil {
return appErr
}
if err := o.SqlSettings.isValid(); err != nil {
return err
if appErr := o.SqlSettings.isValid(); appErr != nil {
return appErr
}
if err := o.FileSettings.isValid(); err != nil {
return err
if appErr := o.FileSettings.isValid(); appErr != nil {
return appErr
}
if err := o.EmailSettings.isValid(); err != nil {
return err
if appErr := o.EmailSettings.isValid(); appErr != nil {
return appErr
}
if err := o.LdapSettings.isValid(); err != nil {
return err
if appErr := o.LdapSettings.isValid(); appErr != nil {
return appErr
}
if err := o.SamlSettings.isValid(); err != nil {
return err
if appErr := o.SamlSettings.isValid(); appErr != nil {
return appErr
}
if *o.PasswordSettings.MinimumLength < PasswordMinimumLength || *o.PasswordSettings.MinimumLength > PasswordMaximumLength {
return NewAppError("Config.IsValid", "model.config.is_valid.password_length.app_error", map[string]any{"MinLength": PasswordMinimumLength, "MaxLength": PasswordMaximumLength}, "", http.StatusBadRequest)
}
if err := o.RateLimitSettings.isValid(); err != nil {
return err
if appErr := o.RateLimitSettings.isValid(); appErr != nil {
return appErr
}
if err := o.ServiceSettings.isValid(); err != nil {
return err
if appErr := o.ServiceSettings.isValid(); appErr != nil {
return appErr
}
if err := o.ElasticsearchSettings.isValid(); err != nil {
return err
if appErr := o.ElasticsearchSettings.isValid(); appErr != nil {
return appErr
}
if err := o.BleveSettings.isValid(); err != nil {
return err
if appErr := o.BleveSettings.isValid(); appErr != nil {
return appErr
}
if err := o.DataRetentionSettings.isValid(); err != nil {
return err
if appErr := o.DataRetentionSettings.isValid(); appErr != nil {
return appErr
}
if err := o.LocalizationSettings.isValid(); err != nil {
return err
if appErr := o.LocalizationSettings.isValid(); appErr != nil {
return appErr
}
if err := o.MessageExportSettings.isValid(); err != nil {
return err
if appErr := o.MessageExportSettings.isValid(); appErr != nil {
return appErr
}
if err := o.DisplaySettings.isValid(); err != nil {
return err
if appErr := o.DisplaySettings.isValid(); appErr != nil {
return appErr
}
if err := o.ImageProxySettings.isValid(); err != nil {
return err
if appErr := o.ImageProxySettings.isValid(); appErr != nil {
return appErr
}
if err := o.ImportSettings.isValid(); err != nil {
return err
if appErr := o.ImportSettings.isValid(); appErr != nil {
return appErr
}
return nil
}
@@ -3500,19 +3501,19 @@ func (s *LdapSettings) isValid() *AppError {
if *s.UserFilter != "" {
if _, err := ldap.CompileFilter(*s.UserFilter); err != nil {
return NewAppError("ValidateFilter", "ent.ldap.validate_filter.app_error", nil, err.Error(), http.StatusBadRequest)
return NewAppError("ValidateFilter", "ent.ldap.validate_filter.app_error", nil, "", http.StatusBadRequest).Wrap(err)
}
}
if *s.GuestFilter != "" {
if _, err := ldap.CompileFilter(*s.GuestFilter); err != nil {
return NewAppError("LdapSettings.isValid", "ent.ldap.validate_guest_filter.app_error", nil, err.Error(), http.StatusBadRequest)
return NewAppError("LdapSettings.isValid", "ent.ldap.validate_guest_filter.app_error", nil, "", http.StatusBadRequest).Wrap(err)
}
}
if *s.AdminFilter != "" {
if _, err := ldap.CompileFilter(*s.AdminFilter); err != nil {
return NewAppError("LdapSettings.isValid", "ent.ldap.validate_admin_filter.app_error", nil, err.Error(), http.StatusBadRequest)
return NewAppError("LdapSettings.isValid", "ent.ldap.validate_admin_filter.app_error", nil, "", http.StatusBadRequest).Wrap(err)
}
}
}
@@ -3644,13 +3645,13 @@ func (s *ServiceSettings) isValid() *AppError {
if *s.SiteURL != "" {
if _, err := url.ParseRequestURI(*s.SiteURL); err != nil {
return NewAppError("Config.IsValid", "model.config.is_valid.site_url.app_error", nil, err.Error(), http.StatusBadRequest)
return NewAppError("Config.IsValid", "model.config.is_valid.site_url.app_error", nil, "", http.StatusBadRequest).Wrap(err)
}
}
if *s.WebsocketURL != "" {
if _, err := url.ParseRequestURI(*s.WebsocketURL); err != nil {
return NewAppError("Config.IsValid", "model.config.is_valid.websocket_url.app_error", nil, err.Error(), http.StatusBadRequest)
return NewAppError("Config.IsValid", "model.config.is_valid.websocket_url.app_error", nil, "", http.StatusBadRequest).Wrap(err)
}
}
@@ -3706,7 +3707,7 @@ func (s *ElasticsearchSettings) isValid() *AppError {
}
if _, err := time.Parse("15:04", *s.PostsAggregatorJobStartTime); err != nil {
return NewAppError("Config.IsValid", "model.config.is_valid.elastic_search.posts_aggregator_job_start_time.app_error", nil, err.Error(), http.StatusBadRequest)
return NewAppError("Config.IsValid", "model.config.is_valid.elastic_search.posts_aggregator_job_start_time.app_error", nil, "", http.StatusBadRequest).Wrap(err)
}
if *s.LiveIndexingBatchSize < 1 {
@@ -3756,7 +3757,7 @@ func (s *DataRetentionSettings) isValid() *AppError {
}
if _, err := time.Parse("15:04", *s.DeletionJobStartTime); err != nil {
return NewAppError("Config.IsValid", "model.config.is_valid.data_retention.deletion_job_start_time.app_error", nil, err.Error(), http.StatusBadRequest)
return NewAppError("Config.IsValid", "model.config.is_valid.data_retention.deletion_job_start_time.app_error", nil, "", http.StatusBadRequest).Wrap(err)
}
return nil
@@ -3782,7 +3783,7 @@ func (s *MessageExportSettings) isValid() *AppError {
} else if s.DailyRunTime == nil {
return NewAppError("Config.IsValid", "model.config.is_valid.message_export.daily_runtime.app_error", nil, "", http.StatusBadRequest)
} else if _, err := time.Parse("15:04", *s.DailyRunTime); err != nil {
return NewAppError("Config.IsValid", "model.config.is_valid.message_export.daily_runtime.app_error", nil, err.Error(), http.StatusBadRequest)
return NewAppError("Config.IsValid", "model.config.is_valid.message_export.daily_runtime.app_error", nil, "", http.StatusBadRequest).Wrap(err)
} else if s.BatchSize == nil || *s.BatchSize < 0 {
return NewAppError("Config.IsValid", "model.config.is_valid.message_export.batch_size.app_error", nil, "", http.StatusBadRequest)
} else if s.ExportFormat == nil || (*s.ExportFormat != ComplianceExportTypeActiance && *s.ExportFormat != ComplianceExportTypeGlobalrelay && *s.ExportFormat != ComplianceExportTypeCsv) {

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

@@ -159,8 +159,8 @@ func TestConfigIsValidDefaultAlgorithms(t *testing.T) {
*c1.SamlSettings.EmailAttribute = "Email"
*c1.SamlSettings.UsernameAttribute = "Username"
err := c1.SamlSettings.isValid()
require.Nil(t, err)
appErr := c1.SamlSettings.isValid()
require.Nil(t, appErr)
}
func TestConfigServiceProviderDefault(t *testing.T) {
@@ -180,8 +180,8 @@ func TestConfigServiceProviderDefault(t *testing.T) {
c1.SetDefaults()
assert.Equal(t, *c1.SamlSettings.ServiceProviderIdentifier, *c1.SamlSettings.IdpDescriptorURL)
err := c1.SamlSettings.isValid()
require.Nil(t, err)
appErr := c1.SamlSettings.isValid()
require.Nil(t, appErr)
}
func TestConfigIsValidFakeAlgorithm(t *testing.T) {
@@ -202,17 +202,17 @@ func TestConfigIsValidFakeAlgorithm(t *testing.T) {
temp := *c1.SamlSettings.CanonicalAlgorithm
*c1.SamlSettings.CanonicalAlgorithm = "Fake Algorithm"
err := c1.SamlSettings.isValid()
require.NotNil(t, err)
appErr := c1.SamlSettings.isValid()
require.NotNil(t, appErr)
require.Equal(t, "model.config.is_valid.saml_canonical_algorithm.app_error", err.Message)
require.Equal(t, "model.config.is_valid.saml_canonical_algorithm.app_error", appErr.Message)
*c1.SamlSettings.CanonicalAlgorithm = temp
*c1.SamlSettings.SignatureAlgorithm = "Fake Algorithm"
err = c1.SamlSettings.isValid()
require.NotNil(t, err)
appErr = c1.SamlSettings.isValid()
require.NotNil(t, appErr)
require.Equal(t, "model.config.is_valid.saml_signature_algorithm.app_error", err.Message)
require.Equal(t, "model.config.is_valid.saml_signature_algorithm.app_error", appErr.Message)
}
func TestConfigOverwriteGuestSettings(t *testing.T) {
@@ -794,9 +794,9 @@ func TestDisplaySettingsIsValidCustomURLSchemes(t *testing.T) {
ds.CustomURLSchemes = test.value
if err := ds.isValid(); err != nil && test.valid {
t.Error("Expected CustomURLSchemes to be valid but got error:", err)
} else if err == nil && !test.valid {
if appErr := ds.isValid(); appErr != nil && test.valid {
t.Error("Expected CustomURLSchemes to be valid but got error:", appErr)
} else if appErr == nil && !test.valid {
t.Error("Expected CustomURLSchemes to be invalid but got no error")
}
})
@@ -837,9 +837,9 @@ func TestListenAddressIsValidated(t *testing.T) {
if expected {
require.Nil(t, ss.isValid(), fmt.Sprintf("Got an error from '%v'.", key))
} else {
err := ss.isValid()
require.NotNil(t, err, fmt.Sprintf("Expected '%v' to throw an error.", key))
require.Equal(t, "model.config.is_valid.listen_address.app_error", err.Message)
appErr := ss.isValid()
require.NotNil(t, appErr, fmt.Sprintf("Expected '%v' to throw an error.", key))
require.Equal(t, "model.config.is_valid.listen_address.app_error", appErr.Message)
}
}
@@ -926,11 +926,11 @@ func TestImageProxySettingsIsValid(t *testing.T) {
RemoteImageProxyOptions: &test.RemoteImageProxyOptions,
}
err := ips.isValid()
appErr := ips.isValid()
if test.ExpectError {
assert.NotNil(t, err)
assert.NotNil(t, appErr)
} else {
assert.Nil(t, err)
assert.Nil(t, appErr)
}
})
}
@@ -1277,11 +1277,11 @@ func TestLdapSettingsIsValid(t *testing.T) {
t.Run(test.Name, func(t *testing.T) {
test.LdapSettings.SetDefaults()
err := test.LdapSettings.isValid()
appErr := test.LdapSettings.isValid()
if test.ExpectError {
assert.NotNil(t, err)
assert.NotNil(t, appErr)
} else {
assert.Nil(t, err)
assert.Nil(t, appErr)
}
})
}
@@ -1323,7 +1323,7 @@ func TestConfigFilteredByTag(t *testing.T) {
// Remove entire sections but the map is still there
clusterSettings, ok := cfgMap["SqlSettings"].(map[string]any)
require.True(t, ok)
require.Equal(t, 0, len(clusterSettings))
require.Empty(t, clusterSettings)
// Some fields are removed if they have the filtering tag
serviceSettings, ok := cfgMap["ServiceSettings"].(map[string]any)
@@ -1423,20 +1423,20 @@ func TestConfigImportSettingsIsValid(t *testing.T) {
cfg := Config{}
cfg.SetDefaults()
err := cfg.ImportSettings.isValid()
require.Nil(t, err)
appErr := cfg.ImportSettings.isValid()
require.Nil(t, appErr)
*cfg.ImportSettings.Directory = ""
err = cfg.ImportSettings.isValid()
require.NotNil(t, err)
require.Equal(t, "model.config.is_valid.import.directory.app_error", err.Id)
appErr = cfg.ImportSettings.isValid()
require.NotNil(t, appErr)
require.Equal(t, "model.config.is_valid.import.directory.app_error", appErr.Id)
cfg.SetDefaults()
*cfg.ImportSettings.RetentionDays = 0
err = cfg.ImportSettings.isValid()
require.NotNil(t, err)
require.Equal(t, "model.config.is_valid.import.retention_days_too_low.app_error", err.Id)
appErr = cfg.ImportSettings.isValid()
require.NotNil(t, appErr)
require.Equal(t, "model.config.is_valid.import.retention_days_too_low.app_error", appErr.Id)
}
func TestConfigExportSettingsDefaults(t *testing.T) {
@@ -1451,57 +1451,57 @@ func TestConfigExportSettingsIsValid(t *testing.T) {
cfg := Config{}
cfg.SetDefaults()
err := cfg.ExportSettings.isValid()
require.Nil(t, err)
appErr := cfg.ExportSettings.isValid()
require.Nil(t, appErr)
*cfg.ExportSettings.Directory = ""
err = cfg.ExportSettings.isValid()
require.NotNil(t, err)
require.Equal(t, "model.config.is_valid.export.directory.app_error", err.Id)
appErr = cfg.ExportSettings.isValid()
require.NotNil(t, appErr)
require.Equal(t, "model.config.is_valid.export.directory.app_error", appErr.Id)
cfg.SetDefaults()
*cfg.ExportSettings.RetentionDays = 0
err = cfg.ExportSettings.isValid()
require.NotNil(t, err)
require.Equal(t, "model.config.is_valid.export.retention_days_too_low.app_error", err.Id)
appErr = cfg.ExportSettings.isValid()
require.NotNil(t, appErr)
require.Equal(t, "model.config.is_valid.export.retention_days_too_low.app_error", appErr.Id)
}
func TestConfigServiceSettingsIsValid(t *testing.T) {
cfg := Config{}
cfg.SetDefaults()
err := cfg.ServiceSettings.isValid()
require.Nil(t, err)
appErr := cfg.ServiceSettings.isValid()
require.Nil(t, appErr)
*cfg.ServiceSettings.CollapsedThreads = CollapsedThreadsDisabled
err = cfg.ServiceSettings.isValid()
require.Nil(t, err)
appErr = cfg.ServiceSettings.isValid()
require.Nil(t, appErr)
*cfg.ServiceSettings.ThreadAutoFollow = false
err = cfg.ServiceSettings.isValid()
require.Nil(t, err)
appErr = cfg.ServiceSettings.isValid()
require.Nil(t, appErr)
*cfg.ServiceSettings.CollapsedThreads = CollapsedThreadsDefaultOff
err = cfg.ServiceSettings.isValid()
require.NotNil(t, err)
require.Equal(t, "model.config.is_valid.collapsed_threads.autofollow.app_error", err.Id)
appErr = cfg.ServiceSettings.isValid()
require.NotNil(t, appErr)
require.Equal(t, "model.config.is_valid.collapsed_threads.autofollow.app_error", appErr.Id)
*cfg.ServiceSettings.CollapsedThreads = CollapsedThreadsDefaultOn
err = cfg.ServiceSettings.isValid()
require.NotNil(t, err)
require.Equal(t, "model.config.is_valid.collapsed_threads.autofollow.app_error", err.Id)
appErr = cfg.ServiceSettings.isValid()
require.NotNil(t, appErr)
require.Equal(t, "model.config.is_valid.collapsed_threads.autofollow.app_error", appErr.Id)
*cfg.ServiceSettings.CollapsedThreads = CollapsedThreadsAlwaysOn
err = cfg.ServiceSettings.isValid()
require.NotNil(t, err)
require.Equal(t, "model.config.is_valid.collapsed_threads.autofollow.app_error", err.Id)
appErr = cfg.ServiceSettings.isValid()
require.NotNil(t, appErr)
require.Equal(t, "model.config.is_valid.collapsed_threads.autofollow.app_error", appErr.Id)
*cfg.ServiceSettings.ThreadAutoFollow = true
*cfg.ServiceSettings.CollapsedThreads = "test_status"
err = cfg.ServiceSettings.isValid()
require.NotNil(t, err)
require.Equal(t, "model.config.is_valid.collapsed_threads.app_error", err.Id)
appErr = cfg.ServiceSettings.isValid()
require.NotNil(t, appErr)
require.Equal(t, "model.config.is_valid.collapsed_threads.app_error", appErr.Id)
}
func TestConfigDefaultCallsPluginState(t *testing.T) {

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

@@ -161,7 +161,7 @@ func GetInfoForBytes(name string, data io.ReadSeeker, size int) (*FileInfo, *App
if err != nil {
// Still return the rest of the info even though it doesn't appear to be an actual gif
info.HasPreviewImage = true
return info, NewAppError("GetInfoForBytes", "model.file_info.get.gif.app_error", nil, err.Error(), http.StatusBadRequest)
return info, NewAppError("GetInfoForBytes", "model.file_info.get.gif.app_error", nil, "", http.StatusBadRequest).Wrap(err)
}
info.HasPreviewImage = frameCount == 1
} else {

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

@@ -187,8 +187,8 @@ func TestGetInfoForFile(t *testing.T) {
for _, tc := range ttc {
t.Run(tc.testName, func(t *testing.T) {
info, errApp := GetInfoForBytes(tc.filename, bytes.NewReader(tc.file), len(tc.file))
require.Nil(t, errApp)
info, appErr := GetInfoForBytes(tc.filename, bytes.NewReader(tc.file), len(tc.file))
require.Nil(t, appErr)
assert.Equalf(t, tc.filename, info.Name, "Got incorrect filename: %v", info.Name)
assert.Equalf(t, tc.expectedExtension, info.Extension, "Got incorrect extension: %v", info.Extension)

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

@@ -149,9 +149,9 @@ func (group *Group) Patch(patch *GroupPatch) {
}
func (group *Group) IsValidForCreate() *AppError {
err := group.IsValidName()
if err != nil {
return err
appErr := group.IsValidName()
if appErr != nil {
return appErr
}
if l := len(group.DisplayName); l == 0 || l > GroupDisplayNameMaxLength {
@@ -199,8 +199,8 @@ func (group *Group) IsValidForUpdate() *AppError {
if group.UpdateAt == 0 {
return NewAppError("Group.IsValidForUpdate", "model.group.update_at.app_error", nil, "", http.StatusBadRequest)
}
if err := group.IsValidForCreate(); err != nil {
return err
if appErr := group.IsValidForCreate(); appErr != nil {
return appErr
}
return nil
}

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

@@ -123,22 +123,24 @@ func (o *IncomingWebhook) PreUpdate() {
// try to handle that. An example invalid JSON string from an incoming webhook
// might look like this (strings for both "text" and "fallback" attributes are
// invalid JSON strings because they contain unescaped newlines and tabs):
// `{
// "text": "this is a test
// that contains a newline and tabs",
// "attachments": [
// {
// "fallback": "Required plain-text summary of the attachment
// that contains a newline and tabs",
// "color": "#36a64f",
// ...
// "text": "Optional text that appears within the attachment
// that contains a newline and tabs",
// ...
// "thumb_url": "http://example.com/path/to/thumb.png"
// }
// ]
// }`
//
// `{
// "text": "this is a test
// that contains a newline and tabs",
// "attachments": [
// {
// "fallback": "Required plain-text summary of the attachment
// that contains a newline and tabs",
// "color": "#36a64f",
// ...
// "text": "Optional text that appears within the attachment
// that contains a newline and tabs",
// ...
// "thumb_url": "http://example.com/path/to/thumb.png"
// }
// ]
// }`
//
// This function will search for `"key": "value"` pairs, and escape \n, \t
// from the value.
func escapeControlCharsFromPayload(by []byte) []byte {
@@ -191,7 +193,7 @@ func IncomingWebhookRequestFromJSON(data io.Reader) (*IncomingWebhookRequest, *A
if err != nil {
o, err = decodeIncomingWebhookRequest(escapeControlCharsFromPayload(by))
if err != nil {
return nil, NewAppError("IncomingWebhookRequestFromJSON", "model.incoming_hook.parse_data.app_error", nil, err.Error(), http.StatusBadRequest)
return nil, NewAppError("IncomingWebhookRequestFromJSON", "model.incoming_hook.parse_data.app_error", nil, "", http.StatusBadRequest).Wrap(err)
}
}

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

@@ -151,27 +151,30 @@ func TimeRangeToNumberDays(timeRange string) int {
// ChannelPostCountByDuration contains a count of posts by channel id, grouped by ISO8601 date string.
// Example 1 (grouped by day):
// cpc := model.ChannelPostCountByDuration{
// "2009-11-11": {
// "ezbp7nqxzjgdir8riodyafr9ww": 90,
// "p949c1xdojfgzffxma3p3s3ikr": 201,
// },
// "2009-11-12": {
// "ezbp7nqxzjgdir8riodyafr9ww": 45,
// "p949c1xdojfgzffxma3p3s3ikr": 68,
// },
// }
//
// cpc := model.ChannelPostCountByDuration{
// "2009-11-11": {
// "ezbp7nqxzjgdir8riodyafr9ww": 90,
// "p949c1xdojfgzffxma3p3s3ikr": 201,
// },
// "2009-11-12": {
// "ezbp7nqxzjgdir8riodyafr9ww": 45,
// "p949c1xdojfgzffxma3p3s3ikr": 68,
// },
// }
//
// Example 2 (grouped by hour):
// cpc := model.ChannelPostCountByDuration{
// "2009-11-11T01": {
// "ezbp7nqxzjgdir8riodyafr9ww": 90,
// "p949c1xdojfgzffxma3p3s3ikr": 201,
// },
// "2009-11-11T02": {
// "ezbp7nqxzjgdir8riodyafr9ww": 45,
// "p949c1xdojfgzffxma3p3s3ikr": 68,
// },
// }
//
// cpc := model.ChannelPostCountByDuration{
// "2009-11-11T01": {
// "ezbp7nqxzjgdir8riodyafr9ww": 90,
// "p949c1xdojfgzffxma3p3s3ikr": 201,
// },
// "2009-11-11T02": {
// "ezbp7nqxzjgdir8riodyafr9ww": 45,
// "p949c1xdojfgzffxma3p3s3ikr": 68,
// },
// }
type ChannelPostCountByDuration map[string]map[string]int
func blankChannelCountsMap(channelIDs []string) map[string]int {

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

@@ -261,7 +261,7 @@ func GenerateTriggerId(userId string, s crypto.Signer) (string, string, *AppErro
sum.Write([]byte(triggerData))
signature, err := s.Sign(rand.Reader, sum.Sum(nil), h)
if err != nil {
return "", "", NewAppError("GenerateTriggerId", "interactive_message.generate_trigger_id.signing_failed", nil, err.Error(), http.StatusInternalServerError)
return "", "", NewAppError("GenerateTriggerId", "interactive_message.generate_trigger_id.signing_failed", nil, "", http.StatusInternalServerError).Wrap(err)
}
base64Sig := base64.StdEncoding.EncodeToString(signature)
@@ -271,9 +271,9 @@ func GenerateTriggerId(userId string, s crypto.Signer) (string, string, *AppErro
}
func (r *PostActionIntegrationRequest) GenerateTriggerId(s crypto.Signer) (string, string, *AppError) {
clientTriggerId, triggerId, err := GenerateTriggerId(r.UserId, s)
if err != nil {
return "", "", err
clientTriggerId, triggerId, appErr := GenerateTriggerId(r.UserId, s)
if appErr != nil {
return "", "", appErr
}
r.TriggerId = triggerId
@@ -283,7 +283,7 @@ func (r *PostActionIntegrationRequest) GenerateTriggerId(s crypto.Signer) (strin
func DecodeAndVerifyTriggerId(triggerId string, s *ecdsa.PrivateKey) (string, string, *AppError) {
triggerIdBytes, err := base64.StdEncoding.DecodeString(triggerId)
if err != nil {
return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.base64_decode_failed", nil, err.Error(), http.StatusBadRequest)
return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.base64_decode_failed", nil, "", http.StatusBadRequest).Wrap(err)
}
split := strings.Split(string(triggerIdBytes), ":")
@@ -303,7 +303,7 @@ func DecodeAndVerifyTriggerId(triggerId string, s *ecdsa.PrivateKey) (string, st
signature, err := base64.StdEncoding.DecodeString(split[3])
if err != nil {
return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.base64_decode_failed_signature", nil, err.Error(), http.StatusBadRequest)
return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.base64_decode_failed_signature", nil, "", http.StatusBadRequest).Wrap(err)
}
var esig struct {
@@ -311,7 +311,7 @@ func DecodeAndVerifyTriggerId(triggerId string, s *ecdsa.PrivateKey) (string, st
}
if _, err := asn1.Unmarshal(signature, &esig); err != nil {
return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.signature_decode_failed", nil, err.Error(), http.StatusBadRequest)
return "", "", NewAppError("DecodeAndVerifyTriggerId", "interactive_message.decode_trigger_id.signature_decode_failed", nil, "", http.StatusBadRequest).Wrap(err)
}
triggerData := strings.Join([]string{clientTriggerId, userId, timestampStr}, ":") + ":"

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

@@ -20,10 +20,10 @@ func TestTriggerIdDecodeAndVerification(t *testing.T) {
t.Run("should succeed decoding and validation", func(t *testing.T) {
userId := NewId()
clientTriggerId, triggerId, err := GenerateTriggerId(userId, key)
require.Nil(t, err)
decodedClientTriggerId, decodedUserId, err := DecodeAndVerifyTriggerId(triggerId, key)
assert.Nil(t, err)
clientTriggerId, triggerId, appErr := GenerateTriggerId(userId, key)
require.Nil(t, appErr)
decodedClientTriggerId, decodedUserId, appErr := DecodeAndVerifyTriggerId(triggerId, key)
assert.Nil(t, appErr)
assert.Equal(t, clientTriggerId, decodedClientTriggerId)
assert.Equal(t, userId, decodedUserId)
})
@@ -32,53 +32,53 @@ func TestTriggerIdDecodeAndVerification(t *testing.T) {
actionReq := &PostActionIntegrationRequest{
UserId: NewId(),
}
clientTriggerId, triggerId, err := actionReq.GenerateTriggerId(key)
require.Nil(t, err)
clientTriggerId, triggerId, appErr := actionReq.GenerateTriggerId(key)
require.Nil(t, appErr)
dialogReq := &OpenDialogRequest{TriggerId: triggerId}
decodedClientTriggerId, decodedUserId, err := dialogReq.DecodeAndVerifyTriggerId(key)
assert.Nil(t, err)
decodedClientTriggerId, decodedUserId, appErr := dialogReq.DecodeAndVerifyTriggerId(key)
assert.Nil(t, appErr)
assert.Equal(t, clientTriggerId, decodedClientTriggerId)
assert.Equal(t, actionReq.UserId, decodedUserId)
})
t.Run("should fail on base64 decode", func(t *testing.T) {
_, _, err := DecodeAndVerifyTriggerId("junk!", key)
require.NotNil(t, err)
assert.Equal(t, "interactive_message.decode_trigger_id.base64_decode_failed", err.Id)
_, _, appErr := DecodeAndVerifyTriggerId("junk!", key)
require.NotNil(t, appErr)
assert.Equal(t, "interactive_message.decode_trigger_id.base64_decode_failed", appErr.Id)
})
t.Run("should fail on trigger parsing", func(t *testing.T) {
_, _, err := DecodeAndVerifyTriggerId(base64.StdEncoding.EncodeToString([]byte("junk!")), key)
require.NotNil(t, err)
assert.Equal(t, "interactive_message.decode_trigger_id.missing_data", err.Id)
_, _, appErr := DecodeAndVerifyTriggerId(base64.StdEncoding.EncodeToString([]byte("junk!")), key)
require.NotNil(t, appErr)
assert.Equal(t, "interactive_message.decode_trigger_id.missing_data", appErr.Id)
})
t.Run("should fail on expired timestamp", func(t *testing.T) {
_, _, err := DecodeAndVerifyTriggerId(base64.StdEncoding.EncodeToString([]byte("some-trigger-id:some-user-id:1234567890:junksignature")), key)
require.NotNil(t, err)
assert.Equal(t, "interactive_message.decode_trigger_id.expired", err.Id)
_, _, appErr := DecodeAndVerifyTriggerId(base64.StdEncoding.EncodeToString([]byte("some-trigger-id:some-user-id:1234567890:junksignature")), key)
require.NotNil(t, appErr)
assert.Equal(t, "interactive_message.decode_trigger_id.expired", appErr.Id)
})
t.Run("should fail on base64 decoding signature", func(t *testing.T) {
_, _, err := DecodeAndVerifyTriggerId(base64.StdEncoding.EncodeToString([]byte("some-trigger-id:some-user-id:12345678900000:junk!")), key)
require.NotNil(t, err)
assert.Equal(t, "interactive_message.decode_trigger_id.base64_decode_failed_signature", err.Id)
_, _, appErr := DecodeAndVerifyTriggerId(base64.StdEncoding.EncodeToString([]byte("some-trigger-id:some-user-id:12345678900000:junk!")), key)
require.NotNil(t, appErr)
assert.Equal(t, "interactive_message.decode_trigger_id.base64_decode_failed_signature", appErr.Id)
})
t.Run("should fail on bad signature", func(t *testing.T) {
_, _, err := DecodeAndVerifyTriggerId(base64.StdEncoding.EncodeToString([]byte("some-trigger-id:some-user-id:12345678900000:junk")), key)
require.NotNil(t, err)
assert.Equal(t, "interactive_message.decode_trigger_id.signature_decode_failed", err.Id)
_, _, appErr := DecodeAndVerifyTriggerId(base64.StdEncoding.EncodeToString([]byte("some-trigger-id:some-user-id:12345678900000:junk")), key)
require.NotNil(t, appErr)
assert.Equal(t, "interactive_message.decode_trigger_id.signature_decode_failed", appErr.Id)
})
t.Run("should fail on bad key", func(t *testing.T) {
_, triggerId, err := GenerateTriggerId(NewId(), key)
require.Nil(t, err)
_, triggerId, appErr := GenerateTriggerId(NewId(), key)
require.Nil(t, appErr)
newKey, keyErr := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
require.NoError(t, keyErr)
_, _, err = DecodeAndVerifyTriggerId(triggerId, newKey)
require.NotNil(t, err)
assert.Equal(t, "interactive_message.decode_trigger_id.verify_signature_failed", err.Id)
_, _, appErr = DecodeAndVerifyTriggerId(triggerId, newKey)
require.NotNil(t, appErr)
assert.Equal(t, "interactive_message.decode_trigger_id.verify_signature_failed", appErr.Id)
})
}

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

@@ -149,26 +149,26 @@ func TestLicenseRecordIsValid(t *testing.T) {
Bytes: "asdfghjkl;",
}
err := lr.IsValid()
assert.NotNil(t, err)
appErr := lr.IsValid()
assert.NotNil(t, appErr)
lr.Id = NewId()
lr.CreateAt = 0
err = lr.IsValid()
assert.NotNil(t, err)
appErr = lr.IsValid()
assert.NotNil(t, appErr)
lr.CreateAt = GetMillis()
lr.Bytes = ""
err = lr.IsValid()
assert.NotNil(t, err)
appErr = lr.IsValid()
assert.NotNil(t, appErr)
lr.Bytes = strings.Repeat("0123456789", 1001)
err = lr.IsValid()
assert.NotNil(t, err)
appErr = lr.IsValid()
assert.NotNil(t, appErr)
lr.Bytes = "ASDFGHJKL;"
err = lr.IsValid()
assert.Nil(t, err)
appErr = lr.IsValid()
assert.Nil(t, appErr)
}
func TestLicenseRecordPreSave(t *testing.T) {

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

@@ -148,12 +148,12 @@ func TestLinkMetadataIsValid(t *testing.T) {
},
} {
t.Run(test.Name, func(t *testing.T) {
err := test.Metadata.IsValid()
appErr := test.Metadata.IsValid()
if test.Expected {
assert.Nil(t, err)
assert.Nil(t, appErr)
} else {
assert.NotNil(t, err)
assert.NotNil(t, appErr)
}
})
}

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

@@ -112,7 +112,7 @@ func TestUserMentionMap_ToURLValues(t *testing.T) {
// check is that the pairs are preserved, which can be checked converting
// back to a map with FromURLValues. We check that the test is well-formed
// by converting back the expected url.Values too.
require.Equal(t, len(actualValues), len(data.expected))
require.Len(t, actualValues, len(data.expected))
actualMentionMap, actualErr := UserMentionMapFromURLValues(actualValues)
expectedMentionMap, expectedErr := UserMentionMapFromURLValues(data.expected)
@@ -224,7 +224,7 @@ func TestChannelMentionMap_ToURLValues(t *testing.T) {
// check is that the pairs are preserved, which can be checked converting
// back to a map with FromURLValues. We check that the test is well-formed
// by converting back the expected url.Values too.
require.Equal(t, len(actualValues), len(data.expected))
require.Len(t, actualValues, len(data.expected))
actualMentionMap, actualErr := ChannelMentionMapFromURLValues(actualValues)
expectedMentionMap, expectedErr := ChannelMentionMapFromURLValues(data.expected)

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

@@ -15,7 +15,8 @@ const (
)
// ValidId constrains the set of valid plugin identifiers:
// ^[a-zA-Z0-9-_\.]+
//
// ^[a-zA-Z0-9-_\.]+
var validId *regexp.Regexp
func init() {

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

@@ -28,50 +28,50 @@ func TestPostIsValid(t *testing.T) {
o := Post{}
maxPostSize := 10000
err := o.IsValid(maxPostSize)
require.NotNil(t, err)
appErr := o.IsValid(maxPostSize)
require.NotNil(t, appErr)
o.Id = NewId()
err = o.IsValid(maxPostSize)
require.NotNil(t, err)
appErr = o.IsValid(maxPostSize)
require.NotNil(t, appErr)
o.CreateAt = GetMillis()
err = o.IsValid(maxPostSize)
require.NotNil(t, err)
appErr = o.IsValid(maxPostSize)
require.NotNil(t, appErr)
o.UpdateAt = GetMillis()
err = o.IsValid(maxPostSize)
require.NotNil(t, err)
appErr = o.IsValid(maxPostSize)
require.NotNil(t, appErr)
o.UserId = NewId()
err = o.IsValid(maxPostSize)
require.NotNil(t, err)
appErr = o.IsValid(maxPostSize)
require.NotNil(t, appErr)
o.ChannelId = NewId()
o.RootId = "123"
err = o.IsValid(maxPostSize)
require.NotNil(t, err)
appErr = o.IsValid(maxPostSize)
require.NotNil(t, appErr)
o.RootId = ""
o.Message = strings.Repeat("0", maxPostSize+1)
err = o.IsValid(maxPostSize)
require.NotNil(t, err)
appErr = o.IsValid(maxPostSize)
require.NotNil(t, appErr)
o.Message = strings.Repeat("0", maxPostSize)
err = o.IsValid(maxPostSize)
require.Nil(t, err)
appErr = o.IsValid(maxPostSize)
require.Nil(t, appErr)
o.Message = "test"
err = o.IsValid(maxPostSize)
require.Nil(t, err)
appErr = o.IsValid(maxPostSize)
require.Nil(t, appErr)
o.Type = "junk"
err = o.IsValid(maxPostSize)
require.NotNil(t, err)
appErr = o.IsValid(maxPostSize)
require.NotNil(t, appErr)
o.Type = PostCustomTypePrefix + "type"
err = o.IsValid(maxPostSize)
require.Nil(t, err)
appErr = o.IsValid(maxPostSize)
require.Nil(t, appErr)
}
func TestPostPreSave(t *testing.T) {

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

@@ -176,13 +176,13 @@ func TestReactionIsValid(t *testing.T) {
}
for _, test := range tests {
err := test.reaction.IsValid()
appErr := test.reaction.IsValid()
if test.shouldErr {
// there should be an error here
require.NotNil(t, err, test.errMsg)
require.NotNil(t, appErr, test.errMsg)
} else {
// err should be nil here
require.Nil(t, err, test.errMsg)
require.Nil(t, appErr, test.errMsg)
}
}
}

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

@@ -159,8 +159,8 @@ func (f *RemoteClusterFrame) IsValid() *AppError {
return NewAppError("RemoteClusterFrame.IsValid", "api.remote_cluster.invalid_id.app_error", nil, "RemoteId="+f.RemoteId, http.StatusBadRequest)
}
if err := f.Msg.IsValid(); err != nil {
return err
if appErr := f.Msg.IsValid(); appErr != nil {
return appErr
}
return nil

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

@@ -33,11 +33,11 @@ func TestRemoteClusterIsValid(t *testing.T) {
}
for _, item := range data {
err := item.rc.IsValid()
appErr := item.rc.IsValid()
if item.valid {
assert.Nil(t, err, item.name)
assert.Nil(t, appErr, item.name)
} else {
assert.NotNil(t, err, item.name)
assert.NotNil(t, appErr, item.name)
}
}
}
@@ -67,11 +67,11 @@ func TestRemoteClusterMsgIsValid(t *testing.T) {
}
for _, item := range data {
err := item.msg.IsValid()
appErr := item.msg.IsValid()
if item.valid {
assert.Nil(t, err, item.name)
assert.Nil(t, appErr, item.name)
} else {
assert.NotNil(t, err, item.name)
assert.NotNil(t, appErr, item.name)
}
}
}

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

@@ -1784,17 +1784,17 @@ func TestGetAfterDateMillis(t *testing.T) {
}
func TestIsSearchParamsListValid(t *testing.T) {
var err *AppError
var appErr *AppError
err = IsSearchParamsListValid([]*SearchParams{{IncludeDeletedChannels: true}, {IncludeDeletedChannels: true}})
assert.Nil(t, err)
appErr = IsSearchParamsListValid([]*SearchParams{{IncludeDeletedChannels: true}, {IncludeDeletedChannels: true}})
assert.Nil(t, appErr)
err = IsSearchParamsListValid([]*SearchParams{{IncludeDeletedChannels: true}, {IncludeDeletedChannels: false}})
assert.NotNil(t, err)
appErr = IsSearchParamsListValid([]*SearchParams{{IncludeDeletedChannels: true}, {IncludeDeletedChannels: false}})
assert.NotNil(t, appErr)
err = IsSearchParamsListValid([]*SearchParams{{IncludeDeletedChannels: true}})
assert.Nil(t, err)
appErr = IsSearchParamsListValid([]*SearchParams{{IncludeDeletedChannels: true}})
assert.Nil(t, appErr)
err = IsSearchParamsListValid([]*SearchParams{})
assert.Nil(t, err)
appErr = IsSearchParamsListValid([]*SearchParams{})
assert.Nil(t, appErr)
}

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

@@ -34,14 +34,14 @@ const (
SessionUserAccessTokenExpiryHours = 100 * 365 * 24 // 100 years
)
//msgp StringMap
//msgp:tuple StringMap
type StringMap map[string]string
//msgp:tuple Session
// Session contains the user session details.
// This struct's serializer methods are auto-generated. If a new field is added/removed,
// please run make gen-serialized.
//
//msgp:tuple Session
type Session struct {
Id string `json:"id"`
Token string `json:"token"`

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

@@ -62,12 +62,12 @@ func TestSessionIsValid(t *testing.T) {
for _, tc := range tcs {
t.Run(tc.name, func(t *testing.T) {
err := tc.input.IsValid()
appErr := tc.input.IsValid()
if tc.expectedError != "" {
require.NotNil(t, err)
require.Equal(t, tc.expectedError, err.Id)
require.NotNil(t, appErr)
require.Equal(t, tc.expectedError, appErr.Id)
} else {
require.Nil(t, err)
require.Nil(t, appErr)
}
})
}
@@ -98,7 +98,7 @@ func TestSessionDeepCopy(t *testing.T) {
session = &Session{TeamMembers: []*TeamMember{}}
copySession = session.DeepCopy()
assert.Equal(t, 0, len(copySession.TeamMembers))
assert.Empty(t, copySession.TeamMembers)
}
func TestSessionCSRF(t *testing.T) {

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

@@ -37,11 +37,11 @@ func TestSharedChannelIsValid(t *testing.T) {
}
for _, item := range data {
err := item.sc.IsValid()
appErr := item.sc.IsValid()
if item.valid {
assert.Nil(t, err, item.name)
assert.Nil(t, appErr, item.name)
} else {
assert.NotNil(t, err, item.name)
assert.NotNil(t, appErr, item.name)
}
}
}

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

@@ -35,7 +35,7 @@ func TestStatusListToJSON(t *testing.T) {
panic(err)
}
assert.Equal(t, len(dat), 2)
assert.Len(t, dat, 2)
_, ok := dat[0]["active_channel"]
assert.False(t, ok)

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

@@ -13,9 +13,10 @@ const (
USERNAME = "Username"
)
//msgp:tuple TeamMember
// This struct's serializer methods are auto-generated. If a new field is added/removed,
// please run make gen-serialized.
//
//msgp:tuple TeamMember
type TeamMember struct {
TeamId string `json:"team_id"`
UserId string `json:"user_id"`

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

@@ -14,40 +14,40 @@ import (
func TestTeamIsValid(t *testing.T) {
o := Team{}
err := o.IsValid()
require.NotNil(t, err, "should be invalid")
appErr := o.IsValid()
require.NotNil(t, appErr, "should be invalid")
o.Id = NewId()
err = o.IsValid()
require.NotNil(t, err, "should be invalid")
appErr = o.IsValid()
require.NotNil(t, appErr, "should be invalid")
o.CreateAt = GetMillis()
err = o.IsValid()
require.NotNil(t, err, "should be invalid")
appErr = o.IsValid()
require.NotNil(t, appErr, "should be invalid")
o.UpdateAt = GetMillis()
err = o.IsValid()
require.NotNil(t, err, "should be invalid")
appErr = o.IsValid()
require.NotNil(t, appErr, "should be invalid")
o.Email = strings.Repeat("01234567890", 20)
err = o.IsValid()
require.NotNil(t, err, "should be invalid")
appErr = o.IsValid()
require.NotNil(t, appErr, "should be invalid")
o.Email = "corey+test@hulen.com"
o.DisplayName = strings.Repeat("01234567890", 20)
err = o.IsValid()
require.NotNil(t, err, "should be invalid")
appErr = o.IsValid()
require.NotNil(t, appErr, "should be invalid")
o.DisplayName = "1234"
o.Name = "ZZZZZZZ"
err = o.IsValid()
require.NotNil(t, err, "should be invalid")
appErr = o.IsValid()
require.NotNil(t, appErr, "should be invalid")
o.Name = "zzzzz"
o.Type = TeamOpen
o.InviteId = NewId()
err = o.IsValid()
require.Nil(t, err, err)
appErr = o.IsValid()
require.Nil(t, appErr, appErr)
}
func TestTeamPreSave(t *testing.T) {

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

@@ -79,7 +79,7 @@ func (us *UploadSession) IsValid() *AppError {
}
if err := us.Type.IsValid(); err != nil {
return NewAppError("UploadSession.IsValid", "model.upload_session.is_valid.type.app_error", nil, err.Error(), http.StatusBadRequest)
return NewAppError("UploadSession.IsValid", "model.upload_session.is_valid.type.app_error", nil, "", http.StatusBadRequest).Wrap(err)
}
if !IsValidId(us.UserId) && us.UserId != UploadNoUserID {

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

@@ -13,8 +13,8 @@ func TestUploadSessionIsValid(t *testing.T) {
var session UploadSession
t.Run("empty session should fail", func(t *testing.T) {
err := session.IsValid()
require.NotNil(t, err)
appErr := session.IsValid()
require.NotNil(t, appErr)
})
t.Run("valid session should succeed", func(t *testing.T) {
@@ -29,97 +29,97 @@ func TestUploadSessionIsValid(t *testing.T) {
FileSize: 1024,
FileOffset: 0,
}
err := session.IsValid()
require.Nil(t, err)
appErr := session.IsValid()
require.Nil(t, appErr)
})
t.Run("invalid Id should fail", func(t *testing.T) {
us := session
us.Id = "invalid"
err := us.IsValid()
require.NotNil(t, err)
require.Equal(t, "model.upload_session.is_valid.id.app_error", err.Id)
appErr := us.IsValid()
require.NotNil(t, appErr)
require.Equal(t, "model.upload_session.is_valid.id.app_error", appErr.Id)
})
t.Run("invalid type should fail", func(t *testing.T) {
us := session
us.Type = "invalid"
err := us.IsValid()
require.NotNil(t, err)
require.Equal(t, "model.upload_session.is_valid.type.app_error", err.Id)
appErr := us.IsValid()
require.NotNil(t, appErr)
require.Equal(t, "model.upload_session.is_valid.type.app_error", appErr.Id)
})
t.Run("invalid CreateAt should fail", func(t *testing.T) {
us := session
us.CreateAt = 0
err := us.IsValid()
require.NotNil(t, err)
require.Equal(t, "model.upload_session.is_valid.create_at.app_error", err.Id)
appErr := us.IsValid()
require.NotNil(t, appErr)
require.Equal(t, "model.upload_session.is_valid.create_at.app_error", appErr.Id)
})
t.Run("invalid UserId should fail", func(t *testing.T) {
us := session
us.UserId = "invalid"
err := us.IsValid()
require.NotNil(t, err)
require.Equal(t, "model.upload_session.is_valid.user_id.app_error", err.Id)
appErr := us.IsValid()
require.NotNil(t, appErr)
require.Equal(t, "model.upload_session.is_valid.user_id.app_error", appErr.Id)
})
t.Run("invalid ChannelId should fail", func(t *testing.T) {
us := session
us.ChannelId = "invalid"
err := us.IsValid()
require.NotNil(t, err)
require.Equal(t, "model.upload_session.is_valid.channel_id.app_error", err.Id)
appErr := us.IsValid()
require.NotNil(t, appErr)
require.Equal(t, "model.upload_session.is_valid.channel_id.app_error", appErr.Id)
})
t.Run("ChannelId is not validated if type is not attachment", func(t *testing.T) {
us := session
us.ChannelId = ""
us.Type = UploadTypeImport
err := us.IsValid()
require.Nil(t, err)
appErr := us.IsValid()
require.Nil(t, appErr)
})
t.Run("invalid Filename should fail", func(t *testing.T) {
us := session
us.Filename = ""
err := us.IsValid()
require.NotNil(t, err)
require.Equal(t, "model.upload_session.is_valid.filename.app_error", err.Id)
appErr := us.IsValid()
require.NotNil(t, appErr)
require.Equal(t, "model.upload_session.is_valid.filename.app_error", appErr.Id)
})
t.Run("invalid Path should fail", func(t *testing.T) {
us := session
us.Path = ""
err := us.IsValid()
require.NotNil(t, err)
require.Equal(t, "model.upload_session.is_valid.path.app_error", err.Id)
appErr := us.IsValid()
require.NotNil(t, appErr)
require.Equal(t, "model.upload_session.is_valid.path.app_error", appErr.Id)
})
t.Run("invalid FileSize should fail", func(t *testing.T) {
us := session
us.FileSize = 0
err := us.IsValid()
require.NotNil(t, err)
require.Equal(t, "model.upload_session.is_valid.file_size.app_error", err.Id)
appErr := us.IsValid()
require.NotNil(t, appErr)
require.Equal(t, "model.upload_session.is_valid.file_size.app_error", appErr.Id)
us.FileSize = -1
err = us.IsValid()
require.NotNil(t, err)
require.Equal(t, "model.upload_session.is_valid.file_size.app_error", err.Id)
appErr = us.IsValid()
require.NotNil(t, appErr)
require.Equal(t, "model.upload_session.is_valid.file_size.app_error", appErr.Id)
})
t.Run("invalid FileOffset should fail", func(t *testing.T) {
us := session
us.FileOffset = us.FileSize + 1
err := us.IsValid()
require.NotNil(t, err)
require.Equal(t, "model.upload_session.is_valid.file_offset.app_error", err.Id)
appErr := us.IsValid()
require.NotNil(t, appErr)
require.Equal(t, "model.upload_session.is_valid.file_offset.app_error", appErr.Id)
us.FileOffset = -1
err = us.IsValid()
require.NotNil(t, err)
require.Equal(t, "model.upload_session.is_valid.file_offset.app_error", err.Id)
appErr = us.IsValid()
require.NotNil(t, appErr)
require.Equal(t, "model.upload_session.is_valid.file_offset.app_error", appErr.Id)
})
}

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

@@ -381,7 +381,7 @@ func (u *User) IsValid() *AppError {
if len(u.Timezone) > 0 {
if tzJSON, err := json.Marshal(u.Timezone); err != nil {
return NewAppError("User.IsValid", "model.user.is_valid.marshal.app_error", nil, err.Error(), http.StatusInternalServerError)
return NewAppError("User.IsValid", "model.user.is_valid.marshal.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
} else if utf8.RuneCount(tzJSON) > UserTimezoneMaxRunes {
return InvalidUserError("timezone_limit", u.Id)
}

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

@@ -12,21 +12,21 @@ import (
func TestUserAccessTokenIsValid(t *testing.T) {
ad := UserAccessToken{}
err := ad.IsValid()
require.False(t, err == nil || err.Id != "model.user_access_token.is_valid.id.app_error")
appErr := ad.IsValid()
require.False(t, appErr == nil || appErr.Id != "model.user_access_token.is_valid.id.app_error")
ad.Id = NewRandomString(26)
err = ad.IsValid()
require.False(t, err == nil || err.Id != "model.user_access_token.is_valid.token.app_error")
appErr = ad.IsValid()
require.False(t, appErr == nil || appErr.Id != "model.user_access_token.is_valid.token.app_error")
ad.Token = NewRandomString(26)
err = ad.IsValid()
require.False(t, err == nil || err.Id != "model.user_access_token.is_valid.user_id.app_error")
appErr = ad.IsValid()
require.False(t, appErr == nil || appErr.Id != "model.user_access_token.is_valid.user_id.app_error")
ad.UserId = NewRandomString(26)
require.Nil(t, ad.IsValid())
ad.Description = NewRandomString(256)
err = ad.IsValid()
require.False(t, err == nil || err.Id != "model.user_access_token.is_valid.description.app_error")
appErr = ad.IsValid()
require.False(t, appErr == nil || appErr.Id != "model.user_access_token.is_valid.description.app_error")
}

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

@@ -76,38 +76,38 @@ func TestUserUpdateMentionKeysFromUsername(t *testing.T) {
func TestUserIsValid(t *testing.T) {
user := User{}
err := user.IsValid()
require.True(t, HasExpectedUserIsValidError(err, "id", ""), "expected user is valid error: %s", err.Error())
appErr := user.IsValid()
require.True(t, HasExpectedUserIsValidError(appErr, "id", ""), "expected user is valid error: %s", appErr.Error())
user.Id = NewId()
err = user.IsValid()
require.True(t, HasExpectedUserIsValidError(err, "create_at", user.Id), "expected user is valid error: %s", err.Error())
appErr = user.IsValid()
require.True(t, HasExpectedUserIsValidError(appErr, "create_at", user.Id), "expected user is valid error: %s", appErr.Error())
user.CreateAt = GetMillis()
err = user.IsValid()
require.True(t, HasExpectedUserIsValidError(err, "update_at", user.Id), "expected user is valid error: %s", err.Error())
appErr = user.IsValid()
require.True(t, HasExpectedUserIsValidError(appErr, "update_at", user.Id), "expected user is valid error: %s", appErr.Error())
user.UpdateAt = GetMillis()
err = user.IsValid()
require.True(t, HasExpectedUserIsValidError(err, "username", user.Id), "expected user is valid error: %s", err.Error())
appErr = user.IsValid()
require.True(t, HasExpectedUserIsValidError(appErr, "username", user.Id), "expected user is valid error: %s", appErr.Error())
user.Username = NewId() + "^hello#"
err = user.IsValid()
require.True(t, HasExpectedUserIsValidError(err, "username", user.Id), "expected user is valid error: %s", err.Error())
appErr = user.IsValid()
require.True(t, HasExpectedUserIsValidError(appErr, "username", user.Id), "expected user is valid error: %s", appErr.Error())
user.Username = NewId()
err = user.IsValid()
require.True(t, HasExpectedUserIsValidError(err, "email", user.Id), "expected user is valid error: %s", err.Error())
appErr = user.IsValid()
require.True(t, HasExpectedUserIsValidError(appErr, "email", user.Id), "expected user is valid error: %s", appErr.Error())
user.Email = strings.Repeat("01234567890", 20)
err = user.IsValid()
require.True(t, HasExpectedUserIsValidError(err, "email", user.Id), "expected user is valid error: %s", err.Error())
appErr = user.IsValid()
require.True(t, HasExpectedUserIsValidError(appErr, "email", user.Id), "expected user is valid error: %s", appErr.Error())
user.Email = "user@example.com"
user.Nickname = strings.Repeat("a", 65)
err = user.IsValid()
require.True(t, HasExpectedUserIsValidError(err, "nickname", user.Id), "expected user is valid error: %s", err.Error())
appErr = user.IsValid()
require.True(t, HasExpectedUserIsValidError(appErr, "nickname", user.Id), "expected user is valid error: %s", appErr.Error())
user.Nickname = strings.Repeat("a", 64)
require.Nil(t, user.IsValid())
@@ -117,30 +117,30 @@ func TestUserIsValid(t *testing.T) {
require.Nil(t, user.IsValid())
user.FirstName = strings.Repeat("a", 65)
err = user.IsValid()
require.True(t, HasExpectedUserIsValidError(err, "first_name", user.Id), "expected user is valid error: %s", err.Error())
appErr = user.IsValid()
require.True(t, HasExpectedUserIsValidError(appErr, "first_name", user.Id), "expected user is valid error: %s", appErr.Error())
user.FirstName = strings.Repeat("a", 64)
user.LastName = strings.Repeat("a", 65)
err = user.IsValid()
require.True(t, HasExpectedUserIsValidError(err, "last_name", user.Id), "expected user is valid error: %s", err.Error())
appErr = user.IsValid()
require.True(t, HasExpectedUserIsValidError(appErr, "last_name", user.Id), "expected user is valid error: %s", appErr.Error())
user.LastName = strings.Repeat("a", 64)
user.Position = strings.Repeat("a", 128)
require.Nil(t, user.IsValid())
user.Position = strings.Repeat("a", 129)
err = user.IsValid()
require.True(t, HasExpectedUserIsValidError(err, "position", user.Id), "expected user is valid error: %s", err.Error())
appErr = user.IsValid()
require.True(t, HasExpectedUserIsValidError(appErr, "position", user.Id), "expected user is valid error: %s", appErr.Error())
user.Position = ""
user.Roles = strings.Repeat("a", UserRolesMaxLength)
err = user.IsValid()
require.Nil(t, err)
appErr = user.IsValid()
require.Nil(t, appErr)
user.Roles = strings.Repeat("a", UserRolesMaxLength+1)
err = user.IsValid()
require.True(t, HasExpectedUserIsValidError(err, "roles_limit", user.Id), "expected user is valid error: %s", err.Error())
appErr = user.IsValid()
require.True(t, HasExpectedUserIsValidError(appErr, "roles_limit", user.Id), "expected user is valid error: %s", appErr.Error())
}
func HasExpectedUserIsValidError(err *AppError, fieldName string, userId string) bool {
@@ -261,7 +261,7 @@ func TestCleanUsername(t *testing.T) {
assert.Equal(t, CleanUsername("PUNCH"), "punch", "didn't clean name properly")
assert.Equal(t, CleanUsername("spin'punch"), "spin-punch", "didn't clean name properly")
assert.Equal(t, CleanUsername("spin"), "spin", "didn't clean name properly")
assert.Equal(t, len(CleanUsername("all")), 27, "didn't clean name properly")
assert.Len(t, CleanUsername("all"), 27, "didn't clean name properly")
}
func TestRoles(t *testing.T) {
@@ -338,18 +338,18 @@ func TestUserSlice(t *testing.T) {
slice := UserSlice([]*User{user0, user1, user2})
activeUsers := slice.FilterByActive(true)
assert.Equal(t, 2, len(activeUsers))
assert.Len(t, activeUsers, 2)
for _, user := range activeUsers {
assert.True(t, user.DeleteAt == 0)
}
inactiveUsers := slice.FilterByActive(false)
assert.Equal(t, 1, len(inactiveUsers))
assert.Len(t, inactiveUsers, 1)
for _, user := range inactiveUsers {
assert.True(t, user.DeleteAt != 0)
}
nonBotUsers := slice.FilterWithoutBots()
assert.Equal(t, 1, len(nonBotUsers))
assert.Len(t, nonBotUsers, 1)
})
}

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

@@ -234,12 +234,11 @@ func (er *AppError) Error() string {
sb.WriteString(er.DetailedError)
}
// render all wrapped errors
// render the wrapped error
err := er.wrapped
for err != nil {
if err != nil {
sb.WriteString(", ")
sb.WriteString(err.Error())
err = errors.Unwrap(err)
}
return sb.String()
@@ -266,10 +265,30 @@ func (er *AppError) SystemMessage(T i18n.TranslateFunc) string {
}
func (er *AppError) ToJSON() string {
// turn the wrapped error into a detailed message
detailed := er.DetailedError
defer func() {
er.DetailedError = detailed
}()
er.wrappedToDetailed()
b, _ := json.Marshal(er)
return string(b)
}
func (er *AppError) wrappedToDetailed() {
if er.wrapped == nil {
return
}
if er.DetailedError != "" {
er.DetailedError += ", "
}
er.DetailedError += er.wrapped.Error()
}
func (er *AppError) Unwrap() error {
return er.wrapped
}

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

@@ -5,6 +5,7 @@ package model
import (
"bytes"
"errors"
"fmt"
"net/http"
"reflect"
@@ -72,12 +73,12 @@ func TestPadDateStringZeros(t *testing.T) {
}
func TestAppError(t *testing.T) {
err := NewAppError("TestAppError", "message", nil, "", http.StatusInternalServerError)
json := err.ToJSON()
appErr := NewAppError("TestAppError", "message", nil, "", http.StatusInternalServerError)
json := appErr.ToJSON()
rerr := AppErrorFromJSON(strings.NewReader(json))
require.Equal(t, err.Message, rerr.Message)
require.Equal(t, appErr.Message, rerr.Message)
t.Log(err.Error())
t.Log(appErr.Error())
}
func TestAppErrorJunk(t *testing.T) {
@@ -103,12 +104,58 @@ func TestAppErrorRender(t *testing.T) {
t.Run("WrappedMultiple", func(t *testing.T) {
aerr := NewAppError("here", "message", nil, "", http.StatusTeapot).Wrap(fmt.Errorf("my error (%w)", fmt.Errorf("inner error")))
assert.EqualError(t, aerr, "here: message, my error (inner error), inner error")
assert.EqualError(t, aerr, "here: message, my error (inner error)")
})
t.Run("DetailedWrappedMultiple", func(t *testing.T) {
aerr := NewAppError("here", "message", nil, "details", http.StatusTeapot).Wrap(fmt.Errorf("my error (%w)", fmt.Errorf("inner error")))
assert.EqualError(t, aerr, "here: message, details, my error (inner error), inner error")
assert.EqualError(t, aerr, "here: message, details, my error (inner error)")
})
}
func TestAppErrorSerialize(t *testing.T) {
t.Run("Normal", func(t *testing.T) {
aerr := NewAppError("", "message", nil, "", http.StatusTeapot)
js := aerr.ToJSON()
berr := AppErrorFromJSON(strings.NewReader(js))
require.Equal(t, "message", berr.Id)
require.Empty(t, berr.DetailedError)
require.Equal(t, http.StatusTeapot, berr.StatusCode)
require.EqualError(t, berr, aerr.Error())
})
t.Run("Detailed", func(t *testing.T) {
aerr := NewAppError("", "message", nil, "detail", http.StatusTeapot)
js := aerr.ToJSON()
berr := AppErrorFromJSON(strings.NewReader(js))
require.Equal(t, "message", berr.Id)
require.Equal(t, "detail", berr.DetailedError)
require.Equal(t, http.StatusTeapot, berr.StatusCode)
require.EqualError(t, berr, aerr.Error())
})
t.Run("Wrapped", func(t *testing.T) {
aerr := NewAppError("", "message", nil, "", http.StatusTeapot).Wrap(errors.New("wrapped"))
js := aerr.ToJSON()
berr := AppErrorFromJSON(strings.NewReader(js))
require.Equal(t, "message", berr.Id)
require.Equal(t, "wrapped", berr.DetailedError)
require.Equal(t, http.StatusTeapot, berr.StatusCode)
require.EqualError(t, berr, aerr.Error())
})
t.Run("Detailed + Wrapped", func(t *testing.T) {
aerr := NewAppError("", "message", nil, "detail", http.StatusTeapot).Wrap(errors.New("wrapped"))
js := aerr.ToJSON()
berr := AppErrorFromJSON(strings.NewReader(js))
require.Equal(t, "message", berr.Id)
require.Equal(t, "detail, wrapped", berr.DetailedError)
require.Equal(t, http.StatusTeapot, berr.StatusCode)
require.EqualError(t, berr, aerr.Error())
})
}

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

@@ -13,6 +13,7 @@ import (
// It should be maintained in chronological order with most current
// release at the front of the list.
var versions = []string{
"7.3.0",
"7.2.0",
"7.1.0",
"7.0.0",

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

@@ -89,7 +89,7 @@ func NewWebSocketClientWithDialer(dialer *websocket.Dialer, url, authToken strin
func makeClient(dialer *websocket.Dialer, url, connectURL, authToken string, header http.Header) (*WebSocketClient, error) {
conn, _, err := dialer.Dial(connectURL, header)
if err != nil {
return nil, NewAppError("NewWebSocketClient", "model.websocket_client.connect_fail.app_error", nil, err.Error(), http.StatusInternalServerError)
return nil, NewAppError("NewWebSocketClient", "model.websocket_client.connect_fail.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
client := &WebSocketClient{
@@ -140,7 +140,7 @@ func (wsc *WebSocketClient) ConnectWithDialer(dialer *websocket.Dialer) *AppErro
var err error
wsc.Conn, _, err = dialer.Dial(wsc.ConnectURL, nil)
if err != nil {
return NewAppError("Connect", "model.websocket_client.connect_fail.app_error", nil, err.Error(), http.StatusInternalServerError)
return NewAppError("Connect", "model.websocket_client.connect_fail.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
// Super racy and should not be done anyways.
// All of this needs to be redesigned for v6.
@@ -235,7 +235,7 @@ func (wsc *WebSocketClient) Listen() {
_, r, err := wsc.Conn.NextReader()
if err != nil {
if !websocket.IsCloseError(err, websocket.CloseNormalClosure, websocket.CloseNoStatusReceived) {
wsc.ListenError = NewAppError("NewWebSocketClient", "model.websocket_client.connect_fail.app_error", nil, err.Error(), http.StatusInternalServerError)
wsc.ListenError = NewAppError("NewWebSocketClient", "model.websocket_client.connect_fail.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
return
}
@@ -245,7 +245,7 @@ func (wsc *WebSocketClient) Listen() {
// This should use a different error ID, but en.json is not imported anyways.
// It's a different bug altogether but we let it be for now.
// See MM-24520.
wsc.ListenError = NewAppError("NewWebSocketClient", "model.websocket_client.connect_fail.app_error", nil, err.Error(), http.StatusInternalServerError)
wsc.ListenError = NewAppError("NewWebSocketClient", "model.websocket_client.connect_fail.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
return
}