added required validator for the TextField.Pattern option in case it is a primary key
This commit is contained in:
parent
48328bf33f
commit
9fe4f87e5b
|
@ -724,7 +724,7 @@ func TestCollectionCreate(t *testing.T) {
|
||||||
ExpectedContent: []string{
|
ExpectedContent: []string{
|
||||||
`"name":"new"`,
|
`"name":"new"`,
|
||||||
`"type":"view"`,
|
`"type":"view"`,
|
||||||
`"fields":[{"autogeneratePattern":"","hidden":false,"id":"text3208210256","max":0,"min":0,"name":"id","pattern":"","presentable":false,"primaryKey":true,"required":true,"system":true,"type":"text"}]`,
|
`"fields":[{"autogeneratePattern":"","hidden":false,"id":"text3208210256","max":0,"min":0,"name":"id","pattern":"^[a-z0-9]+$","presentable":false,"primaryKey":true,"required":true,"system":true,"type":"text"}]`,
|
||||||
},
|
},
|
||||||
ExpectedEvents: map[string]int{
|
ExpectedEvents: map[string]int{
|
||||||
"*": 0,
|
"*": 0,
|
||||||
|
|
|
@ -902,6 +902,9 @@ func (c *Collection) initIdField() {
|
||||||
field.Required = true
|
field.Required = true
|
||||||
field.PrimaryKey = true
|
field.PrimaryKey = true
|
||||||
field.Hidden = false
|
field.Hidden = false
|
||||||
|
if field.Pattern == "" {
|
||||||
|
field.Pattern = `^[a-z0-9]+$`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -704,7 +704,7 @@ func TestCollectionValidate(t *testing.T) {
|
||||||
collection: func(app core.App) (*core.Collection, error) {
|
collection: func(app core.App) (*core.Collection, error) {
|
||||||
c := core.NewBaseCollection("new_auth")
|
c := core.NewBaseCollection("new_auth")
|
||||||
c.Fields = core.NewFieldsList(
|
c.Fields = core.NewFieldsList(
|
||||||
&core.TextField{Name: "id", PrimaryKey: true, Required: true},
|
&core.TextField{Name: "id", PrimaryKey: true, Required: true, Pattern: `\w+`},
|
||||||
)
|
)
|
||||||
return c, nil
|
return c, nil
|
||||||
},
|
},
|
||||||
|
@ -715,7 +715,7 @@ func TestCollectionValidate(t *testing.T) {
|
||||||
collection: func(app core.App) (*core.Collection, error) {
|
collection: func(app core.App) (*core.Collection, error) {
|
||||||
c := core.NewBaseCollection("new_auth")
|
c := core.NewBaseCollection("new_auth")
|
||||||
c.Fields = core.NewFieldsList(
|
c.Fields = core.NewFieldsList(
|
||||||
&core.TextField{Name: "id", PrimaryKey: true, Required: true},
|
&core.TextField{Name: "id", PrimaryKey: true, Required: true, Pattern: `\w+`},
|
||||||
&core.TextField{Id: "f1", Name: "Test"}, // case-insensitive
|
&core.TextField{Id: "f1", Name: "Test"}, // case-insensitive
|
||||||
&core.BoolField{Id: "f2", Name: "test"},
|
&core.BoolField{Id: "f2", Name: "test"},
|
||||||
)
|
)
|
||||||
|
|
|
@ -391,7 +391,7 @@ func (f *FileField) Intercept(
|
||||||
}
|
}
|
||||||
func (f *FileField) getLatestOldValue(app App, record *Record) any {
|
func (f *FileField) getLatestOldValue(app App, record *Record) any {
|
||||||
if !record.IsNew() {
|
if !record.IsNew() {
|
||||||
latestOriginal, err := app.FindRecordById(record.Collection(), record.Original().Id)
|
latestOriginal, err := app.FindRecordById(record.Collection(), cast.ToString(record.LastSavedPK()))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return latestOriginal.GetRaw(f.Name)
|
return latestOriginal.GetRaw(f.Name)
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,7 +257,7 @@ func (f *TextField) ValidateSettings(ctx context.Context, app App, collection *C
|
||||||
validation.Field(&f.PrimaryKey, validation.By(f.checkOtherFieldsForPK(collection))),
|
validation.Field(&f.PrimaryKey, validation.By(f.checkOtherFieldsForPK(collection))),
|
||||||
validation.Field(&f.Min, validation.Min(0)),
|
validation.Field(&f.Min, validation.Min(0)),
|
||||||
validation.Field(&f.Max, validation.Min(f.Min)),
|
validation.Field(&f.Max, validation.Min(f.Min)),
|
||||||
validation.Field(&f.Pattern, validation.By(validators.IsRegex)),
|
validation.Field(&f.Pattern, validation.When(f.PrimaryKey, validation.Required), validation.By(validators.IsRegex)),
|
||||||
validation.Field(&f.Hidden, validation.When(f.PrimaryKey, validation.Empty)),
|
validation.Field(&f.Hidden, validation.When(f.PrimaryKey, validation.Empty)),
|
||||||
validation.Field(&f.Required, validation.When(f.PrimaryKey, validation.Required)),
|
validation.Field(&f.Required, validation.When(f.PrimaryKey, validation.Required)),
|
||||||
validation.Field(&f.AutogeneratePattern, validation.By(validators.IsRegex), validation.By(f.checkAutogeneratePattern)),
|
validation.Field(&f.AutogeneratePattern, validation.By(validators.IsRegex), validation.By(f.checkAutogeneratePattern)),
|
||||||
|
|
|
@ -317,10 +317,23 @@ func TestTextFieldValidateSettings(t *testing.T) {
|
||||||
Id: "test",
|
Id: "test",
|
||||||
Name: "id",
|
Name: "id",
|
||||||
PrimaryKey: true,
|
PrimaryKey: true,
|
||||||
|
Pattern: `\d+`,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[]string{"required"},
|
[]string{"required"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"primaryKey without pattern",
|
||||||
|
func() *core.TextField {
|
||||||
|
return &core.TextField{
|
||||||
|
Id: "test",
|
||||||
|
Name: "id",
|
||||||
|
PrimaryKey: true,
|
||||||
|
Required: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[]string{"pattern"},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"primaryKey with hidden",
|
"primaryKey with hidden",
|
||||||
func() *core.TextField {
|
func() *core.TextField {
|
||||||
|
@ -330,6 +343,7 @@ func TestTextFieldValidateSettings(t *testing.T) {
|
||||||
Required: true,
|
Required: true,
|
||||||
PrimaryKey: true,
|
PrimaryKey: true,
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
|
Pattern: `\d+`,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[]string{"hidden"},
|
[]string{"hidden"},
|
||||||
|
@ -342,6 +356,7 @@ func TestTextFieldValidateSettings(t *testing.T) {
|
||||||
Name: "test",
|
Name: "test",
|
||||||
PrimaryKey: true,
|
PrimaryKey: true,
|
||||||
Required: true,
|
Required: true,
|
||||||
|
Pattern: `\d+`,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[]string{"name"},
|
[]string{"name"},
|
||||||
|
@ -353,6 +368,7 @@ func TestTextFieldValidateSettings(t *testing.T) {
|
||||||
Id: "test2",
|
Id: "test2",
|
||||||
Name: "id",
|
Name: "id",
|
||||||
PrimaryKey: true,
|
PrimaryKey: true,
|
||||||
|
Pattern: `\d+`,
|
||||||
Required: true,
|
Required: true,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1564,13 +1564,15 @@ func TestRecordValidate(t *testing.T) {
|
||||||
app, _ := tests.NewTestApp()
|
app, _ := tests.NewTestApp()
|
||||||
defer app.Cleanup()
|
defer app.Cleanup()
|
||||||
|
|
||||||
collection := core.NewBaseCollection("test")
|
// dummy collection to ensure that the specified field validators are triggered
|
||||||
|
collection := core.NewBaseCollection("validate_test")
|
||||||
collection.Fields.Add(
|
collection.Fields.Add(
|
||||||
// dummy fields to ensure that its validators are triggered
|
|
||||||
&core.TextField{Name: "f1", Min: 3},
|
&core.TextField{Name: "f1", Min: 3},
|
||||||
&core.NumberField{Name: "f2", Required: true},
|
&core.NumberField{Name: "f2", Required: true},
|
||||||
)
|
)
|
||||||
|
if err := app.Save(collection); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
record := core.NewRecord(collection)
|
record := core.NewRecord(collection)
|
||||||
record.Id = "!invalid"
|
record.Id = "!invalid"
|
||||||
|
@ -1585,7 +1587,7 @@ func TestRecordValidate(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("satisfying the fields validations", func(t *testing.T) {
|
t.Run("satisfying the fields validations", func(t *testing.T) {
|
||||||
record.Id = strings.Repeat("a", 15)
|
record.Id = strings.Repeat("b", 15)
|
||||||
record.Set("f1", "abc")
|
record.Set("f1", "abc")
|
||||||
record.Set("f2", 1)
|
record.Set("f2", 1)
|
||||||
tests.TestValidationErrors(t, app.Validate(record), nil)
|
tests.TestValidationErrors(t, app.Validate(record), nil)
|
||||||
|
|
|
@ -247,6 +247,7 @@ func parseQueryToFields(app App, selectQuery string) (map[string]*queryField, er
|
||||||
System: true,
|
System: true,
|
||||||
Required: true,
|
Required: true,
|
||||||
PrimaryKey: true,
|
PrimaryKey: true,
|
||||||
|
Pattern: `^[a-z0-9]+$`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
|
|
Loading…
Reference in New Issue