Initial QSfera import
This commit is contained in:
@@ -0,0 +1,461 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/qsfera/server/pkg/middleware"
|
||||
settingsmsg "github.com/qsfera/server/protogen/gen/qsfera/messages/settings/v0"
|
||||
v0 "github.com/qsfera/server/protogen/gen/qsfera/services/settings/v0"
|
||||
"github.com/qsfera/server/services/settings/pkg/settings/mocks"
|
||||
"github.com/qsfera/server/services/settings/pkg/store/defaults"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
merrors "go-micro.dev/v4/errors"
|
||||
"go-micro.dev/v4/metadata"
|
||||
)
|
||||
|
||||
var (
|
||||
ctxWithUUID = metadata.Set(context.Background(), middleware.AccountID, "61445573-4dbe-4d56-88dc-88ab47aceba7")
|
||||
ctxWithEmptyUUID = metadata.Set(context.Background(), middleware.AccountID, "")
|
||||
emptyCtx = context.Background()
|
||||
|
||||
scenarios = []struct {
|
||||
name string
|
||||
accountUUID string
|
||||
ctx context.Context
|
||||
expect string
|
||||
}{
|
||||
{
|
||||
name: "context with UUID; identifier = 'me'",
|
||||
ctx: ctxWithUUID,
|
||||
accountUUID: "me",
|
||||
expect: "61445573-4dbe-4d56-88dc-88ab47aceba7",
|
||||
},
|
||||
{
|
||||
name: "context with empty UUID; identifier = 'me'",
|
||||
ctx: ctxWithEmptyUUID,
|
||||
accountUUID: "me",
|
||||
expect: "",
|
||||
},
|
||||
{
|
||||
name: "context without UUID; identifier = 'me'",
|
||||
ctx: emptyCtx,
|
||||
accountUUID: "me",
|
||||
expect: "",
|
||||
},
|
||||
{
|
||||
name: "context with UUID; identifier not 'me'",
|
||||
ctx: ctxWithUUID,
|
||||
accountUUID: "",
|
||||
expect: "",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func TestGetValidatedAccountUUID(t *testing.T) {
|
||||
for _, s := range scenarios {
|
||||
scenario := s
|
||||
t.Run(scenario.name, func(t *testing.T) {
|
||||
got := getValidatedAccountUUID(scenario.ctx, scenario.accountUUID)
|
||||
assert.NotPanics(t, func() {
|
||||
getValidatedAccountUUID(emptyCtx, scenario.accountUUID)
|
||||
})
|
||||
assert.Equal(t, scenario.expect, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEditOwnRoleAssignment(t *testing.T) {
|
||||
manager := &mocks.Manager{}
|
||||
svc := Service{
|
||||
manager: manager,
|
||||
}
|
||||
a := []*settingsmsg.UserRoleAssignment{}
|
||||
manager.On("ListRoleAssignments", mock.Anything).Return(a, nil)
|
||||
manager.On("WriteRoleAssignment", mock.Anything, mock.Anything).Return(nil, nil)
|
||||
// Creating an initial self assignment is expected to succeed for UserRole when no assignment exists yet
|
||||
req := v0.AssignRoleToUserRequest{
|
||||
AccountUuid: "61445573-4dbe-4d56-88dc-88ab47aceba7",
|
||||
RoleId: defaults.BundleUUIDRoleUser,
|
||||
}
|
||||
res := v0.AssignRoleToUserResponse{}
|
||||
err := svc.AssignRoleToUser(ctxWithUUID, &req, &res)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Creating an initial self assignment is expected to succeed for UserLightRole when no assignment exists yet
|
||||
req = v0.AssignRoleToUserRequest{
|
||||
AccountUuid: "61445573-4dbe-4d56-88dc-88ab47aceba7",
|
||||
RoleId: defaults.BundleUUIDRoleUserLight,
|
||||
}
|
||||
res = v0.AssignRoleToUserResponse{}
|
||||
err = svc.AssignRoleToUser(ctxWithUUID, &req, &res)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Creating an initial self assignment is expected to fail for non UserRole when no assignment exists yet
|
||||
req = v0.AssignRoleToUserRequest{
|
||||
AccountUuid: "61445573-4dbe-4d56-88dc-88ab47aceba7",
|
||||
RoleId: defaults.BundleUUIDRoleAdmin,
|
||||
}
|
||||
res = v0.AssignRoleToUserResponse{}
|
||||
err = svc.AssignRoleToUser(ctxWithUUID, &req, &res)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
manager = &mocks.Manager{}
|
||||
svc = Service{
|
||||
manager: manager,
|
||||
}
|
||||
a = []*settingsmsg.UserRoleAssignment{
|
||||
{
|
||||
Id: "00000000-0000-0000-0000-000000000001",
|
||||
AccountUuid: "61445573-4dbe-4d56-88dc-88ab47aceba7",
|
||||
RoleId: "aceb15b8-7486-479f-ae32-c91118e07a39",
|
||||
},
|
||||
}
|
||||
editRolePermission := &settingsmsg.Permission{
|
||||
Operation: settingsmsg.Permission_OPERATION_READWRITE,
|
||||
Constraint: settingsmsg.Permission_CONSTRAINT_ALL,
|
||||
}
|
||||
manager.On("ListRoleAssignments", mock.Anything).Return(a, nil)
|
||||
manager.On("ReadPermissionByID", mock.Anything, mock.Anything).Return(editRolePermission, nil)
|
||||
|
||||
// Creating an self assignment is expect to fail if there is already an assingment
|
||||
req = v0.AssignRoleToUserRequest{
|
||||
AccountUuid: "61445573-4dbe-4d56-88dc-88ab47aceba7",
|
||||
RoleId: defaults.BundleUUIDRoleUser,
|
||||
}
|
||||
res = v0.AssignRoleToUserResponse{}
|
||||
err = svc.AssignRoleToUser(ctxWithUUID, &req, &res)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
manager.On("WriteRoleAssignment", mock.Anything, mock.Anything).Return(nil, nil)
|
||||
// Creating an assignment for somebody else is expected to succeed, give the right permissions
|
||||
req = v0.AssignRoleToUserRequest{
|
||||
AccountUuid: "00000000-0000-0000-0000-000000000000",
|
||||
RoleId: "aceb15b8-7486-479f-ae32-c91118e07a39",
|
||||
}
|
||||
res = v0.AssignRoleToUserResponse{}
|
||||
err = svc.AssignRoleToUser(ctxWithUUID, &req, &res)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestRemoveOwnRoleAssignment(t *testing.T) {
|
||||
manager := &mocks.Manager{}
|
||||
a := []*settingsmsg.UserRoleAssignment{
|
||||
{
|
||||
Id: "00000000-0000-0000-0000-000000000001",
|
||||
AccountUuid: "61445573-4dbe-4d56-88dc-88ab47aceba7",
|
||||
RoleId: "aceb15b8-7486-479f-ae32-c91118e07a39",
|
||||
},
|
||||
}
|
||||
editRolePermission := &settingsmsg.Permission{
|
||||
Operation: settingsmsg.Permission_OPERATION_READWRITE,
|
||||
Constraint: settingsmsg.Permission_CONSTRAINT_ALL,
|
||||
}
|
||||
manager.On("ReadPermissionByID", mock.Anything, mock.Anything).Return(editRolePermission, nil)
|
||||
manager.On("ListRoleAssignments", mock.Anything).Return(a, nil)
|
||||
svc := Service{
|
||||
manager: manager,
|
||||
}
|
||||
|
||||
// Removing a role for oneself is expected to fail
|
||||
req := v0.RemoveRoleFromUserRequest{
|
||||
Id: "00000000-0000-0000-0000-000000000001",
|
||||
}
|
||||
err := svc.RemoveRoleFromUser(ctxWithUUID, &req, nil)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
manager = &mocks.Manager{}
|
||||
manager.On("ListRoleAssignments", mock.Anything).Return(nil, nil)
|
||||
manager.On("RemoveRoleAssignment", mock.Anything).Return(nil)
|
||||
manager.On("ReadPermissionByID", mock.Anything, mock.Anything).Return(editRolePermission, nil)
|
||||
svc = Service{
|
||||
manager: manager,
|
||||
}
|
||||
// Removing a role for someone else is expected to fail
|
||||
req = v0.RemoveRoleFromUserRequest{
|
||||
Id: "00000000-0000-0000-0000-000000000002",
|
||||
}
|
||||
err = svc.RemoveRoleFromUser(ctxWithUUID, &req, nil)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestListPermissionsOfCurrentUser(t *testing.T) {
|
||||
manager := &mocks.Manager{}
|
||||
a := []*settingsmsg.UserRoleAssignment{
|
||||
{
|
||||
Id: "00000000-0000-0000-0000-000000000001",
|
||||
AccountUuid: "61445573-4dbe-4d56-88dc-88ab47aceba7",
|
||||
RoleId: "aceb15b8-7486-479f-ae32-c91118e07a39",
|
||||
},
|
||||
}
|
||||
manager.On("ListRoleAssignments", mock.Anything).Return(a, nil)
|
||||
b := &settingsmsg.Bundle{
|
||||
Id: "aceb15b8-7486-479f-ae32-c91118e07a39",
|
||||
Settings: []*settingsmsg.Setting{
|
||||
{
|
||||
Name: "some-permission",
|
||||
},
|
||||
{
|
||||
Name: "other-permission",
|
||||
},
|
||||
{
|
||||
Name: "duplicate-permission",
|
||||
},
|
||||
{
|
||||
Name: "duplicate-permission",
|
||||
},
|
||||
},
|
||||
}
|
||||
manager.On("ReadBundle", mock.Anything).Return(b, nil)
|
||||
svc := Service{
|
||||
manager: manager,
|
||||
}
|
||||
|
||||
// Listing permissions for yourself
|
||||
req := v0.ListPermissionsRequest{
|
||||
AccountUuid: "61445573-4dbe-4d56-88dc-88ab47aceba7",
|
||||
}
|
||||
res := v0.ListPermissionsResponse{}
|
||||
err := svc.ListPermissions(ctxWithUUID, &req, &res)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, res.Permissions, 3)
|
||||
}
|
||||
|
||||
func TestListPermissionsOfOtherUser(t *testing.T) {
|
||||
manager := &mocks.Manager{}
|
||||
svc := Service{
|
||||
manager: manager,
|
||||
}
|
||||
|
||||
// Listing permissions for another user produces a not found error
|
||||
req := v0.ListPermissionsRequest{
|
||||
AccountUuid: "66666666-4444-4444-8888-88ab47aceba7",
|
||||
}
|
||||
res := v0.ListPermissionsResponse{}
|
||||
err := svc.ListPermissions(ctxWithUUID, &req, &res)
|
||||
assert.Error(t, err)
|
||||
|
||||
// assert the requested account uuid was not found
|
||||
merr, ok := merrors.As(err)
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, int32(http.StatusNotFound), merr.Code)
|
||||
assert.Contains(t, err.Error(), req.AccountUuid)
|
||||
}
|
||||
|
||||
func TestListRoleAssignmentsFilteredValidation(t *testing.T) {
|
||||
manager := &mocks.Manager{}
|
||||
svc := Service{
|
||||
manager: manager,
|
||||
}
|
||||
|
||||
tests := map[string]struct {
|
||||
req *v0.ListRoleAssignmentsFilteredRequest
|
||||
statusCode int32
|
||||
}{
|
||||
"no filters": {
|
||||
req: &v0.ListRoleAssignmentsFilteredRequest{},
|
||||
statusCode: http.StatusBadRequest,
|
||||
},
|
||||
"multiple filters": {
|
||||
req: &v0.ListRoleAssignmentsFilteredRequest{
|
||||
Filters: []*settingsmsg.UserRoleAssignmentFilter{
|
||||
{
|
||||
Type: settingsmsg.UserRoleAssignmentFilter_TYPE_ACCOUNT,
|
||||
Term: &settingsmsg.UserRoleAssignmentFilter_AccountUuid{
|
||||
AccountUuid: "uid",
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: settingsmsg.UserRoleAssignmentFilter_TYPE_ROLE,
|
||||
Term: &settingsmsg.UserRoleAssignmentFilter_RoleId{
|
||||
RoleId: "rid",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
statusCode: http.StatusBadRequest,
|
||||
},
|
||||
"bad filtertype": {
|
||||
req: &v0.ListRoleAssignmentsFilteredRequest{
|
||||
Filters: []*settingsmsg.UserRoleAssignmentFilter{
|
||||
{
|
||||
Type: settingsmsg.UserRoleAssignmentFilter_TYPE_UNKNOWN,
|
||||
},
|
||||
},
|
||||
},
|
||||
statusCode: http.StatusBadRequest,
|
||||
},
|
||||
"account filter without term": {
|
||||
req: &v0.ListRoleAssignmentsFilteredRequest{
|
||||
Filters: []*settingsmsg.UserRoleAssignmentFilter{
|
||||
{
|
||||
Type: settingsmsg.UserRoleAssignmentFilter_TYPE_ACCOUNT,
|
||||
},
|
||||
},
|
||||
},
|
||||
statusCode: http.StatusBadRequest,
|
||||
},
|
||||
"account filter with invalid term": {
|
||||
req: &v0.ListRoleAssignmentsFilteredRequest{
|
||||
Filters: []*settingsmsg.UserRoleAssignmentFilter{
|
||||
{
|
||||
Type: settingsmsg.UserRoleAssignmentFilter_TYPE_ACCOUNT,
|
||||
Term: &settingsmsg.UserRoleAssignmentFilter_AccountUuid{
|
||||
AccountUuid: "invalid-&*&^%$#",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
statusCode: http.StatusBadRequest,
|
||||
},
|
||||
"role filter without term": {
|
||||
req: &v0.ListRoleAssignmentsFilteredRequest{
|
||||
Filters: []*settingsmsg.UserRoleAssignmentFilter{
|
||||
{
|
||||
Type: settingsmsg.UserRoleAssignmentFilter_TYPE_ROLE,
|
||||
},
|
||||
},
|
||||
},
|
||||
statusCode: http.StatusBadRequest,
|
||||
},
|
||||
"role filter with invalid uuid": {
|
||||
req: &v0.ListRoleAssignmentsFilteredRequest{
|
||||
Filters: []*settingsmsg.UserRoleAssignmentFilter{
|
||||
{
|
||||
Type: settingsmsg.UserRoleAssignmentFilter_TYPE_ROLE,
|
||||
Term: &settingsmsg.UserRoleAssignmentFilter_RoleId{
|
||||
RoleId: "this is no uuid",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
statusCode: http.StatusBadRequest,
|
||||
},
|
||||
}
|
||||
|
||||
for name, test := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
res := v0.ListRoleAssignmentsResponse{}
|
||||
err := svc.ListRoleAssignmentsFiltered(ctxWithUUID, test.req, &res)
|
||||
merr, ok := merrors.As(err)
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, int32(test.statusCode), merr.Code)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestListRoleAssignmentsFilteredByAccount(t *testing.T) {
|
||||
accountUUID := "61445573-4dbe-4d56-88dc-88ab47aceba7"
|
||||
|
||||
tests := map[string]struct {
|
||||
result []*settingsmsg.UserRoleAssignment
|
||||
err error
|
||||
status int32
|
||||
}{
|
||||
"handles manager error": {
|
||||
result: nil,
|
||||
err: assert.AnError,
|
||||
status: http.StatusNotFound,
|
||||
},
|
||||
"succeeds with results": {
|
||||
result: []*settingsmsg.UserRoleAssignment{
|
||||
{
|
||||
Id: "00000000-0000-0000-0000-000000000001",
|
||||
AccountUuid: accountUUID,
|
||||
RoleId: "aceb15b8-7486-479f-ae32-c91118e07a39",
|
||||
},
|
||||
},
|
||||
err: nil,
|
||||
status: http.StatusOK,
|
||||
},
|
||||
}
|
||||
|
||||
for name, test := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
manager := &mocks.Manager{}
|
||||
svc := Service{
|
||||
manager: manager,
|
||||
}
|
||||
manager.On("ListRoleAssignments", mock.Anything).Return(test.result, test.err)
|
||||
req := &v0.ListRoleAssignmentsFilteredRequest{
|
||||
Filters: []*settingsmsg.UserRoleAssignmentFilter{
|
||||
{
|
||||
Type: settingsmsg.UserRoleAssignmentFilter_TYPE_ACCOUNT,
|
||||
Term: &settingsmsg.UserRoleAssignmentFilter_AccountUuid{
|
||||
AccountUuid: accountUUID,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
res := v0.ListRoleAssignmentsResponse{}
|
||||
err := svc.ListRoleAssignmentsFiltered(ctxWithUUID, req, &res)
|
||||
switch test.err {
|
||||
case nil:
|
||||
assert.Nil(t, err)
|
||||
default:
|
||||
merr, ok := merrors.As(err)
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, int32(test.status), merr.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestListRoleAssignmentsFilteredByRole(t *testing.T) {
|
||||
roleID := "61445573-4dbe-4d56-88dc-88ab47aceba7"
|
||||
|
||||
tests := map[string]struct {
|
||||
result []*settingsmsg.UserRoleAssignment
|
||||
err error
|
||||
status int32
|
||||
}{
|
||||
"handles manager error": {
|
||||
result: nil,
|
||||
err: assert.AnError,
|
||||
status: http.StatusNotFound,
|
||||
},
|
||||
"succeeds with results": {
|
||||
result: []*settingsmsg.UserRoleAssignment{
|
||||
{
|
||||
Id: "00000000-0000-0000-0000-000000000001",
|
||||
AccountUuid: "aceb15b8-7486-479f-ae32-c91118e07a39",
|
||||
RoleId: roleID,
|
||||
},
|
||||
},
|
||||
err: nil,
|
||||
status: http.StatusOK,
|
||||
},
|
||||
}
|
||||
|
||||
for name, test := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
manager := &mocks.Manager{}
|
||||
svc := Service{
|
||||
manager: manager,
|
||||
}
|
||||
manager.On("ListRoleAssignmentsByRole", mock.Anything).Return(test.result, test.err)
|
||||
req := &v0.ListRoleAssignmentsFilteredRequest{
|
||||
Filters: []*settingsmsg.UserRoleAssignmentFilter{
|
||||
{
|
||||
Type: settingsmsg.UserRoleAssignmentFilter_TYPE_ROLE,
|
||||
Term: &settingsmsg.UserRoleAssignmentFilter_RoleId{
|
||||
RoleId: roleID,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
res := v0.ListRoleAssignmentsResponse{}
|
||||
err := svc.ListRoleAssignmentsFiltered(ctxWithUUID, req, &res)
|
||||
switch test.err {
|
||||
case nil:
|
||||
assert.Nil(t, err)
|
||||
default:
|
||||
merr, ok := merrors.As(err)
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, int32(test.status), merr.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user