2017-04-12 08:27:57 -04:00
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2019-11-29 12:59:40 +01:00
// See LICENSE.txt for license information.
2015-06-14 23:53:32 -08:00
package model
import (
2017-04-17 16:45:51 +02:00
"fmt"
"net/http"
2015-06-14 23:53:32 -08:00
"strings"
"testing"
2018-04-20 08:44:18 -04:00
"github.com/stretchr/testify/assert"
2018-08-09 05:26:38 -04:00
"github.com/stretchr/testify/require"
2015-06-14 23:53:32 -08:00
)
2018-04-20 08:44:18 -04:00
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 ( )
2018-09-03 14:08:40 +02:00
assert . Equal ( t , id , copyUser . Id )
2018-04-20 08:44:18 -04:00
}
2015-06-14 23:53:32 -08:00
func TestUserPreSave ( t * testing . T ) {
user := User { Password : "test" }
user . PreSave ( )
2016-06-14 12:12:46 -04:00
user . Etag ( true , true )
2019-10-11 18:38:49 +05:30
assert . NotNil ( t , user . Timezone , "Timezone is nil" )
2019-10-28 14:08:08 +01:00
assert . Equal ( t , user . Timezone [ "useAutomaticTimezone" ] , "true" , "Timezone is not set to default" )
2015-06-14 23:53:32 -08:00
}
func TestUserPreUpdate ( t * testing . T ) {
user := User { Password : "test" }
user . PreUpdate ( )
}
2016-04-25 08:20:45 -04:00
func TestUserUpdateMentionKeysFromUsername ( t * testing . T ) {
user := User { Username : "user" }
user . SetDefaultNotifications ( )
2020-03-25 09:43:25 -07:00
assert . Equalf ( t , user . NotifyProps [ "mention_keys" ] , "" , "default mention keys are invalid: %v" , user . NotifyProps [ "mention_keys" ] )
2016-04-25 08:20:45 -04:00
user . Username = "person"
user . UpdateMentionKeysFromUsername ( "user" )
2020-03-25 09:43:25 -07:00
assert . Equalf ( t , user . NotifyProps [ "mention_keys" ] , "" , "mention keys are invalid after changing username: %v" , user . NotifyProps [ "mention_keys" ] )
2016-04-25 08:20:45 -04:00
user . NotifyProps [ "mention_keys" ] += ",mention"
user . UpdateMentionKeysFromUsername ( "person" )
2020-03-25 09:43:25 -07:00
assert . Equalf ( t , user . NotifyProps [ "mention_keys" ] , ",mention" , "mention keys are invalid after adding extra mention keyword: %v" , user . NotifyProps [ "mention_keys" ] )
2016-04-25 08:20:45 -04:00
user . Username = "user"
user . UpdateMentionKeysFromUsername ( "person" )
2020-03-25 09:43:25 -07:00
assert . Equalf ( t , user . NotifyProps [ "mention_keys" ] , ",mention" , "mention keys are invalid after changing username with extra mention keyword: %v" , user . NotifyProps [ "mention_keys" ] )
2016-04-25 08:20:45 -04:00
}
2015-06-14 23:53:32 -08:00
func TestUserIsValid ( t * testing . T ) {
user := User { }
2022-08-18 14:53:11 +02:00
appErr := user . IsValid ( )
2022-10-25 14:58:13 +05:30
require . True ( t , HasExpectedUserIsValidError ( appErr , "id" , "" , user . Id ) , "expected user is valid error: %s" , appErr . Error ( ) )
2015-06-14 23:53:32 -08:00
user . Id = NewId ( )
2022-08-18 14:53:11 +02:00
appErr = user . IsValid ( )
2022-10-25 14:58:13 +05:30
require . True ( t , HasExpectedUserIsValidError ( appErr , "create_at" , user . Id , user . CreateAt ) , "expected user is valid error: %s" , appErr . Error ( ) )
2015-06-14 23:53:32 -08:00
user . CreateAt = GetMillis ( )
2022-08-18 14:53:11 +02:00
appErr = user . IsValid ( )
2022-10-25 14:58:13 +05:30
require . True ( t , HasExpectedUserIsValidError ( appErr , "update_at" , user . Id , user . UpdateAt ) , "expected user is valid error: %s" , appErr . Error ( ) )
2015-06-14 23:53:32 -08:00
user . UpdateAt = GetMillis ( )
2022-08-18 14:53:11 +02:00
appErr = user . IsValid ( )
2022-10-25 14:58:13 +05:30
require . True ( t , HasExpectedUserIsValidError ( appErr , "username" , user . Id , user . Username ) , "expected user is valid error: %s" , appErr . Error ( ) )
2015-06-14 23:53:32 -08:00
user . Username = NewId ( ) + "^hello#"
2022-08-18 14:53:11 +02:00
appErr = user . IsValid ( )
2022-10-25 14:58:13 +05:30
require . True ( t , HasExpectedUserIsValidError ( appErr , "username" , user . Id , user . Username ) , "expected user is valid error: %s" , appErr . Error ( ) )
2015-06-14 23:53:32 -08:00
2017-04-18 17:37:25 -04:00
user . Username = NewId ( )
2022-08-18 14:53:11 +02:00
appErr = user . IsValid ( )
2022-10-25 14:58:13 +05:30
require . True ( t , HasExpectedUserIsValidError ( appErr , "email" , user . Id , user . Email ) , "expected user is valid error: %s" , appErr . Error ( ) )
2018-08-01 15:18:14 -04:00
2017-04-18 17:37:25 -04:00
user . Email = strings . Repeat ( "01234567890" , 20 )
2022-08-18 14:53:11 +02:00
appErr = user . IsValid ( )
2022-10-25 14:58:13 +05:30
require . True ( t , HasExpectedUserIsValidError ( appErr , "email" , user . Id , user . Email ) , "expected user is valid error: %s" , appErr . Error ( ) )
2015-06-14 23:53:32 -08:00
2018-08-01 15:18:14 -04:00
user . Email = "user@example.com"
2017-04-17 16:45:51 +02:00
user . Nickname = strings . Repeat ( "a" , 65 )
2022-08-18 14:53:11 +02:00
appErr = user . IsValid ( )
2022-10-25 14:58:13 +05:30
require . True ( t , HasExpectedUserIsValidError ( appErr , "nickname" , user . Id , user . Nickname ) , "expected user is valid error: %s" , appErr . Error ( ) )
2015-06-14 23:53:32 -08:00
2017-04-17 16:45:51 +02:00
user . Nickname = strings . Repeat ( "a" , 64 )
2021-02-24 11:09:52 +01:00
require . Nil ( t , user . IsValid ( ) )
2015-07-13 16:43:59 -04:00
user . FirstName = ""
user . LastName = ""
2021-02-24 11:09:52 +01:00
require . Nil ( t , user . IsValid ( ) )
2015-07-13 16:43:59 -04:00
2017-04-17 16:45:51 +02:00
user . FirstName = strings . Repeat ( "a" , 65 )
2022-08-18 14:53:11 +02:00
appErr = user . IsValid ( )
2022-10-25 14:58:13 +05:30
require . True ( t , HasExpectedUserIsValidError ( appErr , "first_name" , user . Id , user . FirstName ) , "expected user is valid error: %s" , appErr . Error ( ) )
2015-07-13 16:43:59 -04:00
2017-04-17 16:45:51 +02:00
user . FirstName = strings . Repeat ( "a" , 64 )
user . LastName = strings . Repeat ( "a" , 65 )
2022-08-18 14:53:11 +02:00
appErr = user . IsValid ( )
2022-10-25 14:58:13 +05:30
require . True ( t , HasExpectedUserIsValidError ( appErr , "last_name" , user . Id , user . LastName ) , "expected user is valid error: %s" , appErr . Error ( ) )
2016-12-14 11:11:51 +00:00
2017-04-17 16:45:51 +02:00
user . LastName = strings . Repeat ( "a" , 64 )
2018-01-26 08:37:12 -05:00
user . Position = strings . Repeat ( "a" , 128 )
2021-02-24 11:09:52 +01:00
require . Nil ( t , user . IsValid ( ) )
2016-12-14 11:11:51 +00:00
2018-01-26 08:37:12 -05:00
user . Position = strings . Repeat ( "a" , 129 )
2022-08-18 14:53:11 +02:00
appErr = user . IsValid ( )
2022-10-25 14:58:13 +05:30
require . True ( t , HasExpectedUserIsValidError ( appErr , "position" , user . Id , user . Position ) , "expected user is valid error: %s" , appErr . Error ( ) )
2021-10-01 15:31:29 +02:00
user . Position = ""
user . Roles = strings . Repeat ( "a" , UserRolesMaxLength )
2022-08-18 14:53:11 +02:00
appErr = user . IsValid ( )
require . Nil ( t , appErr )
2021-10-01 15:31:29 +02:00
user . Roles = strings . Repeat ( "a" , UserRolesMaxLength + 1 )
2022-08-18 14:53:11 +02:00
appErr = user . IsValid ( )
2022-10-25 14:58:13 +05:30
require . True ( t , HasExpectedUserIsValidError ( appErr , "roles_limit" , user . Id , user . Roles ) , "expected user is valid error: %s" , appErr . Error ( ) )
2015-06-14 23:53:32 -08:00
}
2015-07-13 17:47:57 -04:00
2022-10-25 14:58:13 +05:30
func HasExpectedUserIsValidError ( err * AppError , fieldName , userId string , fieldValue any ) bool {
2017-04-17 16:45:51 +02:00
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 &&
2022-10-25 14:58:13 +05:30
( userId == "" || err . DetailedError == fmt . Sprintf ( "user_id=%s %s=%v" , userId , fieldName , fieldValue ) )
2017-04-17 16:45:51 +02:00
}
2015-07-14 17:07:19 -04:00
func TestUserGetFullName ( t * testing . T ) {
user := User { }
2019-10-11 18:38:49 +05:30
assert . Equal ( t , user . GetFullName ( ) , "" , "Full name should be blank" )
2015-07-14 17:07:19 -04:00
user . FirstName = "first"
2019-10-11 18:38:49 +05:30
assert . Equal ( t , user . GetFullName ( ) , "first" , "Full name should be first name" )
2015-07-14 17:07:19 -04:00
user . FirstName = ""
user . LastName = "last"
2019-10-11 18:38:49 +05:30
assert . Equal ( t , user . GetFullName ( ) , "last" , "Full name should be last name" )
2015-07-14 17:07:19 -04:00
user . FirstName = "first"
2019-10-11 18:38:49 +05:30
assert . Equal ( t , user . GetFullName ( ) , "first last" , "Full name should be first name and last name" )
2015-07-14 17:07:19 -04:00
}
2015-07-13 17:47:57 -04:00
func TestUserGetDisplayName ( t * testing . T ) {
2017-06-30 16:06:59 +08:00
user := User { Username : "username" }
2021-07-12 20:05:36 +02:00
assert . Equal ( t , user . GetDisplayName ( ShowFullName ) , "username" , "Display name should be username" )
assert . Equal ( t , user . GetDisplayName ( ShowNicknameFullName ) , "username" , "Display name should be username" )
assert . Equal ( t , user . GetDisplayName ( ShowUsername ) , "username" , "Display name should be username" )
2015-07-13 17:47:57 -04:00
2015-07-14 17:07:19 -04:00
user . FirstName = "first"
user . LastName = "last"
2017-06-30 16:06:59 +08:00
2021-07-12 20:05:36 +02:00
assert . Equal ( t , user . GetDisplayName ( ShowFullName ) , "first last" , "Display name should be full name" )
assert . Equal ( t , user . GetDisplayName ( ShowNicknameFullName ) , "first last" , "Display name should be full name since there is no nickname" )
assert . Equal ( t , user . GetDisplayName ( ShowUsername ) , "username" , "Display name should be username" )
2017-06-30 16:06:59 +08:00
2015-07-13 17:47:57 -04:00
user . Nickname = "nickname"
2021-07-12 20:05:36 +02:00
assert . Equal ( t , user . GetDisplayName ( ShowNicknameFullName ) , "nickname" , "Display name should be nickname" )
2015-07-13 17:47:57 -04:00
}
2015-08-28 08:37:55 -04:00
2019-08-23 09:46:43 -04:00
func TestUserGetDisplayNameWithPrefix ( t * testing . T ) {
user := User { Username : "username" }
2021-07-12 20:05:36 +02:00
assert . Equal ( t , user . GetDisplayNameWithPrefix ( ShowFullName , "@" ) , "@username" , "Display name should be username" )
assert . Equal ( t , user . GetDisplayNameWithPrefix ( ShowNicknameFullName , "@" ) , "@username" , "Display name should be username" )
assert . Equal ( t , user . GetDisplayNameWithPrefix ( ShowUsername , "@" ) , "@username" , "Display name should be username" )
2019-08-23 09:46:43 -04:00
user . FirstName = "first"
user . LastName = "last"
2021-07-12 20:05:36 +02:00
assert . Equal ( t , user . GetDisplayNameWithPrefix ( ShowFullName , "@" ) , "first last" , "Display name should be full name" )
assert . Equal ( t , user . GetDisplayNameWithPrefix ( ShowNicknameFullName , "@" ) , "first last" , "Display name should be full name since there is no nickname" )
assert . Equal ( t , user . GetDisplayNameWithPrefix ( ShowUsername , "@" ) , "@username" , "Display name should be username" )
2019-08-23 09:46:43 -04:00
user . Nickname = "nickname"
2021-07-12 20:05:36 +02:00
assert . Equal ( t , user . GetDisplayNameWithPrefix ( ShowNicknameFullName , "@" ) , "nickname" , "Display name should be nickname" )
2019-08-23 09:46:43 -04:00
}
2021-04-13 10:40:12 -04:00
type usernamesTest struct {
value string
expected bool
expectedWhenRemote bool
}
var usernames = [ ] usernamesTest {
{ "spin-punch" , true , true } ,
{ "sp" , true , true } ,
{ "s" , true , true } ,
{ "1spin-punch" , true , true } ,
{ "-spin-punch" , true , true } ,
{ ".spin-punch" , true , true } ,
{ "Spin-punch" , false , false } ,
{ "spin punch-" , false , false } ,
{ "spin_punch" , true , true } ,
{ "spin" , true , true } ,
{ "PUNCH" , false , false } ,
{ "spin.punch" , true , true } ,
{ "spin'punch" , false , false } ,
{ "spin*punch" , false , false } ,
{ "all" , false , false } ,
{ "system" , false , false } ,
{ "spin:punch" , false , true } ,
2015-08-28 08:37:55 -04:00
}
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 )
}
}
2021-04-13 10:40:12 -04:00
for _ , v := range usernames {
if IsValidUsernameAllowRemote ( v . value ) != v . expectedWhenRemote {
t . Errorf ( "expect %v as %v" , v . value , v . expectedWhenRemote )
}
}
2015-08-28 08:37:55 -04:00
}
2018-02-05 14:56:01 -05:00
func TestNormalizeUsername ( t * testing . T ) {
2019-10-11 18:38:49 +05:30
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" )
2018-02-05 14:56:01 -05:00
}
func TestNormalizeEmail ( t * testing . T ) {
2019-10-11 18:38:49 +05:30
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" )
2018-02-05 14:56:01 -05:00
}
2015-08-28 08:37:55 -04:00
func TestCleanUsername ( t * testing . T ) {
2019-10-11 18:38:49 +05:30
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" )
2022-08-18 14:53:11 +02:00
assert . Len ( t , CleanUsername ( "all" ) , 27 , "didn't clean name properly" )
2015-08-28 08:37:55 -04:00
}
2015-09-04 11:59:10 -07:00
func TestRoles ( t * testing . T ) {
2018-08-09 05:26:38 -04:00
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" ) )
2015-09-04 11:59:10 -07:00
}
2018-12-19 09:36:39 -05:00
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 ) )
} )
}
}
2019-04-25 08:45:03 -04:00
func TestUserSlice ( t * testing . T ) {
t . Run ( "FilterByActive" , func ( t * testing . T ) {
2019-07-17 20:12:29 -05:00
user0 := & User { Id : "user0" , DeleteAt : 0 , IsBot : true }
user1 := & User { Id : "user1" , DeleteAt : 0 , IsBot : true }
user2 := & User { Id : "user2" , DeleteAt : 1 , IsBot : false }
2019-04-25 08:45:03 -04:00
slice := UserSlice ( [ ] * User { user0 , user1 , user2 } )
activeUsers := slice . FilterByActive ( true )
2022-08-18 14:53:11 +02:00
assert . Len ( t , activeUsers , 2 )
2019-04-25 08:45:03 -04:00
for _ , user := range activeUsers {
assert . True ( t , user . DeleteAt == 0 )
}
inactiveUsers := slice . FilterByActive ( false )
2022-08-18 14:53:11 +02:00
assert . Len ( t , inactiveUsers , 1 )
2019-04-25 08:45:03 -04:00
for _ , user := range inactiveUsers {
assert . True ( t , user . DeleteAt != 0 )
}
2019-07-17 20:12:29 -05:00
nonBotUsers := slice . FilterWithoutBots ( )
2022-08-18 14:53:11 +02:00
assert . Len ( t , nonBotUsers , 1 )
2019-04-25 08:45:03 -04:00
} )
}