PageRenderTime 49ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/model/utils_test.go

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