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  }