fixed number settings 0 max validator
This commit is contained in:
+3
-1
@@ -1,6 +1,8 @@
|
|||||||
## v0.39.3 (WIP)
|
## v0.39.3 (WIP)
|
||||||
|
|
||||||
- Fixed JS error on `file` settings `maxSelect` change.
|
- Fixed JS error on `file` settings `maxSelect` change ([#7731](https://github.com/pocketbase/pocketbase/issues/7731)).
|
||||||
|
|
||||||
|
- Other minor fixes (fixed `number` settings validator to not ignore 0 `max` values, normalized field settings tooltip format, etc.).
|
||||||
|
|
||||||
|
|
||||||
## v0.39.2
|
## v0.39.2
|
||||||
|
|||||||
+18
-6
@@ -2,7 +2,6 @@ package core
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
validation "github.com/go-ozzo/ozzo-validation/v4"
|
validation "github.com/go-ozzo/ozzo-validation/v4"
|
||||||
@@ -23,6 +22,12 @@ var (
|
|||||||
_ SetterFinder = (*NumberField)(nil)
|
_ SetterFinder = (*NumberField)(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
onlyIntValidationError = validation.NewError("validation_only_int_constraint", "Decimal numbers are not allowed")
|
||||||
|
minNumberValidationError = validation.NewError("validation_min_number_constraint", "Must be greater or equal than {{.min}}")
|
||||||
|
maxNumberValidationError = validation.NewError("validation_max_number_constraint", "Must be less or equal than {{.max}}")
|
||||||
|
)
|
||||||
|
|
||||||
// NumberField defines "number" type field for storing numeric (float64) value.
|
// NumberField defines "number" type field for storing numeric (float64) value.
|
||||||
//
|
//
|
||||||
// The respective zero record field value is 0.
|
// The respective zero record field value is 0.
|
||||||
@@ -151,15 +156,15 @@ func (f *NumberField) ValidateValue(ctx context.Context, app App, record *Record
|
|||||||
}
|
}
|
||||||
|
|
||||||
if f.OnlyInt && val != float64(int64(val)) {
|
if f.OnlyInt && val != float64(int64(val)) {
|
||||||
return validation.NewError("validation_only_int_constraint", "Decimal numbers are not allowed")
|
return onlyIntValidationError
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.Min != nil && val < *f.Min {
|
if f.Min != nil && val < *f.Min {
|
||||||
return validation.NewError("validation_min_number_constraint", fmt.Sprintf("Must be larger than %f", *f.Min))
|
return minNumberValidationError.SetParams(map[string]any{"min": *f.Min})
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.Max != nil && val > *f.Max {
|
if f.Max != nil && val > *f.Max {
|
||||||
return validation.NewError("validation_max_number_constraint", fmt.Sprintf("Must be less than %f", *f.Max))
|
return maxNumberValidationError.SetParams(map[string]any{"max": *f.Max})
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -171,7 +176,14 @@ func (f *NumberField) ValidateSettings(ctx context.Context, app App, collection
|
|||||||
validation.By(f.checkOnlyInt),
|
validation.By(f.checkOnlyInt),
|
||||||
}
|
}
|
||||||
if f.Min != nil && f.Max != nil {
|
if f.Min != nil && f.Max != nil {
|
||||||
maxRules = append(maxRules, validation.Min(*f.Min))
|
maxRules = append(maxRules, validation.By(func(value interface{}) error {
|
||||||
|
// similar to validation.Min but doesn't ignore zero values
|
||||||
|
v, _ := value.(*float64)
|
||||||
|
if v == nil || f.Min == nil || *v >= *f.Min {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return minNumberValidationError.SetParams(map[string]any{"min": *f.Min})
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
return validation.ValidateStruct(f,
|
return validation.ValidateStruct(f,
|
||||||
@@ -190,7 +202,7 @@ func (f *NumberField) checkOnlyInt(value any) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if *v != float64(int64(*v)) {
|
if *v != float64(int64(*v)) {
|
||||||
return validation.NewError("validation_only_int_constraint", "Decimal numbers are not allowed.")
|
return onlyIntValidationError
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ func TestNumberFieldValidateSettings(t *testing.T) {
|
|||||||
[]string{},
|
[]string{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"decumal min",
|
"decimal min",
|
||||||
func() *core.NumberField {
|
func() *core.NumberField {
|
||||||
return &core.NumberField{
|
return &core.NumberField{
|
||||||
Id: "test",
|
Id: "test",
|
||||||
@@ -248,7 +248,7 @@ func TestNumberFieldValidateSettings(t *testing.T) {
|
|||||||
[]string{},
|
[]string{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"decumal min (onlyInt)",
|
"decimal min (onlyInt)",
|
||||||
func() *core.NumberField {
|
func() *core.NumberField {
|
||||||
return &core.NumberField{
|
return &core.NumberField{
|
||||||
Id: "test",
|
Id: "test",
|
||||||
@@ -272,7 +272,7 @@ func TestNumberFieldValidateSettings(t *testing.T) {
|
|||||||
[]string{},
|
[]string{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"decumal max",
|
"decimal max",
|
||||||
func() *core.NumberField {
|
func() *core.NumberField {
|
||||||
return &core.NumberField{
|
return &core.NumberField{
|
||||||
Id: "test",
|
Id: "test",
|
||||||
@@ -283,7 +283,7 @@ func TestNumberFieldValidateSettings(t *testing.T) {
|
|||||||
[]string{},
|
[]string{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"decumal max (onlyInt)",
|
"decimal max (onlyInt)",
|
||||||
func() *core.NumberField {
|
func() *core.NumberField {
|
||||||
return &core.NumberField{
|
return &core.NumberField{
|
||||||
Id: "test",
|
Id: "test",
|
||||||
@@ -307,19 +307,31 @@ func TestNumberFieldValidateSettings(t *testing.T) {
|
|||||||
[]string{},
|
[]string{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"min > max",
|
"min > max (0)",
|
||||||
func() *core.NumberField {
|
func() *core.NumberField {
|
||||||
return &core.NumberField{
|
return &core.NumberField{
|
||||||
Id: "test",
|
Id: "test",
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Min: types.Pointer(2.0),
|
Min: types.Pointer(2.0),
|
||||||
Max: types.Pointer(1.0),
|
Max: types.Pointer(0.0),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[]string{"max"},
|
[]string{"max"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"min <= max",
|
"min (0) > max",
|
||||||
|
func() *core.NumberField {
|
||||||
|
return &core.NumberField{
|
||||||
|
Id: "test",
|
||||||
|
Name: "test",
|
||||||
|
Min: types.Pointer(0.0),
|
||||||
|
Max: types.Pointer(-1.0),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[]string{"max"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"min == max",
|
||||||
func() *core.NumberField {
|
func() *core.NumberField {
|
||||||
return &core.NumberField{
|
return &core.NumberField{
|
||||||
Id: "test",
|
Id: "test",
|
||||||
@@ -330,6 +342,18 @@ func TestNumberFieldValidateSettings(t *testing.T) {
|
|||||||
},
|
},
|
||||||
[]string{},
|
[]string{},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"min < max",
|
||||||
|
func() *core.NumberField {
|
||||||
|
return &core.NumberField{
|
||||||
|
Id: "test",
|
||||||
|
Name: "test",
|
||||||
|
Min: types.Pointer(2.0),
|
||||||
|
Max: types.Pointer(3.0),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[]string{},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, s := range scenarios {
|
for _, s := range scenarios {
|
||||||
|
|||||||
Reference in New Issue
Block a user