github.com/gigforks/mattermost-server@v4.9.1-0.20180619094218-800d97fa55d0+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 TestValidEmail(t *testing.T) {
    81  	if !IsValidEmail("corey+test@hulen.com") {
    82  		t.Error("email should be valid")
    83  	}
    84  
    85  	if IsValidEmail("@corey+test@hulen.com") {
    86  		t.Error("should be invalid")
    87  	}
    88  }
    89  
    90  func TestValidLower(t *testing.T) {
    91  	if !IsLower("corey+test@hulen.com") {
    92  		t.Error("should be valid")
    93  	}
    94  
    95  	if IsLower("Corey+test@hulen.com") {
    96  		t.Error("should be invalid")
    97  	}
    98  }
    99  
   100  func TestEtag(t *testing.T) {
   101  	etag := Etag("hello", 24)
   102  	if len(etag) <= 0 {
   103  		t.Fatal()
   104  	}
   105  }
   106  
   107  var hashtags = map[string]string{
   108  	"#test":           "#test",
   109  	"test":            "",
   110  	"#test123":        "#test123",
   111  	"#123test123":     "",
   112  	"#test-test":      "#test-test",
   113  	"#test?":          "#test",
   114  	"hi #there":       "#there",
   115  	"#bug #idea":      "#bug #idea",
   116  	"#bug or #gif!":   "#bug #gif",
   117  	"#hüllo":          "#hüllo",
   118  	"#?test":          "",
   119  	"#-test":          "",
   120  	"#yo_yo":          "#yo_yo",
   121  	"(#brakets)":      "#brakets",
   122  	")#stekarb(":      "#stekarb",
   123  	"<#less_than<":    "#less_than",
   124  	">#greater_than>": "#greater_than",
   125  	"-#minus-":        "#minus",
   126  	"_#under_":        "#under",
   127  	"+#plus+":         "#plus",
   128  	"=#equals=":       "#equals",
   129  	"%#pct%":          "#pct",
   130  	"&#and&":          "#and",
   131  	"^#hat^":          "#hat",
   132  	"##brown#":        "#brown",
   133  	"*#star*":         "#star",
   134  	"|#pipe|":         "#pipe",
   135  	":#colon:":        "#colon",
   136  	";#semi;":         "#semi",
   137  	"#Mötley;":        "#Mötley",
   138  	".#period.":       "#period",
   139  	"¿#upside¿":       "#upside",
   140  	"\"#quote\"":      "#quote",
   141  	"/#slash/":        "#slash",
   142  	"\\#backslash\\":  "#backslash",
   143  	"#a":              "",
   144  	"#1":              "",
   145  	"foo#bar":         "",
   146  }
   147  
   148  func TestParseHashtags(t *testing.T) {
   149  	for input, output := range hashtags {
   150  		if o, _ := ParseHashtags(input); o != output {
   151  			t.Fatal("failed to parse hashtags from input=" + input + " expected=" + output + " actual=" + o)
   152  		}
   153  	}
   154  }
   155  
   156  func TestIsValidAlphaNum(t *testing.T) {
   157  	cases := []struct {
   158  		Input  string
   159  		Result bool
   160  	}{
   161  		{
   162  			Input:  "test",
   163  			Result: true,
   164  		},
   165  		{
   166  			Input:  "test-name",
   167  			Result: true,
   168  		},
   169  		{
   170  			Input:  "test--name",
   171  			Result: true,
   172  		},
   173  		{
   174  			Input:  "test__name",
   175  			Result: true,
   176  		},
   177  		{
   178  			Input:  "-",
   179  			Result: false,
   180  		},
   181  		{
   182  			Input:  "__",
   183  			Result: false,
   184  		},
   185  		{
   186  			Input:  "test-",
   187  			Result: false,
   188  		},
   189  		{
   190  			Input:  "test--",
   191  			Result: false,
   192  		},
   193  		{
   194  			Input:  "test__",
   195  			Result: false,
   196  		},
   197  		{
   198  			Input:  "test:name",
   199  			Result: false,
   200  		},
   201  	}
   202  
   203  	for _, tc := range cases {
   204  		actual := IsValidAlphaNum(tc.Input)
   205  		if actual != tc.Result {
   206  			t.Fatalf("case: %v\tshould returned: %#v", tc, tc.Result)
   207  		}
   208  	}
   209  }
   210  
   211  func TestGetServerIpAddress(t *testing.T) {
   212  	if len(GetServerIpAddress()) == 0 {
   213  		t.Fatal("Should find local ip address")
   214  	}
   215  }
   216  
   217  func TestIsValidAlphaNumHyphenUnderscore(t *testing.T) {
   218  	casesWithFormat := []struct {
   219  		Input  string
   220  		Result bool
   221  	}{
   222  		{
   223  			Input:  "test",
   224  			Result: true,
   225  		},
   226  		{
   227  			Input:  "test-name",
   228  			Result: true,
   229  		},
   230  		{
   231  			Input:  "test--name",
   232  			Result: true,
   233  		},
   234  		{
   235  			Input:  "test__name",
   236  			Result: true,
   237  		},
   238  		{
   239  			Input:  "test_name",
   240  			Result: true,
   241  		},
   242  		{
   243  			Input:  "test_-name",
   244  			Result: true,
   245  		},
   246  		{
   247  			Input:  "-",
   248  			Result: false,
   249  		},
   250  		{
   251  			Input:  "__",
   252  			Result: false,
   253  		},
   254  		{
   255  			Input:  "test-",
   256  			Result: false,
   257  		},
   258  		{
   259  			Input:  "test--",
   260  			Result: false,
   261  		},
   262  		{
   263  			Input:  "test__",
   264  			Result: false,
   265  		},
   266  		{
   267  			Input:  "test:name",
   268  			Result: false,
   269  		},
   270  	}
   271  
   272  	for _, tc := range casesWithFormat {
   273  		actual := IsValidAlphaNumHyphenUnderscore(tc.Input, true)
   274  		if actual != tc.Result {
   275  			t.Fatalf("case: %v\tshould returned: %#v", tc, tc.Result)
   276  		}
   277  	}
   278  
   279  	casesWithoutFormat := []struct {
   280  		Input  string
   281  		Result bool
   282  	}{
   283  		{
   284  			Input:  "test",
   285  			Result: true,
   286  		},
   287  		{
   288  			Input:  "test-name",
   289  			Result: true,
   290  		},
   291  		{
   292  			Input:  "test--name",
   293  			Result: true,
   294  		},
   295  		{
   296  			Input:  "test__name",
   297  			Result: true,
   298  		},
   299  		{
   300  			Input:  "test_name",
   301  			Result: true,
   302  		},
   303  		{
   304  			Input:  "test_-name",
   305  			Result: true,
   306  		},
   307  		{
   308  			Input:  "-",
   309  			Result: true,
   310  		},
   311  		{
   312  			Input:  "_",
   313  			Result: true,
   314  		},
   315  		{
   316  			Input:  "test-",
   317  			Result: true,
   318  		},
   319  		{
   320  			Input:  "test--",
   321  			Result: true,
   322  		},
   323  		{
   324  			Input:  "test__",
   325  			Result: true,
   326  		},
   327  		{
   328  			Input:  ".",
   329  			Result: false,
   330  		},
   331  
   332  		{
   333  			Input:  "test,",
   334  			Result: false,
   335  		},
   336  		{
   337  			Input:  "test:name",
   338  			Result: false,
   339  		},
   340  	}
   341  
   342  	for _, tc := range casesWithoutFormat {
   343  		actual := IsValidAlphaNumHyphenUnderscore(tc.Input, false)
   344  		if actual != tc.Result {
   345  			t.Fatalf("case: '%v'\tshould returned: %#v", tc.Input, tc.Result)
   346  		}
   347  	}
   348  }
   349  
   350  func TestIsValidId(t *testing.T) {
   351  	cases := []struct {
   352  		Input  string
   353  		Result bool
   354  	}{
   355  		{
   356  			Input:  NewId(),
   357  			Result: true,
   358  		},
   359  		{
   360  			Input:  "",
   361  			Result: false,
   362  		},
   363  		{
   364  			Input:  "junk",
   365  			Result: false,
   366  		},
   367  		{
   368  			Input:  "qwertyuiop1234567890asdfg{",
   369  			Result: false,
   370  		},
   371  		{
   372  			Input:  NewId() + "}",
   373  			Result: false,
   374  		},
   375  	}
   376  
   377  	for _, tc := range cases {
   378  		actual := IsValidId(tc.Input)
   379  		if actual != tc.Result {
   380  			t.Fatalf("case: %v\tshould returned: %#v", tc, tc.Result)
   381  		}
   382  	}
   383  }
   384  
   385  func TestNowhereNil(t *testing.T) {
   386  	t.Parallel()
   387  
   388  	var nilStringPtr *string
   389  	var nonNilStringPtr *string = new(string)
   390  	var nilSlice []string
   391  	var nilStruct *struct{}
   392  	var nilMap map[bool]bool
   393  
   394  	var nowhereNilStruct = struct {
   395  		X *string
   396  		Y *string
   397  	}{
   398  		nonNilStringPtr,
   399  		nonNilStringPtr,
   400  	}
   401  	var somewhereNilStruct = struct {
   402  		X *string
   403  		Y *string
   404  	}{
   405  		nonNilStringPtr,
   406  		nilStringPtr,
   407  	}
   408  
   409  	var privateSomewhereNilStruct = struct {
   410  		X *string
   411  		y *string
   412  	}{
   413  		nonNilStringPtr,
   414  		nilStringPtr,
   415  	}
   416  
   417  	testCases := []struct {
   418  		Description string
   419  		Value       interface{}
   420  		Expected    bool
   421  	}{
   422  		{
   423  			"nil",
   424  			nil,
   425  			false,
   426  		},
   427  		{
   428  			"empty string",
   429  			"",
   430  			true,
   431  		},
   432  		{
   433  			"non-empty string",
   434  			"not empty!",
   435  			true,
   436  		},
   437  		{
   438  			"nil string pointer",
   439  			nilStringPtr,
   440  			false,
   441  		},
   442  		{
   443  			"non-nil string pointer",
   444  			nonNilStringPtr,
   445  			true,
   446  		},
   447  		{
   448  			"0",
   449  			0,
   450  			true,
   451  		},
   452  		{
   453  			"1",
   454  			1,
   455  			true,
   456  		},
   457  		{
   458  			"0 (int64)",
   459  			int64(0),
   460  			true,
   461  		},
   462  		{
   463  			"1 (int64)",
   464  			int64(1),
   465  			true,
   466  		},
   467  		{
   468  			"true",
   469  			true,
   470  			true,
   471  		},
   472  		{
   473  			"false",
   474  			false,
   475  			true,
   476  		},
   477  		{
   478  			"nil slice",
   479  			nilSlice,
   480  			// A nil slice is observably the same as an empty slice, so allow it.
   481  			true,
   482  		},
   483  		{
   484  			"empty slice",
   485  			[]string{},
   486  			true,
   487  		},
   488  		{
   489  			"slice containing nils",
   490  			[]*string{nil, nil},
   491  			true,
   492  		},
   493  		{
   494  			"nil map",
   495  			nilMap,
   496  			false,
   497  		},
   498  		{
   499  			"non-nil map",
   500  			make(map[bool]bool),
   501  			true,
   502  		},
   503  		{
   504  			"non-nil map containing nil",
   505  			map[bool]*string{true: nilStringPtr, false: nonNilStringPtr},
   506  			// Map values are not checked
   507  			true,
   508  		},
   509  		{
   510  			"nil struct",
   511  			nilStruct,
   512  			false,
   513  		},
   514  		{
   515  			"empty struct",
   516  			struct{}{},
   517  			true,
   518  		},
   519  		{
   520  			"struct containing no nil",
   521  			nowhereNilStruct,
   522  			true,
   523  		},
   524  		{
   525  			"struct containing nil",
   526  			somewhereNilStruct,
   527  			false,
   528  		},
   529  		{
   530  			"struct pointer containing no nil",
   531  			&nowhereNilStruct,
   532  			true,
   533  		},
   534  		{
   535  			"struct pointer containing nil",
   536  			&somewhereNilStruct,
   537  			false,
   538  		},
   539  		{
   540  			"struct containing private nil",
   541  			privateSomewhereNilStruct,
   542  			true,
   543  		},
   544  		{
   545  			"struct pointer containing private nil",
   546  			&privateSomewhereNilStruct,
   547  			true,
   548  		},
   549  	}
   550  
   551  	for _, testCase := range testCases {
   552  		testCase := testCase
   553  		t.Run(testCase.Description, func(t *testing.T) {
   554  			defer func() {
   555  				if r := recover(); r != nil {
   556  					t.Errorf("panic: %v", r)
   557  				}
   558  			}()
   559  
   560  			t.Parallel()
   561  			require.Equal(t, testCase.Expected, checkNowhereNil(t, "value", testCase.Value))
   562  		})
   563  	}
   564  }