3
0
corteza/compose/service/module_test.go
2021-01-25 18:05:24 +01:00

212 lines
5.7 KiB
Go

package service
import (
"context"
"testing"
"github.com/cortezaproject/corteza-server/compose/types"
"github.com/cortezaproject/corteza-server/pkg/eventbus"
"github.com/cortezaproject/corteza-server/pkg/rbac"
"github.com/cortezaproject/corteza-server/store"
"github.com/cortezaproject/corteza-server/store/sqlite3"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
)
func TestModules(t *testing.T) {
var (
ctx = context.Background()
s, err = sqlite3.ConnectInMemory(ctx)
// ctx = logger.ContextWithValue(context.Background(), logger.MakeDebugLogger())
// s, err = sqlite3.ConnectInMemoryWithDebug(ctx)
namespaceID = nextID()
ns *types.Namespace
)
if err != nil {
t.Fatalf("failed to init sqlite in-memory db: %v", err)
}
if err = store.Upgrade(ctx, zap.NewNop(), s); err != nil {
t.Fatalf("failed to upgrade store: %v", err)
}
if err = s.TruncateComposeNamespaces(ctx); err != nil {
t.Fatalf("failed to truncate compose namespaces: %v", err)
}
if err = s.TruncateComposeModules(ctx); err != nil {
t.Fatalf("failed to truncate compose modules: %v", err)
}
ns = &types.Namespace{Name: "testing", ID: namespaceID, CreatedAt: *now()}
if err = store.CreateComposeNamespace(ctx, s, ns); err != nil {
t.Fatalf("failed to seed namespaces: %v", err)
}
t.Run("crud", func(t *testing.T) {
req := require.New(t)
svc := module{
store: s,
ac: AccessControl(&rbac.ServiceAllowAll{}),
eventbus: eventbus.New(),
}
res, err := svc.Create(ctx, &types.Module{Name: "My first module", NamespaceID: namespaceID})
req.NoError(err)
req.NotNil(res)
res, err = svc.FindByID(ctx, namespaceID, res.ID)
req.NoError(err)
req.NotNil(res)
res, err = svc.FindByHandle(ctx, namespaceID, res.Handle)
req.NoError(err)
req.NotNil(res)
res.Name = "Changed"
res, err = svc.Update(ctx, res)
req.NoError(err)
req.NotNil(res)
req.NotNil(res.UpdatedAt)
req.Equal(res.Name, "Changed")
res, err = svc.FindByID(ctx, namespaceID, res.ID)
req.NoError(err)
req.NotNil(res)
req.Equal(res.Name, "Changed")
err = svc.DeleteByID(ctx, namespaceID, res.ID)
req.NoError(err)
req.NotNil(res)
// this works because we're allowed to do everything
res, err = svc.FindByID(ctx, namespaceID, res.ID)
req.NoError(err)
req.NotNil(res)
req.NotNil(res.DeletedAt)
})
t.Run("labels", func(t *testing.T) {
t.Run("search", func(t *testing.T) {
req := require.New(t)
svc := module{
store: s,
ac: AccessControl(&rbac.ServiceAllowAll{}),
eventbus: eventbus.New(),
}
makeModule := func(n ...string) *types.Module {
mod := &types.Module{
NamespaceID: namespaceID,
Name: n[0],
Labels: map[string]string{},
}
for i := 1; i < len(n); i += 2 {
mod.Labels[n[i]] = n[i+1]
}
out, err := svc.Create(ctx, mod)
req.NoError(err)
return out
}
findModules := func(labels map[string]string, IDs []uint64) types.ModuleSet {
f := types.ModuleFilter{NamespaceID: namespaceID, Labels: labels, ModuleID: IDs}
set, _, err := svc.Find(ctx, f)
req.NoError(err)
return set
}
makeModule("labeled module 1", "label1", "value1", "label2", "value2")
m2 := makeModule("labeled module 2", "label1", "value1")
m3 := makeModule("labeled module 3")
// return all -- no label/ID filter, return all
req.Len(findModules(nil, nil), 3)
// return 2 - both that have label1=valu1
req.Len(findModules(map[string]string{"label1": "value1"}, nil), 2)
// return 0 - none have foo=foo
req.Len(findModules(map[string]string{"missing": "missing"}, nil), 0)
// one has label2=value2
req.Len(findModules(map[string]string{"label2": "value2"}, nil), 1)
// explicit by ID and label
req.Len(findModules(map[string]string{"label1": "value1"}, []uint64{m2.ID}), 1)
// none with this combo
req.Len(findModules(map[string]string{"foo": "foo"}, []uint64{m3.ID}), 0)
// one with explicit ID (regression) and nil for label filter
req.Len(findModules(nil, []uint64{m3.ID}), 1)
// one with explicit ID (regression) and empty map for label filter
req.Len(findModules(map[string]string{}, []uint64{m3.ID}), 1)
})
t.Run("CRUD", func(t *testing.T) {
req := require.New(t)
svc := module{
store: s,
ac: AccessControl(&rbac.ServiceAllowAll{}),
eventbus: eventbus.New(),
}
findAndReturnLabel := func(id uint64) map[string]string {
res, err := svc.FindByID(ctx, namespaceID, id)
req.NoError(err)
req.NotNil(res)
return res.Labels
}
// create unlabeled module
res, err := svc.Create(ctx, &types.Module{Name: "unLabeledIDs", NamespaceID: namespaceID})
req.NoError(err)
req.NotNil(res)
req.Nil(res.Labels)
// no labels should be present
req.Nil(findAndReturnLabel(res.ID))
// update the module with labels
res.Labels = map[string]string{"label1": "1st"}
res, err = svc.Update(ctx, res)
req.NoError(err)
req.NotNil(res)
req.Contains(res.Labels, "label1")
// must contain the added label
req.Contains(findAndReturnLabel(res.ID), "label1")
res, err = svc.Create(ctx, &types.Module{Name: "LabeledIDs", NamespaceID: namespaceID, Labels: map[string]string{"label2": "2nd"}})
req.NoError(err)
req.NotNil(res)
req.Contains(res.Labels, "label2")
// must contain the added label
req.Contains(findAndReturnLabel(res.ID), "label2")
// update with Labels:nil (should keep labels intact)
res.Labels = nil
res, err = svc.Update(ctx, res)
req.NoError(err)
req.Contains(findAndReturnLabel(res.ID), "label2")
// update with Labels:empty-map (should remove all labels)
res.Labels = map[string]string{}
res, err = svc.Update(ctx, res)
req.NoError(err)
req.Empty(findAndReturnLabel(res.ID))
})
})
}