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 }