mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-02-22 05:29:01 -06:00
Graph test coverage (#5136)
* Add unit tests for users.go * Do not choke on broken spaces * Generate mocks for the RoleService * Increase test coverage * Increase test coverage
This commit is contained in:
@@ -29,6 +29,7 @@ ci-go-generate: $(MOCKERY) # CI runs ci-node-generate automatically before this
|
||||
$(MOCKERY) --dir pkg/service/v0 --case underscore --name HTTPClient
|
||||
$(MOCKERY) --dir pkg/service/v0 --case underscore --name Publisher
|
||||
$(MOCKERY) --dir pkg/service/v0 --case underscore --name Permissions
|
||||
$(MOCKERY) --dir pkg/service/v0 --case underscore --name RoleService
|
||||
$(MOCKERY) --dir pkg/identity --output pkg/identity/mocks --case underscore --name Backend
|
||||
$(MOCKERY) --srcpkg github.com/go-ldap/ldap/v3 --case underscore --filename ldapclient.go --name Client
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.10.4. DO NOT EDIT.
|
||||
// Code generated by mockery v2.14.1. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
@@ -76,3 +76,18 @@ func (_m *Permissions) ListPermissionsByResource(ctx context.Context, in *v0.Lis
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
type mockConstructorTestingTNewPermissions interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}
|
||||
|
||||
// NewPermissions creates a new instance of Permissions. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewPermissions(t mockConstructorTestingTNewPermissions) *Permissions {
|
||||
mock := &Permissions{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
||||
155
services/graph/mocks/role_service.go
Normal file
155
services/graph/mocks/role_service.go
Normal file
@@ -0,0 +1,155 @@
|
||||
// Code generated by mockery v2.14.1. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
client "go-micro.dev/v4/client"
|
||||
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
v0 "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
|
||||
)
|
||||
|
||||
// RoleService is an autogenerated mock type for the RoleService type
|
||||
type RoleService struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// AssignRoleToUser provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *RoleService) AssignRoleToUser(ctx context.Context, in *v0.AssignRoleToUserRequest, opts ...client.CallOption) (*v0.AssignRoleToUserResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
var r0 *v0.AssignRoleToUserResponse
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v0.AssignRoleToUserRequest, ...client.CallOption) *v0.AssignRoleToUserResponse); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v0.AssignRoleToUserResponse)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *v0.AssignRoleToUserRequest, ...client.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// ListRoleAssignments provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *RoleService) ListRoleAssignments(ctx context.Context, in *v0.ListRoleAssignmentsRequest, opts ...client.CallOption) (*v0.ListRoleAssignmentsResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
var r0 *v0.ListRoleAssignmentsResponse
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v0.ListRoleAssignmentsRequest, ...client.CallOption) *v0.ListRoleAssignmentsResponse); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v0.ListRoleAssignmentsResponse)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *v0.ListRoleAssignmentsRequest, ...client.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// ListRoles provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *RoleService) ListRoles(ctx context.Context, in *v0.ListBundlesRequest, opts ...client.CallOption) (*v0.ListBundlesResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
var r0 *v0.ListBundlesResponse
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v0.ListBundlesRequest, ...client.CallOption) *v0.ListBundlesResponse); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*v0.ListBundlesResponse)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *v0.ListBundlesRequest, ...client.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// RemoveRoleFromUser provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *RoleService) RemoveRoleFromUser(ctx context.Context, in *v0.RemoveRoleFromUserRequest, opts ...client.CallOption) (*emptypb.Empty, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
var r0 *emptypb.Empty
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *v0.RemoveRoleFromUserRequest, ...client.CallOption) *emptypb.Empty); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*emptypb.Empty)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *v0.RemoveRoleFromUserRequest, ...client.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
type mockConstructorTestingTNewRoleService interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}
|
||||
|
||||
// NewRoleService creates a new instance of RoleService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewRoleService(t mockConstructorTestingTNewRoleService) *RoleService {
|
||||
mock := &RoleService{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"go-micro.dev/v4/client"
|
||||
mevents "go-micro.dev/v4/events"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
//go:generate make -C ../../.. generate
|
||||
@@ -77,6 +78,14 @@ type HTTPClient interface {
|
||||
// GetGatewayServiceClientFunc is a callback used to pass in a mock during testing
|
||||
type GetGatewayServiceClientFunc func() (GatewayClient, error)
|
||||
|
||||
// RoleService is the interface used to access the role service
|
||||
type RoleService interface {
|
||||
ListRoles(ctx context.Context, in *settingssvc.ListBundlesRequest, opts ...client.CallOption) (*settingssvc.ListBundlesResponse, error)
|
||||
ListRoleAssignments(ctx context.Context, in *settingssvc.ListRoleAssignmentsRequest, opts ...client.CallOption) (*settingssvc.ListRoleAssignmentsResponse, error)
|
||||
AssignRoleToUser(ctx context.Context, in *settingssvc.AssignRoleToUserRequest, opts ...client.CallOption) (*settingssvc.AssignRoleToUserResponse, error)
|
||||
RemoveRoleFromUser(ctx context.Context, in *settingssvc.RemoveRoleFromUserRequest, opts ...client.CallOption) (*emptypb.Empty, error)
|
||||
}
|
||||
|
||||
// Graph defines implements the business logic for Service.
|
||||
type Graph struct {
|
||||
config *config.Config
|
||||
@@ -84,7 +93,7 @@ type Graph struct {
|
||||
logger *log.Logger
|
||||
identityBackend identity.Backend
|
||||
gatewayClient GatewayClient
|
||||
roleService settingssvc.RoleService
|
||||
roleService RoleService
|
||||
permissionsService Permissions
|
||||
spacePropertiesCache *ttlcache.Cache
|
||||
eventsPublisher events.Publisher
|
||||
|
||||
@@ -21,7 +21,7 @@ type Options struct {
|
||||
Middleware []func(http.Handler) http.Handler
|
||||
GatewayClient GatewayClient
|
||||
IdentityBackend identity.Backend
|
||||
RoleService settingssvc.RoleService
|
||||
RoleService RoleService
|
||||
PermissionService Permissions
|
||||
RoleManager *roles.Manager
|
||||
EventsPublisher events.Publisher
|
||||
@@ -73,8 +73,8 @@ func WithIdentityBackend(val identity.Backend) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// RoleService provides a function to set the RoleService option.
|
||||
func RoleService(val settingssvc.RoleService) Option {
|
||||
// WithRoleService provides a function to set the RoleService option.
|
||||
func WithRoleService(val RoleService) Option {
|
||||
return func(o *Options) {
|
||||
o.RoleService = val
|
||||
}
|
||||
|
||||
@@ -257,6 +257,7 @@ func (g Graph) GetUser(w http.ResponseWriter, r *http.Request) {
|
||||
d, err := g.cs3StorageSpaceToDrive(r.Context(), wdu, sp)
|
||||
if err != nil {
|
||||
logger.Debug().Err(err).Interface("id", sp.Id).Msg("error converting space to drive")
|
||||
continue
|
||||
}
|
||||
quota, err := g.getDriveQuota(r.Context(), sp)
|
||||
if err != nil {
|
||||
|
||||
529
services/graph/pkg/service/v0/users_test.go
Normal file
529
services/graph/pkg/service/v0/users_test.go
Normal file
@@ -0,0 +1,529 @@
|
||||
package svc_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
|
||||
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||
ctxpkg "github.com/cs3org/reva/v2/pkg/ctx"
|
||||
"github.com/cs3org/reva/v2/pkg/rgrpc/status"
|
||||
"github.com/go-chi/chi/v5"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/stretchr/testify/mock"
|
||||
|
||||
libregraph "github.com/owncloud/libre-graph-api-go"
|
||||
ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/shared"
|
||||
settingssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
|
||||
"github.com/owncloud/ocis/v2/services/graph/mocks"
|
||||
"github.com/owncloud/ocis/v2/services/graph/pkg/config"
|
||||
"github.com/owncloud/ocis/v2/services/graph/pkg/config/defaults"
|
||||
identitymocks "github.com/owncloud/ocis/v2/services/graph/pkg/identity/mocks"
|
||||
service "github.com/owncloud/ocis/v2/services/graph/pkg/service/v0"
|
||||
)
|
||||
|
||||
type userList struct {
|
||||
Value []*libregraph.User
|
||||
}
|
||||
|
||||
var _ = Describe("Users", func() {
|
||||
var (
|
||||
svc service.Service
|
||||
ctx context.Context
|
||||
cfg *config.Config
|
||||
gatewayClient *mocks.GatewayClient
|
||||
eventsPublisher mocks.Publisher
|
||||
roleService *mocks.RoleService
|
||||
identityBackend *identitymocks.Backend
|
||||
|
||||
rr *httptest.ResponseRecorder
|
||||
|
||||
currentUser = &userv1beta1.User{
|
||||
Id: &userv1beta1.UserId{
|
||||
OpaqueId: "user",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
eventsPublisher.On("Publish", mock.Anything, mock.Anything, mock.Anything).Return(nil)
|
||||
|
||||
identityBackend = &identitymocks.Backend{}
|
||||
roleService = &mocks.RoleService{}
|
||||
gatewayClient = &mocks.GatewayClient{}
|
||||
|
||||
rr = httptest.NewRecorder()
|
||||
ctx = context.Background()
|
||||
|
||||
cfg = defaults.FullDefaultConfig()
|
||||
cfg.Identity.LDAP.CACert = "" // skip the startup checks, we don't use LDAP at all in this tests
|
||||
cfg.TokenManager.JWTSecret = "loremipsum"
|
||||
cfg.Commons = &shared.Commons{}
|
||||
cfg.GRPCClientTLS = &shared.GRPCClientTLS{}
|
||||
|
||||
_ = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
|
||||
svc = service.NewService(
|
||||
service.Config(cfg),
|
||||
service.WithGatewayClient(gatewayClient),
|
||||
service.EventsPublisher(&eventsPublisher),
|
||||
service.WithIdentityBackend(identityBackend),
|
||||
service.WithRoleService(roleService),
|
||||
)
|
||||
})
|
||||
|
||||
Describe("GetMe", func() {
|
||||
It("handles missing user", func() {
|
||||
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/me", nil)
|
||||
svc.GetMe(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusInternalServerError))
|
||||
})
|
||||
|
||||
It("gets the information", func() {
|
||||
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/me", nil)
|
||||
r = r.WithContext(ctxpkg.ContextSetUser(ctx, currentUser))
|
||||
svc.GetMe(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusOK))
|
||||
})
|
||||
|
||||
It("expands the user", func() {
|
||||
user := &libregraph.User{}
|
||||
identityBackend.On("GetUser", mock.Anything, mock.Anything, mock.Anything).Return(user, nil)
|
||||
|
||||
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/me?$expand=memberOf", nil)
|
||||
r = r.WithContext(ctxpkg.ContextSetUser(ctx, currentUser))
|
||||
svc.GetMe(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusOK))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("GetUsers", func() {
|
||||
It("handles invalid requests", func() {
|
||||
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/me/users?$invalid=true", nil)
|
||||
svc.GetUsers(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusBadRequest))
|
||||
})
|
||||
|
||||
It("lists the users", func() {
|
||||
user := &libregraph.User{}
|
||||
user.SetId("user1")
|
||||
users := []*libregraph.User{user}
|
||||
|
||||
identityBackend.On("GetUsers", mock.Anything, mock.Anything, mock.Anything).Return(users, nil)
|
||||
|
||||
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/me/users", nil)
|
||||
svc.GetUsers(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusOK))
|
||||
data, err := ioutil.ReadAll(rr.Body)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
res := userList{}
|
||||
err = json.Unmarshal(data, &res)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
Expect(len(res.Value)).To(Equal(1))
|
||||
Expect(res.Value[0].GetId()).To(Equal("user1"))
|
||||
})
|
||||
|
||||
It("sorts", func() {
|
||||
user := &libregraph.User{}
|
||||
user.SetId("user1")
|
||||
user.SetMail("z@example.com")
|
||||
user.SetDisplayName("9")
|
||||
user.SetOnPremisesSamAccountName("9")
|
||||
user2 := &libregraph.User{}
|
||||
user2.SetId("user2")
|
||||
user2.SetMail("a@example.com")
|
||||
user2.SetDisplayName("1")
|
||||
user2.SetOnPremisesSamAccountName("1")
|
||||
users := []*libregraph.User{user, user2}
|
||||
|
||||
identityBackend.On("GetUsers", mock.Anything, mock.Anything, mock.Anything).Return(users, nil)
|
||||
|
||||
getUsers := func(path string) []*libregraph.User {
|
||||
r := httptest.NewRequest(http.MethodGet, path, nil)
|
||||
rec := httptest.NewRecorder()
|
||||
svc.GetUsers(rec, r)
|
||||
|
||||
Expect(rec.Code).To(Equal(http.StatusOK))
|
||||
data, err := ioutil.ReadAll(rec.Body)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
res := userList{}
|
||||
err = json.Unmarshal(data, &res)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
return res.Value
|
||||
}
|
||||
|
||||
unsorted := getUsers("/graph/v1.0/me/users")
|
||||
Expect(len(unsorted)).To(Equal(2))
|
||||
Expect(unsorted[0].GetId()).To(Equal("user1"))
|
||||
Expect(unsorted[1].GetId()).To(Equal("user2"))
|
||||
|
||||
byMail := getUsers("/graph/v1.0/me/users?$orderby=mail")
|
||||
Expect(len(byMail)).To(Equal(2))
|
||||
Expect(byMail[0].GetId()).To(Equal("user2"))
|
||||
Expect(byMail[1].GetId()).To(Equal("user1"))
|
||||
byMail = getUsers("/graph/v1.0/me/users?$orderby=mail%20asc")
|
||||
Expect(len(byMail)).To(Equal(2))
|
||||
Expect(byMail[0].GetId()).To(Equal("user2"))
|
||||
Expect(byMail[1].GetId()).To(Equal("user1"))
|
||||
byMail = getUsers("/graph/v1.0/me/users?$orderby=mail%20desc")
|
||||
Expect(len(byMail)).To(Equal(2))
|
||||
Expect(byMail[0].GetId()).To(Equal("user1"))
|
||||
Expect(byMail[1].GetId()).To(Equal("user2"))
|
||||
|
||||
byDisplayName := getUsers("/graph/v1.0/me/users?$orderby=displayName")
|
||||
Expect(len(byDisplayName)).To(Equal(2))
|
||||
Expect(byDisplayName[0].GetId()).To(Equal("user2"))
|
||||
Expect(byDisplayName[1].GetId()).To(Equal("user1"))
|
||||
byDisplayName = getUsers("/graph/v1.0/me/users?$orderby=displayName%20asc")
|
||||
Expect(len(byDisplayName)).To(Equal(2))
|
||||
Expect(byDisplayName[0].GetId()).To(Equal("user2"))
|
||||
Expect(byDisplayName[1].GetId()).To(Equal("user1"))
|
||||
byDisplayName = getUsers("/graph/v1.0/me/users?$orderby=displayName%20desc")
|
||||
Expect(len(byDisplayName)).To(Equal(2))
|
||||
Expect(byDisplayName[0].GetId()).To(Equal("user1"))
|
||||
Expect(byDisplayName[1].GetId()).To(Equal("user2"))
|
||||
|
||||
byOnPremisesSamAccountName := getUsers("/graph/v1.0/me/users?$orderby=onPremisesSamAccountName")
|
||||
Expect(len(byOnPremisesSamAccountName)).To(Equal(2))
|
||||
Expect(byOnPremisesSamAccountName[0].GetId()).To(Equal("user2"))
|
||||
Expect(byOnPremisesSamAccountName[1].GetId()).To(Equal("user1"))
|
||||
byOnPremisesSamAccountName = getUsers("/graph/v1.0/me/users?$orderby=onPremisesSamAccountName%20asc")
|
||||
Expect(len(byOnPremisesSamAccountName)).To(Equal(2))
|
||||
Expect(byOnPremisesSamAccountName[0].GetId()).To(Equal("user2"))
|
||||
Expect(byOnPremisesSamAccountName[1].GetId()).To(Equal("user1"))
|
||||
byOnPremisesSamAccountName = getUsers("/graph/v1.0/me/users?$orderby=onPremisesSamAccountName%20desc")
|
||||
Expect(len(byOnPremisesSamAccountName)).To(Equal(2))
|
||||
Expect(byOnPremisesSamAccountName[0].GetId()).To(Equal("user1"))
|
||||
Expect(byOnPremisesSamAccountName[1].GetId()).To(Equal("user2"))
|
||||
|
||||
// Handles invalid sort field
|
||||
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/me/users?$orderby=invalid", nil)
|
||||
svc.GetUsers(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusBadRequest))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("GetUser", func() {
|
||||
It("handles missing userids", func() {
|
||||
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/me/users", nil)
|
||||
svc.GetUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusBadRequest))
|
||||
})
|
||||
|
||||
It("gets the user", func() {
|
||||
user := &libregraph.User{}
|
||||
user.SetId("user1")
|
||||
|
||||
identityBackend.On("GetUser", mock.Anything, mock.Anything, mock.Anything).Return(user, nil)
|
||||
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/me/users", nil)
|
||||
rctx := chi.NewRouteContext()
|
||||
rctx.URLParams.Add("userID", *user.Id)
|
||||
r = r.WithContext(context.WithValue(ctxpkg.ContextSetUser(ctx, currentUser), chi.RouteCtxKey, rctx))
|
||||
svc.GetUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusOK))
|
||||
data, err := ioutil.ReadAll(rr.Body)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
responseUser := &libregraph.User{}
|
||||
err = json.Unmarshal(data, &responseUser)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(responseUser.GetId()).To(Equal("user1"))
|
||||
Expect(len(responseUser.GetDrives())).To(Equal(0))
|
||||
})
|
||||
|
||||
It("includes the personal space if requested", func() {
|
||||
user := &libregraph.User{}
|
||||
user.SetId("user1")
|
||||
|
||||
identityBackend.On("GetUser", mock.Anything, mock.Anything, mock.Anything).Return(user, nil)
|
||||
gatewayClient.On("GetQuota", mock.Anything, mock.Anything, mock.Anything).Return(&provider.GetQuotaResponse{
|
||||
Status: status.NewOK(ctx),
|
||||
TotalBytes: 10,
|
||||
}, nil)
|
||||
gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything, mock.Anything).Return(&provider.ListStorageSpacesResponse{
|
||||
Status: status.NewOK(ctx),
|
||||
StorageSpaces: []*provider.StorageSpace{
|
||||
{
|
||||
Id: &provider.StorageSpaceId{OpaqueId: "drive1"},
|
||||
Root: &provider.ResourceId{SpaceId: "space", OpaqueId: "space"},
|
||||
SpaceType: "project",
|
||||
},
|
||||
{
|
||||
Id: &provider.StorageSpaceId{OpaqueId: "personal"},
|
||||
Root: &provider.ResourceId{SpaceId: "personal", OpaqueId: "personal"},
|
||||
SpaceType: "personal",
|
||||
},
|
||||
},
|
||||
}, nil)
|
||||
|
||||
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/me/users?$expand=drive", nil)
|
||||
rctx := chi.NewRouteContext()
|
||||
rctx.URLParams.Add("userID", *user.Id)
|
||||
r = r.WithContext(context.WithValue(ctxpkg.ContextSetUser(ctx, currentUser), chi.RouteCtxKey, rctx))
|
||||
svc.GetUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusOK))
|
||||
data, err := ioutil.ReadAll(rr.Body)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
responseUser := &libregraph.User{}
|
||||
err = json.Unmarshal(data, &responseUser)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(responseUser.GetId()).To(Equal("user1"))
|
||||
Expect(*responseUser.GetDrive().Id).To(Equal("personal"))
|
||||
})
|
||||
|
||||
It("includes the drives if requested", func() {
|
||||
user := &libregraph.User{}
|
||||
user.SetId("user1")
|
||||
|
||||
identityBackend.On("GetUser", mock.Anything, mock.Anything, mock.Anything).Return(user, nil)
|
||||
gatewayClient.On("GetQuota", mock.Anything, mock.Anything, mock.Anything).Return(&provider.GetQuotaResponse{
|
||||
Status: status.NewOK(ctx),
|
||||
TotalBytes: 10,
|
||||
}, nil)
|
||||
gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything, mock.Anything).Return(&provider.ListStorageSpacesResponse{
|
||||
Status: status.NewOK(ctx),
|
||||
StorageSpaces: []*provider.StorageSpace{
|
||||
{
|
||||
Id: &provider.StorageSpaceId{OpaqueId: "drive1"},
|
||||
Root: &provider.ResourceId{SpaceId: "space", OpaqueId: "space"},
|
||||
},
|
||||
},
|
||||
}, nil)
|
||||
|
||||
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/me/users?$expand=drives", nil)
|
||||
rctx := chi.NewRouteContext()
|
||||
rctx.URLParams.Add("userID", *user.Id)
|
||||
r = r.WithContext(context.WithValue(ctxpkg.ContextSetUser(ctx, currentUser), chi.RouteCtxKey, rctx))
|
||||
svc.GetUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusOK))
|
||||
data, err := ioutil.ReadAll(rr.Body)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
responseUser := &libregraph.User{}
|
||||
err = json.Unmarshal(data, &responseUser)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(responseUser.GetId()).To(Equal("user1"))
|
||||
Expect(len(responseUser.GetDrives())).To(Equal(1))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("PostUser", func() {
|
||||
var (
|
||||
user *libregraph.User
|
||||
|
||||
assertHandleBadAttributes = func(user *libregraph.User) {
|
||||
userJson, err := json.Marshal(user)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
r := httptest.NewRequest(http.MethodPost, "/graph/v1.0/me/users", bytes.NewBuffer(userJson))
|
||||
svc.PostUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusBadRequest))
|
||||
}
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
user = &libregraph.User{}
|
||||
user.SetDisplayName("Display Name")
|
||||
user.SetOnPremisesSamAccountName("user")
|
||||
user.SetMail("user@example.com")
|
||||
})
|
||||
|
||||
It("handles invalid bodies", func() {
|
||||
r := httptest.NewRequest(http.MethodPost, "/graph/v1.0/me/users?$invalid=true", nil)
|
||||
svc.PostUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusBadRequest))
|
||||
})
|
||||
|
||||
It("handles missing display names", func() {
|
||||
user.DisplayName = nil
|
||||
assertHandleBadAttributes(user)
|
||||
|
||||
})
|
||||
|
||||
It("handles missing OnPremisesSamAccountName", func() {
|
||||
user.OnPremisesSamAccountName = nil
|
||||
assertHandleBadAttributes(user)
|
||||
|
||||
user.SetOnPremisesSamAccountName("")
|
||||
assertHandleBadAttributes(user)
|
||||
})
|
||||
|
||||
It("handles bad Mails", func() {
|
||||
user.Mail = nil
|
||||
assertHandleBadAttributes(user)
|
||||
|
||||
user.SetMail("not-a-mail-address")
|
||||
assertHandleBadAttributes(user)
|
||||
})
|
||||
|
||||
It("handles set Ids - they are read-only", func() {
|
||||
user.SetId("/users/user")
|
||||
assertHandleBadAttributes(user)
|
||||
})
|
||||
|
||||
It("creates a user", func() {
|
||||
roleService.On("AssignRoleToUser", mock.Anything, mock.Anything).Return(&settingssvc.AssignRoleToUserResponse{}, nil)
|
||||
identityBackend.On("CreateUser", mock.Anything, mock.Anything).Return(func(ctx context.Context, user libregraph.User) *libregraph.User {
|
||||
user.SetId("/users/user")
|
||||
return &user
|
||||
}, nil)
|
||||
userJson, err := json.Marshal(user)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
r := httptest.NewRequest(http.MethodPost, "/graph/v1.0/me/users", bytes.NewBuffer(userJson))
|
||||
r = r.WithContext(ctxpkg.ContextSetUser(ctx, currentUser))
|
||||
svc.PostUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusOK))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("DeleteUser", func() {
|
||||
It("handles missing userids", func() {
|
||||
r := httptest.NewRequest(http.MethodDelete, "/graph/v1.0/me/users/{userid}", nil)
|
||||
svc.DeleteUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusBadRequest))
|
||||
})
|
||||
|
||||
It("prevents a user from deleting themselves", func() {
|
||||
lu := libregraph.User{}
|
||||
lu.SetId(currentUser.Id.OpaqueId)
|
||||
identityBackend.On("GetUser", mock.Anything, mock.Anything, mock.Anything).Return(&lu, nil)
|
||||
|
||||
r := httptest.NewRequest(http.MethodDelete, "/graph/v1.0/me/users/{userid}", nil)
|
||||
rctx := chi.NewRouteContext()
|
||||
rctx.URLParams.Add("userID", currentUser.Id.OpaqueId)
|
||||
r = r.WithContext(context.WithValue(ctxpkg.ContextSetUser(ctx, currentUser), chi.RouteCtxKey, rctx))
|
||||
svc.DeleteUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusForbidden))
|
||||
})
|
||||
|
||||
It("deletes a user from deleting themselves", func() {
|
||||
otheruser := &userv1beta1.User{
|
||||
Id: &userv1beta1.UserId{
|
||||
OpaqueId: "otheruser",
|
||||
},
|
||||
}
|
||||
|
||||
lu := libregraph.User{}
|
||||
lu.SetId(otheruser.Id.OpaqueId)
|
||||
identityBackend.On("GetUser", mock.Anything, mock.Anything, mock.Anything).Return(&lu, nil)
|
||||
identityBackend.On("DeleteUser", mock.Anything, mock.Anything).Return(nil)
|
||||
gatewayClient.On("DeleteStorageSpace", mock.Anything, mock.Anything).Return(&provider.DeleteStorageSpaceResponse{
|
||||
Status: status.NewOK(ctx),
|
||||
}, nil)
|
||||
gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything, mock.Anything).Return(&provider.ListStorageSpacesResponse{
|
||||
Status: status.NewOK(ctx),
|
||||
StorageSpaces: []*provider.StorageSpace{
|
||||
{
|
||||
Opaque: &typesv1beta1.Opaque{},
|
||||
Id: &provider.StorageSpaceId{OpaqueId: "drive1"},
|
||||
Root: &provider.ResourceId{SpaceId: "space", OpaqueId: "space"},
|
||||
SpaceType: "personal",
|
||||
Owner: otheruser,
|
||||
},
|
||||
},
|
||||
}, nil)
|
||||
|
||||
r := httptest.NewRequest(http.MethodDelete, "/graph/v1.0/me/users/{userid}", nil)
|
||||
rctx := chi.NewRouteContext()
|
||||
rctx.URLParams.Add("userID", lu.GetId())
|
||||
r = r.WithContext(context.WithValue(ctxpkg.ContextSetUser(ctx, currentUser), chi.RouteCtxKey, rctx))
|
||||
svc.DeleteUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusNoContent))
|
||||
gatewayClient.AssertNumberOfCalls(GinkgoT(), "DeleteStorageSpace", 2) // 2 calls for the home space. first trash, then purge
|
||||
})
|
||||
})
|
||||
|
||||
Describe("PatchUser", func() {
|
||||
var (
|
||||
user *libregraph.User
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
user = &libregraph.User{}
|
||||
user.SetDisplayName("Display Name")
|
||||
user.SetOnPremisesSamAccountName("user")
|
||||
user.SetMail("user@example.com")
|
||||
user.SetId("/users/user")
|
||||
|
||||
identityBackend.On("GetUser", mock.Anything, mock.Anything, mock.Anything).Return(&user, nil)
|
||||
})
|
||||
|
||||
It("handles missing userids", func() {
|
||||
r := httptest.NewRequest(http.MethodPatch, "/graph/v1.0/me/users/{userid}", nil)
|
||||
svc.PatchUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusBadRequest))
|
||||
})
|
||||
|
||||
It("handles invalid bodies", func() {
|
||||
r := httptest.NewRequest(http.MethodPost, "/graph/v1.0/me/users?$invalid=true", nil)
|
||||
rctx := chi.NewRouteContext()
|
||||
rctx.URLParams.Add("userID", user.GetId())
|
||||
r = r.WithContext(context.WithValue(ctxpkg.ContextSetUser(ctx, currentUser), chi.RouteCtxKey, rctx))
|
||||
svc.PatchUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusBadRequest))
|
||||
})
|
||||
|
||||
It("handles invalid email", func() {
|
||||
user.SetMail("invalid")
|
||||
data, err := json.Marshal(user)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
r := httptest.NewRequest(http.MethodPost, "/graph/v1.0/me/users?$invalid=true", bytes.NewBuffer(data))
|
||||
rctx := chi.NewRouteContext()
|
||||
rctx.URLParams.Add("userID", user.GetId())
|
||||
r = r.WithContext(context.WithValue(ctxpkg.ContextSetUser(ctx, currentUser), chi.RouteCtxKey, rctx))
|
||||
svc.PatchUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusBadRequest))
|
||||
})
|
||||
|
||||
It("updates attributes", func() {
|
||||
identityBackend.On("UpdateUser", mock.Anything, user.GetId(), mock.Anything).Return(user, nil)
|
||||
|
||||
user.SetDisplayName("New Display Name")
|
||||
data, err := json.Marshal(user)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
r := httptest.NewRequest(http.MethodPost, "/graph/v1.0/me/users?$invalid=true", bytes.NewBuffer(data))
|
||||
rctx := chi.NewRouteContext()
|
||||
rctx.URLParams.Add("userID", user.GetId())
|
||||
r = r.WithContext(context.WithValue(ctxpkg.ContextSetUser(ctx, currentUser), chi.RouteCtxKey, rctx))
|
||||
svc.PatchUser(rr, r)
|
||||
|
||||
Expect(rr.Code).To(Equal(http.StatusOK))
|
||||
data, err = ioutil.ReadAll(rr.Body)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
updatedUser := libregraph.User{}
|
||||
err = json.Unmarshal(data, &updatedUser)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(updatedUser.GetDisplayName()).To(Equal("New Display Name"))
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user