github.com/haalcala/mattermost-server-change-repo/v5@v5.33.2/model/user_test.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package model 5 6 import ( 7 "fmt" 8 "math/rand" 9 "net/http" 10 "strings" 11 "testing" 12 13 "github.com/stretchr/testify/assert" 14 "github.com/stretchr/testify/require" 15 ) 16 17 func TestPasswordHash(t *testing.T) { 18 hash := HashPassword("Test") 19 20 assert.True(t, ComparePassword(hash, "Test"), "Passwords don't match") 21 assert.False(t, ComparePassword(hash, "Test2"), "Passwords should not have matched") 22 } 23 24 func TestUserDeepCopy(t *testing.T) { 25 id := NewId() 26 authData := "authdata" 27 mapKey := "key" 28 mapValue := "key" 29 30 user := &User{Id: id, AuthData: NewString(authData), Props: map[string]string{}, NotifyProps: map[string]string{}, Timezone: map[string]string{}} 31 user.Props[mapKey] = mapValue 32 user.NotifyProps[mapKey] = mapValue 33 user.Timezone[mapKey] = mapValue 34 35 copyUser := user.DeepCopy() 36 copyUser.Id = "someid" 37 *copyUser.AuthData = "changed" 38 copyUser.Props[mapKey] = "changed" 39 copyUser.NotifyProps[mapKey] = "changed" 40 copyUser.Timezone[mapKey] = "changed" 41 42 assert.Equal(t, id, user.Id) 43 assert.Equal(t, authData, *user.AuthData) 44 assert.Equal(t, mapValue, user.Props[mapKey]) 45 assert.Equal(t, mapValue, user.NotifyProps[mapKey]) 46 assert.Equal(t, mapValue, user.Timezone[mapKey]) 47 48 user = &User{Id: id} 49 copyUser = user.DeepCopy() 50 51 assert.Equal(t, id, copyUser.Id) 52 } 53 54 func TestUserJson(t *testing.T) { 55 user := User{Id: NewId(), Username: NewId()} 56 json := user.ToJson() 57 ruser := UserFromJson(strings.NewReader(json)) 58 59 assert.Equal(t, user.Id, ruser.Id, "Ids do not match") 60 } 61 62 func TestUserPreSave(t *testing.T) { 63 user := User{Password: "test"} 64 user.PreSave() 65 user.Etag(true, true) 66 assert.NotNil(t, user.Timezone, "Timezone is nil") 67 assert.Equal(t, user.Timezone["useAutomaticTimezone"], "true", "Timezone is not set to default") 68 } 69 70 func TestUserPreUpdate(t *testing.T) { 71 user := User{Password: "test"} 72 user.PreUpdate() 73 } 74 75 func TestUserUpdateMentionKeysFromUsername(t *testing.T) { 76 user := User{Username: "user"} 77 user.SetDefaultNotifications() 78 assert.Equalf(t, user.NotifyProps["mention_keys"], "", "default mention keys are invalid: %v", user.NotifyProps["mention_keys"]) 79 80 user.Username = "person" 81 user.UpdateMentionKeysFromUsername("user") 82 assert.Equalf(t, user.NotifyProps["mention_keys"], "", "mention keys are invalid after changing username: %v", user.NotifyProps["mention_keys"]) 83 84 user.NotifyProps["mention_keys"] += ",mention" 85 user.UpdateMentionKeysFromUsername("person") 86 assert.Equalf(t, user.NotifyProps["mention_keys"], ",mention", "mention keys are invalid after adding extra mention keyword: %v", user.NotifyProps["mention_keys"]) 87 88 user.Username = "user" 89 user.UpdateMentionKeysFromUsername("person") 90 assert.Equalf(t, user.NotifyProps["mention_keys"], ",mention", "mention keys are invalid after changing username with extra mention keyword: %v", user.NotifyProps["mention_keys"]) 91 } 92 93 func TestUserIsValid(t *testing.T) { 94 user := User{} 95 err := user.IsValid() 96 require.True(t, HasExpectedUserIsValidError(err, "id", ""), "expected user is valid error: %s", err.Error()) 97 98 user.Id = NewId() 99 err = user.IsValid() 100 require.True(t, HasExpectedUserIsValidError(err, "create_at", user.Id), "expected user is valid error: %s", err.Error()) 101 102 user.CreateAt = GetMillis() 103 err = user.IsValid() 104 require.True(t, HasExpectedUserIsValidError(err, "update_at", user.Id), "expected user is valid error: %s", err.Error()) 105 106 user.UpdateAt = GetMillis() 107 err = user.IsValid() 108 require.True(t, HasExpectedUserIsValidError(err, "username", user.Id), "expected user is valid error: %s", err.Error()) 109 110 user.Username = NewId() + "^hello#" 111 err = user.IsValid() 112 require.True(t, HasExpectedUserIsValidError(err, "username", user.Id), "expected user is valid error: %s", err.Error()) 113 114 user.Username = NewId() 115 err = user.IsValid() 116 require.True(t, HasExpectedUserIsValidError(err, "email", user.Id), "expected user is valid error: %s", err.Error()) 117 118 user.Email = strings.Repeat("01234567890", 20) 119 err = user.IsValid() 120 require.True(t, HasExpectedUserIsValidError(err, "email", user.Id), "expected user is valid error: %s", err.Error()) 121 122 user.Email = "user@example.com" 123 124 user.Nickname = strings.Repeat("a", 65) 125 err = user.IsValid() 126 require.True(t, HasExpectedUserIsValidError(err, "nickname", user.Id), "expected user is valid error: %s", err.Error()) 127 128 user.Nickname = strings.Repeat("a", 64) 129 require.Error(t, user.IsValid()) 130 131 user.FirstName = "" 132 user.LastName = "" 133 require.Error(t, user.IsValid()) 134 135 user.FirstName = strings.Repeat("a", 65) 136 err = user.IsValid() 137 require.True(t, HasExpectedUserIsValidError(err, "first_name", user.Id), "expected user is valid error: %s", err.Error()) 138 139 user.FirstName = strings.Repeat("a", 64) 140 user.LastName = strings.Repeat("a", 65) 141 err = user.IsValid() 142 require.True(t, HasExpectedUserIsValidError(err, "last_name", user.Id), "expected user is valid error: %s", err.Error()) 143 144 user.LastName = strings.Repeat("a", 64) 145 user.Position = strings.Repeat("a", 128) 146 require.Error(t, user.IsValid()) 147 148 user.Position = strings.Repeat("a", 129) 149 err = user.IsValid() 150 require.True(t, HasExpectedUserIsValidError(err, "position", user.Id), "expected user is valid error: %s", err.Error()) 151 } 152 153 func HasExpectedUserIsValidError(err *AppError, fieldName string, userId string) bool { 154 if err == nil { 155 return false 156 } 157 158 return err.Where == "User.IsValid" && 159 err.Id == fmt.Sprintf("model.user.is_valid.%s.app_error", fieldName) && 160 err.StatusCode == http.StatusBadRequest && 161 (userId == "" || err.DetailedError == "user_id="+userId) 162 } 163 164 func TestUserGetFullName(t *testing.T) { 165 user := User{} 166 assert.Equal(t, user.GetFullName(), "", "Full name should be blank") 167 168 user.FirstName = "first" 169 assert.Equal(t, user.GetFullName(), "first", "Full name should be first name") 170 171 user.FirstName = "" 172 user.LastName = "last" 173 assert.Equal(t, user.GetFullName(), "last", "Full name should be last name") 174 175 user.FirstName = "first" 176 assert.Equal(t, user.GetFullName(), "first last", "Full name should be first name and last name") 177 } 178 179 func TestUserGetDisplayName(t *testing.T) { 180 user := User{Username: "username"} 181 182 assert.Equal(t, user.GetDisplayName(SHOW_FULLNAME), "username", "Display name should be username") 183 assert.Equal(t, user.GetDisplayName(SHOW_NICKNAME_FULLNAME), "username", "Display name should be username") 184 assert.Equal(t, user.GetDisplayName(SHOW_USERNAME), "username", "Display name should be username") 185 186 user.FirstName = "first" 187 user.LastName = "last" 188 189 assert.Equal(t, user.GetDisplayName(SHOW_FULLNAME), "first last", "Display name should be full name") 190 assert.Equal(t, user.GetDisplayName(SHOW_NICKNAME_FULLNAME), "first last", "Display name should be full name since there is no nickname") 191 assert.Equal(t, user.GetDisplayName(SHOW_USERNAME), "username", "Display name should be username") 192 193 user.Nickname = "nickname" 194 assert.Equal(t, user.GetDisplayName(SHOW_NICKNAME_FULLNAME), "nickname", "Display name should be nickname") 195 } 196 197 func TestUserGetDisplayNameWithPrefix(t *testing.T) { 198 user := User{Username: "username"} 199 200 assert.Equal(t, user.GetDisplayNameWithPrefix(SHOW_FULLNAME, "@"), "@username", "Display name should be username") 201 assert.Equal(t, user.GetDisplayNameWithPrefix(SHOW_NICKNAME_FULLNAME, "@"), "@username", "Display name should be username") 202 assert.Equal(t, user.GetDisplayNameWithPrefix(SHOW_USERNAME, "@"), "@username", "Display name should be username") 203 204 user.FirstName = "first" 205 user.LastName = "last" 206 207 assert.Equal(t, user.GetDisplayNameWithPrefix(SHOW_FULLNAME, "@"), "first last", "Display name should be full name") 208 assert.Equal(t, user.GetDisplayNameWithPrefix(SHOW_NICKNAME_FULLNAME, "@"), "first last", "Display name should be full name since there is no nickname") 209 assert.Equal(t, user.GetDisplayNameWithPrefix(SHOW_USERNAME, "@"), "@username", "Display name should be username") 210 211 user.Nickname = "nickname" 212 assert.Equal(t, user.GetDisplayNameWithPrefix(SHOW_NICKNAME_FULLNAME, "@"), "nickname", "Display name should be nickname") 213 } 214 215 var usernames = []struct { 216 value string 217 expected bool 218 }{ 219 {"spin-punch", true}, 220 {"sp", true}, 221 {"s", true}, 222 {"1spin-punch", true}, 223 {"-spin-punch", true}, 224 {".spin-punch", true}, 225 {"Spin-punch", false}, 226 {"spin punch-", false}, 227 {"spin_punch", true}, 228 {"spin", true}, 229 {"PUNCH", false}, 230 {"spin.punch", true}, 231 {"spin'punch", false}, 232 {"spin*punch", false}, 233 {"all", false}, 234 {"system", false}, 235 } 236 237 func TestValidUsername(t *testing.T) { 238 for _, v := range usernames { 239 if IsValidUsername(v.value) != v.expected { 240 t.Errorf("expect %v as %v", v.value, v.expected) 241 } 242 } 243 } 244 245 func TestNormalizeUsername(t *testing.T) { 246 assert.Equal(t, NormalizeUsername("Spin-punch"), "spin-punch", "didn't normalize username properly") 247 assert.Equal(t, NormalizeUsername("PUNCH"), "punch", "didn't normalize username properly") 248 assert.Equal(t, NormalizeUsername("spin"), "spin", "didn't normalize username properly") 249 } 250 251 func TestNormalizeEmail(t *testing.T) { 252 assert.Equal(t, NormalizeEmail("TEST@EXAMPLE.COM"), "test@example.com", "didn't normalize email properly") 253 assert.Equal(t, NormalizeEmail("TEST2@example.com"), "test2@example.com", "didn't normalize email properly") 254 assert.Equal(t, NormalizeEmail("test3@example.com"), "test3@example.com", "didn't normalize email properly") 255 } 256 257 func TestCleanUsername(t *testing.T) { 258 assert.Equal(t, CleanUsername("Spin-punch"), "spin-punch", "didn't clean name properly") 259 assert.Equal(t, CleanUsername("PUNCH"), "punch", "didn't clean name properly") 260 assert.Equal(t, CleanUsername("spin'punch"), "spin-punch", "didn't clean name properly") 261 assert.Equal(t, CleanUsername("spin"), "spin", "didn't clean name properly") 262 assert.Equal(t, len(CleanUsername("all")), 27, "didn't clean name properly") 263 } 264 265 func TestRoles(t *testing.T) { 266 require.True(t, IsValidUserRoles("team_user")) 267 require.False(t, IsValidUserRoles("system_admin")) 268 require.True(t, IsValidUserRoles("system_user system_admin")) 269 require.False(t, IsInRole("system_admin junk", "admin")) 270 require.True(t, IsInRole("system_admin junk", "system_admin")) 271 require.False(t, IsInRole("admin", "system_admin")) 272 } 273 274 func TestIsValidLocale(t *testing.T) { 275 for _, test := range []struct { 276 Name string 277 Locale string 278 Expected bool 279 }{ 280 { 281 Name: "empty locale", 282 Locale: "", 283 Expected: true, 284 }, 285 { 286 Name: "locale with only language", 287 Locale: "fr", 288 Expected: true, 289 }, 290 { 291 Name: "locale with region", 292 Locale: "en-DE", // English, as used in Germany 293 Expected: true, 294 }, 295 { 296 Name: "invalid locale", 297 Locale: "'", 298 Expected: false, 299 }, 300 301 // Note that the following cases are all valid language tags, but they're considered invalid here because of 302 // the max length of the User.Locale field. 303 { 304 Name: "locale with extended language subtag", 305 Locale: "zh-yue-HK", // Chinese, Cantonese, as used in Hong Kong 306 Expected: false, 307 }, 308 { 309 Name: "locale with script", 310 Locale: "hy-Latn-IT-arevela", // Eastern Armenian written in Latin script, as used in Italy 311 Expected: false, 312 }, 313 { 314 Name: "locale with variant", 315 Locale: "sl-rozaj-biske", // San Giorgio dialect of Resian dialect of Slovenian 316 Expected: false, 317 }, 318 { 319 Name: "locale with extension", 320 Locale: "de-DE-u-co-phonebk", // German, as used in Germany, using German phonebook sort order 321 Expected: false, 322 }, 323 } { 324 t.Run(test.Name, func(t *testing.T) { 325 assert.Equal(t, test.Expected, IsValidLocale(test.Locale)) 326 }) 327 } 328 } 329 330 func TestUserSlice(t *testing.T) { 331 t.Run("FilterByActive", func(t *testing.T) { 332 user0 := &User{Id: "user0", DeleteAt: 0, IsBot: true} 333 user1 := &User{Id: "user1", DeleteAt: 0, IsBot: true} 334 user2 := &User{Id: "user2", DeleteAt: 1, IsBot: false} 335 336 slice := UserSlice([]*User{user0, user1, user2}) 337 338 activeUsers := slice.FilterByActive(true) 339 assert.Equal(t, 2, len(activeUsers)) 340 for _, user := range activeUsers { 341 assert.True(t, user.DeleteAt == 0) 342 } 343 344 inactiveUsers := slice.FilterByActive(false) 345 assert.Equal(t, 1, len(inactiveUsers)) 346 for _, user := range inactiveUsers { 347 assert.True(t, user.DeleteAt != 0) 348 } 349 350 nonBotUsers := slice.FilterWithoutBots() 351 assert.Equal(t, 1, len(nonBotUsers)) 352 }) 353 } 354 355 func TestGeneratePassword(t *testing.T) { 356 passwordRandom = lockedRand{ 357 rn: rand.New(rand.NewSource(12345)), 358 } 359 360 t.Run("Should be the minimum length or 4, whichever is less", func(t *testing.T) { 361 password1 := GeneratePassword(5) 362 assert.Len(t, password1, 5) 363 password2 := GeneratePassword(10) 364 assert.Len(t, password2, 10) 365 password3 := GeneratePassword(1) 366 assert.Len(t, password3, 4) 367 }) 368 369 t.Run("Should contain at least one of symbols, upper case, lower case and numbers", func(t *testing.T) { 370 password := GeneratePassword(4) 371 require.Len(t, password, 4) 372 assert.Contains(t, []rune(passwordUpperCaseLetters), []rune(password)[0]) 373 assert.Contains(t, []rune(passwordNumbers), []rune(password)[1]) 374 assert.Contains(t, []rune(passwordLowerCaseLetters), []rune(password)[2]) 375 assert.Contains(t, []rune(passwordSpecialChars), []rune(password)[3]) 376 }) 377 378 t.Run("Should not fail on concurrent calls", func(t *testing.T) { 379 for i := 0; i < 10; i++ { 380 go GeneratePassword(10) 381 } 382 }) 383 }