diff --git a/app/app.go b/app/app.go index 95e99ef80..82e763469 100644 --- a/app/app.go +++ b/app/app.go @@ -62,6 +62,7 @@ type ( func New() *CortezaApp { app := &CortezaApp{lvl: bootLevelWaiting} + app.Opt = options.Init() app.InitCLI() return app } diff --git a/tests/automation/session_test.go b/tests/automation/session_test.go new file mode 100644 index 000000000..180afa75f --- /dev/null +++ b/tests/automation/session_test.go @@ -0,0 +1,85 @@ +package automation + +import ( + "context" + "fmt" + "github.com/cortezaproject/corteza-server/automation/service" + "github.com/cortezaproject/corteza-server/automation/types" + "github.com/cortezaproject/corteza-server/pkg/id" + "github.com/cortezaproject/corteza-server/store" + "github.com/cortezaproject/corteza-server/tests/helpers" + jsonpath "github.com/steinfletcher/apitest-jsonpath" + "net/http" + "testing" + "time" +) + +func (h helper) clearSessions() { + h.noError(store.TruncateAutomationSessions(context.Background(), service.DefaultStore)) +} + +func (h helper) repoMakeSession(wf *types.Workflow, ss ...string) *types.Session { + var r = &types.Session{ + ID: id.Next(), + CreatedAt: time.Now(), + WorkflowID: wf.ID, + } + + if len(ss) > 1 { + r.ResourceType = ss[1] + } else { + r.ResourceType = "h_" + rs() + + } + + h.a.NoError(store.CreateAutomationSession(context.Background(), service.DefaultStore, r)) + + return r +} + +func TestSessionList(t *testing.T) { + h := newHelper(t) + h.clearSessions() + + h.allow(types.AutomationRBACResource, "sessions.search") + + wf := h.repoMakeWorkflow() + h.repoMakeSession(wf) + h.repoMakeSession(wf) + + h.apiInit(). + Get("/sessions/"). + Header("Accept", "application/json"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + Assert(jsonpath.Len(`$.response.set`, 2)). + End() +} + +func TestSessionRead(t *testing.T) { + h := newHelper(t) + h.clearTriggers() + + wf := h.repoMakeWorkflow() + s := h.repoMakeSession(wf) + + h.allow(types.AutomationRBACResource, "sessions.search") + h.allow(types.WorkflowRBACResource.AppendWildcard(), "sessions.manage") + + h.apiInit(). + Get(fmt.Sprintf("/sessions/%d", s.ID)). + Header("Accept", "application/json"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() +} + +func TestSessionTrace(t *testing.T) { + t.Skip("pending implementation") +} + +func TestSessionDelete(t *testing.T) { + t.Skip("pending implementation") +} diff --git a/tests/automation/trigger_test.go b/tests/automation/trigger_test.go index a62d824ef..f4e468ca3 100644 --- a/tests/automation/trigger_test.go +++ b/tests/automation/trigger_test.go @@ -281,6 +281,26 @@ func TestTriggerDelete(t *testing.T) { h.a.NotNil(res.DeletedAt) } +func TestTriggerUndelete(t *testing.T) { + h := newHelper(t) + h.allow(types.WorkflowRBACResource.AppendWildcard(), "triggers.manage") + + wf := h.repoMakeWorkflow() + res := h.repoMakeTrigger(wf) + + h.apiInit(). + Post(fmt.Sprintf("/triggers/%d/undelete", res.ID)). + Header("Accept", "application/json"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + res = h.lookupTriggerByID(res.ID) + h.a.NotNil(res) + h.a.Nil(res.DeletedAt) +} + func TestTriggerLabels(t *testing.T) { h := newHelper(t) h.clearTriggers() diff --git a/tests/automation/workflow_test.go b/tests/automation/workflow_test.go index 41a070239..3f03ef5da 100644 --- a/tests/automation/workflow_test.go +++ b/tests/automation/workflow_test.go @@ -304,6 +304,25 @@ func TestWorkflowDelete(t *testing.T) { h.a.NotNil(res.DeletedAt) } +func TestWorkflowUndelete(t *testing.T) { + h := newHelper(t) + h.allow(types.WorkflowRBACResource.AppendWildcard(), "undelete") + + res := h.repoMakeWorkflow() + + h.apiInit(). + Post(fmt.Sprintf("/workflows/%d/undelete", res.ID)). + Header("Accept", "application/json"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + res = h.lookupWorkflowByID(res.ID) + h.a.NotNil(res) + h.a.Nil(res.DeletedAt) +} + func TestWorkflowLabels(t *testing.T) { h := newHelper(t) h.clearWorkflows() diff --git a/tests/compose/attachment_test.go b/tests/compose/attachment_test.go new file mode 100644 index 000000000..443f61b3b --- /dev/null +++ b/tests/compose/attachment_test.go @@ -0,0 +1,80 @@ +package compose + +import ( + "context" + "fmt" + "github.com/cortezaproject/corteza-server/compose/service" + "github.com/cortezaproject/corteza-server/compose/types" + "github.com/cortezaproject/corteza-server/pkg/id" + "github.com/cortezaproject/corteza-server/store" + "github.com/cortezaproject/corteza-server/tests/helpers" + jsonpath "github.com/steinfletcher/apitest-jsonpath" + "net/http" + "testing" + "time" +) + +func (h helper) clearAttachment() { + h.noError(store.TruncateAttachments(context.Background(), service.DefaultStore)) +} + +func (h helper) repoMakeAttachment(ss ...string) *types.Attachment { + var res = &types.Attachment{ + ID: id.Next(), + CreatedAt: time.Now(), + Kind: types.RecordAttachment, + } + + if len(ss) > 0 { + res.Name = ss[0] + } else { + res.Name = "n_" + rs() + } + + h.a.NoError(store.CreateComposeAttachment(context.Background(), service.DefaultStore, res)) + + return res +} + +func (h helper) lookupAttachmentByID(ID uint64) *types.Attachment { + res, err := store.LookupComposeAttachmentByID(context.Background(), service.DefaultStore, ID) + h.noError(err) + return res +} + +func TestAttachmentRead(t *testing.T) { + h := newHelper(t) + h.clearAttachment() + + ns := h.makeNamespace("some-namespace") + a := h.repoMakeAttachment() + + h.apiInit(). + Get(fmt.Sprintf("/namespace/%d/attachment/%s/%d", ns.ID, a.Kind, a.ID)). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + Assert(jsonpath.Equal(`$.response.name`, a.Name)). + Assert(jsonpath.Equal(`$.response.attachmentID`, fmt.Sprintf("%d", a.ID))). + End() +} + +func TestAttachmentDelete(t *testing.T) { + h := newHelper(t) + h.clearAttachment() + + ns := h.makeNamespace("some-namespace") + a := h.repoMakeAttachment() + + h.apiInit(). + Delete(fmt.Sprintf("/namespace/%d/attachment/%s/%d", ns.ID, a.Kind, a.ID)). + Header("Accept", "application/json"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + a = h.lookupAttachmentByID(a.ID) + h.a.NotNil(a) + h.a.NotNil(a.DeletedAt) +} diff --git a/tests/compose/main_test.go b/tests/compose/main_test.go index 84ac244e5..218e1b0b6 100644 --- a/tests/compose/main_test.go +++ b/tests/compose/main_test.go @@ -13,6 +13,7 @@ import ( "github.com/cortezaproject/corteza-server/pkg/id" "github.com/cortezaproject/corteza-server/pkg/logger" "github.com/cortezaproject/corteza-server/pkg/objstore/plain" + "github.com/cortezaproject/corteza-server/pkg/rand" "github.com/cortezaproject/corteza-server/pkg/rbac" sysTypes "github.com/cortezaproject/corteza-server/system/types" "github.com/cortezaproject/corteza-server/tests/helpers" @@ -47,6 +48,16 @@ func init() { helpers.RecursiveDotEnvLoad() } +// random string, 10 chars long by default +func rs(a ...int) string { + var l = 10 + if len(a) > 0 { + l = a[0] + } + + return string(rand.Bytes(l)) +} + func InitTestApp() { if testApp == nil { ctx := logger.ContextWithValue(cli.Context(), logger.MakeDebugLogger()) diff --git a/tests/compose/page_test.go b/tests/compose/page_test.go index e70d4d25d..fc0c19273 100644 --- a/tests/compose/page_test.go +++ b/tests/compose/page_test.go @@ -201,6 +201,23 @@ func TestPageUpdate(t *testing.T) { h.a.Equal("changed-name", res.Title) } +func TestPageReorder(t *testing.T) { + h := newHelper(t) + h.clearPages() + + h.allow(types.PageRBACResource.AppendWildcard(), "update") + h.allow(types.NamespaceRBACResource.AppendWildcard(), "read") + ns := h.makeNamespace("some-namespace") + res := h.repoMakePage(ns, "some-page") + + h.apiInit(). + Post(fmt.Sprintf("/namespace/%d/page/%d/reorder", ns.ID, res.ID)). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() +} + func TestPageDeleteForbidden(t *testing.T) { h := newHelper(t) h.clearPages() diff --git a/tests/system/actionlog_test.go b/tests/system/actionlog_test.go new file mode 100644 index 000000000..cf178c696 --- /dev/null +++ b/tests/system/actionlog_test.go @@ -0,0 +1,49 @@ +package system + +import ( + "context" + "github.com/cortezaproject/corteza-server/pkg/actionlog" + "github.com/cortezaproject/corteza-server/pkg/id" + "github.com/cortezaproject/corteza-server/store" + "github.com/cortezaproject/corteza-server/system/service" + "github.com/cortezaproject/corteza-server/system/types" + "github.com/cortezaproject/corteza-server/tests/helpers" + jsonpath "github.com/steinfletcher/apitest-jsonpath" + "net/http" + "testing" + "time" +) + +func (h helper) clearActionLog() { + h.noError(store.TruncateActionlogs(context.Background(), service.DefaultStore)) +} + +func (h helper) repoMakeActionLog() *actionlog.Action { + var res = &actionlog.Action{ + ID: id.Next(), + Timestamp: time.Now(), + ActorID: id.Next(), + Resource: types.SystemRBACResource.String(), + Action: "lookup", + } + + h.a.NoError(store.CreateActionlog(context.Background(), service.DefaultStore, res)) + + return res +} + +func TestActionLogList(t *testing.T) { + h := newHelper(t) + h.clearActionLog() + + h.repoMakeActionLog() + h.repoMakeActionLog() + + h.apiInit(). + Get("/actionlog/"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + Assert(jsonpath.Len(`$.response.set`, 2)). + End() +} diff --git a/tests/system/application_test.go b/tests/system/application_test.go index f477321dd..9692381c1 100644 --- a/tests/system/application_test.go +++ b/tests/system/application_test.go @@ -317,6 +317,25 @@ func TestApplicationDelete(t *testing.T) { h.a.NotNil(res.DeletedAt) } +func TestApplicationUndelete(t *testing.T) { + h := newHelper(t) + h.allow(types.ApplicationRBACResource.AppendWildcard(), "delete") + + res := h.repoMakeApplication() + + h.apiInit(). + Post(fmt.Sprintf("/application/%d/undelete", res.ID)). + Header("Accept", "application/json"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + res = h.lookupApplicationByID(res.ID) + h.a.NotNil(res) + h.a.Nil(res.DeletedAt) +} + func TestApplicationLabels(t *testing.T) { h := newHelper(t) h.clearApplications() diff --git a/tests/system/attachment_test.go b/tests/system/attachment_test.go new file mode 100644 index 000000000..d8a23208e --- /dev/null +++ b/tests/system/attachment_test.go @@ -0,0 +1,80 @@ +package system + +import ( + "context" + "fmt" + jsonpath "github.com/steinfletcher/apitest-jsonpath" + "net/http" + "testing" + "time" + + "github.com/cortezaproject/corteza-server/pkg/id" + "github.com/cortezaproject/corteza-server/store" + "github.com/cortezaproject/corteza-server/system/service" + "github.com/cortezaproject/corteza-server/system/types" + "github.com/cortezaproject/corteza-server/tests/helpers" +) + +func (h helper) clearAttachments() { + h.noError(store.TruncateAttachments(context.Background(), service.DefaultStore)) +} + +func (h helper) repoMakeAttachment(ss ...string) *types.Attachment { + var res = &types.Attachment{ + ID: id.Next(), + CreatedAt: time.Now(), + Kind: "json", + } + + if len(ss) > 0 { + res.Name = ss[0] + } else { + res.Name = "n_" + rs() + } + + h.a.NoError(store.CreateAttachment(context.Background(), service.DefaultStore, res)) + + return res +} + +func (h helper) lookupAttachmentByID(ID uint64) *types.Attachment { + res, err := store.LookupAttachmentByID(context.Background(), service.DefaultStore, ID) + h.noError(err) + return res +} + +func TestAttachmentRead(t *testing.T) { + h := newHelper(t) + h.clearAttachments() + + a := h.repoMakeAttachment() + + h.apiInit(). + Get(fmt.Sprintf("/attachment/%s/%d", a.Kind, a.ID)). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + Assert(jsonpath.Equal(`$.response.name`, a.Name)). + Assert(jsonpath.Equal(`$.response.attachmentID`, fmt.Sprintf("%d", a.ID))). + End() +} + +func TestAttachmentDelete(t *testing.T) { + h := newHelper(t) + h.clearAttachments() + + a := h.repoMakeAttachment() + h.allow(types.ApplicationRBACResource.AppendWildcard(), "delete") + + h.apiInit(). + Delete(fmt.Sprintf("/attachment/%s/%d", a.Kind, a.ID)). + Header("Accept", "application/json"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + a = h.lookupAttachmentByID(a.ID) + h.a.NotNil(a) + h.a.NotNil(a.DeletedAt) +} diff --git a/tests/system/auth_client_test.go b/tests/system/auth_client_test.go new file mode 100644 index 000000000..ed332ccb6 --- /dev/null +++ b/tests/system/auth_client_test.go @@ -0,0 +1,167 @@ +package system + +import ( + "context" + "fmt" + "github.com/cortezaproject/corteza-server/pkg/id" + "github.com/cortezaproject/corteza-server/store" + "github.com/cortezaproject/corteza-server/system/service" + "github.com/cortezaproject/corteza-server/system/types" + "github.com/cortezaproject/corteza-server/tests/helpers" + jsonpath "github.com/steinfletcher/apitest-jsonpath" + "net/http" + "testing" + "time" +) + +func (h helper) clearAuthClients() { + h.noError(store.TruncateAuthClients(context.Background(), service.DefaultStore)) +} + +func (h helper) repoMakeAuthClient(ss ...string) *types.AuthClient { + res := &types.AuthClient{ + ID: id.Next(), + CreatedAt: time.Now(), + } + + if len(ss) > 0 { + res.Handle = ss[0] + } else { + res.Handle = "n_" + rs() + } + + h.a.NoError(store.CreateAuthClient(context.Background(), service.DefaultStore, res)) + + return res +} + +func (h helper) lookupAuthClientByID(id uint64) *types.AuthClient { + res, err := store.LookupAuthClientByID(context.Background(), service.DefaultStore, id) + h.noError(err) + return res +} + +func (h helper) lookupAuthClientByHandle(handle string) *types.AuthClient { + res, err := store.LookupAuthClientByHandle(context.Background(), service.DefaultStore, handle) + h.noError(err) + return res +} + +func TestAuthClientList(t *testing.T) { + h := newHelper(t) + h.clearAuthClients() + + h.repoMakeAuthClient() + h.repoMakeAuthClient() + + h.allow(types.AuthClientRBACResource.AppendWildcard(), "read") + + h.apiInit(). + Get("/auth/clients/"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + Assert(jsonpath.Len(`$.response.set`, 2)). + End() +} + +func TestAuthClientRead(t *testing.T) { + h := newHelper(t) + h.clearAuthClients() + + client := h.repoMakeAuthClient() + + h.allow(types.AuthClientRBACResource.AppendWildcard(), "read") + + h.apiInit(). + Get(fmt.Sprintf("/auth/clients/%d", client.ID)). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() +} + +func TestAuthClientCreate(t *testing.T) { + h := newHelper(t) + h.clearAuthClients() + + handle := rs() + + h.allow(types.SystemRBACResource, "auth-client.create") + + h.apiInit(). + Post("/auth/clients/"). + FormData("handle", handle). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + res := h.lookupAuthClientByHandle(handle) + h.a.NotNil(res) + h.a.Equal(handle, res.Handle) +} + +func TestAuthClientUpdate(t *testing.T) { + h := newHelper(t) + h.clearAuthClients() + + client := h.repoMakeAuthClient() + client.Handle = rs() + + h.allow(types.AuthClientRBACResource.AppendWildcard(), "update") + + h.apiInit(). + Put(fmt.Sprintf("/auth/clients/%d", client.ID)). + Header("Accept", "application/json"). + JSON(helpers.JSON(client)). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + res := h.lookupAuthClientByHandle(client.Handle) + h.a.NotNil(res) +} + +func TestAuthClientDelete(t *testing.T) { + h := newHelper(t) + h.clearAuthClients() + + client := h.repoMakeAuthClient() + + h.allow(types.AuthClientRBACResource.AppendWildcard(), "delete") + + h.apiInit(). + Delete(fmt.Sprintf("/auth/clients/%d", client.ID)). + Header("Accept", "application/json"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + res := h.lookupAuthClientByID(client.ID) + h.a.NotNil(res) + h.a.NotNil(res.DeletedAt) +} + +func TestAuthClientUnDelete(t *testing.T) { + h := newHelper(t) + h.clearAuthClients() + + client := h.repoMakeAuthClient() + + h.allow(types.AuthClientRBACResource.AppendWildcard(), "delete") + + h.apiInit(). + Post(fmt.Sprintf("/auth/clients/%d/undelete", client.ID)). + Header("Accept", "application/json"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + res := h.lookupAuthClientByID(client.ID) + h.a.NotNil(res) + h.a.Nil(res.DeletedAt) +} diff --git a/tests/system/queues_test.go b/tests/system/queues_test.go new file mode 100644 index 000000000..f231e5319 --- /dev/null +++ b/tests/system/queues_test.go @@ -0,0 +1,173 @@ +package system + +import ( + "context" + "fmt" + "github.com/cortezaproject/corteza-server/pkg/id" + "github.com/cortezaproject/corteza-server/pkg/messagebus" + "github.com/cortezaproject/corteza-server/store" + "github.com/cortezaproject/corteza-server/system/service" + "github.com/cortezaproject/corteza-server/system/types" + "github.com/cortezaproject/corteza-server/tests/helpers" + jsonpath "github.com/steinfletcher/apitest-jsonpath" + "net/http" + "testing" + "time" +) + +func (h helper) clearMessagebusQueueSettings() { + h.noError(store.TruncateMessagebusQueueSettings(context.Background(), service.DefaultStore)) +} + +func (h helper) repoMakeMessagebusQueueSetting(consumer ...string) *messagebus.QueueSettings { + res := &messagebus.QueueSettings{ + ID: id.Next(), + Queue: rs(), + CreatedAt: time.Now(), + } + + if len(consumer) == 0 { + res.Consumer = string(messagebus.ConsumerCorteza) + } else { + res.Consumer = consumer[0] + } + + h.a.NoError(store.CreateMessagebusQueueSetting(context.Background(), service.DefaultStore, res)) + + return res +} + +func (h helper) lookupByID(id uint64) *messagebus.QueueSettings { + res, err := store.LookupMessagebusQueueSettingByID(context.Background(), service.DefaultStore, id) + h.noError(err) + return res +} + +func (h helper) lookupByQueue(queue string) *messagebus.QueueSettings { + res, err := store.LookupMessagebusQueueSettingByQueue(context.Background(), service.DefaultStore, queue) + h.noError(err) + return res +} + +func TestQueueList(t *testing.T) { + h := newHelper(t) + h.clearMessagebusQueueSettings() + + h.repoMakeMessagebusQueueSetting() + h.repoMakeMessagebusQueueSetting() + + h.allow(types.MessagebusQueueRBACResource.AppendWildcard(), "read") + + h.apiInit(). + Get("/queues/"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + Assert(jsonpath.Len(`$.response.set`, 2)). + End() +} + +func TestQueueRead(t *testing.T) { + h := newHelper(t) + h.clearMessagebusQueueSettings() + + res := h.repoMakeMessagebusQueueSetting() + + h.allow(types.MessagebusQueueRBACResource.AppendWildcard(), "read") + + h.apiInit(). + Get(fmt.Sprintf("/queues/%d", res.ID)). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() +} + +func TestQueueCreate(t *testing.T) { + h := newHelper(t) + h.clearMessagebusQueueSettings() + + h.allow(types.SystemRBACResource, "messagebus-queue.create") + + consumer := string(messagebus.ConsumerStore) + queue := rs() + + h.apiInit(). + Put("/queues"). + FormData("consumer", consumer). + FormData("queue", queue). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + res := h.lookupByQueue(queue) + h.a.NotNil(res) + h.a.Equal(consumer, res.Consumer) +} + +func TestQueueUpdate(t *testing.T) { + h := newHelper(t) + h.clearMessagebusQueueSettings() + + consumer := string(messagebus.ConsumerRedis) + res := h.repoMakeMessagebusQueueSetting() + res.Consumer = consumer + + h.allow(types.MessagebusQueueRBACResource.AppendWildcard(), "update") + + h.apiInit(). + Post(fmt.Sprintf("/queues/%d", res.ID)). + Header("Accept", "application/json"). + JSON(helpers.JSON(res)). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + res = h.lookupByID(res.ID) + h.a.NotNil(res) + h.a.Equal(consumer, res.Consumer) +} + +func TestQueueDelete(t *testing.T) { + h := newHelper(t) + h.clearMessagebusQueueSettings() + + res := h.repoMakeMessagebusQueueSetting() + + h.allow(types.MessagebusQueueRBACResource.AppendWildcard(), "delete") + + h.apiInit(). + Delete(fmt.Sprintf("/queues/%d", res.ID)). + Header("Accept", "application/json"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + res = h.lookupByID(res.ID) + h.a.NotNil(res) + h.a.NotNil(res.DeletedAt) +} + +func TestQueueUnDelete(t *testing.T) { + h := newHelper(t) + h.clearMessagebusQueueSettings() + + res := h.repoMakeMessagebusQueueSetting() + + h.allow(types.MessagebusQueueRBACResource.AppendWildcard(), "delete") + + h.apiInit(). + Post(fmt.Sprintf("/queues/%d/undelete", res.ID)). + Header("Accept", "application/json"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + res = h.lookupByID(res.ID) + h.a.NotNil(res) + h.a.Nil(res.DeletedAt) +} diff --git a/tests/system/role_test.go b/tests/system/role_test.go index 896a53906..4dbded228 100644 --- a/tests/system/role_test.go +++ b/tests/system/role_test.go @@ -66,6 +66,17 @@ func (h helper) lookupRoleByID(ID uint64) *types.Role { return res } +func (h helper) createRoleMember(userID, roleID uint64) *types.RoleMember { + var r = &types.RoleMember{ + RoleID: roleID, + UserID: userID, + } + + h.a.NoError(store.CreateRoleMember(context.Background(), service.DefaultStore, r)) + + return r +} + func TestRoleRead(t *testing.T) { h := newHelper(t) @@ -239,6 +250,60 @@ func TestRoleDelete(t *testing.T) { h.a.NotNil(res.DeletedAt) } +func TestRoleUndelete(t *testing.T) { + h := newHelper(t) + h.allow(types.RoleRBACResource.AppendWildcard(), "delete") + + res := h.repoMakeRole() + + h.apiInit(). + Post(fmt.Sprintf("/roles/%d/undelete", res.ID)). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + res = h.lookupRoleByID(res.ID) + h.a.NotNil(res) + h.a.Nil(res.DeletedAt) +} + +func TestRoleArchive(t *testing.T) { + h := newHelper(t) + h.allow(types.RoleRBACResource.AppendWildcard(), "update") + + res := h.repoMakeRole() + + h.apiInit(). + Post(fmt.Sprintf("/roles/%d/archive", res.ID)). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + res = h.lookupRoleByID(res.ID) + h.a.NotNil(res) + h.a.NotNil(res.ArchivedAt) +} + +func TestRoleUnarchive(t *testing.T) { + h := newHelper(t) + h.allow(types.RoleRBACResource.AppendWildcard(), "delete") + + res := h.repoMakeRole() + + h.apiInit(). + Post(fmt.Sprintf("/roles/%d/unarchive", res.ID)). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + res = h.lookupRoleByID(res.ID) + h.a.NotNil(res) + h.a.Nil(res.ArchivedAt) +} + func TestRoleLabels(t *testing.T) { h := newHelper(t) h.clearRoles() @@ -319,3 +384,50 @@ func TestRoleLabels(t *testing.T) { req.NotNil(set.FindByID(ID).Labels) }) } + +func TestMemberList(t *testing.T) { + h := newHelper(t) + h.allow(types.RoleRBACResource, "read") + + r := h.repoMakeRole(h.randEmail()) + h.createRoleMember(id.Next(), r.ID) + h.createRoleMember(id.Next(), r.ID) + + h.apiInit(). + Get(fmt.Sprintf("/roles/%d/members", r.ID)). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + Assert(jsonpath.Len(`$.response`, 2)). + End() +} + +func TestMemberAdd(t *testing.T) { + h := newHelper(t) + h.allow(types.RoleRBACResource.AppendWildcard(), "members.manage") + + r := h.repoMakeRole(h.randEmail()) + u := h.createUserWithEmail(h.randEmail()) + + h.apiInit(). + Post(fmt.Sprintf("/roles/%d/member/%d", r.ID, u.ID)). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() +} + +func TestMemberRemove(t *testing.T) { + h := newHelper(t) + h.allow(types.RoleRBACResource.AppendWildcard(), "members.manage") + + r := h.repoMakeRole(h.randEmail()) + u := h.createUserWithEmail(h.randEmail()) + + h.apiInit(). + Post(fmt.Sprintf("/roles/%d/member/%d", r.ID, u.ID)). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() +} diff --git a/tests/system/settings_test.go b/tests/system/settings_test.go index af116020a..9baa46da5 100644 --- a/tests/system/settings_test.go +++ b/tests/system/settings_test.go @@ -127,3 +127,28 @@ func TestSettingsGet_noPermissions(t *testing.T) { Assert(helpers.AssertError("not allowed to read settings")). End() } + +func TestSettingsSet_noPermissions(t *testing.T) { + h := newHelper(t) + h.deny(types.SystemRBACResource, "settings.read") + + h.apiInit(). + Get("/settings/t_sys_k1.s1"). + Header("Accept", "application/json"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertError("not allowed to read settings")). + End() +} + +func TestSettingsCurrent(t *testing.T) { + h := newHelper(t) + h.allow(types.SystemRBACResource, "settings.read") + + h.apiInit(). + Get("/settings/current"). + Expect(t). + Status(http.StatusOK). + Assert(jsonpath.Present(`$.response`)). + End() +} diff --git a/tests/system/template_test.go b/tests/system/template_test.go index 4856c25f3..88f99ef0d 100644 --- a/tests/system/template_test.go +++ b/tests/system/template_test.go @@ -199,6 +199,26 @@ func TestTemplateDelete(t *testing.T) { h.a.NotNil(res.DeletedAt) } +func TestTemplateUndelete(t *testing.T) { + h := newHelper(t) + h.clearTemplates() + h.allow(types.TemplateRBACResource.AppendWildcard(), "delete") + + res := h.repoMakeTemplate() + + h.apiInit(). + Post(fmt.Sprintf("/template/%d/undelete", res.ID)). + Header("Accept", "application/json"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + res = h.lookupTemplateByID(res.ID) + h.a.NotNil(res) + h.a.Nil(res.DeletedAt) +} + func TestTemplateRenderForbiden(t *testing.T) { h := newHelper(t) h.clearTemplates() diff --git a/tests/system/user_test.go b/tests/system/user_test.go index f9034c677..3431d93df 100644 --- a/tests/system/user_test.go +++ b/tests/system/user_test.go @@ -41,6 +41,12 @@ func (h helper) clearUsers() { h.noError(store.TruncateUsers(context.Background(), service.DefaultStore)) } +func (h helper) lookupUserByEmail(email string) *types.User { + res, err := store.LookupUserByEmail(context.Background(), service.DefaultStore, email) + h.noError(err) + return res +} + func TestUserRead(t *testing.T) { h := newHelper(t) h.clearUsers() @@ -357,6 +363,60 @@ func TestUserUpdate(t *testing.T) { End() } +func TestUserSetPassword(t *testing.T) { + h := newHelper(t) + h.clearUsers() + + u := h.createUserWithEmail(h.randEmail()) + h.allow(types.UserRBACResource.AppendWildcard(), "update") + + h.apiInit(). + Post(fmt.Sprintf("/users/%d/password", u.ID)). + FormData("password", "newPassword"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() +} + +func TestUserSuspend(t *testing.T) { + h := newHelper(t) + h.clearUsers() + + u := h.createUserWithEmail(h.randEmail()) + h.allow(types.UserRBACResource.AppendWildcard(), "suspend") + + h.apiInit(). + Post(fmt.Sprintf("/users/%d/suspend", u.ID)). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + u = h.lookupUserByEmail(u.Email) + h.a.NotNil(u) + h.a.NotNil(u.SuspendedAt) +} + +func TestUserUnsuspend(t *testing.T) { + h := newHelper(t) + h.clearUsers() + + u := h.createUserWithEmail(h.randEmail()) + h.allow(types.UserRBACResource.AppendWildcard(), "unsuspend") + + h.apiInit(). + Post(fmt.Sprintf("/users/%d/unsuspend", u.ID)). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + u = h.lookupUserByEmail(u.Email) + h.a.NotNil(u) + h.a.Nil(u.SuspendedAt) +} + func TestUserDeleteForbidden(t *testing.T) { h := newHelper(t) h.clearUsers() @@ -388,6 +448,26 @@ func TestUserDelete(t *testing.T) { End() } +func TestUserUndelete(t *testing.T) { + h := newHelper(t) + h.clearUsers() + + h.allow(types.UserRBACResource.AppendWildcard(), "delete") + + u := h.createUserWithEmail(h.randEmail()) + + h.apiInit(). + Post(fmt.Sprintf("/users/%d/undelete", u.ID)). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + u = h.lookupUserByEmail(u.Email) + h.a.NotNil(u) + h.a.Nil(u.DeletedAt) +} + func TestUserLabels(t *testing.T) { h := newHelper(t) h.clearUsers() @@ -468,3 +548,60 @@ func TestUserLabels(t *testing.T) { req.NotNil(set.FindByID(ID).Labels) }) } + +func TestUserMemberList(t *testing.T) { + h := newHelper(t) + h.clearUsers() + h.allow(types.RoleRBACResource, "read") + + u := h.createUserWithEmail(h.randEmail()) + + r1 := h.repoMakeRole(h.randEmail()) + r2 := h.repoMakeRole(h.randEmail()) + h.createRoleMember(u.ID, r1.ID) + h.createRoleMember(u.ID, r2.ID) + + h.apiInit(). + Get(fmt.Sprintf("/users/%d/membership", u.ID)). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + Assert(jsonpath.Len(`$.response`, 2)). + End() +} + +func TestUserMemberAdd(t *testing.T) { + h := newHelper(t) + h.clearUsers() + h.allow(types.RoleRBACResource.AppendWildcard(), "members.manage") + + u := h.createUserWithEmail(h.randEmail()) + + r := h.repoMakeRole(h.randEmail()) + + h.apiInit(). + Post(fmt.Sprintf("/users/%d/membership/%d", u.ID, r.ID)). + Header("Accept", "application/json"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() +} + +func TestUserMemberRemove(t *testing.T) { + h := newHelper(t) + h.clearUsers() + h.allow(types.RoleRBACResource.AppendWildcard(), "members.manage") + + u := h.createUserWithEmail(h.randEmail()) + + r := h.repoMakeRole(h.randEmail()) + + h.apiInit(). + Delete(fmt.Sprintf("/users/%d/membership/%d", u.ID, r.ID)). + Header("Accept", "application/json"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() +}