validationmdl_test.go 11.6 KiB
Newer Older
Rahul A. Sutar's avatar
Rahul A. Sutar committed
package validationmdl

import (
	"bytes"
	"net/http"
	"net/url"
	"reflect"
	"strings"
	"testing"

	"github.com/caibirdme/yql"
	"github.com/pquerna/ffjson/ffjson"
	"github.com/thedevsaddam/govalidator"
)

type RequestBodyData struct {
	Email    string `json:"email"`
	Password string `json:"password"`
}

//Validation rules
var validationRules = govalidator.MapData{
	"email":    []string{"required", "min:7", "max:20", "email"},
	"password": []string{"required"},
}

//Validation messages
var validationMessages = govalidator.MapData{
	"email":    []string{"required:Email required", "min:Email min len", "max:Email max len", "email:Invalid email"},
	"password": []string{"required:Password required"},
}

func TestValidateRequest(t *testing.T) {

	//Cases for sending raw data in request
	//Case 1: Http request for sunny day scenario
	sunnyDayData := RequestBodyData{Email: "test@mkcl.org", Password: "test"}
	sunnyDayByteArray, _ := ffjson.Marshal(&sunnyDayData)
	sunnyDayHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(sunnyDayByteArray)))
	sunnyDayHTTPRequest.Header.Set("Content-Type", "application/json")

	//Case 2 : Http request for blank email
	blankEmailData := RequestBodyData{Email: "", Password: "test"}
	blankEmailByteArray, _ := ffjson.Marshal(&blankEmailData)
	blankEmailHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(blankEmailByteArray)))
	blankEmailHTTPRequest.Header.Set("Content-Type", "application/json")
	blankEmailExpectedResult := map[string]interface{}{
		"validationErrors": url.Values{
			"email": []string{"Email required", "Email min len", "Invalid email"},
		},
	}

	//Case 3 : Http request for blank password
	blankPasswordData := RequestBodyData{Email: "test@mkcl.org", Password: ""}
	blankPasswordByteArray, _ := ffjson.Marshal(&blankPasswordData)
	blankPasswordHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(blankPasswordByteArray)))
	blankPasswordHTTPRequest.Header.Set("Content-Type", "application/json")
	blankPasswordExpectedResult := map[string]interface{}{
		"validationErrors": url.Values{
			"password": []string{"Password required"},
		},
	}

	//Case 4 : Http request for email with shorter length than required
	shortEmailLengthData := RequestBodyData{Email: "a@c.v", Password: "test"}
	shortEmailLengthByteArray, _ := ffjson.Marshal(&shortEmailLengthData)
	shortEmailLengthHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(shortEmailLengthByteArray)))
	shortEmailLengthHTTPRequest.Header.Set("Content-Type", "application/json")
	shortEmailLengthExpectedResult := map[string]interface{}{
		"validationErrors": url.Values{
			"email": []string{"Email min len"},
		},
	}

	//Case 5 : Http request for email with longer length than required
	longEmailLengthData := RequestBodyData{Email: "testEmail@Testcompany.testdomain", Password: "test"}
	longEmailLengthByteArray, _ := ffjson.Marshal(&longEmailLengthData)
	longEmailLengthHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(longEmailLengthByteArray)))
	longEmailLengthHTTPRequest.Header.Set("Content-Type", "application/json")
	longEmailLengthExpectedResult := map[string]interface{}{
		"validationErrors": url.Values{
			"email": []string{"Email max len"},
		},
	}

	//Case 6 : Http request for invalid email id
	invalidEmailData := RequestBodyData{Email: "testemail", Password: "test"}
	invalidEmailByteArray, _ := ffjson.Marshal(&invalidEmailData)
	invalidEmailHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(invalidEmailByteArray)))
	invalidEmailHTTPRequest.Header.Set("Content-Type", "application/json")
	invalidEmailExpectedResult := map[string]interface{}{
		"validationErrors": url.Values{
			"email": []string{"Invalid email"},
		},
	}

	//Case 7 : Http request for blank email using form encoding
	sunnyDayForm := url.Values{}
	sunnyDayForm.Add("email", "")
	sunnyDayForm.Add("password", "password")
	sunnyDayHTTPRequestFormEnc, _ := http.NewRequest("POST", "test.com", strings.NewReader(sunnyDayForm.Encode()))
	sunnyDayHTTPRequestFormEnc.PostForm = sunnyDayForm
	sunnyDayHTTPRequestFormEnc.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	sunnyDayExpectedResultFormEnc := map[string]interface{}{
		"validationErrors": url.Values{
			"email": []string{"Email required", "Email min len", "Invalid email"},
		},
	}

	//Case 8 : Http request for blank email using form encoding
	blankEmailForm := url.Values{}
	blankEmailForm.Add("email", "")
	blankEmailForm.Add("password", "password")
	blankEmailHTTPRequestFormEnc, _ := http.NewRequest("POST", "test.com", strings.NewReader(blankEmailForm.Encode()))
	blankEmailHTTPRequestFormEnc.PostForm = blankEmailForm
	blankEmailHTTPRequestFormEnc.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	blankEmailExpectedResultFormEnc := map[string]interface{}{
		"validationErrors": url.Values{
			"email": []string{"Email required", "Email min len", "Invalid email"},
		},
	}

	//Case 9 : Http request for blank password using form encoding
	blankPasswordForm := url.Values{}
	blankPasswordForm.Add("email", "test@mkcl.org")
	blankPasswordForm.Add("password", "")
	blankPasswordHTTPRequestFormEnc, _ := http.NewRequest("POST", "test.com", strings.NewReader(blankPasswordForm.Encode()))
	blankPasswordHTTPRequestFormEnc.PostForm = blankPasswordForm
	blankPasswordHTTPRequestFormEnc.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	blankPasswordExpectedResultFormEnc := map[string]interface{}{
		"validationErrors": url.Values{
			"password": []string{"Password required"},
		},
	}

	//Case 10 : Http request for email with shorter length than required using form encoding
	shortEmailLengthForm := url.Values{}
	shortEmailLengthForm.Add("email", "a@v.c")
	shortEmailLengthForm.Add("password", "testPass")
	shortEmailLengthHTTPRequestFormEnc, _ := http.NewRequest("POST", "test.com", strings.NewReader(shortEmailLengthForm.Encode()))
	shortEmailLengthHTTPRequestFormEnc.PostForm = shortEmailLengthForm
	shortEmailLengthHTTPRequestFormEnc.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	shortEmailLengthExpectedResultFormEnc := map[string]interface{}{
		"validationErrors": url.Values{
			"email": []string{"Email min len"},
		},
	}

	//Case 11 : Http request for email with longer length than required using form encoding
	longEmailLengthForm := url.Values{}
	longEmailLengthForm.Add("email", "testEmail@Testcompany.testdomain")
	longEmailLengthForm.Add("password", "testPass")
	longEmailLengthHTTPRequestFormEnc, _ := http.NewRequest("POST", "test.com", strings.NewReader(longEmailLengthForm.Encode()))
	longEmailLengthHTTPRequestFormEnc.PostForm = longEmailLengthForm
	longEmailLengthHTTPRequestFormEnc.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	longEmailLengthExpectedResultFormEnc := map[string]interface{}{
		"validationErrors": url.Values{
			"email": []string{"Email max len"},
		},
	}

	//Case 12 : Http request for invalid email using form encoding
	invalidEmailLengthForm := url.Values{}
	invalidEmailLengthForm.Add("email", "testasdfasdf")
	invalidEmailLengthForm.Add("password", "test")
	invalidEmailLengthHTTPRequestFormEnc, _ := http.NewRequest("POST", "test.com", strings.NewReader(invalidEmailLengthForm.Encode()))
	invalidEmailLengthHTTPRequestFormEnc.PostForm = invalidEmailLengthForm
	invalidEmailLengthHTTPRequestFormEnc.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	invalidEmailLengthExpectedResultFormEnc := map[string]interface{}{
		"validationErrors": url.Values{
			"email": []string{"Invalid email"},
		},
	}

	type args struct {
		httpRequest        *http.Request
		validationRules    govalidator.MapData
		validationMessages govalidator.MapData
	}
	tests := []struct {
		name string
		args args
		want map[string]interface{}
	}{
		{"TestSunnyDay", args{sunnyDayHTTPRequest, validationRules, validationMessages}, nil},
		{"BlankEmailValidation", args{blankEmailHTTPRequest, validationRules, validationMessages}, blankEmailExpectedResult},
		{"BlankPasswordValidation", args{blankPasswordHTTPRequest, validationRules, validationMessages}, blankPasswordExpectedResult},
		{"ShortEmailLengthValidation", args{shortEmailLengthHTTPRequest, validationRules, validationMessages}, shortEmailLengthExpectedResult},
		{"LongEmailLengthValidation", args{longEmailLengthHTTPRequest, validationRules, validationMessages}, longEmailLengthExpectedResult},
		{"InvalidEmailValidation", args{invalidEmailHTTPRequest, validationRules, validationMessages}, invalidEmailExpectedResult},
		{"SunnyDayFormEnc", args{sunnyDayHTTPRequestFormEnc, validationRules, validationMessages}, sunnyDayExpectedResultFormEnc},
		{"BlankEmailValidationFormEnc", args{blankEmailHTTPRequestFormEnc, validationRules, validationMessages}, blankEmailExpectedResultFormEnc},
		{"BlankPasswordValidationFormEnc", args{blankPasswordHTTPRequestFormEnc, validationRules, validationMessages}, blankPasswordExpectedResultFormEnc},
		{"ShortEmailLengthValidationFormEnc", args{shortEmailLengthHTTPRequestFormEnc, validationRules, validationMessages}, shortEmailLengthExpectedResultFormEnc},
		{"LongEmailLengthValidationFormEnc", args{longEmailLengthHTTPRequestFormEnc, validationRules, validationMessages}, longEmailLengthExpectedResultFormEnc},
		{"InvalidEmailLengthValidationFormEnc", args{invalidEmailLengthHTTPRequestFormEnc, validationRules, validationMessages}, invalidEmailLengthExpectedResultFormEnc},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := ValidateRequest(tt.args.httpRequest, tt.args.validationRules, tt.args.validationMessages); !reflect.DeepEqual(got, tt.want) {
				t.Errorf("ValidateRequest() = %v, want %v", got, tt.want)
			}
		})
	}

}

