Build and publish Docker images / Build and publish images (push) Failing after 25s
225 lines
4.8 KiB
Go
225 lines
4.8 KiB
Go
package validator
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/gin-gonic/gin/binding"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// testStruct is a sample struct with validation tags for testing.
|
|
type testStruct struct {
|
|
Name string `validate:"required"`
|
|
Email string `validate:"required,email"`
|
|
Age int `validate:"gte=0,lte=130"`
|
|
}
|
|
|
|
func TestInit(t *testing.T) {
|
|
// Should not panic
|
|
Init()
|
|
// validate should be set
|
|
assert.NotNil(t, validate)
|
|
}
|
|
|
|
func TestValidateStruct_Valid(t *testing.T) {
|
|
// Ensure initialized
|
|
Init()
|
|
|
|
s := testStruct{
|
|
Name: "Alice",
|
|
Email: "alice@example.com",
|
|
Age: 30,
|
|
}
|
|
err := ValidateStruct(s)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestValidateStruct_Invalid_MissingRequired(t *testing.T) {
|
|
Init()
|
|
|
|
s := testStruct{
|
|
Name: "",
|
|
Email: "alice@example.com",
|
|
Age: 30,
|
|
}
|
|
err := ValidateStruct(s)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestValidateStruct_Invalid_BadEmail(t *testing.T) {
|
|
Init()
|
|
|
|
s := testStruct{
|
|
Name: "Alice",
|
|
Email: "not-an-email",
|
|
Age: 30,
|
|
}
|
|
err := ValidateStruct(s)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestValidateStruct_Invalid_AgeOutOfRange(t *testing.T) {
|
|
Init()
|
|
|
|
s := testStruct{
|
|
Name: "Alice",
|
|
Email: "alice@example.com",
|
|
Age: 200,
|
|
}
|
|
err := ValidateStruct(s)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestValidateStruct_Invalid_NegativeAge(t *testing.T) {
|
|
Init()
|
|
|
|
s := testStruct{
|
|
Name: "Alice",
|
|
Email: "alice@example.com",
|
|
Age: -1,
|
|
}
|
|
err := ValidateStruct(s)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestValidateStruct_AutoInit(t *testing.T) {
|
|
// Reset validate to nil to test auto-initialization
|
|
validate = nil
|
|
|
|
s := testStruct{
|
|
Name: "Bob",
|
|
Email: "bob@example.com",
|
|
Age: 25,
|
|
}
|
|
err := ValidateStruct(s)
|
|
assert.NoError(t, err)
|
|
// validate should have been auto-initialized
|
|
assert.NotNil(t, validate)
|
|
}
|
|
|
|
func TestVar_Valid(t *testing.T) {
|
|
Init()
|
|
|
|
err := Var("test@example.com", "required,email")
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestVar_Invalid(t *testing.T) {
|
|
Init()
|
|
|
|
err := Var("not-an-email", "email")
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestVar_Required_Empty(t *testing.T) {
|
|
Init()
|
|
|
|
err := Var("", "required")
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestVar_MinLength(t *testing.T) {
|
|
Init()
|
|
|
|
err := Var("ab", "min=3")
|
|
assert.Error(t, err)
|
|
|
|
err = Var("abc", "min=3")
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestVar_AutoInit(t *testing.T) {
|
|
// Reset validate to nil to test auto-initialization
|
|
validate = nil
|
|
|
|
err := Var("test@example.com", "email")
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, validate)
|
|
}
|
|
|
|
func TestValidateStruct_ReturnsLocalizedWrappedError(t *testing.T) {
|
|
type request struct {
|
|
Password string `json:"password" validate:"min=6"`
|
|
}
|
|
|
|
err := ValidateStruct(request{Password: "123"})
|
|
require.Error(t, err)
|
|
wrapped := fmt.Errorf("validation error: %w", err)
|
|
assert.True(t, IsValidationError(wrapped))
|
|
assert.Equal(t, "密码长度不能少于 6 个字符", ValidationMessage(wrapped))
|
|
}
|
|
|
|
func TestValidationMessage_LoginPasswordMin(t *testing.T) {
|
|
type loginRequest struct {
|
|
Password string `json:"password" binding:"required,min=6"`
|
|
}
|
|
|
|
err := binding.Validator.ValidateStruct(loginRequest{Password: "123"})
|
|
require.Error(t, err)
|
|
assert.True(t, IsValidationError(err))
|
|
assert.Equal(t, "密码长度不能少于 6 个字符", ValidationMessage(err))
|
|
assert.NotContains(t, err.Error(), "Field validation")
|
|
}
|
|
|
|
func TestValidationMessage_MultipleFields(t *testing.T) {
|
|
type request struct {
|
|
Email string `json:"email" binding:"required,email"`
|
|
Password string `json:"password" binding:"required,min=6"`
|
|
}
|
|
|
|
err := binding.Validator.ValidateStruct(request{})
|
|
require.Error(t, err)
|
|
message := ValidationMessage(err)
|
|
assert.Contains(t, message, "请填写邮箱")
|
|
assert.Contains(t, message, "请填写密码")
|
|
assert.NotContains(t, message, "Key:")
|
|
}
|
|
|
|
func TestValidationMessageText_RemovesRawValidatorDetails(t *testing.T) {
|
|
raw := "Key: 'LoginRequest.Password' Error:Field validation for 'Password' failed on the 'min' tag"
|
|
assert.Equal(t, "请求参数不符合要求", ValidationMessageText(raw))
|
|
assert.Equal(t, "密码长度不能少于 6 个字符", ValidationMessageText("validation: 密码长度不能少于 6 个字符"))
|
|
}
|
|
|
|
func TestValidateStruct_Pointer(t *testing.T) {
|
|
Init()
|
|
|
|
s := &testStruct{
|
|
Name: "Alice",
|
|
Email: "alice@example.com",
|
|
Age: 30,
|
|
}
|
|
err := ValidateStruct(s)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestValidateStruct_InvalidPointer(t *testing.T) {
|
|
Init()
|
|
|
|
s := &testStruct{
|
|
Name: "",
|
|
Email: "bad",
|
|
Age: 500,
|
|
}
|
|
err := ValidateStruct(s)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestValidateStruct_NonStruct(t *testing.T) {
|
|
Init()
|
|
|
|
// Validating a non-struct with Struct() should return an error
|
|
err := ValidateStruct("just a string")
|
|
require.Error(t, err)
|
|
}
|
|
|
|
func TestValidateStruct_Nil(t *testing.T) {
|
|
Init()
|
|
|
|
// validate.Struct(nil) returns an error
|
|
err := ValidateStruct(nil)
|
|
assert.Error(t, err)
|
|
}
|