Add tests for reference constraints

This commit is contained in:
Tomaž Jerman
2020-11-30 18:51:46 +01:00
parent 5f3efdbfe6
commit 593235848a
13 changed files with 405 additions and 1 deletions
+201
View File
@@ -0,0 +1,201 @@
package envoy
import (
"context"
"fmt"
"strconv"
"testing"
"github.com/cortezaproject/corteza-server/compose/types"
su "github.com/cortezaproject/corteza-server/pkg/envoy/store"
"github.com/cortezaproject/corteza-server/store"
"github.com/stretchr/testify/require"
)
// TestProvision_batch simulates the worst possible case, where two namespaces
// have exact same items.
func TestProvision_batch(t *testing.T) {
var (
ctx = context.Background()
s, err = initStore(ctx)
)
if err != nil {
t.Fatalf("failed to init sqlite in-memory db: %v", err)
}
ni := uint64(0)
su.NextID = func() uint64 {
ni++
return ni
}
prepare := func(ctx context.Context, s store.Storer, t *testing.T, suite string) (*require.Assertions, error) {
req := require.New(t)
nn, err := dd(ctx, suite)
req.NoError(err)
return req, encode(ctx, s, nn)
}
// Prepare
s, err = initStore(ctx)
err = ce(
err,
s.TruncateActionlogs(ctx),
s.TruncateApplications(ctx),
s.TruncateAttachments(ctx),
s.TruncateComposeAttachments(ctx),
s.TruncateComposeCharts(ctx),
s.TruncateComposeNamespaces(ctx),
s.TruncateComposeModules(ctx),
s.TruncateComposeModuleFields(ctx),
s.TruncateComposePages(ctx),
s.TruncateComposeRecords(ctx, nil),
storeRole(ctx, s, 1, "everyone"),
storeRole(ctx, s, 2, "admins"),
)
if err != nil {
t.Fatal(err.Error())
}
req, err := prepare(ctx, s, t, "provision_batch")
req.NoError(err)
checkBatchProvision(ctx, t, req, s, "ns1")
checkBatchProvision(ctx, t, req, s, "ns2")
}
func checkBatchProvision(ctx context.Context, t *testing.T, req *require.Assertions, s store.Storer, slug string) {
var (
ns = &types.Namespace{}
mod1 = &types.Module{}
mod2 = &types.Module{}
mods = &types.Module{}
pg1 = &types.Page{}
rpg2 = &types.Page{}
chr1 = &types.Chart{}
rr = types.RecordSet{}
)
// Preload things
// * NS
ns, err := store.LookupComposeNamespaceBySlug(ctx, s, slug)
req.NoError(err)
req.NotNil(ns)
// * Mods
mod1, err = fullModLoad(ctx, s, req, ns.ID, "mod1")
req.NoError(err)
req.NotNil(mod1)
mod2, err = fullModLoad(ctx, s, req, ns.ID, "mod2")
req.NoError(err)
req.NotNil(mod2)
mods, err = fullModLoad(ctx, s, req, ns.ID, "settings")
req.NoError(err)
req.NotNil(mods)
// * Pages
pg1, err = store.LookupComposePageByNamespaceIDHandle(ctx, s, ns.ID, "pg1")
req.NoError(err)
req.NotNil(pg1)
rpg2, err = store.LookupComposePageByNamespaceIDHandle(ctx, s, ns.ID, "rpg2")
req.NoError(err)
req.NotNil(rpg2)
// * Charts
chr1, err = store.LookupComposeChartByNamespaceIDHandle(ctx, s, ns.ID, "chr1")
req.NoError(err)
req.NotNil(chr1)
// * Records
rr, _, err = store.SearchComposeRecords(ctx, s, mods, types.RecordFilter{
ModuleID: mods.ID,
NamespaceID: ns.ID,
})
req.NoError(err)
req.NotNil(rr)
req.Len(rr, 1)
// Check things
t.Run("NS", func(t *testing.T) {
req.Equal(fmt.Sprintf("%s name", slug), ns.Name)
})
t.Run("mod1", func(t *testing.T) {
req.Equal(fmt.Sprintf("%s mod1 name", slug), mod1.Name)
req.Len(mod1.Fields, 1)
f1 := mod1.Fields[0]
req.Equal(strconv.FormatUint(mod2.ID, 10), f1.Options.String("moduleID"))
})
t.Run("mod2", func(t *testing.T) {
req.Equal(fmt.Sprintf("%s mod2 name", slug), mod2.Name)
req.Len(mod2.Fields, 3)
f1 := mod2.Fields[1]
req.Equal(strconv.FormatUint(mod2.ID, 10), f1.Options.String("moduleID"))
})
t.Run("mods", func(t *testing.T) {
req.Equal(fmt.Sprintf("%s settings", slug), mods.Name)
req.Len(mods.Fields, 1)
})
t.Run("pg1", func(t *testing.T) {
req.Equal(fmt.Sprintf("%s pg1 title", slug), pg1.Title)
req.Len(pg1.Blocks, 4)
req.Equal("pg1 RecordList", pg1.Blocks[0].Title)
req.Equal(strconv.FormatUint(mod1.ID, 10), pg1.Blocks[0].Options["moduleID"])
req.Equal("pg1 Chart", pg1.Blocks[1].Title)
req.Equal(strconv.FormatUint(chr1.ID, 10), pg1.Blocks[1].Options["chartID"])
req.Equal("pg1 Calendar", pg1.Blocks[2].Title)
f := pg1.Blocks[2].Options["feeds"].([]interface{})[0]
feed, _ := f.(map[string]interface{})
fOpts, _ := (feed["options"]).(map[string]interface{})
id, _ := fOpts["moduleID"].(string)
req.Equal(strconv.FormatUint(mod1.ID, 10), id)
req.Equal("pg1 Metric", pg1.Blocks[3].Title)
m := pg1.Blocks[3].Options["metrics"].([]interface{})[0]
mops, _ := m.(map[string]interface{})
id = mops["moduleID"].(string)
req.Equal(strconv.FormatUint(mod1.ID, 10), id)
})
t.Run("rpg2", func(t *testing.T) {
req.Equal(fmt.Sprintf("%s Record page for module \"mod1\"", slug), rpg2.Title)
})
t.Run("chr1", func(t *testing.T) {
req.Equal(fmt.Sprintf("%s chr1 name", slug), chr1.Name)
req.Equal(mod1.ID, chr1.Config.Reports[0].ModuleID)
})
t.Run("rr", func(t *testing.T) {
req.Len(rr, 1)
v := rr[0].Values.FilterByName("s1")[0]
req.Equal(fmt.Sprintf("%s value", slug), v.Value)
})
}
func fullModLoad(ctx context.Context, s store.Storer, req *require.Assertions, nsID uint64, handle string) (*types.Module, error) {
mod, err := store.LookupComposeModuleByNamespaceIDHandle(ctx, s, nsID, handle)
req.NoError(err)
req.NotNil(mod)
mod.Fields, _, err = store.SearchComposeModuleFields(ctx, s, types.ModuleFieldFilter{ModuleID: []uint64{mod.ID}})
req.NoError(err)
req.NotNil(mod.Fields)
return mod, err
}
+3
View File
@@ -67,6 +67,8 @@ func TestProvision(t *testing.T) {
err = ce(
err,
s.TruncateRbacRules(ctx),
s.TruncateRoles(ctx),
s.TruncateActionlogs(ctx),
s.TruncateApplications(ctx),
s.TruncateAttachments(ctx),
@@ -76,6 +78,7 @@ func TestProvision(t *testing.T) {
s.TruncateComposeModules(ctx),
s.TruncateComposeModuleFields(ctx),
s.TruncateComposePages(ctx),
s.TruncateComposeRecords(ctx, nil),
storeRole(ctx, s, 1, "everyone"),
storeRole(ctx, s, 2, "admins"),
+7 -1
View File
@@ -57,11 +57,17 @@ func TestShaping_simple(t *testing.T) {
err = ce(
err,
s.TruncateRoleMembers(ctx),
s.TruncateRbacRules(ctx),
s.TruncateRoles(ctx),
s.TruncateActionlogs(ctx),
s.TruncateApplications(ctx),
s.TruncateAttachments(ctx),
s.TruncateComposeAttachments(ctx),
s.TruncateComposeCharts(ctx),
s.TruncateComposeNamespaces(ctx),
s.TruncateComposeModules(ctx),
s.TruncateComposeModuleFields(ctx),
s.TruncateComposePages(ctx),
storeRole(ctx, s, 1, "everyone"),
storeRole(ctx, s, 2, "admins"),
@@ -0,0 +1,3 @@
namespaces:
ns1:
name: ns1 name
@@ -0,0 +1,43 @@
# Provides a complete set of things to cover regarding modules and module fields.
# mod1: relates to mod2
# mod2: defines a self-ref
# settings: regular module
namespace: ns1
modules:
mod1:
name: ns1 mod1 name
fields:
f1:
label: f1 label
kind: Record
options:
labelField: f_label
module: mod2
queryFields:
- f1
mod2:
name: ns1 mod2 name
fields:
f_label:
label: f_label record label
f_ref_self:
label: f_ref_self label
kind: Record
options:
labelField: f_label
module: mod2
queryFields:
- f1
f1:
label: f1 label
kind: String
required: true
settings:
name: ns1 settings
fields:
s1:
label: s1 label
kind: String
@@ -0,0 +1,38 @@
namespace: ns1
pages:
pg1:
title: ns1 pg1 title
blocks:
- title: pg1 RecordList
kind: RecordList
xywh: [0, 1, 1, 1]
options:
module: mod1
- title: pg1 Chart
kind: Chart
xywh: [0, 2, 1, 1]
options:
chart: chr1
- title: pg1 Calendar
kind: Calendar
xywh: [0, 2, 1, 1]
options:
feeds:
- endField: f1
options:
module: mod1
- title: pg1 Metric
kind: Metric
options:
metrics:
- module: mod1
children:
rpg2:
handle: rpg2
module: mod1
title: ns1 Record page for module "mod1"
@@ -0,0 +1,8 @@
namespace: ns1
charts:
chr1:
name: ns1 chr1 name
config:
reports:
- dimensions:
module: mod1
@@ -0,0 +1,5 @@
namespace: ns1
records:
settings:
- values:
s1: ns1 value
@@ -0,0 +1,3 @@
namespaces:
ns2:
name: ns2 name
@@ -0,0 +1,43 @@
# Provides a complete set of things to cover regarding modules and module fields.
# mod1: relates to mod2
# mod2: defines a self-ref
# settings: regular module
namespace: ns2
modules:
mod1:
name: ns2 mod1 name
fields:
f1:
label: f1 label
kind: Record
options:
labelField: f_label
module: mod2
queryFields:
- f1
mod2:
name: ns2 mod2 name
fields:
f_label:
label: f_label record label
f_ref_self:
label: f_ref_self label
kind: Record
options:
labelField: f_label
module: mod2
queryFields:
- f1
f1:
label: f1 label
kind: String
required: true
settings:
name: ns2 settings
fields:
s1:
label: s1 label
kind: String
@@ -0,0 +1,38 @@
namespace: ns2
pages:
pg1:
title: ns2 pg1 title
blocks:
- title: pg1 RecordList
kind: RecordList
xywh: [0, 1, 1, 1]
options:
module: mod1
- title: pg1 Chart
kind: Chart
xywh: [0, 2, 1, 1]
options:
chart: chr1
- title: pg1 Calendar
kind: Calendar
xywh: [0, 2, 1, 1]
options:
feeds:
- endField: f1
options:
module: mod1
- title: pg1 Metric
kind: Metric
options:
metrics:
- module: mod1
children:
rpg2:
handle: rpg2
module: mod1
title: ns2 Record page for module "mod1"
@@ -0,0 +1,8 @@
namespace: ns2
charts:
chr1:
name: ns2 chr1 name
config:
reports:
- dimensions:
module: mod1
@@ -0,0 +1,5 @@
namespace: ns2
records:
settings:
- values:
s1: ns2 value