github.com/spline-fu/mattermost-server@v4.10.10+incompatible/model/utils_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  	"net/http"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  func TestNewId(t *testing.T) {
    16  	for i := 0; i < 1000; i++ {
    17  		id := NewId()
    18  		if len(id) > 26 {
    19  			t.Fatal("ids shouldn't be longer than 26 chars")
    20  		}
    21  	}
    22  }
    23  
    24  func TestRandomString(t *testing.T) {
    25  	for i := 0; i < 1000; i++ {
    26  		r := NewRandomString(32)
    27  		if len(r) != 32 {
    28  			t.Fatal("should be 32 chars")
    29  		}
    30  	}
    31  }
    32  
    33  func TestAppError(t *testing.T) {
    34  	err := NewAppError("TestAppError", "message", nil, "", http.StatusInternalServerError)
    35  	json := err.ToJson()
    36  	rerr := AppErrorFromJson(strings.NewReader(json))
    37  	if err.Message != rerr.Message {
    38  		t.Fatal()
    39  	}
    40  
    41  	t.Log(err.Error())
    42  }
    43  
    44  func TestAppErrorJunk(t *testing.T) {
    45  	rerr := AppErrorFromJson(strings.NewReader("<html><body>This is a broken test</body></html>"))
    46  	if "body: <html><body>This is a broken test</body></html>" != rerr.DetailedError {
    47  		t.Fatal()
    48  	}
    49  }
    50  
    51  func TestCopyStringMap(t *testing.T) {
    52  	itemKey := "item1"
    53  	originalMap := make(map[string]string)
    54  	originalMap[itemKey] = "val1"
    55  
    56  	copyMap := CopyStringMap(originalMap)
    57  	copyMap[itemKey] = "changed"
    58  
    59  	assert.Equal(t, "val1", originalMap[itemKey])
    60  }
    61  
    62  func TestMapJson(t *testing.T) {
    63  
    64  	m := make(map[string]string)
    65  	m["id"] = "test_id"
    66  	json := MapToJson(m)
    67  
    68  	rm := MapFromJson(strings.NewReader(json))
    69  
    70  	if rm["id"] != "test_id" {
    71  		t.Fatal("map should be valid")
    72  	}
    73  
    74  	rm2 := MapFromJson(strings.NewReader(""))
    75  	if len(rm2) > 0 {
    76  		t.Fatal("make should be ivalid")
    77  	}
    78  }
    79  
    80  func TestIsValidEmail(t *testing.T) {
    81  	for _, testCase := range []struct {
    82  		Input    string
    83  		Expected bool
    84  	}{
    85  		{
    86  			Input:    "corey",
    87  			Expected: false,
    88  		},
    89  		{
    90  			Input:    "corey@example.com",
    91  			Expected: true,
    92  		},
    93  		{
    94  			Input:    "corey+test@example.com",
    95  			Expected: true,
    96  		},
    97  		{
    98  			Input:    "@corey+test@example.com",
    99  			Expected: false,
   100  		},
   101  		{
   102  			Input:    "firstname.lastname@example.com",
   103  			Expected: true,
   104  		},
   105  		{
   106  			Input:    "firstname.lastname@subdomain.example.com",
   107  			Expected: true,
   108  		},
   109  		{
   110  			Input:    "123454567@domain.com",
   111  			Expected: true,
   112  		},
   113  		{
   114  			Input:    "email@domain-one.com",
   115  			Expected: true,
   116  		},
   117  		{
   118  			Input:    "email@domain.co.jp",
   119  			Expected: true,
   120  		},
   121  		{
   122  			Input:    "firstname-lastname@domain.com",
   123  			Expected: true,
   124  		},
   125  		{
   126  			Input:    "@domain.com",
   127  			Expected: false,
   128  		},
   129  		{
   130  			Input:    "Billy Bob <billy@example.com>",
   131  			Expected: false,
   132  		},
   133  		{
   134  			Input:    "email.domain.com",
   135  			Expected: false,
   136  		},
   137  		{
   138  			Input:    "email.@domain.com",
   139  			Expected: false,
   140  		},
   141  		{
   142  			Input:    "email@domain@domain.com",
   143  			Expected: false,
   144  		},
   145  		{
   146  			Input:    "(email@domain.com)",
   147  			Expected: false,
   148  		},
   149  		{
   150  			Input:    "email@汤.中国",
   151  			Expected: true,
   152  		},
   153  		{
   154  			Input:    "email1@domain.com, email2@domain.com",
   155  			Expected: false,
   156  		},
   157  	} {
   158  		t.Run(testCase.Input, func(t *testing.T) {
   159  			assert.Equal(t, testCase.Expected, IsValidEmail(testCase.Input))
   160  		})
   161  	}
   162  }
   163  
   164  func TestValidLower(t *testing.T) {
   165  	if !IsLower("corey+test@hulen.com") {
   166  		t.Error("should be valid")
   167  	}
   168  
   169  	if IsLower("Corey+test@hulen.com") {
   170  		t.Error("should be invalid")
   171  	}
   172  }
   173  
   174  func TestEtag(t *testing.T) {
   175  	etag := Etag("hello", 24)
   176  	if len(etag) <= 0 {
   177  		t.Fatal()
   178  	}
   179  }
   180  
   181  var hashtags = map[string]string{
   182  	"#test":           "#test",
   183  	"test":            "",
   184  	"#test123":        "#test123",
   185  	"#123test123":     "",
   186  	"#test-test":      "#test-test",
   187  	"#test?":          "#test",
   188  	"hi #there":       "#there",
   189  	"#bug #idea":      "#bug #idea",
   190  	"#bug or #gif!":   "#bug #gif",
   191  	"#hüllo":          "#hüllo",
   192  	"#?test":          "",
   193  	"#-test":          "",
   194  	"#yo_yo":          "#yo_yo",
   195  	"(#brakets)":      "#brakets",
   196  	")#stekarb(":      "#stekarb",
   197  	"<#less_than<":    "#less_than",
   198  	">#greater_than>": "#greater_than",
   199  	"-#minus-":        "#minus",
   200  	"_#under_":        "#under",
   201  	"+#plus+":         "#plus",
   202  	"=#equals=":       "#equals",
   203  	"%#pct%":          "#pct",
   204  	"&#and&":          "#and",
   205  	"^#hat^":          "#hat",
   206  	"##brown#":        "#brown",
   207  	"*#star*":         "#star",
   208  	"|#pipe|":         "#pipe",
   209  	":#colon:":        "#colon",
   210  	";#semi;":         "#semi",
   211  	"#Mötley;":        "#Mötley",
   212  	".#period.":       "#period",
   213  	"¿#upside¿":       "#upside",
   214  	"\"#quote\"":      "#quote",
   215  	"/#slash/":        "#slash",
   216  	"\\#backslash\\":  "#backslash",
   217  	"#a":              "",
   218  	"#1":              "",
   219  	"foo#bar":         "",
   220  }
   221  
   222  func TestParseHashtags(t *testing.T) {
   223  	for input, output := range hashtags {
   224  		if o, _ := ParseHashtags(input); o != output {
   225  			t.Fatal("failed to parse hashtags from input=" + input + " expected=" + output + " actual=" + o)
   226  		}
   227  	}
   228  }
   229  
   230  func TestIsValidAlphaNum(t *testing.T) {
   231  	cases := []struct {
   232  		Input  string
   233  		Result bool
   234  	}{
   235  		{
   236  			Input:  "test",
   237  			Result: true,
   238  		},
   239  		{
   240  			Input:  "test-name",
   241  			Result: true,
   242  		},
   243  		{
   244  			Input:  "test--name",
   245  			Result: true,
   246  		},
   247  		{
   248  			Input:  "test__name",
   249  			Result: true,
   250  		},
   251  		{
   252  			Input:  "-",
   253  			Result: false,
   254  		},
   255  		{
   256  			Input:  "__",
   257  			Result: false,
   258  		},
   259  		{
   260  			Input:  "test-",
   261  			Result: false,
   262  		},
   263  		{
   264  			Input:  "test--",
   265  			Result: false,
   266  		},
   267  		{
   268  			Input:  "test__",
   269  			Result: false,
   270  		},
   271  		{
   272  			Input:  "test:name",
   273  			Result: false,
   274  		},
   275  	}
   276  
   277  	for _, tc := range cases {
   278  		actual := IsValidAlphaNum(tc.Input)
   279  		if actual != tc.Result {
   280  			t.Fatalf("case: %v\tshould returned: %#v", tc, tc.Result)
   281  		}
   282  	}
   283  }
   284  
   285  func TestGetServerIpAddress(t *testing.T) {
   286  	if len(GetServerIpAddress()) == 0 {
   287  		t.Fatal("Should find local ip address")
   288  	}
   289  }
   290  
   291  func TestIsValidAlphaNumHyphenUnderscore(t *testing.T) {
   292  	casesWithFormat := []struct {
   293  		Input  string
   294  		Result bool
   295  	}{
   296  		{
   297  			Input:  "test",
   298  			Result: true,
   299  		},
   300  		{
   301  			Input:  "test-name",
   302  			Result: true,
   303  		},
   304  		{
   305  			Input:  "test--name",
   306  			Result: true,
   307  		},
   308  		{
   309  			Input:  "test__name",
   310  			Result: true,
   311  		},
   312  		{
   313  			Input:  "test_name",
   314  			Result: true,
   315  		},
   316  		{
   317  			Input:  "test_-name",
   318  			Result: true,
   319  		},
   320  		{
   321  			Input:  "-",
   322  			Result: false,
   323  		},
   324  		{
   325  			Input:  "__",
   326  			Result: false,
   327  		},
   328  		{
   329  			Input:  "test-",
   330  			Result: false,
   331  		},
   332  		{
   333  			Input:  "test--",
   334  			Result: false,
   335  		},
   336  		{
   337  			Input:  "test__",
   338  			Result: false,
   339  		},
   340  		{
   341  			Input:  "test:name",
   342  			Result: false,
   343  		},
   344  	}
   345  
   346  	for _, tc := range casesWithFormat {
   347  		actual := IsValidAlphaNumHyphenUnderscore(tc.Input, true)
   348  		if actual != tc.Result {
   349  			t.Fatalf("case: %v\tshould returned: %#v", tc, tc.Result)
   350  		}
   351  	}
   352  
   353  	casesWithoutFormat := []struct {
   354  		Input  string
   355  		Result bool
   356  	}{
   357  		{
   358  			Input:  "test",
   359  			Result: true,
   360  		},
   361  		{
   362  			Input:  "test-name",
   363  			Result: true,
   364  		},
   365  		{
   366  			Input:  "test--name",
   367  			Result: true,
   368  		},
   369  		{
   370  			Input:  "test__name",
   371  			Result: true,
   372  		},
   373  		{
   374  			Input:  "test_name",
   375  			Result: true,
   376  		},
   377  		{
   378  			Input:  "test_-name",
   379  			Result: true,
   380  		},
   381  		{
   382  			Input:  "-",
   383  			Result: true,
   384  		},
   385  		{
   386  			Input:  "_",
   387  			Result: true,
   388  		},
   389  		{
   390  			Input:  "test-",
   391  			Result: true,
   392  		},
   393  		{
   394  			Input:  "test--",
   395  			Result: true,
   396  		},
   397  		{
   398  			Input:  "test__",
   399  			Result: true,
   400  		},
   401  		{
   402  			Input:  ".",
   403  			Result: false,
   404  		},
   405  
   406  		{
   407  			Input:  "test,",
   408  			Result: false,
   409  		},
   410  		{
   411  			Input:  "test:name",
   412  			Result: false,
   413  		},
   414  	}
   415  
   416  	for _, tc := range casesWithoutFormat {
   417  		actual := IsValidAlphaNumHyphenUnderscore(tc.Input, false)
   418  		if actual != tc.Result {
   419  			t.Fatalf("case: '%v'\tshould returned: %#v", tc.Input, tc.Result)
   420  		}
   421  	}
   422  }
   423  
   424  func TestIsValidId(t *testing.T) {
   425  	cases := []struct {
   426  		Input  string
   427  		Result bool
   428  	}{
   429  		{
   430  			Input:  NewId(),
   431  			Result: true,
   432  		},
   433  		{
   434  			Input:  "",
   435  			Result: false,
   436  		},
   437  		{
   438  			Input:  "junk",
   439  			Result: false,
   440  		},
   441  		{
   442  			Input:  "qwertyuiop1234567890asdfg{",
   443  			Result: false,
   444  		},
   445  		{
   446  			Input:  NewId() + "}",
   447  			Result: false,
   448  		},
   449  	}
   450  
   451  	for _, tc := range cases {
   452  		actual := IsValidId(tc.Input)
   453  		if actual != tc.Result {
   454  			t.Fatalf("case: %v\tshould returned: %#v", tc, tc.Result)
   455  		}
   456  	}
   457  }
   458  
   459  func TestNowhereNil(t *testing.T) {
   460  	t.Parallel()
   461  
   462  	var nilStringPtr *string
   463  	var nonNilStringPtr *string = new(string)
   464  	var nilSlice []string
   465  	var nilStruct *struct{}
   466  	var nilMap map[bool]bool
   467  
   468  	var nowhereNilStruct = struct {
   469  		X *string
   470  		Y *string
   471  	}{
   472  		nonNilStringPtr,
   473  		nonNilStringPtr,
   474  	}
   475  	var somewhereNilStruct = struct {
   476  		X *string
   477  		Y *string
   478  	}{
   479  		nonNilStringPtr,
   480  		nilStringPtr,
   481  	}
   482  
   483  	var privateSomewhereNilStruct = struct {
   484  		X *string
   485  		y *string
   486  	}{
   487  		nonNilStringPtr,
   488  		nilStringPtr,
   489  	}
   490  
   491  	testCases := []struct {
   492  		Description string
   493  		Value       interface{}
   494  		Expected    bool
   495  	}{
   496  		{
   497  			"nil",
   498  			nil,
   499  			false,
   500  		},
   501  		{
   502  			"empty string",
   503  			"",
   504  			true,
   505  		},
   506  		{
   507  			"non-empty string",
   508  			"not empty!",
   509  			true,
   510  		},
   511  		{
   512  			"nil string pointer",
   513  			nilStringPtr,
   514  			false,
   515  		},
   516  		{
   517  			"non-nil string pointer",
   518  			nonNilStringPtr,
   519  			true,
   520  		},
   521  		{
   522  			"0",
   523  			0,
   524  			true,
   525  		},
   526  		{
   527  			"1",
   528  			1,
   529  			true,
   530  		},
   531  		{
   532  			"0 (int64)",
   533  			int64(0),
   534  			true,
   535  		},
   536  		{
   537  			"1 (int64)",
   538  			int64(1),
   539  			true,
   540  		},
   541  		{
   542  			"true",
   543  			true,
   544  			true,
   545  		},
   546  		{
   547  			"false",
   548  			false,
   549  			true,
   550  		},
   551  		{
   552  			"nil slice",
   553  			nilSlice,
   554  			// A nil slice is observably the same as an empty slice, so allow it.
   555  			true,
   556  		},
   557  		{
   558  			"empty slice",
   559  			[]string{},
   560  			true,
   561  		},
   562  		{
   563  			"slice containing nils",
   564  			[]*string{nil, nil},
   565  			true,
   566  		},
   567  		{
   568  			"nil map",
   569  			nilMap,
   570  			false,
   571  		},
   572  		{
   573  			"non-nil map",
   574  			make(map[bool]bool),
   575  			true,
   576  		},
   577  		{
   578  			"non-nil map containing nil",
   579  			map[bool]*string{true: nilStringPtr, false: nonNilStringPtr},
   580  			// Map values are not checked
   581  			true,
   582  		},
   583  		{
   584  			"nil struct",
   585  			nilStruct,
   586  			false,
   587  		},
   588  		{
   589  			"empty struct",
   590  			struct{}{},
   591  			true,
   592  		},
   593  		{
   594  			"struct containing no nil",
   595  			nowhereNilStruct,
   596  			true,
   597  		},
   598  		{
   599  			"struct containing nil",
   600  			somewhereNilStruct,
   601  			false,
   602  		},
   603  		{
   604  			"struct pointer containing no nil",
   605  			&nowhereNilStruct,
   606  			true,
   607  		},
   608  		{
   609  			"struct pointer containing nil",
   610  			&somewhereNilStruct,
   611  			false,
   612  		},
   613  		{
   614  			"struct containing private nil",
   615  			privateSomewhereNilStruct,
   616  			true,
   617  		},
   618  		{
   619  			"struct pointer containing private nil",
   620  			&privateSomewhereNilStruct,
   621  			true,
   622  		},
   623  	}
   624  
   625  	for _, testCase := range testCases {
   626  		testCase := testCase
   627  		t.Run(testCase.Description, func(t *testing.T) {
   628  			defer func() {
   629  				if r := recover(); r != nil {
   630  					t.Errorf("panic: %v", r)
   631  				}
   632  			}()
   633  
   634  			t.Parallel()
   635  			require.Equal(t, testCase.Expected, checkNowhereNil(t, "value", testCase.Value))
   636  		})
   637  	}
   638  }