validation_test.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. // Copyright 2014 beego Author. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package validation
  15. import (
  16. "regexp"
  17. "testing"
  18. "time"
  19. )
  20. func TestRequired(t *testing.T) {
  21. valid := Validation{}
  22. if valid.Required(nil, "nil").Ok {
  23. t.Error("nil object should be false")
  24. }
  25. if !valid.Required(true, "bool").Ok {
  26. t.Error("Bool value should always return true")
  27. }
  28. if !valid.Required(false, "bool").Ok {
  29. t.Error("Bool value should always return true")
  30. }
  31. if valid.Required("", "string").Ok {
  32. t.Error("\"'\" string should be false")
  33. }
  34. if valid.Required(" ", "string").Ok {
  35. t.Error("\" \" string should be false") // For #2361
  36. }
  37. if valid.Required("\n", "string").Ok {
  38. t.Error("new line string should be false") // For #2361
  39. }
  40. if !valid.Required("astaxie", "string").Ok {
  41. t.Error("string should be true")
  42. }
  43. if valid.Required(0, "zero").Ok {
  44. t.Error("Integer should not be equal 0")
  45. }
  46. if !valid.Required(1, "int").Ok {
  47. t.Error("Integer except 0 should be true")
  48. }
  49. if !valid.Required(time.Now(), "time").Ok {
  50. t.Error("time should be true")
  51. }
  52. if valid.Required([]string{}, "emptySlice").Ok {
  53. t.Error("empty slice should be false")
  54. }
  55. if !valid.Required([]interface{}{"ok"}, "slice").Ok {
  56. t.Error("slice should be true")
  57. }
  58. }
  59. func TestMin(t *testing.T) {
  60. valid := Validation{}
  61. if valid.Min(-1, 0, "min0").Ok {
  62. t.Error("-1 is less than the minimum value of 0 should be false")
  63. }
  64. if !valid.Min(1, 0, "min0").Ok {
  65. t.Error("1 is greater or equal than the minimum value of 0 should be true")
  66. }
  67. }
  68. func TestMax(t *testing.T) {
  69. valid := Validation{}
  70. if valid.Max(1, 0, "max0").Ok {
  71. t.Error("1 is greater than the minimum value of 0 should be false")
  72. }
  73. if !valid.Max(-1, 0, "max0").Ok {
  74. t.Error("-1 is less or equal than the maximum value of 0 should be true")
  75. }
  76. }
  77. func TestRange(t *testing.T) {
  78. valid := Validation{}
  79. if valid.Range(-1, 0, 1, "range0_1").Ok {
  80. t.Error("-1 is between 0 and 1 should be false")
  81. }
  82. if !valid.Range(1, 0, 1, "range0_1").Ok {
  83. t.Error("1 is between 0 and 1 should be true")
  84. }
  85. }
  86. func TestMinSize(t *testing.T) {
  87. valid := Validation{}
  88. if valid.MinSize("", 1, "minSize1").Ok {
  89. t.Error("the length of \"\" is less than the minimum value of 1 should be false")
  90. }
  91. if !valid.MinSize("ok", 1, "minSize1").Ok {
  92. t.Error("the length of \"ok\" is greater or equal than the minimum value of 1 should be true")
  93. }
  94. if valid.MinSize([]string{}, 1, "minSize1").Ok {
  95. t.Error("the length of empty slice is less than the minimum value of 1 should be false")
  96. }
  97. if !valid.MinSize([]interface{}{"ok"}, 1, "minSize1").Ok {
  98. t.Error("the length of [\"ok\"] is greater or equal than the minimum value of 1 should be true")
  99. }
  100. }
  101. func TestMaxSize(t *testing.T) {
  102. valid := Validation{}
  103. if valid.MaxSize("ok", 1, "maxSize1").Ok {
  104. t.Error("the length of \"ok\" is greater than the maximum value of 1 should be false")
  105. }
  106. if !valid.MaxSize("", 1, "maxSize1").Ok {
  107. t.Error("the length of \"\" is less or equal than the maximum value of 1 should be true")
  108. }
  109. if valid.MaxSize([]interface{}{"ok", false}, 1, "maxSize1").Ok {
  110. t.Error("the length of [\"ok\", false] is greater than the maximum value of 1 should be false")
  111. }
  112. if !valid.MaxSize([]string{}, 1, "maxSize1").Ok {
  113. t.Error("the length of empty slice is less or equal than the maximum value of 1 should be true")
  114. }
  115. }
  116. func TestLength(t *testing.T) {
  117. valid := Validation{}
  118. if valid.Length("", 1, "length1").Ok {
  119. t.Error("the length of \"\" must equal 1 should be false")
  120. }
  121. if !valid.Length("1", 1, "length1").Ok {
  122. t.Error("the length of \"1\" must equal 1 should be true")
  123. }
  124. if valid.Length([]string{}, 1, "length1").Ok {
  125. t.Error("the length of empty slice must equal 1 should be false")
  126. }
  127. if !valid.Length([]interface{}{"ok"}, 1, "length1").Ok {
  128. t.Error("the length of [\"ok\"] must equal 1 should be true")
  129. }
  130. }
  131. func TestAlpha(t *testing.T) {
  132. valid := Validation{}
  133. if valid.Alpha("a,1-@ $", "alpha").Ok {
  134. t.Error("\"a,1-@ $\" are valid alpha characters should be false")
  135. }
  136. if !valid.Alpha("abCD", "alpha").Ok {
  137. t.Error("\"abCD\" are valid alpha characters should be true")
  138. }
  139. }
  140. func TestNumeric(t *testing.T) {
  141. valid := Validation{}
  142. if valid.Numeric("a,1-@ $", "numeric").Ok {
  143. t.Error("\"a,1-@ $\" are valid numeric characters should be false")
  144. }
  145. if !valid.Numeric("1234", "numeric").Ok {
  146. t.Error("\"1234\" are valid numeric characters should be true")
  147. }
  148. }
  149. func TestAlphaNumeric(t *testing.T) {
  150. valid := Validation{}
  151. if valid.AlphaNumeric("a,1-@ $", "alphaNumeric").Ok {
  152. t.Error("\"a,1-@ $\" are valid alpha or numeric characters should be false")
  153. }
  154. if !valid.AlphaNumeric("1234aB", "alphaNumeric").Ok {
  155. t.Error("\"1234aB\" are valid alpha or numeric characters should be true")
  156. }
  157. }
  158. func TestMatch(t *testing.T) {
  159. valid := Validation{}
  160. if valid.Match("suchuangji@gmail", regexp.MustCompile(`^\w+@\w+\.\w+$`), "match").Ok {
  161. t.Error("\"suchuangji@gmail\" match \"^\\w+@\\w+\\.\\w+$\" should be false")
  162. }
  163. if !valid.Match("suchuangji@gmail.com", regexp.MustCompile(`^\w+@\w+\.\w+$`), "match").Ok {
  164. t.Error("\"suchuangji@gmail\" match \"^\\w+@\\w+\\.\\w+$\" should be true")
  165. }
  166. }
  167. func TestNoMatch(t *testing.T) {
  168. valid := Validation{}
  169. if valid.NoMatch("123@gmail", regexp.MustCompile(`[^\w\d]`), "nomatch").Ok {
  170. t.Error("\"123@gmail\" not match \"[^\\w\\d]\" should be false")
  171. }
  172. if !valid.NoMatch("123gmail", regexp.MustCompile(`[^\w\d]`), "match").Ok {
  173. t.Error("\"123@gmail\" not match \"[^\\w\\d@]\" should be true")
  174. }
  175. }
  176. func TestAlphaDash(t *testing.T) {
  177. valid := Validation{}
  178. if valid.AlphaDash("a,1-@ $", "alphaDash").Ok {
  179. t.Error("\"a,1-@ $\" are valid alpha or numeric or dash(-_) characters should be false")
  180. }
  181. if !valid.AlphaDash("1234aB-_", "alphaDash").Ok {
  182. t.Error("\"1234aB\" are valid alpha or numeric or dash(-_) characters should be true")
  183. }
  184. }
  185. func TestEmail(t *testing.T) {
  186. valid := Validation{}
  187. if valid.Email("not@a email", "email").Ok {
  188. t.Error("\"not@a email\" is a valid email address should be false")
  189. }
  190. if !valid.Email("suchuangji@gmail.com", "email").Ok {
  191. t.Error("\"suchuangji@gmail.com\" is a valid email address should be true")
  192. }
  193. if valid.Email("@suchuangji@gmail.com", "email").Ok {
  194. t.Error("\"@suchuangji@gmail.com\" is a valid email address should be false")
  195. }
  196. if valid.Email("suchuangji@gmail.com ok", "email").Ok {
  197. t.Error("\"suchuangji@gmail.com ok\" is a valid email address should be false")
  198. }
  199. }
  200. func TestIP(t *testing.T) {
  201. valid := Validation{}
  202. if valid.IP("11.255.255.256", "IP").Ok {
  203. t.Error("\"11.255.255.256\" is a valid ip address should be false")
  204. }
  205. if !valid.IP("01.11.11.11", "IP").Ok {
  206. t.Error("\"suchuangji@gmail.com\" is a valid ip address should be true")
  207. }
  208. }
  209. func TestBase64(t *testing.T) {
  210. valid := Validation{}
  211. if valid.Base64("suchuangji@gmail.com", "base64").Ok {
  212. t.Error("\"suchuangji@gmail.com\" are a valid base64 characters should be false")
  213. }
  214. if !valid.Base64("c3VjaHVhbmdqaUBnbWFpbC5jb20=", "base64").Ok {
  215. t.Error("\"c3VjaHVhbmdqaUBnbWFpbC5jb20=\" are a valid base64 characters should be true")
  216. }
  217. }
  218. func TestMobile(t *testing.T) {
  219. valid := Validation{}
  220. if valid.Mobile("19800008888", "mobile").Ok {
  221. t.Error("\"19800008888\" is a valid mobile phone number should be false")
  222. }
  223. if !valid.Mobile("18800008888", "mobile").Ok {
  224. t.Error("\"18800008888\" is a valid mobile phone number should be true")
  225. }
  226. if !valid.Mobile("18000008888", "mobile").Ok {
  227. t.Error("\"18000008888\" is a valid mobile phone number should be true")
  228. }
  229. if !valid.Mobile("8618300008888", "mobile").Ok {
  230. t.Error("\"8618300008888\" is a valid mobile phone number should be true")
  231. }
  232. if !valid.Mobile("+8614700008888", "mobile").Ok {
  233. t.Error("\"+8614700008888\" is a valid mobile phone number should be true")
  234. }
  235. }
  236. func TestTel(t *testing.T) {
  237. valid := Validation{}
  238. if valid.Tel("222-00008888", "telephone").Ok {
  239. t.Error("\"222-00008888\" is a valid telephone number should be false")
  240. }
  241. if !valid.Tel("022-70008888", "telephone").Ok {
  242. t.Error("\"022-70008888\" is a valid telephone number should be true")
  243. }
  244. if !valid.Tel("02270008888", "telephone").Ok {
  245. t.Error("\"02270008888\" is a valid telephone number should be true")
  246. }
  247. if !valid.Tel("70008888", "telephone").Ok {
  248. t.Error("\"70008888\" is a valid telephone number should be true")
  249. }
  250. }
  251. func TestPhone(t *testing.T) {
  252. valid := Validation{}
  253. if valid.Phone("222-00008888", "phone").Ok {
  254. t.Error("\"222-00008888\" is a valid phone number should be false")
  255. }
  256. if !valid.Mobile("+8614700008888", "phone").Ok {
  257. t.Error("\"+8614700008888\" is a valid phone number should be true")
  258. }
  259. if !valid.Tel("02270008888", "phone").Ok {
  260. t.Error("\"02270008888\" is a valid phone number should be true")
  261. }
  262. }
  263. func TestZipCode(t *testing.T) {
  264. valid := Validation{}
  265. if valid.ZipCode("", "zipcode").Ok {
  266. t.Error("\"00008888\" is a valid zipcode should be false")
  267. }
  268. if !valid.ZipCode("536000", "zipcode").Ok {
  269. t.Error("\"536000\" is a valid zipcode should be true")
  270. }
  271. }
  272. func TestValid(t *testing.T) {
  273. type user struct {
  274. ID int
  275. Name string `valid:"Required;Match(/^(test)?\\w*@(/test/);com$/)"`
  276. Age int `valid:"Required;Range(1, 140)"`
  277. }
  278. valid := Validation{}
  279. u := user{Name: "test@/test/;com", Age: 40}
  280. b, err := valid.Valid(u)
  281. if err != nil {
  282. t.Fatal(err)
  283. }
  284. if !b {
  285. t.Error("validation should be passed")
  286. }
  287. uptr := &user{Name: "test", Age: 40}
  288. valid.Clear()
  289. b, err = valid.Valid(uptr)
  290. if err != nil {
  291. t.Fatal(err)
  292. }
  293. if b {
  294. t.Error("validation should not be passed")
  295. }
  296. if len(valid.Errors) != 1 {
  297. t.Fatalf("valid errors len should be 1 but got %d", len(valid.Errors))
  298. }
  299. if valid.Errors[0].Key != "Name.Match" {
  300. t.Errorf("Message key should be `Name.Match` but got %s", valid.Errors[0].Key)
  301. }
  302. u = user{Name: "test@/test/;com", Age: 180}
  303. valid.Clear()
  304. b, err = valid.Valid(u)
  305. if err != nil {
  306. t.Fatal(err)
  307. }
  308. if b {
  309. t.Error("validation should not be passed")
  310. }
  311. if len(valid.Errors) != 1 {
  312. t.Fatalf("valid errors len should be 1 but got %d", len(valid.Errors))
  313. }
  314. if valid.Errors[0].Key != "Age.Range" {
  315. t.Errorf("Message key should be `Name.Match` but got %s", valid.Errors[0].Key)
  316. }
  317. }
  318. func TestRecursiveValid(t *testing.T) {
  319. type User struct {
  320. ID int
  321. Name string `valid:"Required;Match(/^(test)?\\w*@(/test/);com$/)"`
  322. Age int `valid:"Required;Range(1, 140)"`
  323. }
  324. type AnonymouseUser struct {
  325. ID2 int
  326. Name2 string `valid:"Required;Match(/^(test)?\\w*@(/test/);com$/)"`
  327. Age2 int `valid:"Required;Range(1, 140)"`
  328. }
  329. type Account struct {
  330. Password string `valid:"Required"`
  331. U User
  332. AnonymouseUser
  333. }
  334. valid := Validation{}
  335. u := Account{Password: "abc123_", U: User{}}
  336. b, err := valid.RecursiveValid(u)
  337. if err != nil {
  338. t.Fatal(err)
  339. }
  340. if b {
  341. t.Error("validation should not be passed")
  342. }
  343. }
  344. func TestSkipValid(t *testing.T) {
  345. type User struct {
  346. ID int
  347. Email string `valid:"Email"`
  348. ReqEmail string `valid:"Required;Email"`
  349. IP string `valid:"IP"`
  350. ReqIP string `valid:"Required;IP"`
  351. Mobile string `valid:"Mobile"`
  352. ReqMobile string `valid:"Required;Mobile"`
  353. Tel string `valid:"Tel"`
  354. ReqTel string `valid:"Required;Tel"`
  355. Phone string `valid:"Phone"`
  356. ReqPhone string `valid:"Required;Phone"`
  357. ZipCode string `valid:"ZipCode"`
  358. ReqZipCode string `valid:"Required;ZipCode"`
  359. }
  360. u := User{
  361. ReqEmail: "a@a.com",
  362. ReqIP: "127.0.0.1",
  363. ReqMobile: "18888888888",
  364. ReqTel: "02088888888",
  365. ReqPhone: "02088888888",
  366. ReqZipCode: "510000",
  367. }
  368. valid := Validation{}
  369. b, err := valid.Valid(u)
  370. if err != nil {
  371. t.Fatal(err)
  372. }
  373. if b {
  374. t.Fatal("validation should not be passed")
  375. }
  376. valid = Validation{RequiredFirst: true}
  377. b, err = valid.Valid(u)
  378. if err != nil {
  379. t.Fatal(err)
  380. }
  381. if !b {
  382. t.Fatal("validation should be passed")
  383. }
  384. }
  385. func TestPointer(t *testing.T) {
  386. type User struct {
  387. ID int
  388. Email *string `valid:"Email"`
  389. ReqEmail *string `valid:"Required;Email"`
  390. }
  391. u := User{
  392. ReqEmail: nil,
  393. Email: nil,
  394. }
  395. valid := Validation{}
  396. b, err := valid.Valid(u)
  397. if err != nil {
  398. t.Fatal(err)
  399. }
  400. if b {
  401. t.Fatal("validation should not be passed")
  402. }
  403. validEmail := "a@a.com"
  404. u = User{
  405. ReqEmail: &validEmail,
  406. Email: nil,
  407. }
  408. valid = Validation{RequiredFirst: true}
  409. b, err = valid.Valid(u)
  410. if err != nil {
  411. t.Fatal(err)
  412. }
  413. if !b {
  414. t.Fatal("validation should be passed")
  415. }
  416. u = User{
  417. ReqEmail: &validEmail,
  418. Email: nil,
  419. }
  420. valid = Validation{}
  421. b, err = valid.Valid(u)
  422. if err != nil {
  423. t.Fatal(err)
  424. }
  425. if b {
  426. t.Fatal("validation should not be passed")
  427. }
  428. invalidEmail := "a@a"
  429. u = User{
  430. ReqEmail: &validEmail,
  431. Email: &invalidEmail,
  432. }
  433. valid = Validation{RequiredFirst: true}
  434. b, err = valid.Valid(u)
  435. if err != nil {
  436. t.Fatal(err)
  437. }
  438. if b {
  439. t.Fatal("validation should not be passed")
  440. }
  441. u = User{
  442. ReqEmail: &validEmail,
  443. Email: &invalidEmail,
  444. }
  445. valid = Validation{}
  446. b, err = valid.Valid(u)
  447. if err != nil {
  448. t.Fatal(err)
  449. }
  450. if b {
  451. t.Fatal("validation should not be passed")
  452. }
  453. }
  454. func TestCanSkipAlso(t *testing.T) {
  455. type User struct {
  456. ID int
  457. Email string `valid:"Email"`
  458. ReqEmail string `valid:"Required;Email"`
  459. MatchRange int `valid:"Range(10, 20)"`
  460. }
  461. u := User{
  462. ReqEmail: "a@a.com",
  463. Email: "",
  464. MatchRange: 0,
  465. }
  466. valid := Validation{RequiredFirst: true}
  467. b, err := valid.Valid(u)
  468. if err != nil {
  469. t.Fatal(err)
  470. }
  471. if b {
  472. t.Fatal("validation should not be passed")
  473. }
  474. valid = Validation{RequiredFirst: true}
  475. valid.CanSkipAlso("Range")
  476. b, err = valid.Valid(u)
  477. if err != nil {
  478. t.Fatal(err)
  479. }
  480. if !b {
  481. t.Fatal("validation should be passed")
  482. }
  483. }