// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. package app import ( "fmt" "path/filepath" "strings" "testing" "github.com/stretchr/testify/require" "github.com/mattermost/mattermost-server/v5/model" "github.com/mattermost/mattermost-server/v5/utils/fileutils" "github.com/stretchr/testify/assert" ) func TestImportValidateSchemeImportData(t *testing.T) { // Test with minimum required valid properties and team scope. data := SchemeImportData{ Name: ptrStr("name"), DisplayName: ptrStr("display name"), Scope: ptrStr("team"), DefaultTeamAdminRole: &RoleImportData{ Name: ptrStr("name"), DisplayName: ptrStr("display name"), Permissions: &[]string{"invite_user"}, }, DefaultTeamUserRole: &RoleImportData{ Name: ptrStr("name"), DisplayName: ptrStr("display name"), Permissions: &[]string{"invite_user"}, }, DefaultTeamGuestRole: &RoleImportData{ Name: ptrStr("name"), DisplayName: ptrStr("display name"), Permissions: &[]string{"invite_user"}, }, DefaultChannelAdminRole: &RoleImportData{ Name: ptrStr("name"), DisplayName: ptrStr("display name"), Permissions: &[]string{"invite_user"}, }, DefaultChannelUserRole: &RoleImportData{ Name: ptrStr("name"), DisplayName: ptrStr("display name"), Permissions: &[]string{"invite_user"}, }, DefaultChannelGuestRole: &RoleImportData{ Name: ptrStr("name"), DisplayName: ptrStr("display name"), Permissions: &[]string{"invite_user"}, }, } err := validateSchemeImportData(&data) require.Nil(t, err, "Validation failed but should have been valid.") // Test with various invalid names. data.Name = nil err = validateSchemeImportData(&data) require.NotNil(t, err, "Should have failed due to invalid name.") // Test with empty string data.Name = ptrStr("") err = validateSchemeImportData(&data) require.NotNil(t, err, "Should have failed due to invalid name.") // Test with numbers data.Name = ptrStr(strings.Repeat("1234567890", 100)) err = validateSchemeImportData(&data) require.NotNil(t, err, "Should have failed due to invalid name.") data.Name = ptrStr("name") // Test with invalid display name. data.DisplayName = nil err = validateSchemeImportData(&data) require.NotNil(t, err, "Should have failed due to invalid display name.") // Test with display name. data.DisplayName = ptrStr("") err = validateSchemeImportData(&data) require.NotNil(t, err, "Should have failed due to invalid display name.") // Test display name with numbers data.DisplayName = ptrStr(strings.Repeat("1234567890", 100)) err = validateSchemeImportData(&data) require.NotNil(t, err, "Should have failed due to invalid display name.") data.DisplayName = ptrStr("display name") // Test with various missing roles. data.DefaultTeamAdminRole = nil err = validateSchemeImportData(&data) require.NotNil(t, err, "Should have failed due to missing role.") data.DefaultTeamAdminRole = &RoleImportData{ Name: ptrStr("name"), DisplayName: ptrStr("display name"), Permissions: &[]string{"invite_user"}, } data.DefaultTeamUserRole = nil err = validateSchemeImportData(&data) require.NotNil(t, err, "Should have failed due to missing role.") data.DefaultTeamUserRole = &RoleImportData{ Name: ptrStr("name"), DisplayName: ptrStr("display name"), Permissions: &[]string{"invite_user"}, } data.DefaultChannelAdminRole = nil err = validateSchemeImportData(&data) require.NotNil(t, err, "Should have failed due to missing role.") data.DefaultChannelAdminRole = &RoleImportData{ Name: ptrStr("name"), DisplayName: ptrStr("display name"), Permissions: &[]string{"invite_user"}, } data.DefaultChannelUserRole = nil err = validateSchemeImportData(&data) require.NotNil(t, err, "Should have failed due to missing role.") data.DefaultChannelUserRole = &RoleImportData{ Name: ptrStr("name"), DisplayName: ptrStr("display name"), Permissions: &[]string{"invite_user"}, } // Test with various invalid roles. data.DefaultTeamAdminRole.Name = nil err = validateSchemeImportData(&data) require.NotNil(t, err, "Should have failed due to invalid role.") data.DefaultTeamAdminRole.Name = ptrStr("name") data.DefaultTeamUserRole.Name = nil err = validateSchemeImportData(&data) require.NotNil(t, err, "Should have failed due to invalid role.") data.DefaultTeamUserRole.Name = ptrStr("name") data.DefaultChannelAdminRole.Name = nil err = validateSchemeImportData(&data) require.NotNil(t, err, "Should have failed due to invalid role.") data.DefaultChannelAdminRole.Name = ptrStr("name") data.DefaultChannelUserRole.Name = nil err = validateSchemeImportData(&data) require.NotNil(t, err, "Should have failed due to invalid role.") data.DefaultChannelUserRole.Name = ptrStr("name") // Change to a Channel scope role, and check with missing or extra roles again. data.Scope = ptrStr("channel") data.DefaultTeamAdminRole = nil err = validateSchemeImportData(&data) require.NotNil(t, err, "Should have failed due to spurious role.") data.DefaultTeamAdminRole = &RoleImportData{ Name: ptrStr("name"), DisplayName: ptrStr("display name"), Permissions: &[]string{"invite_user"}, } data.DefaultTeamUserRole = nil err = validateSchemeImportData(&data) require.NotNil(t, err, "Should have failed due to spurious role.") data.DefaultTeamUserRole = &RoleImportData{ Name: ptrStr("name"), DisplayName: ptrStr("display name"), Permissions: &[]string{"invite_user"}, } data.DefaultTeamGuestRole = nil err = validateSchemeImportData(&data) require.NotNil(t, err, "Should have failed due to spurious role.") data.DefaultTeamGuestRole = nil data.DefaultTeamUserRole = nil data.DefaultTeamAdminRole = nil err = validateSchemeImportData(&data) require.Nil(t, err, "Should have succeeded.") // Test with all combinations of optional parameters. data.Description = ptrStr(strings.Repeat("1234567890", 1024)) err = validateSchemeImportData(&data) require.NotNil(t, err, "Should have failed due to invalid description.") data.Description = ptrStr("description") err = validateSchemeImportData(&data) require.Nil(t, err, "Should have succeeded.") } func TestImportValidateRoleImportData(t *testing.T) { // Test with minimum required valid properties. data := RoleImportData{ Name: ptrStr("name"), DisplayName: ptrStr("display name"), } err := validateRoleImportData(&data) require.Nil(t, err, "Validation failed but should have been valid.") // Test with various invalid names. data.Name = nil err = validateRoleImportData(&data) require.NotNil(t, err, "Should have failed due to invalid name.") data.Name = ptrStr("") err = validateRoleImportData(&data) require.NotNil(t, err, "Should have failed due to invalid name.") data.Name = ptrStr(strings.Repeat("1234567890", 100)) err = validateRoleImportData(&data) require.NotNil(t, err, "Should have failed due to invalid name.") data.Name = ptrStr("name") // Test with invalid display name. data.DisplayName = nil err = validateRoleImportData(&data) require.NotNil(t, err, "Should have failed due to invalid display name.") data.DisplayName = ptrStr("") err = validateRoleImportData(&data) require.NotNil(t, err, "Should have failed due to invalid display name.") data.DisplayName = ptrStr(strings.Repeat("1234567890", 100)) err = validateRoleImportData(&data) require.NotNil(t, err, "Should have failed due to invalid display name.") data.DisplayName = ptrStr("display name") // Test with various valid/invalid permissions. data.Permissions = &[]string{} err = validateRoleImportData(&data) require.Nil(t, err, "Validation failed but should have been valid.") data.Permissions = &[]string{"invite_user", "add_user_to_team"} err = validateRoleImportData(&data) require.Nil(t, err, "Validation failed but should have been valid.") data.Permissions = &[]string{"invite_user", "add_user_to_team", "derp"} err = validateRoleImportData(&data) require.NotNil(t, err, "Validation should have failed due to invalid permission.") data.Permissions = &[]string{"invite_user", "add_user_to_team"} // Test with various valid/invalid descriptions. data.Description = ptrStr(strings.Repeat("1234567890", 1024)) err = validateRoleImportData(&data) require.NotNil(t, err, "Validation should have failed due to invalid description.") data.Description = ptrStr("description") err = validateRoleImportData(&data) require.Nil(t, err, "Validation failed but should have been valid.") } func TestImportValidateTeamImportData(t *testing.T) { // Test with minimum required valid properties. data := TeamImportData{ Name: ptrStr("teamname"), DisplayName: ptrStr("Display Name"), Type: ptrStr("O"), } err := validateTeamImportData(&data) require.Nil(t, err, "Validation failed but should have been valid.") // Test with various invalid names. data = TeamImportData{ DisplayName: ptrStr("Display Name"), Type: ptrStr("O"), } err = validateTeamImportData(&data) require.NotNil(t, err, "Should have failed due to missing name.") data.Name = ptrStr(strings.Repeat("abcdefghij", 7)) err = validateTeamImportData(&data) require.NotNil(t, err, "Should have failed due to too long name.") data.Name = ptrStr("login") err = validateTeamImportData(&data) require.NotNil(t, err, "Should have failed due to reserved word in name.") data.Name = ptrStr("Test::''ASD") err = validateTeamImportData(&data) require.NotNil(t, err, "Should have failed due to non alphanum characters in name.") data.Name = ptrStr("A") err = validateTeamImportData(&data) require.NotNil(t, err, "Should have failed due to short name.") // Test team various invalid display names. data = TeamImportData{ Name: ptrStr("teamname"), Type: ptrStr("O"), } err = validateTeamImportData(&data) require.NotNil(t, err, "Should have failed due to missing display_name.") data.DisplayName = ptrStr("") err = validateTeamImportData(&data) require.NotNil(t, err, "Should have failed due to empty display_name.") data.DisplayName = ptrStr(strings.Repeat("abcdefghij", 7)) err = validateTeamImportData(&data) require.NotNil(t, err, "Should have failed due to too long display_name.") // Test with various valid and invalid types. data = TeamImportData{ Name: ptrStr("teamname"), DisplayName: ptrStr("Display Name"), } err = validateTeamImportData(&data) require.NotNil(t, err, "Should have failed due to missing type.") data.Type = ptrStr("A") err = validateTeamImportData(&data) require.NotNil(t, err, "Should have failed due to invalid type.") data.Type = ptrStr("I") err = validateTeamImportData(&data) require.Nil(t, err, "Should have succeeded with valid type.") // Test with all the combinations of optional parameters. data = TeamImportData{ Name: ptrStr("teamname"), DisplayName: ptrStr("Display Name"), Type: ptrStr("O"), Description: ptrStr("The team description."), AllowOpenInvite: ptrBool(true), } err = validateTeamImportData(&data) require.Nil(t, err, "Should have succeeded with valid optional properties.") data.AllowOpenInvite = ptrBool(false) err = validateTeamImportData(&data) require.Nil(t, err, "Should have succeeded with allow open invites false.") data.Description = ptrStr(strings.Repeat("abcdefghij ", 26)) err = validateTeamImportData(&data) require.NotNil(t, err, "Should have failed due to too long description.") // Test with an empty scheme name. data.Description = ptrStr("abcdefg") data.Scheme = ptrStr("") err = validateTeamImportData(&data) require.NotNil(t, err, "Should have failed due to empty scheme name.") // Test with a valid scheme name. data.Scheme = ptrStr("abcdefg") err = validateTeamImportData(&data) require.Nil(t, err, "Should have succeeded with valid scheme name.") } func TestImportValidateChannelImportData(t *testing.T) { // Test with minimum required valid properties. data := ChannelImportData{ Team: ptrStr("teamname"), Name: ptrStr("channelname"), DisplayName: ptrStr("Display Name"), Type: ptrStr("O"), } err := validateChannelImportData(&data) require.Nil(t, err, "Validation failed but should have been valid.") // Test with missing team. data = ChannelImportData{ Name: ptrStr("channelname"), DisplayName: ptrStr("Display Name"), Type: ptrStr("O"), } err = validateChannelImportData(&data) require.NotNil(t, err, "Should have failed due to missing team.") // Test with various invalid names. data = ChannelImportData{ Team: ptrStr("teamname"), DisplayName: ptrStr("Display Name"), Type: ptrStr("O"), } err = validateChannelImportData(&data) require.NotNil(t, err, "Should have failed due to missing name.") data.Name = ptrStr(strings.Repeat("abcdefghij", 7)) err = validateChannelImportData(&data) require.NotNil(t, err, "Should have failed due to too long name.") data.Name = ptrStr("Test::''ASD") err = validateChannelImportData(&data) require.NotNil(t, err, "Should have failed due to non alphanum characters in name.") data.Name = ptrStr("A") err = validateChannelImportData(&data) require.NotNil(t, err, "Should have failed due to short name.") // Test team various invalid display names. data = ChannelImportData{ Team: ptrStr("teamname"), Name: ptrStr("channelname"), Type: ptrStr("O"), } err = validateChannelImportData(&data) require.NotNil(t, err, "Should have failed due to missing display_name.") data.DisplayName = ptrStr("") err = validateChannelImportData(&data) require.NotNil(t, err, "Should have failed due to empty display_name.") data.DisplayName = ptrStr(strings.Repeat("abcdefghij", 7)) err = validateChannelImportData(&data) require.NotNil(t, err, "Should have failed due to too long display_name.") // Test with various valid and invalid types. data = ChannelImportData{ Team: ptrStr("teamname"), Name: ptrStr("channelname"), DisplayName: ptrStr("Display Name"), } err = validateChannelImportData(&data) require.NotNil(t, err, "Should have failed due to missing type.") data.Type = ptrStr("A") err = validateChannelImportData(&data) require.NotNil(t, err, "Should have failed due to invalid type.") data.Type = ptrStr("P") err = validateChannelImportData(&data) require.Nil(t, err, "Should have succeeded with valid type.") // Test with all the combinations of optional parameters. data = ChannelImportData{ Team: ptrStr("teamname"), Name: ptrStr("channelname"), DisplayName: ptrStr("Display Name"), Type: ptrStr("O"), Header: ptrStr("Channel Header Here"), Purpose: ptrStr("Channel Purpose Here"), } err = validateChannelImportData(&data) require.Nil(t, err, "Should have succeeded with valid optional properties.") data.Header = ptrStr(strings.Repeat("abcdefghij ", 103)) err = validateChannelImportData(&data) require.NotNil(t, err, "Should have failed due to too long header.") data.Header = ptrStr("Channel Header Here") data.Purpose = ptrStr(strings.Repeat("abcdefghij ", 26)) err = validateChannelImportData(&data) require.NotNil(t, err, "Should have failed due to too long purpose.") // Test with an empty scheme name. data.Purpose = ptrStr("abcdefg") data.Scheme = ptrStr("") err = validateChannelImportData(&data) require.NotNil(t, err, "Should have failed due to empty scheme name.") // Test with a valid scheme name. data.Scheme = ptrStr("abcdefg") err = validateChannelImportData(&data) require.Nil(t, err, "Should have succeeded with valid scheme name.") } func TestImportValidateUserImportData(t *testing.T) { // Test with minimum required valid properties. data := UserImportData{ Username: ptrStr("bob"), Email: ptrStr("bob@example.com"), } err := validateUserImportData(&data) require.Nil(t, err, "Validation failed but should have been valid.") // Invalid Usernames. data.Username = nil err = validateUserImportData(&data) require.NotNil(t, err, "Validation should have failed due to nil Username.") data.Username = ptrStr("") err = validateUserImportData(&data) require.NotNil(t, err, "Validation should have failed due to 0 length Username.") data.Username = ptrStr(strings.Repeat("abcdefghij", 7)) err = validateUserImportData(&data) require.NotNil(t, err, "Validation should have failed due to too long Username.") data.Username = ptrStr("i am a username with spaces and !!!") err = validateUserImportData(&data) require.NotNil(t, err, "Validation should have failed due to invalid characters in Username.") data.Username = ptrStr("bob") // Unexisting Picture Image data.ProfileImage = ptrStr("not-existing-file") err = validateUserImportData(&data) require.NotNil(t, err, "Validation should have failed due to not existing profile image file.") data.ProfileImage = nil // Invalid Emails data.Email = nil err = validateUserImportData(&data) require.NotNil(t, err, "Validation should have failed due to nil Email.") data.Email = ptrStr("") err = validateUserImportData(&data) require.NotNil(t, err, "Validation should have failed due to 0 length Email.") data.Email = ptrStr(strings.Repeat("abcdefghij", 13)) err = validateUserImportData(&data) require.NotNil(t, err, "Validation should have failed due to too long Email.") data.Email = ptrStr("bob@example.com") // Empty AuthService indicates user/password auth. data.AuthService = ptrStr("") checkNoError(t, validateUserImportData(&data)) data.AuthService = ptrStr("saml") data.AuthData = ptrStr(strings.Repeat("abcdefghij", 15)) err = validateUserImportData(&data) require.NotNil(t, err, "Validation should have failed due to too long auth data.") data.AuthData = ptrStr("bobbytables") err = validateUserImportData(&data) require.Nil(t, err, "Validation should have succeeded with valid auth service and auth data.") // Test a valid User with all fields populated. testsDir, _ := fileutils.FindDir("tests") data = UserImportData{ ProfileImage: ptrStr(filepath.Join(testsDir, "test.png")), Username: ptrStr("bob"), Email: ptrStr("bob@example.com"), AuthService: ptrStr("ldap"), AuthData: ptrStr("bob"), Nickname: ptrStr("BobNick"), FirstName: ptrStr("Bob"), LastName: ptrStr("Blob"), Position: ptrStr("The Boss"), Roles: ptrStr("system_user"), Locale: ptrStr("en"), } err = validateUserImportData(&data) require.Nil(t, err, "Validation failed but should have been valid.") // Test various invalid optional field values. data.Nickname = ptrStr(strings.Repeat("abcdefghij", 7)) err = validateUserImportData(&data) require.NotNil(t, err, "Validation should have failed due to too long Nickname.") data.Nickname = ptrStr("BobNick") data.FirstName = ptrStr(strings.Repeat("abcdefghij", 7)) err = validateUserImportData(&data) require.NotNil(t, err, "Validation should have failed due to too long First Name.") data.FirstName = ptrStr("Bob") data.LastName = ptrStr(strings.Repeat("abcdefghij", 7)) err = validateUserImportData(&data) require.NotNil(t, err, "Validation should have failed due to too long Last name.") data.LastName = ptrStr("Blob") data.Position = ptrStr(strings.Repeat("abcdefghij", 13)) err = validateUserImportData(&data) require.NotNil(t, err, "Validation should have failed due to too long Position.") data.Position = ptrStr("The Boss") data.Roles = nil err = validateUserImportData(&data) require.Nil(t, err, "Validation failed but should have been valid.") data.Roles = ptrStr("") err = validateUserImportData(&data) require.Nil(t, err, "Validation failed but should have been valid.") data.Roles = ptrStr("system_user") // Try various valid/invalid notify props. data.NotifyProps = &UserNotifyPropsImportData{} data.NotifyProps.Desktop = ptrStr("invalid") checkError(t, validateUserImportData(&data)) data.NotifyProps.Desktop = ptrStr(model.USER_NOTIFY_ALL) data.NotifyProps.DesktopSound = ptrStr("invalid") checkError(t, validateUserImportData(&data)) data.NotifyProps.DesktopSound = ptrStr("true") data.NotifyProps.Email = ptrStr("invalid") checkError(t, validateUserImportData(&data)) data.NotifyProps.Email = ptrStr("true") data.NotifyProps.Mobile = ptrStr("invalid") checkError(t, validateUserImportData(&data)) data.NotifyProps.Mobile = ptrStr(model.USER_NOTIFY_ALL) data.NotifyProps.MobilePushStatus = ptrStr("invalid") checkError(t, validateUserImportData(&data)) data.NotifyProps.MobilePushStatus = ptrStr(model.STATUS_ONLINE) data.NotifyProps.ChannelTrigger = ptrStr("invalid") checkError(t, validateUserImportData(&data)) data.NotifyProps.ChannelTrigger = ptrStr("true") data.NotifyProps.CommentsTrigger = ptrStr("invalid") checkError(t, validateUserImportData(&data)) data.NotifyProps.CommentsTrigger = ptrStr(model.COMMENTS_NOTIFY_ROOT) data.NotifyProps.MentionKeys = ptrStr("valid") checkNoError(t, validateUserImportData(&data)) //Test the emai batching interval validators //Happy paths data.EmailInterval = ptrStr("immediately") checkNoError(t, validateUserImportData(&data)) data.EmailInterval = ptrStr("fifteen") checkNoError(t, validateUserImportData(&data)) data.EmailInterval = ptrStr("hour") checkNoError(t, validateUserImportData(&data)) //Invalid values data.EmailInterval = ptrStr("invalid") checkError(t, validateUserImportData(&data)) data.EmailInterval = ptrStr("") checkError(t, validateUserImportData(&data)) } func TestImportValidateUserAuth(t *testing.T) { tests := []struct { authService *string authData *string isValid bool }{ {nil, nil, true}, {ptrStr(""), ptrStr(""), true}, {ptrStr("foo"), ptrStr("foo"), true}, {nil, ptrStr(""), true}, {ptrStr(""), nil, true}, {ptrStr("foo"), nil, false}, {ptrStr("foo"), ptrStr(""), false}, {nil, ptrStr("foo"), false}, {ptrStr(""), ptrStr("foo"), false}, } for _, test := range tests { data := UserImportData{ Username: ptrStr("bob"), Email: ptrStr("bob@example.com"), AuthService: test.authService, AuthData: test.authData, } err := validateUserImportData(&data) if test.isValid { require.Nil(t, err, fmt.Sprintf("authService: %v, authData: %v", test.authService, test.authData)) } else { require.NotNil(t, err, fmt.Sprintf("authService: %v, authData: %v", test.authService, test.authData)) require.Equal(t, "app.import.validate_user_import_data.auth_data_and_service_dependency.error", err.Id) } } } func TestImportValidateUserTeamsImportData(t *testing.T) { // Invalid Name. data := []UserTeamImportData{ { Roles: ptrStr("team_admin team_user"), }, } err := validateUserTeamsImportData(&data) require.NotNil(t, err, "Should have failed due to invalid name.") data[0].Name = ptrStr("teamname") // Valid (nil roles) data[0].Roles = nil err = validateUserTeamsImportData(&data) require.Nil(t, err, "Should have succeeded with empty roles.") // Valid (empty roles) data[0].Roles = ptrStr("") err = validateUserTeamsImportData(&data) require.Nil(t, err, "Should have succeeded with empty roles.") // Valid (with roles) data[0].Roles = ptrStr("team_admin team_user") err = validateUserTeamsImportData(&data) require.Nil(t, err, "Should have succeeded with valid roles.") // Valid (with JSON string of theme) data[0].Theme = ptrStr(`{"awayIndicator":"#DBBD4E","buttonBg":"#23A1FF","buttonColor":"#FFFFFF","centerChannelBg":"#ffffff","centerChannelColor":"#333333","codeTheme":"github","image":"/static/files/a4a388b38b32678e83823ef1b3e17766.png","linkColor":"#2389d7","mentionBg":"#2389d7","mentionColor":"#ffffff","mentionHighlightBg":"#fff2bb","mentionHighlightLink":"#2f81b7","newMessageSeparator":"#FF8800","onlineIndicator":"#7DBE00","sidebarBg":"#fafafa","sidebarHeaderBg":"#3481B9","sidebarHeaderTextColor":"#ffffff","sidebarText":"#333333","sidebarTextActiveBorder":"#378FD2","sidebarTextActiveColor":"#111111","sidebarTextHoverBg":"#e6f2fa","sidebarUnreadText":"#333333","type":"Mattermost"}`) err = validateUserTeamsImportData(&data) require.Nil(t, err, "Should have succeeded with valid theme.") // Invalid (invalid JSON string of theme) data[0].Theme = ptrStr(`This is the invalid string which cannot be marshalled to JSON object :) + {"#DBBD4E","buttonBg", "#23A1FF", buttonColor`) err = validateUserTeamsImportData(&data) require.NotNil(t, err, "Should have fail with invalid JSON string of theme.") // Invalid (valid JSON but invalid theme description) data[0].Theme = ptrStr(`{"somekey": 25, "json_obj1": {"color": "#DBBD4E","buttonBg": "#23A1FF"}}`) err = validateUserTeamsImportData(&data) require.NotNil(t, err, "Should have fail with valid JSON which contains invalid string of theme description.") data[0].Theme = nil } func TestImportValidateUserChannelsImportData(t *testing.T) { // Invalid Name. data := []UserChannelImportData{ { Roles: ptrStr("channel_admin channel_user"), }, } err := validateUserChannelsImportData(&data) require.NotNil(t, err, "Should have failed due to invalid name.") data[0].Name = ptrStr("channelname") // Valid (nil roles) data[0].Roles = nil err = validateUserChannelsImportData(&data) require.Nil(t, err, "Should have succeeded with empty roles.") // Valid (empty roles) data[0].Roles = ptrStr("") err = validateUserChannelsImportData(&data) require.Nil(t, err, "Should have succeeded with empty roles.") // Valid (with roles) data[0].Roles = ptrStr("channel_admin channel_user") err = validateUserChannelsImportData(&data) require.Nil(t, err, "Should have succeeded with valid roles.") // Empty notify props. data[0].NotifyProps = &UserChannelNotifyPropsImportData{} err = validateUserChannelsImportData(&data) require.Nil(t, err, "Should have succeeded with empty notify props.") // Invalid desktop notify props. data[0].NotifyProps.Desktop = ptrStr("invalid") err = validateUserChannelsImportData(&data) require.NotNil(t, err, "Should have failed with invalid desktop notify props.") // Invalid mobile notify props. data[0].NotifyProps.Desktop = ptrStr("mention") data[0].NotifyProps.Mobile = ptrStr("invalid") err = validateUserChannelsImportData(&data) require.NotNil(t, err, "Should have failed with invalid mobile notify props.") // Invalid mark_unread notify props. data[0].NotifyProps.Mobile = ptrStr("mention") data[0].NotifyProps.MarkUnread = ptrStr("invalid") err = validateUserChannelsImportData(&data) require.NotNil(t, err, "Should have failed with invalid mark_unread notify props.") // Valid notify props. data[0].NotifyProps.MarkUnread = ptrStr("mention") err = validateUserChannelsImportData(&data) require.Nil(t, err, "Should have succeeded with valid notify props.") } func TestImportValidateReactionImportData(t *testing.T) { // Test with minimum required valid properties. parentCreateAt := model.GetMillis() - 100 data := ReactionImportData{ User: ptrStr("username"), EmojiName: ptrStr("emoji"), CreateAt: ptrInt64(model.GetMillis()), } err := validateReactionImportData(&data, parentCreateAt) require.Nil(t, err, "Validation failed but should have been valid.") // Test with missing required properties. data = ReactionImportData{ EmojiName: ptrStr("emoji"), CreateAt: ptrInt64(model.GetMillis()), } err = validateReactionImportData(&data, parentCreateAt) require.NotNil(t, err, "Should have failed due to missing required property.") data = ReactionImportData{ User: ptrStr("username"), CreateAt: ptrInt64(model.GetMillis()), } err = validateReactionImportData(&data, parentCreateAt) require.NotNil(t, err, "Should have failed due to missing required property.") data = ReactionImportData{ User: ptrStr("username"), EmojiName: ptrStr("emoji"), } err = validateReactionImportData(&data, parentCreateAt) require.NotNil(t, err, "Should have failed due to missing required property.") // Test with invalid emoji name. data = ReactionImportData{ User: ptrStr("username"), EmojiName: ptrStr(strings.Repeat("1234567890", 500)), CreateAt: ptrInt64(model.GetMillis()), } err = validateReactionImportData(&data, parentCreateAt) require.NotNil(t, err, "Should have failed due to too long emoji name.") // Test with invalid CreateAt data = ReactionImportData{ User: ptrStr("username"), EmojiName: ptrStr("emoji"), CreateAt: ptrInt64(0), } err = validateReactionImportData(&data, parentCreateAt) require.NotNil(t, err, "Should have failed due to 0 create-at value.") data = ReactionImportData{ User: ptrStr("username"), EmojiName: ptrStr("emoji"), CreateAt: ptrInt64(parentCreateAt - 100), } err = validateReactionImportData(&data, parentCreateAt) require.NotNil(t, err, "Should have failed due parent with newer create-at value.") } func TestImportValidateReplyImportData(t *testing.T) { // Test with minimum required valid properties. parentCreateAt := model.GetMillis() - 100 maxPostSize := 10000 data := ReplyImportData{ User: ptrStr("username"), Message: ptrStr("message"), CreateAt: ptrInt64(model.GetMillis()), } err := validateReplyImportData(&data, parentCreateAt, maxPostSize) require.Nil(t, err, "Validation failed but should have been valid.") // Test with missing required properties. data = ReplyImportData{ Message: ptrStr("message"), CreateAt: ptrInt64(model.GetMillis()), } err = validateReplyImportData(&data, parentCreateAt, maxPostSize) require.NotNil(t, err, "Should have failed due to missing required property.") data = ReplyImportData{ User: ptrStr("username"), CreateAt: ptrInt64(model.GetMillis()), } err = validateReplyImportData(&data, parentCreateAt, maxPostSize) require.NotNil(t, err, "Should have failed due to missing required property.") data = ReplyImportData{ User: ptrStr("username"), Message: ptrStr("message"), } err = validateReplyImportData(&data, parentCreateAt, maxPostSize) require.NotNil(t, err, "Should have failed due to missing required property.") // Test with invalid message. data = ReplyImportData{ User: ptrStr("username"), Message: ptrStr(strings.Repeat("0", maxPostSize+1)), CreateAt: ptrInt64(model.GetMillis()), } err = validateReplyImportData(&data, parentCreateAt, maxPostSize) require.NotNil(t, err, "Should have failed due to too long message.") // Test with invalid CreateAt data = ReplyImportData{ User: ptrStr("username"), Message: ptrStr("message"), CreateAt: ptrInt64(0), } err = validateReplyImportData(&data, parentCreateAt, maxPostSize) require.NotNil(t, err, "Should have failed due to 0 create-at value.") data = ReplyImportData{ User: ptrStr("username"), Message: ptrStr("message"), CreateAt: ptrInt64(parentCreateAt - 100), } err = validateReplyImportData(&data, parentCreateAt, maxPostSize) require.NotNil(t, err, "Should have failed due parent with newer create-at value.") } func TestImportValidatePostImportData(t *testing.T) { maxPostSize := 10000 t.Run("Test with minimum required valid properties", func(t *testing.T) { data := PostImportData{ Team: ptrStr("teamname"), Channel: ptrStr("channelname"), User: ptrStr("username"), Message: ptrStr("message"), CreateAt: ptrInt64(model.GetMillis()), } err := validatePostImportData(&data, maxPostSize) require.Nil(t, err, "Validation failed but should have been valid.") }) t.Run("Test with missing required properties", func(t *testing.T) { data := PostImportData{ Channel: ptrStr("channelname"), User: ptrStr("username"), Message: ptrStr("message"), CreateAt: ptrInt64(model.GetMillis()), } err := validatePostImportData(&data, maxPostSize) require.NotNil(t, err, "Should have failed due to missing required property.") assert.Equal(t, err.Id, "app.import.validate_post_import_data.team_missing.error") data = PostImportData{ Team: ptrStr("teamname"), User: ptrStr("username"), Message: ptrStr("message"), CreateAt: ptrInt64(model.GetMillis()), } err = validatePostImportData(&data, maxPostSize) require.NotNil(t, err, "Should have failed due to missing required property.") assert.Equal(t, err.Id, "app.import.validate_post_import_data.channel_missing.error") data = PostImportData{ Team: ptrStr("teamname"), Channel: ptrStr("channelname"), Message: ptrStr("message"), CreateAt: ptrInt64(model.GetMillis()), } err = validatePostImportData(&data, maxPostSize) require.NotNil(t, err, "Should have failed due to missing required property.") assert.Equal(t, err.Id, "app.import.validate_post_import_data.user_missing.error") data = PostImportData{ Team: ptrStr("teamname"), Channel: ptrStr("channelname"), User: ptrStr("username"), CreateAt: ptrInt64(model.GetMillis()), } err = validatePostImportData(&data, maxPostSize) require.NotNil(t, err, "Should have failed due to missing required property.") assert.Equal(t, err.Id, "app.import.validate_post_import_data.message_missing.error") data = PostImportData{ Team: ptrStr("teamname"), Channel: ptrStr("channelname"), User: ptrStr("username"), Message: ptrStr("message"), } err = validatePostImportData(&data, maxPostSize) require.NotNil(t, err, "Should have failed due to missing required property.") assert.Equal(t, err.Id, "app.import.validate_post_import_data.create_at_missing.error") }) t.Run("Test with invalid message", func(t *testing.T) { data := PostImportData{ Team: ptrStr("teamname"), Channel: ptrStr("channelname"), User: ptrStr("username"), Message: ptrStr(strings.Repeat("0", maxPostSize+1)), CreateAt: ptrInt64(model.GetMillis()), } err := validatePostImportData(&data, maxPostSize) require.NotNil(t, err, "Should have failed due to too long message.") assert.Equal(t, err.Id, "app.import.validate_post_import_data.message_length.error") }) t.Run("Test with invalid CreateAt", func(t *testing.T) { data := PostImportData{ Team: ptrStr("teamname"), Channel: ptrStr("channelname"), User: ptrStr("username"), Message: ptrStr("message"), CreateAt: ptrInt64(0), } err := validatePostImportData(&data, maxPostSize) require.NotNil(t, err, "Should have failed due to 0 create-at value.") assert.Equal(t, err.Id, "app.import.validate_post_import_data.create_at_zero.error") }) t.Run("Test with valid all optional parameters", func(t *testing.T) { reactions := []ReactionImportData{{ User: ptrStr("username"), EmojiName: ptrStr("emoji"), CreateAt: ptrInt64(model.GetMillis()), }} replies := []ReplyImportData{{ User: ptrStr("username"), Message: ptrStr("message"), CreateAt: ptrInt64(model.GetMillis()), }} data := PostImportData{ Team: ptrStr("teamname"), Channel: ptrStr("channelname"), User: ptrStr("username"), Message: ptrStr("message"), CreateAt: ptrInt64(model.GetMillis()), Reactions: &reactions, Replies: &replies, } err := validatePostImportData(&data, maxPostSize) require.Nil(t, err, "Should have succeeded.") }) t.Run("Test with props too large", func(t *testing.T) { props := model.StringInterface{ "attachment": strings.Repeat("a", model.POST_PROPS_MAX_RUNES), } data := PostImportData{ Team: ptrStr("teamname"), Channel: ptrStr("channelname"), User: ptrStr("username"), Message: ptrStr("message"), Props: &props, CreateAt: ptrInt64(model.GetMillis()), } err := validatePostImportData(&data, maxPostSize) require.NotNil(t, err, "Should have failed due to long props.") assert.Equal(t, err.Id, "app.import.validate_post_import_data.props_too_large.error") }) } func TestImportValidateDirectChannelImportData(t *testing.T) { // Test with valid number of members for direct message. data := DirectChannelImportData{ Members: &[]string{ model.NewId(), model.NewId(), }, } err := validateDirectChannelImportData(&data) require.Nil(t, err, "Validation failed but should have been valid.") // Test with valid number of members for group message. data = DirectChannelImportData{ Members: &[]string{ model.NewId(), model.NewId(), model.NewId(), }, } err = validateDirectChannelImportData(&data) require.Nil(t, err, "Validation failed but should have been valid.") // Test with all the combinations of optional parameters. data = DirectChannelImportData{ Members: &[]string{ model.NewId(), model.NewId(), }, Header: ptrStr("Channel Header Here"), } err = validateDirectChannelImportData(&data) require.Nil(t, err, "Should have succeeded with valid optional properties.") // Test with invalid Header. data.Header = ptrStr(strings.Repeat("abcdefghij ", 103)) err = validateDirectChannelImportData(&data) require.NotNil(t, err, "Should have failed due to too long header.") // Test with different combinations of invalid member counts. data = DirectChannelImportData{ Members: &[]string{}, } err = validateDirectChannelImportData(&data) require.NotNil(t, err, "Validation should have failed due to invalid number of members.") data = DirectChannelImportData{ Members: &[]string{ model.NewId(), }, } err = validateDirectChannelImportData(&data) require.NotNil(t, err, "Validation should have failed due to invalid number of members.") data = DirectChannelImportData{ Members: &[]string{ model.NewId(), model.NewId(), model.NewId(), model.NewId(), model.NewId(), model.NewId(), model.NewId(), model.NewId(), model.NewId(), }, } err = validateDirectChannelImportData(&data) require.NotNil(t, err, "Validation should have failed due to invalid number of members.") // Test with invalid FavoritedBy member1 := model.NewId() member2 := model.NewId() data = DirectChannelImportData{ Members: &[]string{ member1, member2, }, FavoritedBy: &[]string{ member1, model.NewId(), }, } err = validateDirectChannelImportData(&data) require.NotNil(t, err, "Validation should have failed due to non-member favorited.") // Test with valid FavoritedBy data = DirectChannelImportData{ Members: &[]string{ member1, member2, }, FavoritedBy: &[]string{ member1, member2, }, } err = validateDirectChannelImportData(&data) require.Nil(t, err, "Validation should succeed with valid favorited member") } func TestImportValidateDirectPostImportData(t *testing.T) { maxPostSize := 10000 // Test with minimum required valid properties. data := DirectPostImportData{ ChannelMembers: &[]string{ model.NewId(), model.NewId(), }, User: ptrStr("username"), Message: ptrStr("message"), CreateAt: ptrInt64(model.GetMillis()), } err := validateDirectPostImportData(&data, maxPostSize) require.Nil(t, err, "Validation failed but should have been valid.") // Test with missing required properties. data = DirectPostImportData{ User: ptrStr("username"), Message: ptrStr("message"), CreateAt: ptrInt64(model.GetMillis()), } err = validateDirectPostImportData(&data, maxPostSize) require.NotNil(t, err, "Should have failed due to missing required property.") data = DirectPostImportData{ ChannelMembers: &[]string{ model.NewId(), model.NewId(), }, Message: ptrStr("message"), CreateAt: ptrInt64(model.GetMillis()), } err = validateDirectPostImportData(&data, maxPostSize) require.NotNil(t, err, "Should have failed due to missing required property.") data = DirectPostImportData{ ChannelMembers: &[]string{ model.NewId(), model.NewId(), }, User: ptrStr("username"), CreateAt: ptrInt64(model.GetMillis()), } err = validateDirectPostImportData(&data, maxPostSize) require.NotNil(t, err, "Should have failed due to missing required property.") data = DirectPostImportData{ ChannelMembers: &[]string{ model.NewId(), model.NewId(), }, User: ptrStr("username"), Message: ptrStr("message"), } err = validateDirectPostImportData(&data, maxPostSize) require.NotNil(t, err, "Should have failed due to missing required property.") // Test with invalid numbers of channel members. data = DirectPostImportData{ ChannelMembers: &[]string{}, User: ptrStr("username"), Message: ptrStr("message"), CreateAt: ptrInt64(model.GetMillis()), } err = validateDirectPostImportData(&data, maxPostSize) require.NotNil(t, err, "Should have failed due to unsuitable number of members.") data = DirectPostImportData{ ChannelMembers: &[]string{ model.NewId(), }, User: ptrStr("username"), Message: ptrStr("message"), CreateAt: ptrInt64(model.GetMillis()), } err = validateDirectPostImportData(&data, maxPostSize) require.NotNil(t, err, "Should have failed due to unsuitable number of members.") data = DirectPostImportData{ ChannelMembers: &[]string{ model.NewId(), model.NewId(), model.NewId(), model.NewId(), model.NewId(), model.NewId(), model.NewId(), model.NewId(), model.NewId(), model.NewId(), }, User: ptrStr("username"), Message: ptrStr("message"), CreateAt: ptrInt64(model.GetMillis()), } err = validateDirectPostImportData(&data, maxPostSize) require.NotNil(t, err, "Should have failed due to unsuitable number of members.") // Test with group message number of members. data = DirectPostImportData{ ChannelMembers: &[]string{ model.NewId(), model.NewId(), model.NewId(), }, User: ptrStr("username"), Message: ptrStr("message"), CreateAt: ptrInt64(model.GetMillis()), } err = validateDirectPostImportData(&data, maxPostSize) require.Nil(t, err, "Validation failed but should have been valid.") // Test with invalid message. data = DirectPostImportData{ ChannelMembers: &[]string{ model.NewId(), model.NewId(), }, User: ptrStr("username"), Message: ptrStr(strings.Repeat("0", maxPostSize+1)), CreateAt: ptrInt64(model.GetMillis()), } err = validateDirectPostImportData(&data, maxPostSize) require.NotNil(t, err, "Should have failed due to too long message.") // Test with invalid CreateAt data = DirectPostImportData{ ChannelMembers: &[]string{ model.NewId(), model.NewId(), }, User: ptrStr("username"), Message: ptrStr("message"), CreateAt: ptrInt64(0), } err = validateDirectPostImportData(&data, maxPostSize) require.NotNil(t, err, "Should have failed due to 0 create-at value.") // Test with invalid FlaggedBy member1 := model.NewId() member2 := model.NewId() data = DirectPostImportData{ ChannelMembers: &[]string{ member1, member2, }, FlaggedBy: &[]string{ member1, model.NewId(), }, User: ptrStr("username"), Message: ptrStr("message"), CreateAt: ptrInt64(model.GetMillis()), } err = validateDirectPostImportData(&data, maxPostSize) require.NotNil(t, err, "Validation should have failed due to non-member flagged.") // Test with valid FlaggedBy data = DirectPostImportData{ ChannelMembers: &[]string{ member1, member2, }, FlaggedBy: &[]string{ member1, member2, }, User: ptrStr("username"), Message: ptrStr("message"), CreateAt: ptrInt64(model.GetMillis()), } err = validateDirectPostImportData(&data, maxPostSize) require.Nil(t, err, "Validation should succeed with post flagged by members") // Test with valid all optional parameters. reactions := []ReactionImportData{{ User: ptrStr("username"), EmojiName: ptrStr("emoji"), CreateAt: ptrInt64(model.GetMillis()), }} replies := []ReplyImportData{{ User: ptrStr("username"), Message: ptrStr("message"), CreateAt: ptrInt64(model.GetMillis()), }} data = DirectPostImportData{ ChannelMembers: &[]string{ member1, member2, }, FlaggedBy: &[]string{ member1, member2, }, User: ptrStr("username"), Message: ptrStr("message"), CreateAt: ptrInt64(model.GetMillis()), Reactions: &reactions, Replies: &replies, } err = validateDirectPostImportData(&data, maxPostSize) require.Nil(t, err, "Validation should succeed with valid optional parameters") } func TestImportValidateEmojiImportData(t *testing.T) { data := EmojiImportData{ Name: ptrStr("parrot"), Image: ptrStr("/path/to/image"), } err := validateEmojiImportData(&data) assert.Nil(t, err, "Validation should succeed") *data.Name = "smiley" err = validateEmojiImportData(&data) assert.NotNil(t, err) *data.Name = "" err = validateEmojiImportData(&data) assert.NotNil(t, err) *data.Name = "" *data.Image = "" err = validateEmojiImportData(&data) assert.NotNil(t, err) *data.Image = "/path/to/image" data.Name = nil err = validateEmojiImportData(&data) assert.NotNil(t, err) data.Name = ptrStr("parrot") data.Image = nil err = validateEmojiImportData(&data) assert.NotNil(t, err) }