func BenchmarkValidationTest(b *testing.B) {

Rahul A. Sutar's avatar
Rahul A. Sutar committed
	//Validation rules
	validationRules := govalidator.MapData{
		"email":    []string{"required", "min:5", "max:20", "email"},
		"password": []string{"required"},
	}
	//Validation messages
	validationMessages := govalidator.MapData{
		"email":    []string{"required:Email Id is required", "min:Min length 5 required", "max:Max length 20 allowed", "email:Enter a valid email"},
		"password": []string{"required:Password is required"},
	}

	sunnyDayData := RequestBodyData{Email: "test@mkcl.org", Password: "test"}
	sunnyDayByteArray, _ := ffjson.Marshal(&sunnyDayData)
	sunnyDayHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(sunnyDayByteArray)))
	sunnyDayHTTPRequest.Header.Set("Content-Type", "application/json")
Rahul A. Sutar's avatar
Rahul A. Sutar committed
	for i := 0; i < b.N; i++ {
Rahul A. Sutar's avatar
Rahul A. Sutar committed

		ValidateRequest(sunnyDayHTTPRequest, validationRules, validationMessages)

	}
}

func BenchmarkYQLTestAgainstValidator(b *testing.B) {

	for i := 0; i < b.N; i++ {

		rawYQL := `age>=23`
		yql.Match(rawYQL, map[string]interface{}{
			"age": int64(24),
		})
	}
}

