fixed number settings 0 max validator

This commit is contained in:
Gani Georgiev
2026-06-08 12:41:13 +03:00
parent b66a4e32cc
commit f868756721
3 changed files with 52 additions and 14 deletions
+3 -1
View File
@@ -1,6 +1,8 @@
## 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
+18 -6
View File
@@ -2,7 +2,6 @@ package core
import (
"context"
"fmt"
"math"
validation "github.com/go-ozzo/ozzo-validation/v4"
@@ -23,6 +22,12 @@ var (
_ 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.
//
// 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)) {
return validation.NewError("validation_only_int_constraint", "Decimal numbers are not allowed")
return onlyIntValidationError
}
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 {
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
@@ -171,7 +176,14 @@ func (f *NumberField) ValidateSettings(ctx context.Context, app App, collection
validation.By(f.checkOnlyInt),
}
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,
@@ -190,7 +202,7 @@ func (f *NumberField) checkOnlyInt(value any) error {
}
if *v != float64(int64(*v)) {
return validation.NewError("validation_only_int_constraint", "Decimal numbers are not allowed.")
return onlyIntValidationError
}
return nil
+31 -7
View File
@@ -237,7 +237,7 @@ func TestNumberFieldValidateSettings(t *testing.T) {
[]string{},
},
{
"decumal min",
"decimal min",
func() *core.NumberField {
return &core.NumberField{
Id: "test",
@@ -248,7 +248,7 @@ func TestNumberFieldValidateSettings(t *testing.T) {
[]string{},
},
{
"decumal min (onlyInt)",
"decimal min (onlyInt)",
func() *core.NumberField {
return &core.NumberField{
Id: "test",
@@ -272,7 +272,7 @@ func TestNumberFieldValidateSettings(t *testing.T) {
[]string{},
},
{
"decumal max",
"decimal max",
func() *core.NumberField {
return &core.NumberField{
Id: "test",
@@ -283,7 +283,7 @@ func TestNumberFieldValidateSettings(t *testing.T) {
[]string{},
},
{
"decumal max (onlyInt)",
"decimal max (onlyInt)",
func() *core.NumberField {
return &core.NumberField{
Id: "test",
@@ -307,19 +307,31 @@ func TestNumberFieldValidateSettings(t *testing.T) {
[]string{},
},
{
"min > max",
"min > max (0)",
func() *core.NumberField {
return &core.NumberField{
Id: "test",
Name: "test",
Min: types.Pointer(2.0),
Max: types.Pointer(1.0),
Max: types.Pointer(0.0),
}
},
[]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 {
return &core.NumberField{
Id: "test",
@@ -330,6 +342,18 @@ func TestNumberFieldValidateSettings(t *testing.T) {
},
[]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 {