github.com/astaxie/beego@v1.12.3/validation/validation_test.go (about) 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 15 package validation 16 17 import ( 18 "regexp" 19 "testing" 20 "time" 21 ) 22 23 func TestRequired(t *testing.T) { 24 valid := Validation{} 25 26 if valid.Required(nil, "nil").Ok { 27 t.Error("nil object should be false") 28 } 29 if !valid.Required(true, "bool").Ok { 30 t.Error("Bool value should always return true") 31 } 32 if !valid.Required(false, "bool").Ok { 33 t.Error("Bool value should always return true") 34 } 35 if valid.Required("", "string").Ok { 36 t.Error("\"'\" string should be false") 37 } 38 if valid.Required(" ", "string").Ok { 39 t.Error("\" \" string should be false") // For #2361 40 } 41 if valid.Required("\n", "string").Ok { 42 t.Error("new line string should be false") // For #2361 43 } 44 if !valid.Required("astaxie", "string").Ok { 45 t.Error("string should be true") 46 } 47 if valid.Required(0, "zero").Ok { 48 t.Error("Integer should not be equal 0") 49 } 50 if !valid.Required(1, "int").Ok { 51 t.Error("Integer except 0 should be true") 52 } 53 if !valid.Required(time.Now(), "time").Ok { 54 t.Error("time should be true") 55 } 56 if valid.Required([]string{}, "emptySlice").Ok { 57 t.Error("empty slice should be false") 58 } 59 if !valid.Required([]interface{}{"ok"}, "slice").Ok { 60 t.Error("slice should be true") 61 } 62 } 63 64 func TestMin(t *testing.T) { 65 valid := Validation{} 66 67 if valid.Min(-1, 0, "min0").Ok { 68 t.Error("-1 is less than the minimum value of 0 should be false") 69 } 70 if !valid.Min(1, 0, "min0").Ok { 71 t.Error("1 is greater or equal than the minimum value of 0 should be true") 72 } 73 } 74 75 func TestMax(t *testing.T) { 76 valid := Validation{} 77 78 if valid.Max(1, 0, "max0").Ok { 79 t.Error("1 is greater than the minimum value of 0 should be false") 80 } 81 if !valid.Max(-1, 0, "max0").Ok { 82 t.Error("-1 is less or equal than the maximum value of 0 should be true") 83 } 84 } 85 86 func TestRange(t *testing.T) { 87 valid := Validation{} 88 89 if valid.Range(-1, 0, 1, "range0_1").Ok { 90 t.Error("-1 is between 0 and 1 should be false") 91 } 92 if !valid.Range(1, 0, 1, "range0_1").Ok { 93 t.Error("1 is between 0 and 1 should be true") 94 } 95 } 96 97 func TestMinSize(t *testing.T) { 98 valid := Validation{} 99 100 if valid.MinSize("", 1, "minSize1").Ok { 101 t.Error("the length of \"\" is less than the minimum value of 1 should be false") 102 } 103 if !valid.MinSize("ok", 1, "minSize1").Ok { 104 t.Error("the length of \"ok\" is greater or equal than the minimum value of 1 should be true") 105 } 106 if valid.MinSize([]string{}, 1, "minSize1").Ok { 107 t.Error("the length of empty slice is less than the minimum value of 1 should be false") 108 } 109 if !valid.MinSize([]interface{}{"ok"}, 1, "minSize1").Ok { 110 t.Error("the length of [\"ok\"] is greater or equal than the minimum value of 1 should be true") 111 } 112 } 113 114 func TestMaxSize(t *testing.T) { 115 valid := Validation{} 116 117 if valid.MaxSize("ok", 1, "maxSize1").Ok { 118 t.Error("the length of \"ok\" is greater than the maximum value of 1 should be false") 119 } 120 if !valid.MaxSize("", 1, "maxSize1").Ok { 121 t.Error("the length of \"\" is less or equal than the maximum value of 1 should be true") 122 } 123 if valid.MaxSize([]interface{}{"ok", false}, 1, "maxSize1").Ok { 124 t.Error("the length of [\"ok\", false] is greater than the maximum value of 1 should be false") 125 } 126 if !valid.MaxSize([]string{}, 1, "maxSize1").Ok { 127 t.Error("the length of empty slice is less or equal than the maximum value of 1 should be true") 128 } 129 } 130 131 func TestLength(t *testing.T) { 132 valid := Validation{} 133 134 if valid.Length("", 1, "length1").Ok { 135 t.Error("the length of \"\" must equal 1 should be false") 136 } 137 if !valid.Length("1", 1, "length1").Ok { 138 t.Error("the length of \"1\" must equal 1 should be true") 139 } 140 if valid.Length([]string{}, 1, "length1").Ok { 141 t.Error("the length of empty slice must equal 1 should be false") 142 } 143 if !valid.Length([]interface{}{"ok"}, 1, "length1").Ok { 144 t.Error("the length of [\"ok\"] must equal 1 should be true") 145 } 146 } 147 148 func TestAlpha(t *testing.T) { 149 valid := Validation{} 150 151 if valid.Alpha("a,1-@ $", "alpha").Ok { 152 t.Error("\"a,1-@ $\" are valid alpha characters should be false") 153 } 154 if !valid.Alpha("abCD", "alpha").Ok { 155 t.Error("\"abCD\" are valid alpha characters should be true") 156 } 157 } 158 159 func TestNumeric(t *testing.T) { 160 valid := Validation{} 161 162 if valid.Numeric("a,1-@ $", "numeric").Ok { 163 t.Error("\"a,1-@ $\" are valid numeric characters should be false") 164 } 165 if !valid.Numeric("1234", "numeric").Ok { 166 t.Error("\"1234\" are valid numeric characters should be true") 167 } 168 } 169 170 func TestAlphaNumeric(t *testing.T) { 171 valid := Validation{} 172 173 if valid.AlphaNumeric("a,1-@ $", "alphaNumeric").Ok { 174 t.Error("\"a,1-@ $\" are valid alpha or numeric characters should be false") 175 } 176 if !valid.AlphaNumeric("1234aB", "alphaNumeric").Ok { 177 t.Error("\"1234aB\" are valid alpha or numeric characters should be true") 178 } 179 } 180 181 func TestMatch(t *testing.T) { 182 valid := Validation{} 183 184 if valid.Match("suchuangji@gmail", regexp.MustCompile(`^\w+@\w+\.\w+$`), "match").Ok { 185 t.Error("\"suchuangji@gmail\" match \"^\\w+@\\w+\\.\\w+$\" should be false") 186 } 187 if !valid.Match("suchuangji@gmail.com", regexp.MustCompile(`^\w+@\w+\.\w+$`), "match").Ok { 188 t.Error("\"suchuangji@gmail\" match \"^\\w+@\\w+\\.\\w+$\" should be true") 189 } 190 } 191 192 func TestNoMatch(t *testing.T) { 193 valid := Validation{} 194 195 if valid.NoMatch("123@gmail", regexp.MustCompile(`[^\w\d]`), "nomatch").Ok { 196 t.Error("\"123@gmail\" not match \"[^\\w\\d]\" should be false") 197 } 198 if !valid.NoMatch("123gmail", regexp.MustCompile(`[^\w\d]`), "match").Ok { 199 t.Error("\"123@gmail\" not match \"[^\\w\\d@]\" should be true") 200 } 201 } 202 203 func TestAlphaDash(t *testing.T) { 204 valid := Validation{} 205 206 if valid.AlphaDash("a,1-@ $", "alphaDash").Ok { 207 t.Error("\"a,1-@ $\" are valid alpha or numeric or dash(-_) characters should be false") 208 } 209 if !valid.AlphaDash("1234aB-_", "alphaDash").Ok { 210 t.Error("\"1234aB\" are valid alpha or numeric or dash(-_) characters should be true") 211 } 212 } 213 214 func TestEmail(t *testing.T) { 215 valid := Validation{} 216 217 if valid.Email("not@a email", "email").Ok { 218 t.Error("\"not@a email\" is a valid email address should be false") 219 } 220 if !valid.Email("suchuangji@gmail.com", "email").Ok { 221 t.Error("\"suchuangji@gmail.com\" is a valid email address should be true") 222 } 223 if valid.Email("@suchuangji@gmail.com", "email").Ok { 224 t.Error("\"@suchuangji@gmail.com\" is a valid email address should be false") 225 } 226 if valid.Email("suchuangji@gmail.com ok", "email").Ok { 227 t.Error("\"suchuangji@gmail.com ok\" is a valid email address should be false") 228 } 229 } 230 231 func TestIP(t *testing.T) { 232 valid := Validation{} 233 234 if valid.IP("11.255.255.256", "IP").Ok { 235 t.Error("\"11.255.255.256\" is a valid ip address should be false") 236 } 237 if !valid.IP("01.11.11.11", "IP").Ok { 238 t.Error("\"suchuangji@gmail.com\" is a valid ip address should be true") 239 } 240 } 241 242 func TestBase64(t *testing.T) { 243 valid := Validation{} 244 245 if valid.Base64("suchuangji@gmail.com", "base64").Ok { 246 t.Error("\"suchuangji@gmail.com\" are a valid base64 characters should be false") 247 } 248 if !valid.Base64("c3VjaHVhbmdqaUBnbWFpbC5jb20=", "base64").Ok { 249 t.Error("\"c3VjaHVhbmdqaUBnbWFpbC5jb20=\" are a valid base64 characters should be true") 250 } 251 } 252 253 func TestMobile(t *testing.T) { 254 valid := Validation{} 255 256 validMobiles := []string{ 257 "19800008888", 258 "18800008888", 259 "18000008888", 260 "8618300008888", 261 "+8614700008888", 262 "17300008888", 263 "+8617100008888", 264 "8617500008888", 265 "8617400008888", 266 "16200008888", 267 "16500008888", 268 "16600008888", 269 "16700008888", 270 "13300008888", 271 "14900008888", 272 "15300008888", 273 "17300008888", 274 "17700008888", 275 "18000008888", 276 "18900008888", 277 "19100008888", 278 "19900008888", 279 "19300008888", 280 "13000008888", 281 "13100008888", 282 "13200008888", 283 "14500008888", 284 "15500008888", 285 "15600008888", 286 "16600008888", 287 "17100008888", 288 "17500008888", 289 "17600008888", 290 "18500008888", 291 "18600008888", 292 "13400008888", 293 "13500008888", 294 "13600008888", 295 "13700008888", 296 "13800008888", 297 "13900008888", 298 "14700008888", 299 "15000008888", 300 "15100008888", 301 "15200008888", 302 "15800008888", 303 "15900008888", 304 "17200008888", 305 "17800008888", 306 "18200008888", 307 "18300008888", 308 "18400008888", 309 "18700008888", 310 "18800008888", 311 "19800008888", 312 } 313 314 for _, m := range validMobiles { 315 if !valid.Mobile(m, "mobile").Ok { 316 t.Error(m + " is a valid mobile phone number should be true") 317 } 318 } 319 } 320 321 func TestTel(t *testing.T) { 322 valid := Validation{} 323 324 if valid.Tel("222-00008888", "telephone").Ok { 325 t.Error("\"222-00008888\" is a valid telephone number should be false") 326 } 327 if !valid.Tel("022-70008888", "telephone").Ok { 328 t.Error("\"022-70008888\" is a valid telephone number should be true") 329 } 330 if !valid.Tel("02270008888", "telephone").Ok { 331 t.Error("\"02270008888\" is a valid telephone number should be true") 332 } 333 if !valid.Tel("70008888", "telephone").Ok { 334 t.Error("\"70008888\" is a valid telephone number should be true") 335 } 336 } 337 338 func TestPhone(t *testing.T) { 339 valid := Validation{} 340 341 if valid.Phone("222-00008888", "phone").Ok { 342 t.Error("\"222-00008888\" is a valid phone number should be false") 343 } 344 if !valid.Mobile("+8614700008888", "phone").Ok { 345 t.Error("\"+8614700008888\" is a valid phone number should be true") 346 } 347 if !valid.Tel("02270008888", "phone").Ok { 348 t.Error("\"02270008888\" is a valid phone number should be true") 349 } 350 } 351 352 func TestZipCode(t *testing.T) { 353 valid := Validation{} 354 355 if valid.ZipCode("", "zipcode").Ok { 356 t.Error("\"00008888\" is a valid zipcode should be false") 357 } 358 if !valid.ZipCode("536000", "zipcode").Ok { 359 t.Error("\"536000\" is a valid zipcode should be true") 360 } 361 } 362 363 func TestValid(t *testing.T) { 364 type user struct { 365 ID int 366 Name string `valid:"Required;Match(/^(test)?\\w*@(/test/);com$/)"` 367 Age int `valid:"Required;Range(1, 140)"` 368 } 369 valid := Validation{} 370 371 u := user{Name: "test@/test/;com", Age: 40} 372 b, err := valid.Valid(u) 373 if err != nil { 374 t.Fatal(err) 375 } 376 if !b { 377 t.Error("validation should be passed") 378 } 379 380 uptr := &user{Name: "test", Age: 40} 381 valid.Clear() 382 b, err = valid.Valid(uptr) 383 if err != nil { 384 t.Fatal(err) 385 } 386 if b { 387 t.Error("validation should not be passed") 388 } 389 if len(valid.Errors) != 1 { 390 t.Fatalf("valid errors len should be 1 but got %d", len(valid.Errors)) 391 } 392 if valid.Errors[0].Key != "Name.Match" { 393 t.Errorf("Message key should be `Name.Match` but got %s", valid.Errors[0].Key) 394 } 395 396 u = user{Name: "test@/test/;com", Age: 180} 397 valid.Clear() 398 b, err = valid.Valid(u) 399 if err != nil { 400 t.Fatal(err) 401 } 402 if b { 403 t.Error("validation should not be passed") 404 } 405 if len(valid.Errors) != 1 { 406 t.Fatalf("valid errors len should be 1 but got %d", len(valid.Errors)) 407 } 408 if valid.Errors[0].Key != "Age.Range." { 409 t.Errorf("Message key should be `Age.Range` but got %s", valid.Errors[0].Key) 410 } 411 } 412 413 func TestRecursiveValid(t *testing.T) { 414 type User struct { 415 ID int 416 Name string `valid:"Required;Match(/^(test)?\\w*@(/test/);com$/)"` 417 Age int `valid:"Required;Range(1, 140)"` 418 } 419 420 type AnonymouseUser struct { 421 ID2 int 422 Name2 string `valid:"Required;Match(/^(test)?\\w*@(/test/);com$/)"` 423 Age2 int `valid:"Required;Range(1, 140)"` 424 } 425 426 type Account struct { 427 Password string `valid:"Required"` 428 U User 429 AnonymouseUser 430 } 431 valid := Validation{} 432 433 u := Account{Password: "abc123_", U: User{}} 434 b, err := valid.RecursiveValid(u) 435 if err != nil { 436 t.Fatal(err) 437 } 438 if b { 439 t.Error("validation should not be passed") 440 } 441 } 442 443 func TestSkipValid(t *testing.T) { 444 type User struct { 445 ID int 446 447 Email string `valid:"Email"` 448 ReqEmail string `valid:"Required;Email"` 449 450 IP string `valid:"IP"` 451 ReqIP string `valid:"Required;IP"` 452 453 Mobile string `valid:"Mobile"` 454 ReqMobile string `valid:"Required;Mobile"` 455 456 Tel string `valid:"Tel"` 457 ReqTel string `valid:"Required;Tel"` 458 459 Phone string `valid:"Phone"` 460 ReqPhone string `valid:"Required;Phone"` 461 462 ZipCode string `valid:"ZipCode"` 463 ReqZipCode string `valid:"Required;ZipCode"` 464 } 465 466 u := User{ 467 ReqEmail: "a@a.com", 468 ReqIP: "127.0.0.1", 469 ReqMobile: "18888888888", 470 ReqTel: "02088888888", 471 ReqPhone: "02088888888", 472 ReqZipCode: "510000", 473 } 474 475 valid := Validation{} 476 b, err := valid.Valid(u) 477 if err != nil { 478 t.Fatal(err) 479 } 480 if b { 481 t.Fatal("validation should not be passed") 482 } 483 484 valid = Validation{RequiredFirst: true} 485 b, err = valid.Valid(u) 486 if err != nil { 487 t.Fatal(err) 488 } 489 if !b { 490 t.Fatal("validation should be passed") 491 } 492 } 493 494 func TestPointer(t *testing.T) { 495 type User struct { 496 ID int 497 498 Email *string `valid:"Email"` 499 ReqEmail *string `valid:"Required;Email"` 500 } 501 502 u := User{ 503 ReqEmail: nil, 504 Email: nil, 505 } 506 507 valid := Validation{} 508 b, err := valid.Valid(u) 509 if err != nil { 510 t.Fatal(err) 511 } 512 if b { 513 t.Fatal("validation should not be passed") 514 } 515 516 validEmail := "a@a.com" 517 u = User{ 518 ReqEmail: &validEmail, 519 Email: nil, 520 } 521 522 valid = Validation{RequiredFirst: true} 523 b, err = valid.Valid(u) 524 if err != nil { 525 t.Fatal(err) 526 } 527 if !b { 528 t.Fatal("validation should be passed") 529 } 530 531 u = User{ 532 ReqEmail: &validEmail, 533 Email: nil, 534 } 535 536 valid = Validation{} 537 b, err = valid.Valid(u) 538 if err != nil { 539 t.Fatal(err) 540 } 541 if b { 542 t.Fatal("validation should not be passed") 543 } 544 545 invalidEmail := "a@a" 546 u = User{ 547 ReqEmail: &validEmail, 548 Email: &invalidEmail, 549 } 550 551 valid = Validation{RequiredFirst: true} 552 b, err = valid.Valid(u) 553 if err != nil { 554 t.Fatal(err) 555 } 556 if b { 557 t.Fatal("validation should not be passed") 558 } 559 560 u = User{ 561 ReqEmail: &validEmail, 562 Email: &invalidEmail, 563 } 564 565 valid = Validation{} 566 b, err = valid.Valid(u) 567 if err != nil { 568 t.Fatal(err) 569 } 570 if b { 571 t.Fatal("validation should not be passed") 572 } 573 } 574 575 func TestCanSkipAlso(t *testing.T) { 576 type User struct { 577 ID int 578 579 Email string `valid:"Email"` 580 ReqEmail string `valid:"Required;Email"` 581 MatchRange int `valid:"Range(10, 20)"` 582 } 583 584 u := User{ 585 ReqEmail: "a@a.com", 586 Email: "", 587 MatchRange: 0, 588 } 589 590 valid := Validation{RequiredFirst: true} 591 b, err := valid.Valid(u) 592 if err != nil { 593 t.Fatal(err) 594 } 595 if b { 596 t.Fatal("validation should not be passed") 597 } 598 599 valid = Validation{RequiredFirst: true} 600 valid.CanSkipAlso("Range") 601 b, err = valid.Valid(u) 602 if err != nil { 603 t.Fatal(err) 604 } 605 if !b { 606 t.Fatal("validation should be passed") 607 } 608 609 }