Files
mattermost/model/user_test.go
2020-03-25 09:43:25 -07:00

376 lines
13 KiB
Go

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package model
import (
"fmt"
"math/rand"
"net/http"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestPasswordHash(t *testing.T) {
hash := HashPassword("Test")
assert.True(t, ComparePassword(hash, "Test"), "Passwords don't match")
assert.False(t, ComparePassword(hash, "Test2"), "Passwords should not have matched")
}
func TestUserDeepCopy(t *testing.T) {
id := NewId()
authData := "authdata"
mapKey := "key"
mapValue := "key"
user := &User{Id: id, AuthData: NewString(authData), Props: map[string]string{}, NotifyProps: map[string]string{}, Timezone: map[string]string{}}
user.Props[mapKey] = mapValue
user.NotifyProps[mapKey] = mapValue
user.Timezone[mapKey] = mapValue
copyUser := user.DeepCopy()
copyUser.Id = "someid"
*copyUser.AuthData = "changed"
copyUser.Props[mapKey] = "changed"
copyUser.NotifyProps[mapKey] = "changed"
copyUser.Timezone[mapKey] = "changed"
assert.Equal(t, id, user.Id)
assert.Equal(t, authData, *user.AuthData)
assert.Equal(t, mapValue, user.Props[mapKey])
assert.Equal(t, mapValue, user.NotifyProps[mapKey])
assert.Equal(t, mapValue, user.Timezone[mapKey])
user = &User{Id: id}
copyUser = user.DeepCopy()
assert.Equal(t, id, copyUser.Id)
}
func TestUserJson(t *testing.T) {
user := User{Id: NewId(), Username: NewId()}
json := user.ToJson()
ruser := UserFromJson(strings.NewReader(json))
assert.Equal(t, user.Id, ruser.Id, "Ids do not match")
}
func TestUserPreSave(t *testing.T) {
user := User{Password: "test"}
user.PreSave()
user.Etag(true, true)
assert.NotNil(t, user.Timezone, "Timezone is nil")
assert.Equal(t, user.Timezone["useAutomaticTimezone"], "true", "Timezone is not set to default")
}
func TestUserPreUpdate(t *testing.T) {
user := User{Password: "test"}
user.PreUpdate()
}
func TestUserUpdateMentionKeysFromUsername(t *testing.T) {
user := User{Username: "user"}
user.SetDefaultNotifications()
assert.Equalf(t, user.NotifyProps["mention_keys"], "", "default mention keys are invalid: %v", user.NotifyProps["mention_keys"])
user.Username = "person"
user.UpdateMentionKeysFromUsername("user")
assert.Equalf(t, user.NotifyProps["mention_keys"], "", "mention keys are invalid after changing username: %v", user.NotifyProps["mention_keys"])
user.NotifyProps["mention_keys"] += ",mention"
user.UpdateMentionKeysFromUsername("person")
assert.Equalf(t, user.NotifyProps["mention_keys"], ",mention", "mention keys are invalid after adding extra mention keyword: %v", user.NotifyProps["mention_keys"])
user.Username = "user"
user.UpdateMentionKeysFromUsername("person")
assert.Equalf(t, user.NotifyProps["mention_keys"], ",mention", "mention keys are invalid after changing username with extra mention keyword: %v", user.NotifyProps["mention_keys"])
}
func TestUserIsValid(t *testing.T) {
user := User{}
err := user.IsValid()
require.True(t, HasExpectedUserIsValidError(err, "id", ""), "expected user is valid error: %s", err.Error())
user.Id = NewId()
err = user.IsValid()
require.True(t, HasExpectedUserIsValidError(err, "create_at", user.Id), "expected user is valid error: %s", err.Error())
user.CreateAt = GetMillis()
err = user.IsValid()
require.True(t, HasExpectedUserIsValidError(err, "update_at", user.Id), "expected user is valid error: %s", err.Error())
user.UpdateAt = GetMillis()
err = user.IsValid()
require.True(t, HasExpectedUserIsValidError(err, "username", user.Id), "expected user is valid error: %s", err.Error())
user.Username = NewId() + "^hello#"
err = user.IsValid()
require.True(t, HasExpectedUserIsValidError(err, "username", user.Id), "expected user is valid error: %s", err.Error())
user.Username = NewId()
err = user.IsValid()
require.True(t, HasExpectedUserIsValidError(err, "email", user.Id), "expected user is valid error: %s", err.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())
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())
user.Nickname = strings.Repeat("a", 64)
require.Error(t, user.IsValid())
user.FirstName = ""
user.LastName = ""
require.Error(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())
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())
user.LastName = strings.Repeat("a", 64)
user.Position = strings.Repeat("a", 128)
require.Error(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())
}
func HasExpectedUserIsValidError(err *AppError, fieldName string, userId string) bool {
if err == nil {
return false
}
return err.Where == "User.IsValid" &&
err.Id == fmt.Sprintf("model.user.is_valid.%s.app_error", fieldName) &&
err.StatusCode == http.StatusBadRequest &&
(userId == "" || err.DetailedError == "user_id="+userId)
}
func TestUserGetFullName(t *testing.T) {
user := User{}
assert.Equal(t, user.GetFullName(), "", "Full name should be blank")
user.FirstName = "first"
assert.Equal(t, user.GetFullName(), "first", "Full name should be first name")
user.FirstName = ""
user.LastName = "last"
assert.Equal(t, user.GetFullName(), "last", "Full name should be last name")
user.FirstName = "first"
assert.Equal(t, user.GetFullName(), "first last", "Full name should be first name and last name")
}
func TestUserGetDisplayName(t *testing.T) {
user := User{Username: "username"}
assert.Equal(t, user.GetDisplayName(SHOW_FULLNAME), "username", "Display name should be username")
assert.Equal(t, user.GetDisplayName(SHOW_NICKNAME_FULLNAME), "username", "Display name should be username")
assert.Equal(t, user.GetDisplayName(SHOW_USERNAME), "username", "Display name should be username")
user.FirstName = "first"
user.LastName = "last"
assert.Equal(t, user.GetDisplayName(SHOW_FULLNAME), "first last", "Display name should be full name")
assert.Equal(t, user.GetDisplayName(SHOW_NICKNAME_FULLNAME), "first last", "Display name should be full name since there is no nickname")
assert.Equal(t, user.GetDisplayName(SHOW_USERNAME), "username", "Display name should be username")
user.Nickname = "nickname"
assert.Equal(t, user.GetDisplayName(SHOW_NICKNAME_FULLNAME), "nickname", "Display name should be nickname")
}
func TestUserGetDisplayNameWithPrefix(t *testing.T) {
user := User{Username: "username"}
assert.Equal(t, user.GetDisplayNameWithPrefix(SHOW_FULLNAME, "@"), "@username", "Display name should be username")
assert.Equal(t, user.GetDisplayNameWithPrefix(SHOW_NICKNAME_FULLNAME, "@"), "@username", "Display name should be username")
assert.Equal(t, user.GetDisplayNameWithPrefix(SHOW_USERNAME, "@"), "@username", "Display name should be username")
user.FirstName = "first"
user.LastName = "last"
assert.Equal(t, user.GetDisplayNameWithPrefix(SHOW_FULLNAME, "@"), "first last", "Display name should be full name")
assert.Equal(t, user.GetDisplayNameWithPrefix(SHOW_NICKNAME_FULLNAME, "@"), "first last", "Display name should be full name since there is no nickname")
assert.Equal(t, user.GetDisplayNameWithPrefix(SHOW_USERNAME, "@"), "@username", "Display name should be username")
user.Nickname = "nickname"
assert.Equal(t, user.GetDisplayNameWithPrefix(SHOW_NICKNAME_FULLNAME, "@"), "nickname", "Display name should be nickname")
}
var usernames = []struct {
value string
expected bool
}{
{"spin-punch", true},
{"sp", true},
{"s", true},
{"1spin-punch", true},
{"-spin-punch", true},
{".spin-punch", true},
{"Spin-punch", false},
{"spin punch-", false},
{"spin_punch", true},
{"spin", true},
{"PUNCH", false},
{"spin.punch", true},
{"spin'punch", false},
{"spin*punch", false},
{"all", false},
{"system", false},
}
func TestValidUsername(t *testing.T) {
for _, v := range usernames {
if IsValidUsername(v.value) != v.expected {
t.Errorf("expect %v as %v", v.value, v.expected)
}
}
}
func TestNormalizeUsername(t *testing.T) {
assert.Equal(t, NormalizeUsername("Spin-punch"), "spin-punch", "didn't normalize username properly")
assert.Equal(t, NormalizeUsername("PUNCH"), "punch", "didn't normalize username properly")
assert.Equal(t, NormalizeUsername("spin"), "spin", "didn't normalize username properly")
}
func TestNormalizeEmail(t *testing.T) {
assert.Equal(t, NormalizeEmail("TEST@EXAMPLE.COM"), "test@example.com", "didn't normalize email properly")
assert.Equal(t, NormalizeEmail("TEST2@example.com"), "test2@example.com", "didn't normalize email properly")
assert.Equal(t, NormalizeEmail("test3@example.com"), "test3@example.com", "didn't normalize email properly")
}
func TestCleanUsername(t *testing.T) {
assert.Equal(t, CleanUsername("Spin-punch"), "spin-punch", "didn't clean name properly")
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")
}
func TestRoles(t *testing.T) {
require.True(t, IsValidUserRoles("team_user"))
require.False(t, IsValidUserRoles("system_admin"))
require.True(t, IsValidUserRoles("system_user system_admin"))
require.False(t, IsInRole("system_admin junk", "admin"))
require.True(t, IsInRole("system_admin junk", "system_admin"))
require.False(t, IsInRole("admin", "system_admin"))
}
func TestIsValidLocale(t *testing.T) {
for _, test := range []struct {
Name string
Locale string
Expected bool
}{
{
Name: "empty locale",
Locale: "",
Expected: true,
},
{
Name: "locale with only language",
Locale: "fr",
Expected: true,
},
{
Name: "locale with region",
Locale: "en-DE", // English, as used in Germany
Expected: true,
},
{
Name: "invalid locale",
Locale: "'",
Expected: false,
},
// Note that the following cases are all valid language tags, but they're considered invalid here because of
// the max length of the User.Locale field.
{
Name: "locale with extended language subtag",
Locale: "zh-yue-HK", // Chinese, Cantonese, as used in Hong Kong
Expected: false,
},
{
Name: "locale with script",
Locale: "hy-Latn-IT-arevela", // Eastern Armenian written in Latin script, as used in Italy
Expected: false,
},
{
Name: "locale with variant",
Locale: "sl-rozaj-biske", // San Giorgio dialect of Resian dialect of Slovenian
Expected: false,
},
{
Name: "locale with extension",
Locale: "de-DE-u-co-phonebk", // German, as used in Germany, using German phonebook sort order
Expected: false,
},
} {
t.Run(test.Name, func(t *testing.T) {
assert.Equal(t, test.Expected, IsValidLocale(test.Locale))
})
}
}
func TestUserSlice(t *testing.T) {
t.Run("FilterByActive", func(t *testing.T) {
user0 := &User{Id: "user0", DeleteAt: 0, IsBot: true}
user1 := &User{Id: "user1", DeleteAt: 0, IsBot: true}
user2 := &User{Id: "user2", DeleteAt: 1, IsBot: false}
slice := UserSlice([]*User{user0, user1, user2})
activeUsers := slice.FilterByActive(true)
assert.Equal(t, 2, len(activeUsers))
for _, user := range activeUsers {
assert.True(t, user.DeleteAt == 0)
}
inactiveUsers := slice.FilterByActive(false)
assert.Equal(t, 1, len(inactiveUsers))
for _, user := range inactiveUsers {
assert.True(t, user.DeleteAt != 0)
}
nonBotUsers := slice.FilterWithoutBots()
assert.Equal(t, 1, len(nonBotUsers))
})
}
func TestGeneratePassword(t *testing.T) {
passwordRandomSource = rand.NewSource(12345)
t.Run("Should be the minimum length or 4, whichever is less", func(t *testing.T) {
password1 := GeneratePassword(5)
assert.Len(t, password1, 5)
password2 := GeneratePassword(10)
assert.Len(t, password2, 10)
password3 := GeneratePassword(1)
assert.Len(t, password3, 4)
})
t.Run("Should contain at least one of symbols, upper case, lower case and numbers", func(t *testing.T) {
password := GeneratePassword(4)
require.Len(t, password, 4)
assert.Contains(t, []rune(passwordUpperCaseLetters), []rune(password)[0])
assert.Contains(t, []rune(passwordNumbers), []rune(password)[1])
assert.Contains(t, []rune(passwordLowerCaseLetters), []rune(password)[2])
assert.Contains(t, []rune(passwordSpecialChars), []rune(password)[3])
})
}