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  }