3
0

Tweak default compose record value logic

This commit is contained in:
Tomaž Jerman
2021-03-08 17:16:52 +01:00
parent 92123d0755
commit 28aa9b3744
3 changed files with 180 additions and 11 deletions
+49
View File
@@ -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
View File
@@ -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) {
+115
View File
@@ -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()