func BenchmarkValidationTestAgainstYQL(b *testing.B) {

	type TestData struct {
		Age int64 `json:"age"`
	}

Rahul A. Sutar's avatar
Rahul A. Sutar committed
	validationRules := govalidator.MapData{
		"age": []string{"required", "min:23"},
	}
Rahul A. Sutar's avatar
Rahul A. Sutar committed
	sunnyDayData := TestData{Age: 24}
	sunnyDayByteArray, _ := ffjson.Marshal(&sunnyDayData)
	sunnyDayHTTPRequest, _ := http.NewRequest("POST", "test.com", bytes.NewBufferString(string(sunnyDayByteArray)))
	sunnyDayHTTPRequest.Header.Set("Content-Type", "application/json")
Rahul A. Sutar's avatar
Rahul A. Sutar committed
	for i := 0; i < b.N; i++ {
Rahul A. Sutar's avatar
Rahul A. Sutar committed
		ValidateRequest(sunnyDayHTTPRequest, validationRules, nil)
	}
}
Rahul A. Sutar's avatar
Rahul A. Sutar committed

func BenchmarkStructValidation(b *testing.B) {

	type EmailValidation struct {
		Email    string `json:"email"`
		Password string `json:"password"`
	}

	emailValidation := EmailValidation{}
	emailValidation.Email = "test@mkcl.org"
	emailValidation.Password = "testPassword"

	for i := 0; i < b.N; i++ {
		ValidateStruct(emailValidation, validationRules, validationMessages)
	}
}