3
0

Add integ. tests for automation scripts & triggers

This commit is contained in:
Denis Arh
2019-09-11 13:40:06 +02:00
parent 2dc003077c
commit d6b7e0c9bf
15 changed files with 779 additions and 218 deletions
+10 -8
View File
@@ -77,7 +77,7 @@ func (ctrl AutomationTrigger) List(ctx context.Context, r *request.AutomationTri
func (ctrl AutomationTrigger) Create(ctx context.Context, r *request.AutomationTriggerCreate) (interface{}, error) {
s, _, err := ctrl.loadCombo(ctx, r.NamespaceID, r.ScriptID, 0)
if err != nil {
return nil, errors.Wrap(err, "can not create trigger")
return nil, err
}
var (
@@ -94,9 +94,9 @@ func (ctrl AutomationTrigger) Create(ctx context.Context, r *request.AutomationT
}
func (ctrl AutomationTrigger) Read(ctx context.Context, r *request.AutomationTriggerRead) (interface{}, error) {
_, t, err := ctrl.loadCombo(ctx, r.NamespaceID, r.ScriptID, 0)
_, t, err := ctrl.loadCombo(ctx, r.NamespaceID, r.ScriptID, r.TriggerID)
if err != nil {
return nil, errors.Wrap(err, "can not read trigger")
return nil, err
}
return ctrl.makePayload(ctx, t, err)
@@ -105,7 +105,7 @@ func (ctrl AutomationTrigger) Read(ctx context.Context, r *request.AutomationTri
func (ctrl AutomationTrigger) Update(ctx context.Context, r *request.AutomationTriggerUpdate) (interface{}, error) {
s, t, err := ctrl.loadCombo(ctx, r.NamespaceID, r.ScriptID, r.TriggerID)
if err != nil {
return nil, errors.Wrap(err, "can not update trigger")
return nil, err
}
t.Event = r.Event
@@ -120,7 +120,7 @@ func (ctrl AutomationTrigger) Update(ctx context.Context, r *request.AutomationT
func (ctrl AutomationTrigger) Delete(ctx context.Context, r *request.AutomationTriggerDelete) (interface{}, error) {
s, t, err := ctrl.loadCombo(ctx, r.NamespaceID, r.ScriptID, r.TriggerID)
if err != nil {
return nil, errors.Wrap(err, "can not update trigger")
return nil, err
}
return resputil.OK(), ctrl.triggers.Delete(ctx, s, t)
@@ -128,13 +128,15 @@ func (ctrl AutomationTrigger) Delete(ctx context.Context, r *request.AutomationT
func (ctrl AutomationTrigger) loadCombo(ctx context.Context, namespaceID, scriptID, triggerID uint64) (s *automation.Script, t *automation.Trigger, err error) {
if triggerID > 0 {
t, err = ctrl.triggers.FindByID(ctx, triggerID)
return
if t, err = ctrl.triggers.FindByID(ctx, triggerID); err != nil {
return
}
}
if scriptID > 0 {
s, err = ctrl.scripts.FindByID(ctx, namespaceID, scriptID)
if err != nil && s.NamespaceID != namespaceID {
if err == nil && s.NamespaceID != namespaceID {
err = repository.ErrNamespaceNotFound
}
+4 -5
View File
@@ -58,6 +58,8 @@ func AutomationScript(sm automationScriptManager) automationScript {
func (svc automationScript) FindByID(ctx context.Context, namespaceID, scriptID uint64) (*automation.Script, error) {
if _, s, err := svc.loadCombo(ctx, namespaceID, scriptID); err != nil {
return nil, err
} else if !svc.ac.CanReadAutomationScript(ctx, s) {
return nil, ErrNoReadPermissions
} else {
return s, nil
}
@@ -114,7 +116,7 @@ func (svc automationScript) Update(ctx context.Context, namespaceID uint64, mod
}
if !svc.ac.CanUpdateAutomationScript(ctx, s) {
return ErrNoCreatePermissions.withStack()
return ErrNoUpdatePermissions.withStack()
}
// Users need to have grant privileges to
@@ -152,7 +154,7 @@ func (svc automationScript) Delete(ctx context.Context, namespaceID, scriptID ui
if _, s, err := svc.loadCombo(ctx, namespaceID, scriptID); err != nil {
return err
} else if !svc.ac.CanDeleteAutomationScript(ctx, s) {
return ErrNoCreatePermissions.withStack()
return ErrNoDeletePermissions.withStack()
} else {
return svc.scriptManager.DeleteScript(ctx, s)
}
@@ -174,9 +176,6 @@ func (svc automationScript) loadCombo(ctx context.Context, namespaceID, scriptID
if scriptID > 0 {
if s, err = svc.scriptManager.FindScriptByID(ctx, scriptID); err != nil {
return
} else if !svc.ac.CanReadAutomationScript(ctx, s) {
err = ErrNoCreatePermissions.withStack()
return
}
}
+9 -4
View File
@@ -3,6 +3,7 @@ package service
import (
"context"
"github.com/pkg/errors"
"go.uber.org/zap"
"github.com/cortezaproject/corteza-server/compose/types"
@@ -93,13 +94,17 @@ func (svc automationTrigger) Delete(ctx context.Context, s *automation.Script, t
// Validates trigger (in compose context)
func (svc automationTrigger) isValid(ctx context.Context, s *automation.Script, t *automation.Trigger) error {
if s == nil {
return errors.WithStack(automation.ErrAutomationScriptInvalid)
}
if !t.Enabled {
return nil
}
if t.Resource != "compose:record" {
// Accepting only compose:record resources
return automation.ErrAutomationTriggerInvalidResource
return errors.WithStack(automation.ErrAutomationTriggerInvalidResource)
}
if t.IsDeferred() {
@@ -114,18 +119,18 @@ func (svc automationTrigger) isValid(ctx context.Context, s *automation.Script,
var moduleID = t.Uint64Condition()
if t.Event != "manual" && moduleID == 0 {
return automation.ErrAutomationTriggerInvalidCondition
return errors.WithStack(automation.ErrAutomationTriggerInvalidCondition)
}
if moduleID > 0 {
if m, err := svc.mod.With(ctx).FindByID(s.NamespaceID, moduleID); err != nil {
return err
} else if !svc.ac.CanManageAutomationTriggersOnModule(ctx, m) {
return ErrNoTriggerManagementPermissions
return errors.WithStack(ErrNoTriggerManagementPermissions)
}
}
default:
return automation.ErrAutomationTriggerInvalidEvent
return errors.WithStack(automation.ErrAutomationTriggerInvalidEvent)
}
return nil
+29 -19
View File
@@ -22,6 +22,12 @@ type (
Watch(ctx context.Context)
}
automationManager interface {
automationScriptManager
automationTriggerManager
automationScriptsFinder
}
Config struct {
Storage options.StorageOpt
Corredor options.CorredorOpt
@@ -40,10 +46,13 @@ var (
// DefaultAccessControl Access control checking
DefaultAccessControl *accessControl
// DefaultAutomationScriptManager manages scripts
// DefaultInternalAutomationManager manages automation scripts, triggers, runnable scripts
DefaultInternalAutomationManager automationManager
// DefaultAutomationScriptManager manages compose automation scripts
DefaultAutomationScriptManager automationScript
// DefaultAutomationTriggerManager manages triggerManager
// DefaultAutomationTriggerManager manages compose automation triggers
DefaultAutomationTriggerManager automationTrigger
// DefaultAutomationRunner runs automation scripts by listening to triggerManager and invoking Corredor service
@@ -95,23 +104,24 @@ func Init(ctx context.Context, log *zap.Logger, c Config) (err error) {
DefaultSystemUser = SystemUser(systemProto.NewUsersClient(systemClientConn))
}
// ias: Internal Automatinon Service
// handles script & trigger management & keeping runnables cripts in internal cache
ias := automation.Service(automation.AutomationServiceConfig{
Logger: DefaultLogger,
DbTablePrefix: "compose",
DB: db,
TokenMaker: func(ctx context.Context, userID uint64) (s string, e error) {
ctx = auth.SetSuperUserContext(ctx)
return DefaultSystemUser.MakeJWT(ctx, userID)
},
})
// Pass automation manager to
DefaultAutomationTriggerManager = AutomationTrigger(ias)
DefaultAutomationScriptManager = AutomationScript(ias)
{
if DefaultInternalAutomationManager == nil {
// handles script & trigger management & keeping runnable scripts in internal cache
DefaultInternalAutomationManager = automation.Service(automation.AutomationServiceConfig{
Logger: DefaultLogger,
DbTablePrefix: "compose",
DB: db,
TokenMaker: func(ctx context.Context, userID uint64) (s string, e error) {
ctx = auth.SetSuperUserContext(ctx)
return DefaultSystemUser.MakeJWT(ctx, userID)
},
})
}
// Pass internal automation manager to compose's script & trigger managers
DefaultAutomationTriggerManager = AutomationTrigger(DefaultInternalAutomationManager)
DefaultAutomationScriptManager = AutomationScript(DefaultInternalAutomationManager)
var scriptRunnerClient corredor.ScriptRunnerClient
if c.Corredor.Enabled {
@@ -131,7 +141,7 @@ func Init(ctx context.Context, log *zap.Logger, c Config) (err error) {
ApiBaseURLMessaging: c.Corredor.ApiBaseURLMessaging,
ApiBaseURLCompose: c.Corredor.ApiBaseURLCompose,
},
ias,
DefaultInternalAutomationManager,
scriptRunnerClient,
)
}
+4
View File
@@ -98,6 +98,10 @@ const (
STMS_REPLACE
)
var (
ErrAutomationScriptInvalid = errors.New("AutomationScriptInvalid")
)
// IsValid - enabled, deleted?
func (s *Script) IsValid() bool {
return s != nil && s.Enabled && s.DeletedAt == nil
-57
View File
@@ -1,57 +0,0 @@
// +build integration
package automation
import (
"os"
"testing"
"time"
"github.com/titpetric/factory"
"github.com/cortezaproject/corteza-server/internal/test"
)
func TestScriptRepository_findByID(t *testing.T) {
factory.Database.Add("compose", os.Getenv("COMPOSE_DB_DSN"))
var (
nsID = factory.Sonyflake.NextID()
scriptID = factory.Sonyflake.NextID()
err error
ss ScriptSet
script *Script
db = factory.Database.MustGet("compose")
srepo = ScriptRepository("compose")
)
db.Begin()
defer db.Rollback()
_, err = db.Exec("insert into compose_namespace (id, name, slug, meta, enabled) values (?, 'test ns', 'test slug', '{}', true)", nsID)
test.NoError(t, err, "unexpected error")
_, err = srepo.findByID(db, scriptID)
test.Error(t, err, "expecting error")
// runnable script
script = &Script{ID: scriptID, CreatedAt: time.Now(), Enabled: true, NamespaceID: nsID}
err = srepo.create(db, script)
test.NoError(t, err, "unexpected error: %v")
// find this script now
script, err = srepo.findByID(db, scriptID)
test.NoError(t, err, "script not found")
test.Assert(t, script != nil && script.ID == scriptID, "script not found (in runnable scripts)")
// find the script through find func
ss, _, err = srepo.find(db, ScriptFilter{NamespaceID: nsID})
test.NoError(t, err, "unexpected error: %v")
test.Assert(t, len(ss) > 0, "could not find the script")
test.Assert(t, ss.FindByID(scriptID) != nil, "could not find the script")
err = srepo.update(db, script)
test.NoError(t, err, "unexpected error when updating the script: %v")
}
-82
View File
@@ -1,82 +0,0 @@
// +build integration
package automation
import (
"os"
"testing"
"time"
"github.com/titpetric/factory"
"github.com/cortezaproject/corteza-server/internal/test"
)
func TestTriggerRepository_findByID(t *testing.T) {
factory.Database.Add("compose", os.Getenv("COMPOSE_DB_DSN"))
var (
nsID = factory.Sonyflake.NextID()
scriptID = factory.Sonyflake.NextID()
triggerID = factory.Sonyflake.NextID()
err error
trigger *Trigger
tt TriggerSet
script *Script
db = factory.Database.MustGet("compose")
trepo = TriggerRepository("compose")
srepo = ScriptRepository("compose")
)
db.Begin()
defer db.Rollback()
_, err = db.Exec("insert into compose_namespace (id, name, slug, meta, enabled) values (?, 'test ns', 'test slug', '{}', true)", nsID)
test.NoError(t, err, "unexpected error")
_, err = trepo.findByID(db, triggerID)
test.Error(t, err, "expecting error")
// should have script present
script = &Script{ID: scriptID, CreatedAt: time.Now(), NamespaceID: nsID}
err = srepo.create(db, script)
test.NoError(t, err, "unexpected error: %v")
// runnable trigger
trigger = &Trigger{ID: triggerID, Resource: "test", Event: "test", CreatedAt: time.Now(), Enabled: true, ScriptID: scriptID}
err = trepo.replace(db, trigger)
test.NoError(t, err, "unexpected error: %v")
// find this trigger now
trigger, err = trepo.findByID(db, triggerID)
test.NoError(t, err, "trigger not found")
test.Assert(t, trigger != nil && trigger.ID == triggerID, "trigger not found")
tt, err = trepo.findRunnable(db)
test.NoError(t, err, "unexpected error: %v")
test.Assert(t, tt.FindByID(triggerID) != nil, "trigger not found (in runnable)")
// find the trigger through find func
tt, _, err = trepo.find(db, TriggerFilter{
ScriptID: script.ID,
Resource: "test",
Event: "test",
})
test.NoError(t, err, "unexpected error: %v")
test.Assert(t, len(tt) == 1, "could not find the trigger")
test.Assert(t, tt[0].ID == triggerID, "unexpected trigger")
err = trepo.replace(db, trigger)
test.NoError(t, err, "unexpected error when replacing the trigger: %v")
err = trepo.deleteByScriptID(db, scriptID)
test.NoError(t, err, "unexpected error when updating the trigger: %v")
// find this trigger now
trigger, err = trepo.findByID(db, triggerID)
test.Error(t, err, "expecting error")
}
+8 -7
View File
@@ -76,7 +76,7 @@ func (ctrl AutomationTrigger) List(ctx context.Context, r *request.AutomationTri
func (ctrl AutomationTrigger) Create(ctx context.Context, r *request.AutomationTriggerCreate) (interface{}, error) {
s, _, err := ctrl.loadCombo(ctx, r.ScriptID, 0)
if err != nil {
return nil, errors.Wrap(err, "can not create trigger")
return nil, err
}
var (
@@ -93,9 +93,9 @@ func (ctrl AutomationTrigger) Create(ctx context.Context, r *request.AutomationT
}
func (ctrl AutomationTrigger) Read(ctx context.Context, r *request.AutomationTriggerRead) (interface{}, error) {
_, t, err := ctrl.loadCombo(ctx, r.ScriptID, 0)
_, t, err := ctrl.loadCombo(ctx, r.ScriptID, r.TriggerID)
if err != nil {
return nil, errors.Wrap(err, "can not read trigger")
return nil, err
}
return ctrl.makePayload(ctx, t, err)
@@ -104,7 +104,7 @@ func (ctrl AutomationTrigger) Read(ctx context.Context, r *request.AutomationTri
func (ctrl AutomationTrigger) Update(ctx context.Context, r *request.AutomationTriggerUpdate) (interface{}, error) {
s, t, err := ctrl.loadCombo(ctx, r.ScriptID, r.TriggerID)
if err != nil {
return nil, errors.Wrap(err, "can not update trigger")
return nil, err
}
t.Event = r.Event
@@ -119,7 +119,7 @@ func (ctrl AutomationTrigger) Update(ctx context.Context, r *request.AutomationT
func (ctrl AutomationTrigger) Delete(ctx context.Context, r *request.AutomationTriggerDelete) (interface{}, error) {
s, t, err := ctrl.loadCombo(ctx, r.ScriptID, r.TriggerID)
if err != nil {
return nil, errors.Wrap(err, "can not update trigger")
return nil, err
}
return resputil.OK(), ctrl.triggers.Delete(ctx, s, t)
@@ -127,8 +127,9 @@ func (ctrl AutomationTrigger) Delete(ctx context.Context, r *request.AutomationT
func (ctrl AutomationTrigger) loadCombo(ctx context.Context, scriptID, triggerID uint64) (s *automation.Script, t *automation.Trigger, err error) {
if triggerID > 0 {
t, err = ctrl.triggers.FindByID(ctx, triggerID)
return
if t, err = ctrl.triggers.FindByID(ctx, triggerID); err != nil {
return
}
}
if scriptID > 0 {
+3 -3
View File
@@ -97,7 +97,7 @@ func (svc automationScript) Update(ctx context.Context, mod *automation.Script)
}
if !svc.ac.CanUpdateAutomationScript(ctx, s) {
return ErrNoCreatePermissions.withStack()
return ErrNoUpdatePermissions.withStack()
}
// Users need to have grant privileges to
@@ -137,7 +137,7 @@ func (svc automationScript) Delete(ctx context.Context, scriptID uint64) (err er
if s, err := svc.loadCombo(ctx, scriptID); err != nil {
return err
} else if !svc.ac.CanDeleteAutomationScript(ctx, s) {
return ErrNoCreatePermissions.withStack()
return ErrNoDeletePermissions.withStack()
} else {
return svc.scriptManager.DeleteScript(ctx, s)
}
@@ -149,7 +149,7 @@ func (svc automationScript) loadCombo(ctx context.Context, scriptID uint64) (s *
if s, err = svc.scriptManager.FindScriptByID(ctx, scriptID); err != nil {
return
} else if !svc.ac.CanReadAutomationScript(ctx, s) {
err = ErrNoCreatePermissions.withStack()
err = ErrNoReadPermissions.withStack()
return
}
}
+1
View File
@@ -14,6 +14,7 @@ const (
ErrNoGrantPermissions serviceError = "NoGrantPermissions"
ErrNoCreatePermissions serviceError = "NoCreatePermissions"
ErrNoUpdatePermissions serviceError = "NoUpdatePermissions"
ErrNoDeletePermissions serviceError = "NoDeletePermissions"
ErrNoReadPermissions serviceError = "NoReadPermissions"
ErrNoTriggerManagementPermissions serviceError = "NoTriggerManagementPermissions"
ErrNoScriptCreatePermissions serviceError = "NoScriptCreatePermissions"
+36 -25
View File
@@ -19,11 +19,18 @@ type (
db interface {
Transaction(callback func() error) error
}
permissionServicer interface {
accessControlPermissionServicer
Watch(ctx context.Context)
}
automationManager interface {
automationScriptManager
automationTriggerManager
automationScriptsFinder
}
Config struct {
Storage options.StorageOpt
Corredor options.CorredorOpt
@@ -43,6 +50,9 @@ var (
// DefaultAccessControl Access control checking
DefaultAccessControl *accessControl
// DefaultInternalAutomationManager manages automation scripts, triggers, runnable scripts
DefaultInternalAutomationManager automationManager
// DefaultAutomationScriptManager manages scripts
DefaultAutomationScriptManager automationScript
@@ -91,31 +101,32 @@ func Init(ctx context.Context, log *zap.Logger, c Config) (err error) {
DefaultAuthNotification = AuthNotification(ctx)
DefaultAuth = Auth(ctx)
// ias: Internal Automatinon Service
// handles script & trigger management & keeping runnables cripts in internal cache
ias := automation.Service(automation.AutomationServiceConfig{
Logger: DefaultLogger,
DbTablePrefix: "sys",
DB: repository.DB(ctx),
TokenMaker: func(ctx context.Context, userID uint64) (jwt string, err error) {
var u *types.User
ctx = intAuth.SetSuperUserContext(ctx)
if u, err = DefaultUser.FindByID(userID); err != nil {
return
} else if err = DefaultAuth.LoadRoleMemberships(u); err != nil {
return
}
return intAuth.DefaultJwtHandler.Encode(u), nil
},
})
// Pass automation manager to
DefaultAutomationTriggerManager = AutomationTrigger(ias)
DefaultAutomationScriptManager = AutomationScript(ias)
{
if DefaultInternalAutomationManager == nil {
// handles script & trigger management & keeping runnables cripts in internal cache
DefaultInternalAutomationManager = automation.Service(automation.AutomationServiceConfig{
Logger: DefaultLogger,
DbTablePrefix: "sys",
DB: repository.DB(ctx),
TokenMaker: func(ctx context.Context, userID uint64) (jwt string, err error) {
var u *types.User
ctx = intAuth.SetSuperUserContext(ctx)
if u, err = DefaultUser.FindByID(userID); err != nil {
return
} else if err = DefaultAuth.LoadRoleMemberships(u); err != nil {
return
}
return intAuth.DefaultJwtHandler.Encode(u), nil
},
})
}
// Pass automation manager to
DefaultAutomationTriggerManager = AutomationTrigger(DefaultInternalAutomationManager)
DefaultAutomationScriptManager = AutomationScript(DefaultInternalAutomationManager)
var scriptRunnerClient corredor.ScriptRunnerClient
if c.Corredor.Enabled {
@@ -135,7 +146,7 @@ func Init(ctx context.Context, log *zap.Logger, c Config) (err error) {
ApiBaseURLMessaging: c.Corredor.ApiBaseURLMessaging,
ApiBaseURLCompose: c.Corredor.ApiBaseURLCompose,
},
ias,
DefaultInternalAutomationManager,
scriptRunnerClient,
)
}
+169 -2
View File
@@ -1,9 +1,176 @@
package compose
import (
"context"
"fmt"
"net/http"
"testing"
jsonpath "github.com/steinfletcher/apitest-jsonpath"
"github.com/cortezaproject/corteza-server/compose/service"
"github.com/cortezaproject/corteza-server/compose/types"
"github.com/cortezaproject/corteza-server/pkg/automation"
"github.com/cortezaproject/corteza-server/tests/helpers"
)
func TestAutomationScript(t *testing.T) {
t.Skip("pending implementation")
// We're using pkg/automation service layer for low-level tasks
func (h helper) svcMakeAutomationScript(namespace *types.Namespace, name string) *automation.Script {
script := &automation.Script{
NamespaceID: namespace.ID,
Name: name,
}
h.a.NoError(service.DefaultInternalAutomationManager.CreateScript(
context.Background(),
script,
))
return script
}
func TestAutomationScriptRead(t *testing.T) {
h := newHelper(t)
h.allow(types.NamespacePermissionResource.AppendWildcard(), "read")
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "read")
ns := h.repoMakeNamespace("some-namespace")
script := h.svcMakeAutomationScript(ns, "my little automation script")
h.apiInit().
Get(fmt.Sprintf("/namespace/%d/automation/script/%d", ns.ID, script.ID)).
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertNoErrors).
Assert(jsonpath.Equal(`$.response.name`, script.Name)).
Assert(jsonpath.Equal(`$.response.scriptID`, fmt.Sprintf("%d", script.ID))).
End()
}
func TestAutomationScriptList(t *testing.T) {
h := newHelper(t)
h.allow(types.NamespacePermissionResource.AppendWildcard(), "read")
ns := h.repoMakeNamespace("some-namespace")
h.svcMakeAutomationScript(ns, "app")
h.svcMakeAutomationScript(ns, "app")
h.apiInit().
Get(fmt.Sprintf("/namespace/%d/automation/script/", ns.ID)).
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertNoErrors).
End()
}
func TestAutomationScriptCreateForbidden(t *testing.T) {
h := newHelper(t)
ns := h.repoMakeNamespace("some-namespace")
h.apiInit().
Post(fmt.Sprintf("/namespace/%d/automation/script/", ns.ID)).
FormData("name", "my little automation script").
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertError("compose.service.NoCreatePermissions")).
End()
}
func TestAutomationScriptCreate(t *testing.T) {
h := newHelper(t)
h.allow(types.NamespacePermissionResource.AppendWildcard(), "read")
h.allow(types.NamespacePermissionResource.AppendWildcard(), "automation-script.create")
ns := h.repoMakeNamespace("some-namespace")
h.apiInit().
Post(fmt.Sprintf("/namespace/%d/automation/script/", ns.ID)).
FormData("name", "my little automation script").
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertNoErrors).
End()
}
func TestAutomationScriptUpdateForbidden(t *testing.T) {
h := newHelper(t)
h.allow(types.NamespacePermissionResource.AppendWildcard(), "read")
ns := h.repoMakeNamespace("some-namespace")
script := h.svcMakeAutomationScript(ns, "my little automation script")
h.apiInit().
Post(fmt.Sprintf("/namespace/%d/automation/script/%d", ns.ID, script.ID)).
FormData("name", "changed-name").
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertError("compose.service.NoUpdatePermissions")).
End()
}
func TestAutomationScriptUpdate(t *testing.T) {
h := newHelper(t)
h.allow(types.NamespacePermissionResource.AppendWildcard(), "read")
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "update")
ns := h.repoMakeNamespace("some-namespace")
script := h.svcMakeAutomationScript(ns, "my little automation script")
h.apiInit().
Post(fmt.Sprintf("/namespace/%d/automation/script/%d", ns.ID, script.ID)).
FormData("name", "changed-name").
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertNoErrors).
End()
script, err := service.DefaultInternalAutomationManager.FindScriptByID(context.Background(), script.ID)
h.a.NoError(err)
h.a.NotNil(script)
h.a.Equal("changed-name", script.Name)
}
func TestAutomationScriptDeleteForbidden(t *testing.T) {
h := newHelper(t)
h.allow(types.NamespacePermissionResource.AppendWildcard(), "read")
ns := h.repoMakeNamespace("some-namespace")
script := h.svcMakeAutomationScript(ns, "my little automation script")
h.apiInit().
Delete(fmt.Sprintf("/namespace/%d/automation/script/%d", ns.ID, script.ID)).
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertError("compose.service.NoDeletePermissions")).
End()
}
func TestAutomationScriptDelete(t *testing.T) {
h := newHelper(t)
h.allow(types.NamespacePermissionResource.AppendWildcard(), "read")
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "delete")
ns := h.repoMakeNamespace("some-namespace")
script := h.svcMakeAutomationScript(ns, "my little automation script")
h.apiInit().
Delete(fmt.Sprintf("/namespace/%d/automation/script/%d", ns.ID, script.ID)).
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertNoErrors).
End()
script, err := service.DefaultInternalAutomationManager.FindScriptByID(context.Background(), script.ID)
h.a.NoError(err)
h.a.NotNil(script)
h.a.NotNil(script.DeletedAt)
}
+184 -2
View File
@@ -1,9 +1,191 @@
package compose
import (
"context"
"fmt"
"net/http"
"testing"
jsonpath "github.com/steinfletcher/apitest-jsonpath"
"github.com/cortezaproject/corteza-server/compose/service"
"github.com/cortezaproject/corteza-server/compose/types"
"github.com/cortezaproject/corteza-server/pkg/automation"
"github.com/cortezaproject/corteza-server/tests/helpers"
)
func TestAutomationTrigger(t *testing.T) {
t.Skip("pending implementation")
// We're using pkg/automation service layer for low-level tasks
func (h helper) svcMakeAutomationTrigger(script *automation.Script, event string) *automation.Trigger {
trigger := &automation.Trigger{
ScriptID: script.ID,
Event: event,
}
h.a.NoError(service.DefaultInternalAutomationManager.CreateTrigger(
context.Background(),
script,
trigger,
))
return trigger
}
func TestAutomationTriggerRead(t *testing.T) {
h := newHelper(t)
h.allow(types.NamespacePermissionResource.AppendWildcard(), "read")
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "read")
ns := h.repoMakeNamespace("some-namespace")
script := h.svcMakeAutomationScript(ns, "dummy")
trigger := h.svcMakeAutomationTrigger(script, "manual")
h.apiInit().
Get(fmt.Sprintf("/namespace/%d/automation/script/%d/trigger/%d", ns.ID, script.ID, trigger.ID)).
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertNoErrors).
Assert(jsonpath.Equal(`$.response.event`, trigger.Event)).
Assert(jsonpath.Equal(`$.response.triggerID`, fmt.Sprintf("%d", trigger.ID))).
End()
}
func TestAutomationTriggerList(t *testing.T) {
h := newHelper(t)
h.allow(types.NamespacePermissionResource.AppendWildcard(), "read")
ns := h.repoMakeNamespace("some-namespace")
script := h.svcMakeAutomationScript(ns, "dummy")
h.svcMakeAutomationTrigger(script, "app")
h.svcMakeAutomationTrigger(script, "app")
h.apiInit().
Get(fmt.Sprintf("/namespace/%d/automation/script/%d/trigger/", ns.ID, script.ID)).
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertNoErrors).
End()
}
func TestAutomationTriggerCreateForbidden(t *testing.T) {
h := newHelper(t)
h.allow(types.NamespacePermissionResource.AppendWildcard(), "read")
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "read")
ns := h.repoMakeNamespace("some-namespace")
script := h.svcMakeAutomationScript(ns, "dummy")
h.apiInit().
Post(fmt.Sprintf("/namespace/%d/automation/script/%d/trigger/", ns.ID, script.ID)).
FormData("event", "my-event").
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertError("compose.service.NoTriggerManagementPermissions")).
End()
}
func TestAutomationTriggerCreate(t *testing.T) {
h := newHelper(t)
h.allow(types.NamespacePermissionResource.AppendWildcard(), "read")
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "read")
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "update")
ns := h.repoMakeNamespace("some-namespace")
script := h.svcMakeAutomationScript(ns, "dummy")
h.apiInit().
Post(fmt.Sprintf("/namespace/%d/automation/script/%d/trigger/", ns.ID, script.ID)).
FormData("event", "my-event").
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertNoErrors).
End()
}
func TestAutomationTriggerUpdateForbidden(t *testing.T) {
h := newHelper(t)
h.allow(types.NamespacePermissionResource.AppendWildcard(), "read")
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "read")
ns := h.repoMakeNamespace("some-namespace")
script := h.svcMakeAutomationScript(ns, "dummy")
trigger := h.svcMakeAutomationTrigger(script, "my little automation trigger")
h.apiInit().
Post(fmt.Sprintf("/namespace/%d/automation/script/%d/trigger/%d", ns.ID, script.ID, trigger.ID)).
FormData("name", "manual").
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertError("compose.service.NoTriggerManagementPermissions")).
End()
}
func TestAutomationTriggerUpdate(t *testing.T) {
h := newHelper(t)
h.allow(types.NamespacePermissionResource.AppendWildcard(), "read")
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "read")
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "update")
ns := h.repoMakeNamespace("some-namespace")
script := h.svcMakeAutomationScript(ns, "dummy")
trigger := h.svcMakeAutomationTrigger(script, "my little automation trigger")
h.apiInit().
Post(fmt.Sprintf("/namespace/%d/automation/script/%d/trigger/%d", ns.ID, script.ID, trigger.ID)).
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertNoErrors).
End()
trigger, err := service.DefaultInternalAutomationManager.FindTriggerByID(context.Background(), trigger.ID)
h.a.NoError(err)
h.a.NotNil(trigger)
}
func TestAutomationTriggerDeleteForbidden(t *testing.T) {
h := newHelper(t)
h.allow(types.NamespacePermissionResource.AppendWildcard(), "read")
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "read")
ns := h.repoMakeNamespace("some-namespace")
script := h.svcMakeAutomationScript(ns, "dummy")
trigger := h.svcMakeAutomationTrigger(script, "my little automation trigger")
h.apiInit().
Delete(fmt.Sprintf("/namespace/%d/automation/script/%d/trigger/%d", ns.ID, script.ID, trigger.ID)).
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertError("compose.service.NoTriggerManagementPermissions")).
End()
}
func TestAutomationTriggerDelete(t *testing.T) {
h := newHelper(t)
h.allow(types.NamespacePermissionResource.AppendWildcard(), "read")
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "read")
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "update")
ns := h.repoMakeNamespace("some-namespace")
script := h.svcMakeAutomationScript(ns, "dummy")
trigger := h.svcMakeAutomationTrigger(script, "my little automation trigger")
h.apiInit().
Delete(fmt.Sprintf("/namespace/%d/automation/script/%d/trigger/%d", ns.ID, script.ID, trigger.ID)).
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertNoErrors).
End()
trigger, err := service.DefaultInternalAutomationManager.FindTriggerByID(context.Background(), trigger.ID)
h.a.NoError(err)
h.a.NotNil(trigger)
h.a.NotNil(trigger.DeletedAt)
}
+155 -2
View File
@@ -1,9 +1,162 @@
package system
import (
"context"
"fmt"
"net/http"
"testing"
jsonpath "github.com/steinfletcher/apitest-jsonpath"
"github.com/cortezaproject/corteza-server/pkg/automation"
"github.com/cortezaproject/corteza-server/system/service"
"github.com/cortezaproject/corteza-server/system/types"
"github.com/cortezaproject/corteza-server/tests/helpers"
)
func TestAutomationScript(t *testing.T) {
t.Skip("pending implementation")
// We're using pkg/automation service layer for low-level tasks
func (h helper) svcMakeAutomationScript(name string) *automation.Script {
script := &automation.Script{
Name: name,
}
h.a.NoError(service.DefaultInternalAutomationManager.CreateScript(
context.Background(),
script,
))
return script
}
func TestAutomationScriptRead(t *testing.T) {
h := newHelper(t)
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "read")
script := h.svcMakeAutomationScript("my little automation script")
h.apiInit().
Get(fmt.Sprintf("/automation/script/%d", script.ID)).
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertNoErrors).
Assert(jsonpath.Equal(`$.response.name`, script.Name)).
Assert(jsonpath.Equal(`$.response.scriptID`, fmt.Sprintf("%d", script.ID))).
End()
}
func TestAutomationScriptList(t *testing.T) {
h := newHelper(t)
h.svcMakeAutomationScript("app")
h.svcMakeAutomationScript("app")
h.apiInit().
Get(fmt.Sprintf("/automation/script/")).
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertNoErrors).
End()
}
func TestAutomationScriptCreateForbidden(t *testing.T) {
h := newHelper(t)
h.deny(types.SystemPermissionResource, "automation-script.create")
h.apiInit().
Post(fmt.Sprintf("/automation/script/")).
FormData("name", "my little automation script").
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertError("system.service.NoCreatePermissions")).
End()
}
func TestAutomationScriptCreate(t *testing.T) {
h := newHelper(t)
h.allow(types.SystemPermissionResource, "automation-script.create")
h.apiInit().
Post(fmt.Sprintf("/automation/script/")).
FormData("name", "my little automation script").
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertNoErrors).
End()
}
func TestAutomationScriptUpdateForbidden(t *testing.T) {
h := newHelper(t)
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "read")
script := h.svcMakeAutomationScript("my little automation script")
h.apiInit().
Post(fmt.Sprintf("/automation/script/%d", script.ID)).
FormData("name", "changed-name").
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertError("system.service.NoUpdatePermissions")).
End()
}
func TestAutomationScriptUpdate(t *testing.T) {
h := newHelper(t)
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "read")
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "update")
script := h.svcMakeAutomationScript("my little automation script")
h.apiInit().
Post(fmt.Sprintf("/automation/script/%d", script.ID)).
FormData("name", "changed-name").
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertNoErrors).
End()
script, err := service.DefaultInternalAutomationManager.FindScriptByID(context.Background(), script.ID)
h.a.NoError(err)
h.a.NotNil(script)
h.a.Equal("changed-name", script.Name)
}
func TestAutomationScriptDeleteForbidden(t *testing.T) {
h := newHelper(t)
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "read")
script := h.svcMakeAutomationScript("my little automation script")
h.apiInit().
Delete(fmt.Sprintf("/automation/script/%d", script.ID)).
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertError("system.service.NoDeletePermissions")).
End()
}
func TestAutomationScriptDelete(t *testing.T) {
h := newHelper(t)
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "read")
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "delete")
script := h.svcMakeAutomationScript("my little automation script")
h.apiInit().
Delete(fmt.Sprintf("/automation/script/%d", script.ID)).
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertNoErrors).
End()
script, err := service.DefaultInternalAutomationManager.FindScriptByID(context.Background(), script.ID)
h.a.NoError(err)
h.a.NotNil(script)
h.a.NotNil(script.DeletedAt)
}
+167 -2
View File
@@ -1,9 +1,174 @@
package system
import (
"context"
"fmt"
"net/http"
"testing"
jsonpath "github.com/steinfletcher/apitest-jsonpath"
"github.com/cortezaproject/corteza-server/pkg/automation"
"github.com/cortezaproject/corteza-server/system/service"
"github.com/cortezaproject/corteza-server/system/types"
"github.com/cortezaproject/corteza-server/tests/helpers"
)
func TestAutomationTrigger(t *testing.T) {
t.Skip("pending implementation")
// We're using pkg/automation service layer for low-level tasks
func (h helper) svcMakeAutomationTrigger(script *automation.Script, event string) *automation.Trigger {
trigger := &automation.Trigger{
ScriptID: script.ID,
Event: event,
}
h.a.NoError(service.DefaultInternalAutomationManager.CreateTrigger(
context.Background(),
script,
trigger,
))
return trigger
}
func TestAutomationTriggerRead(t *testing.T) {
h := newHelper(t)
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "read")
script := h.svcMakeAutomationScript("dummy")
trigger := h.svcMakeAutomationTrigger(script, "manual")
h.apiInit().
Get(fmt.Sprintf("/automation/script/%d/trigger/%d", script.ID, trigger.ID)).
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertNoErrors).
Assert(jsonpath.Equal(`$.response.event`, trigger.Event)).
Assert(jsonpath.Equal(`$.response.triggerID`, fmt.Sprintf("%d", trigger.ID))).
End()
}
func TestAutomationTriggerList(t *testing.T) {
h := newHelper(t)
script := h.svcMakeAutomationScript("dummy")
h.svcMakeAutomationTrigger(script, "app")
h.svcMakeAutomationTrigger(script, "app")
h.apiInit().
Get(fmt.Sprintf("/automation/script/%d/trigger/", script.ID)).
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertNoErrors).
End()
}
func TestAutomationTriggerCreateForbidden(t *testing.T) {
h := newHelper(t)
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "read")
script := h.svcMakeAutomationScript("dummy")
h.apiInit().
Post(fmt.Sprintf("/automation/script/%d/trigger/", script.ID)).
FormData("event", "my-event").
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertError("system.service.NoTriggerManagementPermissions")).
End()
}
func TestAutomationTriggerCreate(t *testing.T) {
h := newHelper(t)
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "read")
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "update")
script := h.svcMakeAutomationScript("dummy")
h.apiInit().
Post(fmt.Sprintf("/automation/script/%d/trigger/", script.ID)).
FormData("event", "my-event").
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertNoErrors).
End()
}
func TestAutomationTriggerUpdateForbidden(t *testing.T) {
h := newHelper(t)
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "read")
script := h.svcMakeAutomationScript("dummy")
trigger := h.svcMakeAutomationTrigger(script, "my little automation trigger")
h.apiInit().
Post(fmt.Sprintf("/automation/script/%d/trigger/%d", script.ID, trigger.ID)).
FormData("name", "manual").
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertError("system.service.NoTriggerManagementPermissions")).
End()
}
func TestAutomationTriggerUpdate(t *testing.T) {
h := newHelper(t)
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "read")
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "update")
script := h.svcMakeAutomationScript("dummy")
trigger := h.svcMakeAutomationTrigger(script, "my little automation trigger")
h.apiInit().
Post(fmt.Sprintf("/automation/script/%d/trigger/%d", script.ID, trigger.ID)).
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertNoErrors).
End()
trigger, err := service.DefaultInternalAutomationManager.FindTriggerByID(context.Background(), trigger.ID)
h.a.NoError(err)
h.a.NotNil(trigger)
}
func TestAutomationTriggerDeleteForbidden(t *testing.T) {
h := newHelper(t)
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "read")
script := h.svcMakeAutomationScript("dummy")
trigger := h.svcMakeAutomationTrigger(script, "my little automation trigger")
h.apiInit().
Delete(fmt.Sprintf("/automation/script/%d/trigger/%d", script.ID, trigger.ID)).
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertError("system.service.NoTriggerManagementPermissions")).
End()
}
func TestAutomationTriggerDelete(t *testing.T) {
h := newHelper(t)
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "read")
h.allow(types.AutomationScriptPermissionResource.AppendWildcard(), "update")
script := h.svcMakeAutomationScript("dummy")
trigger := h.svcMakeAutomationTrigger(script, "my little automation trigger")
h.apiInit().
Delete(fmt.Sprintf("/automation/script/%d/trigger/%d", script.ID, trigger.ID)).
Expect(t).
Status(http.StatusOK).
Assert(helpers.AssertNoErrors).
End()
trigger, err := service.DefaultInternalAutomationManager.FindTriggerByID(context.Background(), trigger.ID)
h.a.NoError(err)
h.a.NotNil(trigger)
h.a.NotNil(trigger.DeletedAt)
}