Tweak default compose record value logic
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/compose/service/event"
|
||||
"github.com/cortezaproject/corteza-server/compose/service/values"
|
||||
"github.com/cortezaproject/corteza-server/compose/types"
|
||||
"github.com/cortezaproject/corteza-server/pkg/actionlog"
|
||||
"github.com/cortezaproject/corteza-server/pkg/errors"
|
||||
@@ -522,6 +523,12 @@ func updateModuleFields(ctx context.Context, s store.Storer, new, old *types.Mod
|
||||
}
|
||||
}
|
||||
|
||||
// Next preproc any default values
|
||||
new.Fields, err = moduleFieldDefaultPreparer(ctx, s, new, new.Fields)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Assure; create/update remaining fields
|
||||
idx := 0
|
||||
ff = make(types.ModuleFieldSet, 0, len(old.Fields))
|
||||
@@ -579,6 +586,48 @@ func updateModuleFields(ctx context.Context, s store.Storer, new, old *types.Mod
|
||||
return nil
|
||||
}
|
||||
|
||||
func moduleFieldDefaultPreparer(ctx context.Context, s store.Storer, m *types.Module, newFields types.ModuleFieldSet) (types.ModuleFieldSet, error) {
|
||||
var err error
|
||||
|
||||
for _, f := range newFields {
|
||||
if f.DefaultValue == nil || len(f.DefaultValue) == 0 {
|
||||
continue
|
||||
}
|
||||
vv := f.DefaultValue
|
||||
vv.SetUpdatedFlag(true)
|
||||
// Module field default values should not have a field name, so let's temporarily add it
|
||||
vv.Walk(func(rv *types.RecordValue) error {
|
||||
rv.Name = f.Name
|
||||
return nil
|
||||
})
|
||||
|
||||
if err = RecordValueSanitazion(m, vv); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vv = values.Sanitizer().Run(m, vv)
|
||||
|
||||
r := &types.Record{
|
||||
Values: vv,
|
||||
}
|
||||
rve := defaultValidator().Run(ctx, s, m, r)
|
||||
if !rve.IsValid() {
|
||||
return nil, rve
|
||||
}
|
||||
|
||||
vv = values.Formatter().Run(m, vv)
|
||||
|
||||
// Module field default values should not have a field name, so let's remove it
|
||||
vv.Walk(func(rv *types.RecordValue) error {
|
||||
rv.Name = ""
|
||||
return nil
|
||||
})
|
||||
|
||||
f.DefaultValue = vv
|
||||
}
|
||||
return newFields, nil
|
||||
}
|
||||
|
||||
func loadModuleFields(ctx context.Context, s store.Storer, mm ...*types.Module) (err error) {
|
||||
if len(mm) == 0 {
|
||||
return nil
|
||||
|
||||
+16
-11
@@ -141,6 +141,21 @@ type (
|
||||
)
|
||||
|
||||
func Record() RecordService {
|
||||
|
||||
return &record{
|
||||
actionlog: DefaultActionlog,
|
||||
ac: DefaultAccessControl,
|
||||
eventbus: eventbus.Service(),
|
||||
optEmitEvents: true,
|
||||
store: DefaultStore,
|
||||
|
||||
formatter: values.Formatter(),
|
||||
sanitizer: values.Sanitizer(),
|
||||
validator: defaultValidator(),
|
||||
}
|
||||
}
|
||||
|
||||
func defaultValidator() recordValuesValidator {
|
||||
// Initialize validator and setup all checkers it needs
|
||||
validator := values.Validator()
|
||||
|
||||
@@ -175,17 +190,7 @@ func Record() RecordService {
|
||||
return r != nil, err
|
||||
})
|
||||
|
||||
return &record{
|
||||
actionlog: DefaultActionlog,
|
||||
ac: DefaultAccessControl,
|
||||
eventbus: eventbus.Service(),
|
||||
optEmitEvents: true,
|
||||
store: DefaultStore,
|
||||
|
||||
formatter: values.Formatter(),
|
||||
sanitizer: values.Sanitizer(),
|
||||
validator: validator,
|
||||
}
|
||||
return validator
|
||||
}
|
||||
|
||||
func (svc *record) EventEmitting(enable bool) {
|
||||
|
||||
@@ -265,6 +265,121 @@ func TestModuleFieldsUpdate(t *testing.T) {
|
||||
h.a.Equal(m.Fields[1].Kind, "DateTime")
|
||||
}
|
||||
|
||||
func TestModuleFieldsDefaultValue(t *testing.T) {
|
||||
var ns *types.Namespace
|
||||
|
||||
h := newHelper(t)
|
||||
h.allow(types.NamespaceRBACResource.AppendWildcard(), "read")
|
||||
|
||||
prep := func() {
|
||||
h.clearModules()
|
||||
ns = h.makeNamespace("some-namespace")
|
||||
}
|
||||
|
||||
t.Run("boolean; true", func(t *testing.T) {
|
||||
prep()
|
||||
|
||||
m := h.makeModule(ns, "some-module", &types.ModuleField{ID: id.Next(), Kind: "Boolean", Name: "boolean"})
|
||||
h.allow(types.ModuleRBACResource.AppendWildcard(), "update")
|
||||
|
||||
f := m.Fields[0]
|
||||
fjs := fmt.Sprintf(`{ "name": "%s", "fields": [{ "fieldID": "%d", "name": "boolean", "kind": "Boolean", "defaultValue": [{"name": "boolean", "value": "1"}] }] }`, m.Name, f.ID)
|
||||
h.apiInit().
|
||||
Post(fmt.Sprintf("/namespace/%d/module/%d", ns.ID, m.ID)).
|
||||
JSON(fjs).
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
End()
|
||||
|
||||
m = h.lookupModuleByID(m.ID)
|
||||
h.a.NotNil(m)
|
||||
h.a.NotNil(m.Fields)
|
||||
h.a.Len(m.Fields, 1)
|
||||
|
||||
h.a.NotNil(m.Fields[0].DefaultValue)
|
||||
h.a.Len(m.Fields[0].DefaultValue, 1)
|
||||
h.a.Equal("1", m.Fields[0].DefaultValue[0].Value)
|
||||
})
|
||||
|
||||
t.Run("boolean; false", func(t *testing.T) {
|
||||
prep()
|
||||
|
||||
m := h.makeModule(ns, "some-module", &types.ModuleField{ID: id.Next(), Kind: "Boolean", Name: "boolean"})
|
||||
h.allow(types.ModuleRBACResource.AppendWildcard(), "update")
|
||||
|
||||
f := m.Fields[0]
|
||||
fjs := fmt.Sprintf(`{ "name": "%s", "fields": [{ "fieldID": "%d", "name": "boolean", "kind": "Boolean", "defaultValue": [{"name": "boolean", "value": ""}] }] }`, m.Name, f.ID)
|
||||
h.apiInit().
|
||||
Post(fmt.Sprintf("/namespace/%d/module/%d", ns.ID, m.ID)).
|
||||
JSON(fjs).
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
End()
|
||||
|
||||
m = h.lookupModuleByID(m.ID)
|
||||
h.a.NotNil(m)
|
||||
h.a.NotNil(m.Fields)
|
||||
h.a.Len(m.Fields, 1)
|
||||
|
||||
h.a.NotNil(m.Fields[0].DefaultValue)
|
||||
h.a.Len(m.Fields[0].DefaultValue, 1)
|
||||
h.a.Equal("", m.Fields[0].DefaultValue[0].Value)
|
||||
})
|
||||
|
||||
t.Run("boolean; undefined", func(t *testing.T) {
|
||||
prep()
|
||||
|
||||
m := h.makeModule(ns, "some-module", &types.ModuleField{ID: id.Next(), Kind: "Boolean", Name: "boolean"})
|
||||
h.allow(types.ModuleRBACResource.AppendWildcard(), "update")
|
||||
|
||||
f := m.Fields[0]
|
||||
fjs := fmt.Sprintf(`{ "name": "%s", "fields": [{ "fieldID": "%d", "name": "boolean", "kind": "Boolean" }] }`, m.Name, f.ID)
|
||||
h.apiInit().
|
||||
Post(fmt.Sprintf("/namespace/%d/module/%d", ns.ID, m.ID)).
|
||||
JSON(fjs).
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
End()
|
||||
|
||||
m = h.lookupModuleByID(m.ID)
|
||||
h.a.NotNil(m)
|
||||
h.a.NotNil(m.Fields)
|
||||
h.a.Len(m.Fields, 1)
|
||||
|
||||
h.a.Nil(m.Fields[0].DefaultValue)
|
||||
h.a.Len(m.Fields[0].DefaultValue, 0)
|
||||
})
|
||||
|
||||
t.Run("boolean; true; compact form", func(t *testing.T) {
|
||||
prep()
|
||||
|
||||
m := h.makeModule(ns, "some-module", &types.ModuleField{ID: id.Next(), Kind: "Boolean", Name: "boolean"})
|
||||
h.allow(types.ModuleRBACResource.AppendWildcard(), "update")
|
||||
|
||||
f := m.Fields[0]
|
||||
fjs := fmt.Sprintf(`{ "name": "%s", "fields": [{ "fieldID": "%d", "name": "boolean", "kind": "Boolean", "defaultValue": [{"value": "1"}] }] }`, m.Name, f.ID)
|
||||
h.apiInit().
|
||||
Post(fmt.Sprintf("/namespace/%d/module/%d", ns.ID, m.ID)).
|
||||
JSON(fjs).
|
||||
Expect(t).
|
||||
Status(http.StatusOK).
|
||||
Assert(helpers.AssertNoErrors).
|
||||
End()
|
||||
|
||||
m = h.lookupModuleByID(m.ID)
|
||||
h.a.NotNil(m)
|
||||
h.a.NotNil(m.Fields)
|
||||
h.a.Len(m.Fields, 1)
|
||||
|
||||
h.a.NotNil(m.Fields[0].DefaultValue)
|
||||
h.a.Len(m.Fields[0].DefaultValue, 1)
|
||||
h.a.Equal("1", m.Fields[0].DefaultValue[0].Value)
|
||||
})
|
||||
}
|
||||
|
||||
func TestModuleFieldsUpdate_removed(t *testing.T) {
|
||||
h := newHelper(t)
|
||||
h.clearModules()
|
||||
|
||||
Reference in New Issue
Block a user