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