mirror of
https://github.com/astaxie/beego.git
synced 2024-12-01 18:31:29 +00:00
581e48679e
Fix issue 3866
610 lines
14 KiB
Go
610 lines
14 KiB
Go
// Copyright 2014 beego Author. All Rights Reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package validation
|
|
|
|
import (
|
|
"regexp"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestRequired(t *testing.T) {
|
|
valid := Validation{}
|
|
|
|
if valid.Required(nil, "nil").Ok {
|
|
t.Error("nil object should be false")
|
|
}
|
|
if !valid.Required(true, "bool").Ok {
|
|
t.Error("Bool value should always return true")
|
|
}
|
|
if !valid.Required(false, "bool").Ok {
|
|
t.Error("Bool value should always return true")
|
|
}
|
|
if valid.Required("", "string").Ok {
|
|
t.Error("\"'\" string should be false")
|
|
}
|
|
if valid.Required(" ", "string").Ok {
|
|
t.Error("\" \" string should be false") // For #2361
|
|
}
|
|
if valid.Required("\n", "string").Ok {
|
|
t.Error("new line string should be false") // For #2361
|
|
}
|
|
if !valid.Required("astaxie", "string").Ok {
|
|
t.Error("string should be true")
|
|
}
|
|
if valid.Required(0, "zero").Ok {
|
|
t.Error("Integer should not be equal 0")
|
|
}
|
|
if !valid.Required(1, "int").Ok {
|
|
t.Error("Integer except 0 should be true")
|
|
}
|
|
if !valid.Required(time.Now(), "time").Ok {
|
|
t.Error("time should be true")
|
|
}
|
|
if valid.Required([]string{}, "emptySlice").Ok {
|
|
t.Error("empty slice should be false")
|
|
}
|
|
if !valid.Required([]interface{}{"ok"}, "slice").Ok {
|
|
t.Error("slice should be true")
|
|
}
|
|
}
|
|
|
|
func TestMin(t *testing.T) {
|
|
valid := Validation{}
|
|
|
|
if valid.Min(-1, 0, "min0").Ok {
|
|
t.Error("-1 is less than the minimum value of 0 should be false")
|
|
}
|
|
if !valid.Min(1, 0, "min0").Ok {
|
|
t.Error("1 is greater or equal than the minimum value of 0 should be true")
|
|
}
|
|
}
|
|
|
|
func TestMax(t *testing.T) {
|
|
valid := Validation{}
|
|
|
|
if valid.Max(1, 0, "max0").Ok {
|
|
t.Error("1 is greater than the minimum value of 0 should be false")
|
|
}
|
|
if !valid.Max(-1, 0, "max0").Ok {
|
|
t.Error("-1 is less or equal than the maximum value of 0 should be true")
|
|
}
|
|
}
|
|
|
|
func TestRange(t *testing.T) {
|
|
valid := Validation{}
|
|
|
|
if valid.Range(-1, 0, 1, "range0_1").Ok {
|
|
t.Error("-1 is between 0 and 1 should be false")
|
|
}
|
|
if !valid.Range(1, 0, 1, "range0_1").Ok {
|
|
t.Error("1 is between 0 and 1 should be true")
|
|
}
|
|
}
|
|
|
|
func TestMinSize(t *testing.T) {
|
|
valid := Validation{}
|
|
|
|
if valid.MinSize("", 1, "minSize1").Ok {
|
|
t.Error("the length of \"\" is less than the minimum value of 1 should be false")
|
|
}
|
|
if !valid.MinSize("ok", 1, "minSize1").Ok {
|
|
t.Error("the length of \"ok\" is greater or equal than the minimum value of 1 should be true")
|
|
}
|
|
if valid.MinSize([]string{}, 1, "minSize1").Ok {
|
|
t.Error("the length of empty slice is less than the minimum value of 1 should be false")
|
|
}
|
|
if !valid.MinSize([]interface{}{"ok"}, 1, "minSize1").Ok {
|
|
t.Error("the length of [\"ok\"] is greater or equal than the minimum value of 1 should be true")
|
|
}
|
|
}
|
|
|
|
func TestMaxSize(t *testing.T) {
|
|
valid := Validation{}
|
|
|
|
if valid.MaxSize("ok", 1, "maxSize1").Ok {
|
|
t.Error("the length of \"ok\" is greater than the maximum value of 1 should be false")
|
|
}
|
|
if !valid.MaxSize("", 1, "maxSize1").Ok {
|
|
t.Error("the length of \"\" is less or equal than the maximum value of 1 should be true")
|
|
}
|
|
if valid.MaxSize([]interface{}{"ok", false}, 1, "maxSize1").Ok {
|
|
t.Error("the length of [\"ok\", false] is greater than the maximum value of 1 should be false")
|
|
}
|
|
if !valid.MaxSize([]string{}, 1, "maxSize1").Ok {
|
|
t.Error("the length of empty slice is less or equal than the maximum value of 1 should be true")
|
|
}
|
|
}
|
|
|
|
func TestLength(t *testing.T) {
|
|
valid := Validation{}
|
|
|
|
if valid.Length("", 1, "length1").Ok {
|
|
t.Error("the length of \"\" must equal 1 should be false")
|
|
}
|
|
if !valid.Length("1", 1, "length1").Ok {
|
|
t.Error("the length of \"1\" must equal 1 should be true")
|
|
}
|
|
if valid.Length([]string{}, 1, "length1").Ok {
|
|
t.Error("the length of empty slice must equal 1 should be false")
|
|
}
|
|
if !valid.Length([]interface{}{"ok"}, 1, "length1").Ok {
|
|
t.Error("the length of [\"ok\"] must equal 1 should be true")
|
|
}
|
|
}
|
|
|
|
func TestAlpha(t *testing.T) {
|
|
valid := Validation{}
|
|
|
|
if valid.Alpha("a,1-@ $", "alpha").Ok {
|
|
t.Error("\"a,1-@ $\" are valid alpha characters should be false")
|
|
}
|
|
if !valid.Alpha("abCD", "alpha").Ok {
|
|
t.Error("\"abCD\" are valid alpha characters should be true")
|
|
}
|
|
}
|
|
|
|
func TestNumeric(t *testing.T) {
|
|
valid := Validation{}
|
|
|
|
if valid.Numeric("a,1-@ $", "numeric").Ok {
|
|
t.Error("\"a,1-@ $\" are valid numeric characters should be false")
|
|
}
|
|
if !valid.Numeric("1234", "numeric").Ok {
|
|
t.Error("\"1234\" are valid numeric characters should be true")
|
|
}
|
|
}
|
|
|
|
func TestAlphaNumeric(t *testing.T) {
|
|
valid := Validation{}
|
|
|
|
if valid.AlphaNumeric("a,1-@ $", "alphaNumeric").Ok {
|
|
t.Error("\"a,1-@ $\" are valid alpha or numeric characters should be false")
|
|
}
|
|
if !valid.AlphaNumeric("1234aB", "alphaNumeric").Ok {
|
|
t.Error("\"1234aB\" are valid alpha or numeric characters should be true")
|
|
}
|
|
}
|
|
|
|
func TestMatch(t *testing.T) {
|
|
valid := Validation{}
|
|
|
|
if valid.Match("suchuangji@gmail", regexp.MustCompile(`^\w+@\w+\.\w+$`), "match").Ok {
|
|
t.Error("\"suchuangji@gmail\" match \"^\\w+@\\w+\\.\\w+$\" should be false")
|
|
}
|
|
if !valid.Match("suchuangji@gmail.com", regexp.MustCompile(`^\w+@\w+\.\w+$`), "match").Ok {
|
|
t.Error("\"suchuangji@gmail\" match \"^\\w+@\\w+\\.\\w+$\" should be true")
|
|
}
|
|
}
|
|
|
|
func TestNoMatch(t *testing.T) {
|
|
valid := Validation{}
|
|
|
|
if valid.NoMatch("123@gmail", regexp.MustCompile(`[^\w\d]`), "nomatch").Ok {
|
|
t.Error("\"123@gmail\" not match \"[^\\w\\d]\" should be false")
|
|
}
|
|
if !valid.NoMatch("123gmail", regexp.MustCompile(`[^\w\d]`), "match").Ok {
|
|
t.Error("\"123@gmail\" not match \"[^\\w\\d@]\" should be true")
|
|
}
|
|
}
|
|
|
|
func TestAlphaDash(t *testing.T) {
|
|
valid := Validation{}
|
|
|
|
if valid.AlphaDash("a,1-@ $", "alphaDash").Ok {
|
|
t.Error("\"a,1-@ $\" are valid alpha or numeric or dash(-_) characters should be false")
|
|
}
|
|
if !valid.AlphaDash("1234aB-_", "alphaDash").Ok {
|
|
t.Error("\"1234aB\" are valid alpha or numeric or dash(-_) characters should be true")
|
|
}
|
|
}
|
|
|
|
func TestEmail(t *testing.T) {
|
|
valid := Validation{}
|
|
|
|
if valid.Email("not@a email", "email").Ok {
|
|
t.Error("\"not@a email\" is a valid email address should be false")
|
|
}
|
|
if !valid.Email("suchuangji@gmail.com", "email").Ok {
|
|
t.Error("\"suchuangji@gmail.com\" is a valid email address should be true")
|
|
}
|
|
if valid.Email("@suchuangji@gmail.com", "email").Ok {
|
|
t.Error("\"@suchuangji@gmail.com\" is a valid email address should be false")
|
|
}
|
|
if valid.Email("suchuangji@gmail.com ok", "email").Ok {
|
|
t.Error("\"suchuangji@gmail.com ok\" is a valid email address should be false")
|
|
}
|
|
}
|
|
|
|
func TestIP(t *testing.T) {
|
|
valid := Validation{}
|
|
|
|
if valid.IP("11.255.255.256", "IP").Ok {
|
|
t.Error("\"11.255.255.256\" is a valid ip address should be false")
|
|
}
|
|
if !valid.IP("01.11.11.11", "IP").Ok {
|
|
t.Error("\"suchuangji@gmail.com\" is a valid ip address should be true")
|
|
}
|
|
}
|
|
|
|
func TestBase64(t *testing.T) {
|
|
valid := Validation{}
|
|
|
|
if valid.Base64("suchuangji@gmail.com", "base64").Ok {
|
|
t.Error("\"suchuangji@gmail.com\" are a valid base64 characters should be false")
|
|
}
|
|
if !valid.Base64("c3VjaHVhbmdqaUBnbWFpbC5jb20=", "base64").Ok {
|
|
t.Error("\"c3VjaHVhbmdqaUBnbWFpbC5jb20=\" are a valid base64 characters should be true")
|
|
}
|
|
}
|
|
|
|
func TestMobile(t *testing.T) {
|
|
valid := Validation{}
|
|
|
|
validMobiles := []string{
|
|
"19800008888",
|
|
"18800008888",
|
|
"18000008888",
|
|
"8618300008888",
|
|
"+8614700008888",
|
|
"17300008888",
|
|
"+8617100008888",
|
|
"8617500008888",
|
|
"8617400008888",
|
|
"16200008888",
|
|
"16500008888",
|
|
"16600008888",
|
|
"16700008888",
|
|
"13300008888",
|
|
"14900008888",
|
|
"15300008888",
|
|
"17300008888",
|
|
"17700008888",
|
|
"18000008888",
|
|
"18900008888",
|
|
"19100008888",
|
|
"19900008888",
|
|
"19300008888",
|
|
"13000008888",
|
|
"13100008888",
|
|
"13200008888",
|
|
"14500008888",
|
|
"15500008888",
|
|
"15600008888",
|
|
"16600008888",
|
|
"17100008888",
|
|
"17500008888",
|
|
"17600008888",
|
|
"18500008888",
|
|
"18600008888",
|
|
"13400008888",
|
|
"13500008888",
|
|
"13600008888",
|
|
"13700008888",
|
|
"13800008888",
|
|
"13900008888",
|
|
"14700008888",
|
|
"15000008888",
|
|
"15100008888",
|
|
"15200008888",
|
|
"15800008888",
|
|
"15900008888",
|
|
"17200008888",
|
|
"17800008888",
|
|
"18200008888",
|
|
"18300008888",
|
|
"18400008888",
|
|
"18700008888",
|
|
"18800008888",
|
|
"19800008888",
|
|
}
|
|
|
|
for _, m := range validMobiles {
|
|
if !valid.Mobile(m, "mobile").Ok {
|
|
t.Error(m + " is a valid mobile phone number should be true")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTel(t *testing.T) {
|
|
valid := Validation{}
|
|
|
|
if valid.Tel("222-00008888", "telephone").Ok {
|
|
t.Error("\"222-00008888\" is a valid telephone number should be false")
|
|
}
|
|
if !valid.Tel("022-70008888", "telephone").Ok {
|
|
t.Error("\"022-70008888\" is a valid telephone number should be true")
|
|
}
|
|
if !valid.Tel("02270008888", "telephone").Ok {
|
|
t.Error("\"02270008888\" is a valid telephone number should be true")
|
|
}
|
|
if !valid.Tel("70008888", "telephone").Ok {
|
|
t.Error("\"70008888\" is a valid telephone number should be true")
|
|
}
|
|
}
|
|
|
|
func TestPhone(t *testing.T) {
|
|
valid := Validation{}
|
|
|
|
if valid.Phone("222-00008888", "phone").Ok {
|
|
t.Error("\"222-00008888\" is a valid phone number should be false")
|
|
}
|
|
if !valid.Mobile("+8614700008888", "phone").Ok {
|
|
t.Error("\"+8614700008888\" is a valid phone number should be true")
|
|
}
|
|
if !valid.Tel("02270008888", "phone").Ok {
|
|
t.Error("\"02270008888\" is a valid phone number should be true")
|
|
}
|
|
}
|
|
|
|
func TestZipCode(t *testing.T) {
|
|
valid := Validation{}
|
|
|
|
if valid.ZipCode("", "zipcode").Ok {
|
|
t.Error("\"00008888\" is a valid zipcode should be false")
|
|
}
|
|
if !valid.ZipCode("536000", "zipcode").Ok {
|
|
t.Error("\"536000\" is a valid zipcode should be true")
|
|
}
|
|
}
|
|
|
|
func TestValid(t *testing.T) {
|
|
type user struct {
|
|
ID int
|
|
Name string `valid:"Required;Match(/^(test)?\\w*@(/test/);com$/)"`
|
|
Age int `valid:"Required;Range(1, 140)"`
|
|
}
|
|
valid := Validation{}
|
|
|
|
u := user{Name: "test@/test/;com", Age: 40}
|
|
b, err := valid.Valid(u)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !b {
|
|
t.Error("validation should be passed")
|
|
}
|
|
|
|
uptr := &user{Name: "test", Age: 40}
|
|
valid.Clear()
|
|
b, err = valid.Valid(uptr)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if b {
|
|
t.Error("validation should not be passed")
|
|
}
|
|
if len(valid.Errors) != 1 {
|
|
t.Fatalf("valid errors len should be 1 but got %d", len(valid.Errors))
|
|
}
|
|
if valid.Errors[0].Key != "Name.Match" {
|
|
t.Errorf("Message key should be `Name.Match` but got %s", valid.Errors[0].Key)
|
|
}
|
|
|
|
u = user{Name: "test@/test/;com", Age: 180}
|
|
valid.Clear()
|
|
b, err = valid.Valid(u)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if b {
|
|
t.Error("validation should not be passed")
|
|
}
|
|
if len(valid.Errors) != 1 {
|
|
t.Fatalf("valid errors len should be 1 but got %d", len(valid.Errors))
|
|
}
|
|
if valid.Errors[0].Key != "Age.Range." {
|
|
t.Errorf("Message key should be `Age.Range` but got %s", valid.Errors[0].Key)
|
|
}
|
|
}
|
|
|
|
func TestRecursiveValid(t *testing.T) {
|
|
type User struct {
|
|
ID int
|
|
Name string `valid:"Required;Match(/^(test)?\\w*@(/test/);com$/)"`
|
|
Age int `valid:"Required;Range(1, 140)"`
|
|
}
|
|
|
|
type AnonymouseUser struct {
|
|
ID2 int
|
|
Name2 string `valid:"Required;Match(/^(test)?\\w*@(/test/);com$/)"`
|
|
Age2 int `valid:"Required;Range(1, 140)"`
|
|
}
|
|
|
|
type Account struct {
|
|
Password string `valid:"Required"`
|
|
U User
|
|
AnonymouseUser
|
|
}
|
|
valid := Validation{}
|
|
|
|
u := Account{Password: "abc123_", U: User{}}
|
|
b, err := valid.RecursiveValid(u)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if b {
|
|
t.Error("validation should not be passed")
|
|
}
|
|
}
|
|
|
|
func TestSkipValid(t *testing.T) {
|
|
type User struct {
|
|
ID int
|
|
|
|
Email string `valid:"Email"`
|
|
ReqEmail string `valid:"Required;Email"`
|
|
|
|
IP string `valid:"IP"`
|
|
ReqIP string `valid:"Required;IP"`
|
|
|
|
Mobile string `valid:"Mobile"`
|
|
ReqMobile string `valid:"Required;Mobile"`
|
|
|
|
Tel string `valid:"Tel"`
|
|
ReqTel string `valid:"Required;Tel"`
|
|
|
|
Phone string `valid:"Phone"`
|
|
ReqPhone string `valid:"Required;Phone"`
|
|
|
|
ZipCode string `valid:"ZipCode"`
|
|
ReqZipCode string `valid:"Required;ZipCode"`
|
|
}
|
|
|
|
u := User{
|
|
ReqEmail: "a@a.com",
|
|
ReqIP: "127.0.0.1",
|
|
ReqMobile: "18888888888",
|
|
ReqTel: "02088888888",
|
|
ReqPhone: "02088888888",
|
|
ReqZipCode: "510000",
|
|
}
|
|
|
|
valid := Validation{}
|
|
b, err := valid.Valid(u)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if b {
|
|
t.Fatal("validation should not be passed")
|
|
}
|
|
|
|
valid = Validation{RequiredFirst: true}
|
|
b, err = valid.Valid(u)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !b {
|
|
t.Fatal("validation should be passed")
|
|
}
|
|
}
|
|
|
|
func TestPointer(t *testing.T) {
|
|
type User struct {
|
|
ID int
|
|
|
|
Email *string `valid:"Email"`
|
|
ReqEmail *string `valid:"Required;Email"`
|
|
}
|
|
|
|
u := User{
|
|
ReqEmail: nil,
|
|
Email: nil,
|
|
}
|
|
|
|
valid := Validation{}
|
|
b, err := valid.Valid(u)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if b {
|
|
t.Fatal("validation should not be passed")
|
|
}
|
|
|
|
validEmail := "a@a.com"
|
|
u = User{
|
|
ReqEmail: &validEmail,
|
|
Email: nil,
|
|
}
|
|
|
|
valid = Validation{RequiredFirst: true}
|
|
b, err = valid.Valid(u)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !b {
|
|
t.Fatal("validation should be passed")
|
|
}
|
|
|
|
u = User{
|
|
ReqEmail: &validEmail,
|
|
Email: nil,
|
|
}
|
|
|
|
valid = Validation{}
|
|
b, err = valid.Valid(u)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if b {
|
|
t.Fatal("validation should not be passed")
|
|
}
|
|
|
|
invalidEmail := "a@a"
|
|
u = User{
|
|
ReqEmail: &validEmail,
|
|
Email: &invalidEmail,
|
|
}
|
|
|
|
valid = Validation{RequiredFirst: true}
|
|
b, err = valid.Valid(u)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if b {
|
|
t.Fatal("validation should not be passed")
|
|
}
|
|
|
|
u = User{
|
|
ReqEmail: &validEmail,
|
|
Email: &invalidEmail,
|
|
}
|
|
|
|
valid = Validation{}
|
|
b, err = valid.Valid(u)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if b {
|
|
t.Fatal("validation should not be passed")
|
|
}
|
|
}
|
|
|
|
func TestCanSkipAlso(t *testing.T) {
|
|
type User struct {
|
|
ID int
|
|
|
|
Email string `valid:"Email"`
|
|
ReqEmail string `valid:"Required;Email"`
|
|
MatchRange int `valid:"Range(10, 20)"`
|
|
}
|
|
|
|
u := User{
|
|
ReqEmail: "a@a.com",
|
|
Email: "",
|
|
MatchRange: 0,
|
|
}
|
|
|
|
valid := Validation{RequiredFirst: true}
|
|
b, err := valid.Valid(u)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if b {
|
|
t.Fatal("validation should not be passed")
|
|
}
|
|
|
|
valid = Validation{RequiredFirst: true}
|
|
valid.CanSkipAlso("Range")
|
|
b, err = valid.Valid(u)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !b {
|
|
t.Fatal("validation should be passed")
|
|
}
|
|
|
|
}
|