From 4841240bff4723e1f5f1ba6e647e47c2ce920b12 Mon Sep 17 00:00:00 2001 From: Florian Schade Date: Tue, 23 Apr 2024 18:00:13 +0200 Subject: [PATCH] enhancement: add get share service method --- .../graph/mocks/drives_drive_item_provider.go | 103 ++++++++++++--- .../pkg/service/v0/api_drives_drive_item.go | 40 ++++-- .../service/v0/api_drives_drive_item_test.go | 125 ++++++++++++++---- 3 files changed, 207 insertions(+), 61 deletions(-) diff --git a/services/graph/mocks/drives_drive_item_provider.go b/services/graph/mocks/drives_drive_item_provider.go index 62c3bb710..a521268a2 100644 --- a/services/graph/mocks/drives_drive_item_provider.go +++ b/services/graph/mocks/drives_drive_item_provider.go @@ -27,29 +27,29 @@ func (_m *DrivesDriveItemProvider) EXPECT() *DrivesDriveItemProvider_Expecter { return &DrivesDriveItemProvider_Expecter{mock: &_m.Mock} } -// GetShareAndSiblings provides a mock function with given fields: ctx, shareID, filters -func (_m *DrivesDriveItemProvider) GetShareAndSiblings(ctx context.Context, shareID *collaborationv1beta1.ShareId, filters []*collaborationv1beta1.Filter) ([]*collaborationv1beta1.ReceivedShare, error) { - ret := _m.Called(ctx, shareID, filters) +// GetShare provides a mock function with given fields: ctx, shareID +func (_m *DrivesDriveItemProvider) GetShare(ctx context.Context, shareID *collaborationv1beta1.ShareId) (*collaborationv1beta1.ReceivedShare, error) { + ret := _m.Called(ctx, shareID) if len(ret) == 0 { - panic("no return value specified for GetShareAndSiblings") + panic("no return value specified for GetShare") } - var r0 []*collaborationv1beta1.ReceivedShare + var r0 *collaborationv1beta1.ReceivedShare var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *collaborationv1beta1.ShareId, []*collaborationv1beta1.Filter) ([]*collaborationv1beta1.ReceivedShare, error)); ok { - return rf(ctx, shareID, filters) + if rf, ok := ret.Get(0).(func(context.Context, *collaborationv1beta1.ShareId) (*collaborationv1beta1.ReceivedShare, error)); ok { + return rf(ctx, shareID) } - if rf, ok := ret.Get(0).(func(context.Context, *collaborationv1beta1.ShareId, []*collaborationv1beta1.Filter) []*collaborationv1beta1.ReceivedShare); ok { - r0 = rf(ctx, shareID, filters) + if rf, ok := ret.Get(0).(func(context.Context, *collaborationv1beta1.ShareId) *collaborationv1beta1.ReceivedShare); ok { + r0 = rf(ctx, shareID) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).([]*collaborationv1beta1.ReceivedShare) + r0 = ret.Get(0).(*collaborationv1beta1.ReceivedShare) } } - if rf, ok := ret.Get(1).(func(context.Context, *collaborationv1beta1.ShareId, []*collaborationv1beta1.Filter) error); ok { - r1 = rf(ctx, shareID, filters) + if rf, ok := ret.Get(1).(func(context.Context, *collaborationv1beta1.ShareId) error); ok { + r1 = rf(ctx, shareID) } else { r1 = ret.Error(1) } @@ -57,32 +57,91 @@ func (_m *DrivesDriveItemProvider) GetShareAndSiblings(ctx context.Context, shar return r0, r1 } -// DrivesDriveItemProvider_GetShareAndSiblings_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetShareAndSiblings' -type DrivesDriveItemProvider_GetShareAndSiblings_Call struct { +// DrivesDriveItemProvider_GetShare_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetShare' +type DrivesDriveItemProvider_GetShare_Call struct { *mock.Call } -// GetShareAndSiblings is a helper method to define mock.On call +// GetShare is a helper method to define mock.On call // - ctx context.Context // - shareID *collaborationv1beta1.ShareId -// - filters []*collaborationv1beta1.Filter -func (_e *DrivesDriveItemProvider_Expecter) GetShareAndSiblings(ctx interface{}, shareID interface{}, filters interface{}) *DrivesDriveItemProvider_GetShareAndSiblings_Call { - return &DrivesDriveItemProvider_GetShareAndSiblings_Call{Call: _e.mock.On("GetShareAndSiblings", ctx, shareID, filters)} +func (_e *DrivesDriveItemProvider_Expecter) GetShare(ctx interface{}, shareID interface{}) *DrivesDriveItemProvider_GetShare_Call { + return &DrivesDriveItemProvider_GetShare_Call{Call: _e.mock.On("GetShare", ctx, shareID)} } -func (_c *DrivesDriveItemProvider_GetShareAndSiblings_Call) Run(run func(ctx context.Context, shareID *collaborationv1beta1.ShareId, filters []*collaborationv1beta1.Filter)) *DrivesDriveItemProvider_GetShareAndSiblings_Call { +func (_c *DrivesDriveItemProvider_GetShare_Call) Run(run func(ctx context.Context, shareID *collaborationv1beta1.ShareId)) *DrivesDriveItemProvider_GetShare_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*collaborationv1beta1.ShareId), args[2].([]*collaborationv1beta1.Filter)) + run(args[0].(context.Context), args[1].(*collaborationv1beta1.ShareId)) }) return _c } -func (_c *DrivesDriveItemProvider_GetShareAndSiblings_Call) Return(_a0 []*collaborationv1beta1.ReceivedShare, _a1 error) *DrivesDriveItemProvider_GetShareAndSiblings_Call { +func (_c *DrivesDriveItemProvider_GetShare_Call) Return(_a0 *collaborationv1beta1.ReceivedShare, _a1 error) *DrivesDriveItemProvider_GetShare_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *DrivesDriveItemProvider_GetShareAndSiblings_Call) RunAndReturn(run func(context.Context, *collaborationv1beta1.ShareId, []*collaborationv1beta1.Filter) ([]*collaborationv1beta1.ReceivedShare, error)) *DrivesDriveItemProvider_GetShareAndSiblings_Call { +func (_c *DrivesDriveItemProvider_GetShare_Call) RunAndReturn(run func(context.Context, *collaborationv1beta1.ShareId) (*collaborationv1beta1.ReceivedShare, error)) *DrivesDriveItemProvider_GetShare_Call { + _c.Call.Return(run) + return _c +} + +// GetShares provides a mock function with given fields: ctx, resourceID, filters +func (_m *DrivesDriveItemProvider) GetShares(ctx context.Context, resourceID *providerv1beta1.ResourceId, filters []*collaborationv1beta1.Filter) ([]*collaborationv1beta1.ReceivedShare, error) { + ret := _m.Called(ctx, resourceID, filters) + + if len(ret) == 0 { + panic("no return value specified for GetShares") + } + + var r0 []*collaborationv1beta1.ReceivedShare + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *providerv1beta1.ResourceId, []*collaborationv1beta1.Filter) ([]*collaborationv1beta1.ReceivedShare, error)); ok { + return rf(ctx, resourceID, filters) + } + if rf, ok := ret.Get(0).(func(context.Context, *providerv1beta1.ResourceId, []*collaborationv1beta1.Filter) []*collaborationv1beta1.ReceivedShare); ok { + r0 = rf(ctx, resourceID, filters) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*collaborationv1beta1.ReceivedShare) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *providerv1beta1.ResourceId, []*collaborationv1beta1.Filter) error); ok { + r1 = rf(ctx, resourceID, filters) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DrivesDriveItemProvider_GetShares_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetShares' +type DrivesDriveItemProvider_GetShares_Call struct { + *mock.Call +} + +// GetShares is a helper method to define mock.On call +// - ctx context.Context +// - resourceID *providerv1beta1.ResourceId +// - filters []*collaborationv1beta1.Filter +func (_e *DrivesDriveItemProvider_Expecter) GetShares(ctx interface{}, resourceID interface{}, filters interface{}) *DrivesDriveItemProvider_GetShares_Call { + return &DrivesDriveItemProvider_GetShares_Call{Call: _e.mock.On("GetShares", ctx, resourceID, filters)} +} + +func (_c *DrivesDriveItemProvider_GetShares_Call) Run(run func(ctx context.Context, resourceID *providerv1beta1.ResourceId, filters []*collaborationv1beta1.Filter)) *DrivesDriveItemProvider_GetShares_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*providerv1beta1.ResourceId), args[2].([]*collaborationv1beta1.Filter)) + }) + return _c +} + +func (_c *DrivesDriveItemProvider_GetShares_Call) Return(_a0 []*collaborationv1beta1.ReceivedShare, _a1 error) *DrivesDriveItemProvider_GetShares_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *DrivesDriveItemProvider_GetShares_Call) RunAndReturn(run func(context.Context, *providerv1beta1.ResourceId, []*collaborationv1beta1.Filter) ([]*collaborationv1beta1.ReceivedShare, error)) *DrivesDriveItemProvider_GetShares_Call { _c.Call.Return(run) return _c } diff --git a/services/graph/pkg/service/v0/api_drives_drive_item.go b/services/graph/pkg/service/v0/api_drives_drive_item.go index f49786cd5..545eebca5 100644 --- a/services/graph/pkg/service/v0/api_drives_drive_item.go +++ b/services/graph/pkg/service/v0/api_drives_drive_item.go @@ -36,6 +36,9 @@ var ( // ErrNoShares is returned when no shares are found ErrNoShares = errors.New("no shares found") + // ErrNoShare is returned when no share is found + ErrNoShare = errors.New("no shares found") + // ErrAbsoluteNamePath is returned when the name is an absolute path ErrAbsoluteNamePath = errors.New("name cannot be an absolute path") @@ -82,8 +85,11 @@ type ( // UpdateShares updates multiple shares UpdateShares(ctx context.Context, shares []*collaboration.ReceivedShare, updater UpdateShareClosure) ([]*collaboration.ReceivedShare, error) - // GetShareAndSiblings returns the share and all its siblings - GetShareAndSiblings(ctx context.Context, shareID *collaboration.ShareId, filters []*collaboration.Filter) ([]*collaboration.ReceivedShare, error) + // GetShare returns the share + GetShare(ctx context.Context, shareID *collaboration.ShareId) (*collaboration.ReceivedShare, error) + + // GetShares returns all shares for a given resourceID + GetShares(ctx context.Context, resourceID *storageprovider.ResourceId, filters []*collaboration.Filter) ([]*collaboration.ReceivedShare, error) } ) @@ -101,8 +107,7 @@ func NewDrivesDriveItemService(logger log.Logger, gatewaySelector pool.Selectabl }, nil } -// GetShareAndSiblings returns the share and all its siblings -func (s DrivesDriveItemService) GetShareAndSiblings(ctx context.Context, shareID *collaboration.ShareId, filters []*collaboration.Filter) ([]*collaboration.ReceivedShare, error) { +func (s DrivesDriveItemService) GetShare(ctx context.Context, shareID *collaboration.ShareId) (*collaboration.ReceivedShare, error) { gatewayClient, err := s.gatewaySelector.Next() if err != nil { return nil, err @@ -118,15 +123,12 @@ func (s DrivesDriveItemService) GetShareAndSiblings(ctx context.Context, shareID }, }, ) - if err := errorcode.FromCS3Status(getReceivedShareResponse.GetStatus(), err); err != nil { - return nil, err - } - return s.GetSharesByResourceID(ctx, getReceivedShareResponse.GetShare().GetShare().GetResourceId(), filters) + return getReceivedShareResponse.GetShare(), errorcode.FromCS3Status(getReceivedShareResponse.GetStatus(), err) } -// GetSharesByResourceID returns all shares for a given resourceID -func (s DrivesDriveItemService) GetSharesByResourceID(ctx context.Context, resourceID *storageprovider.ResourceId, filters []*collaboration.Filter) ([]*collaboration.ReceivedShare, error) { +// GetShares returns all shares for a given resourceID +func (s DrivesDriveItemService) GetShares(ctx context.Context, resourceID *storageprovider.ResourceId, filters []*collaboration.Filter) ([]*collaboration.ReceivedShare, error) { // Find all accepted shares for this resource gatewayClient, err := s.gatewaySelector.Next() if err != nil { @@ -211,7 +213,12 @@ func (s DrivesDriveItemService) UpdateShare(ctx context.Context, share *collabor // UnmountShare unmounts a share func (s DrivesDriveItemService) UnmountShare(ctx context.Context, shareID *collaboration.ShareId) error { - availableShares, err := s.GetShareAndSiblings(ctx, shareID, []*collaboration.Filter{ + share, err := s.GetShare(ctx, shareID) + if err != nil { + return err + } + + availableShares, err := s.GetShares(ctx, share.GetShare().GetResourceId(), []*collaboration.Filter{ { Type: collaboration.Filter_TYPE_STATE, Term: &collaboration.Filter_State{ @@ -243,7 +250,7 @@ func (s DrivesDriveItemService) MountShare(ctx context.Context, resourceID *stor name = filepath.Clean(name) } - availableShares, err := s.GetSharesByResourceID(ctx, resourceID, []*collaboration.Filter{ + availableShares, err := s.GetShares(ctx, resourceID, []*collaboration.Filter{ { Type: collaboration.Filter_TYPE_STATE, Term: &collaboration.Filter_State{ @@ -357,7 +364,14 @@ func (api DrivesDriveItemApi) UpdateDriveItem(w http.ResponseWriter, r *http.Req return } - availableShares, err := api.drivesDriveItemService.GetShareAndSiblings(r.Context(), shareID, nil) + share, err := api.drivesDriveItemService.GetShare(r.Context(), shareID) + if err != nil { + api.logger.Debug().Err(err).Msg(ErrNoShare.Error()) + errorcode.InvalidRequest.Render(w, r, http.StatusFailedDependency, ErrNoShare.Error()) + return + } + + availableShares, err := api.drivesDriveItemService.GetShares(r.Context(), share.GetShare().GetResourceId(), nil) if err != nil { api.logger.Debug().Err(err).Msg(ErrGetShareAndSiblings.Error()) errorcode.InvalidRequest.Render(w, r, http.StatusFailedDependency, ErrGetShareAndSiblings.Error()) diff --git a/services/graph/pkg/service/v0/api_drives_drive_item_test.go b/services/graph/pkg/service/v0/api_drives_drive_item_test.go index 7d7dc2152..d89bea22a 100644 --- a/services/graph/pkg/service/v0/api_drives_drive_item_test.go +++ b/services/graph/pkg/service/v0/api_drives_drive_item_test.go @@ -41,14 +41,28 @@ var _ = Describe("DrivesDriveItemService", func() { gatewayClient = cs3mocks.NewGatewayAPIClient(GinkgoT()) gatewaySelector = mocks.NewSelectable[gateway.GatewayAPIClient](GinkgoT()) - gatewaySelector.On("Next").Return(gatewayClient, nil) + gatewaySelector.EXPECT().Next().Return(gatewayClient, nil) service, err := svc.NewDrivesDriveItemService(logger, gatewaySelector) Expect(err).ToNot(HaveOccurred()) drivesDriveItemService = service }) - var _ = Describe("GetSharesByResourceID", func() { + failOnFailingGatewayClientRotation := func(f func() error) { + It("fails if obtaining the next gateway client fails", func() { + someErr := errors.New("some error") + gatewaySelector.EXPECT().Next().Unset() + gatewaySelector.EXPECT().Next().Return(gatewayClient, someErr).Times(1) + Expect(f()).To(MatchError(someErr)) + }) + } + + var _ = Describe("GetShares", func() { + failOnFailingGatewayClientRotation(func() error { + _, err := drivesDriveItemService.GetShares(context.Background(), nil, nil) + return err + }) + It("uses the correct filters to list received shares", func() { resourceID := &storageprovider.ResourceId{ StorageId: "1", @@ -68,7 +82,7 @@ var _ = Describe("DrivesDriveItemService", func() { }). Once() - _, _ = drivesDriveItemService.GetSharesByResourceID(context.Background(), resourceID, []*collaborationv1beta1.Filter{ + _, _ = drivesDriveItemService.GetShares(context.Background(), resourceID, []*collaborationv1beta1.Filter{ { Type: collaborationv1beta1.Filter_TYPE_STATE, Term: &collaborationv1beta1.Filter_State{ @@ -86,7 +100,7 @@ var _ = Describe("DrivesDriveItemService", func() { Return(nil, someErr). Once() - _, err := drivesDriveItemService.GetSharesByResourceID(context.Background(), &storageprovider.ResourceId{}, []*collaborationv1beta1.Filter{}) + _, err := drivesDriveItemService.GetShares(context.Background(), &storageprovider.ResourceId{}, []*collaborationv1beta1.Filter{}) Expect(err).To(MatchError(someErr)) }) @@ -97,7 +111,7 @@ var _ = Describe("DrivesDriveItemService", func() { Return(nil, nil). Once() - _, err := drivesDriveItemService.GetSharesByResourceID(context.Background(), &storageprovider.ResourceId{}, []*collaborationv1beta1.Filter{}) + _, err := drivesDriveItemService.GetShares(context.Background(), &storageprovider.ResourceId{}, []*collaborationv1beta1.Filter{}) Expect(err).To(MatchError(svc.ErrNoShares)) }) @@ -116,13 +130,18 @@ var _ = Describe("DrivesDriveItemService", func() { }, nil). Once() - shares, err := drivesDriveItemService.GetSharesByResourceID(context.Background(), &storageprovider.ResourceId{}, []*collaborationv1beta1.Filter{}) + shares, err := drivesDriveItemService.GetShares(context.Background(), &storageprovider.ResourceId{}, []*collaborationv1beta1.Filter{}) Expect(err).To(BeNil()) Expect(shares).To(Equal(givenShares)) }) }) - var _ = Describe("GetShareAndSiblings", func() { + var _ = Describe("GetShare", func() { + failOnFailingGatewayClientRotation(func() error { + _, err := drivesDriveItemService.GetShare(context.Background(), nil) + return err + }) + It("fails if share lookup reports an error", func() { someErr := errors.New("some error") gatewayClient. @@ -131,7 +150,7 @@ var _ = Describe("DrivesDriveItemService", func() { Return(nil, someErr). Once() - _, err := drivesDriveItemService.GetShareAndSiblings(context.Background(), &collaborationv1beta1.ShareId{}, nil) + _, err := drivesDriveItemService.GetShare(context.Background(), &collaborationv1beta1.ShareId{}) Expect(err).To(MatchError(errorcode.New(errorcode.GeneralException, someErr.Error()))) }) @@ -145,35 +164,38 @@ var _ = Describe("DrivesDriveItemService", func() { }, nil). Once() - _, err := drivesDriveItemService.GetShareAndSiblings(context.Background(), &collaborationv1beta1.ShareId{}, nil) + _, err := drivesDriveItemService.GetShare(context.Background(), &collaborationv1beta1.ShareId{}) Expect(err).To(MatchError(errorcode.New(errorcode.ItemNotFound, someErr.Error()))) }) - It("successfully returns shares", func() { + It("successfully returns a share", func() { gatewayClient. EXPECT(). GetReceivedShare(context.Background(), mock.Anything, mock.Anything). Return(&collaborationv1beta1.GetReceivedShareResponse{ Status: status.NewOK(context.Background()), + Share: &collaborationv1beta1.ReceivedShare{ + Share: &collaborationv1beta1.Share{ + Id: &collaborationv1beta1.ShareId{ + OpaqueId: "123", + }, + }, + }, }, nil). Once() - gatewayClient. - EXPECT(). - ListReceivedShares(context.Background(), mock.Anything, mock.Anything, mock.Anything). - Return(&collaborationv1beta1.ListReceivedSharesResponse{ - Status: status.NewOK(context.Background()), - Shares: make([]*collaborationv1beta1.ReceivedShare, 3), - }, nil). - Once() - - shares, err := drivesDriveItemService.GetShareAndSiblings(context.Background(), &collaborationv1beta1.ShareId{}, nil) + share, err := drivesDriveItemService.GetShare(context.Background(), &collaborationv1beta1.ShareId{}) Expect(err).To(BeNil()) - Expect(shares).To(HaveLen(3)) + Expect(share.GetShare().GetId().GetOpaqueId()).To(Equal("123")) }) }) var _ = Describe("UpdateShare", func() { + failOnFailingGatewayClientRotation(func() error { + _, err := drivesDriveItemService.UpdateShare(context.Background(), nil, nil) + return err + }) + It("fails without an updater", func() { _, err := drivesDriveItemService.UpdateShare(context.Background(), &collaborationv1beta1.ReceivedShare{}, nil) Expect(err).To(MatchError(svc.ErrNoUpdater)) @@ -544,7 +566,7 @@ var _ = Describe("DrivesDriveItemApi", func() { failOninvalidDriveItemBody(drivesDriveItemApi.UpdateDriveItem) - It("fails if retrieving the share ans siblings fails", func() { + It("fails if retrieving the share fails", func() { rCTX.URLParams.Add("driveID", "a0ca6a90-a365-4782-871e-d44447bbc668$a0ca6a90-a365-4782-871e-d44447bbc668") rCTX.URLParams.Add("itemID", "a0ca6a90-a365-4782-871e-d44447bbc668$a0ca6a90-a365-4782-871e-d44447bbc668!1") @@ -560,7 +582,40 @@ var _ = Describe("DrivesDriveItemApi", func() { drivesDriveItemProvider. EXPECT(). - GetShareAndSiblings(mock.Anything, mock.Anything, mock.Anything). + GetShare(mock.Anything, mock.Anything). + Return(nil, errors.New("some error")). + Once() + + drivesDriveItemApi.UpdateDriveItem(w, r) + Expect(w.Code).To(Equal(http.StatusFailedDependency)) + + jsonData := gjson.Get(w.Body.String(), "error") + Expect(jsonData.Get("message").String()).To(Equal(svc.ErrNoShare.Error())) + }) + + It("fails if retrieving the shares fail", func() { + rCTX.URLParams.Add("driveID", "a0ca6a90-a365-4782-871e-d44447bbc668$a0ca6a90-a365-4782-871e-d44447bbc668") + rCTX.URLParams.Add("itemID", "a0ca6a90-a365-4782-871e-d44447bbc668$a0ca6a90-a365-4782-871e-d44447bbc668!1") + + w := httptest.NewRecorder() + + driveItemJson, err := json.Marshal(libregraph.DriveItem{}) + Expect(err).ToNot(HaveOccurred()) + + r := httptest.NewRequest(http.MethodPost, "/", bytes.NewBuffer(driveItemJson)). + WithContext( + context.WithValue(context.Background(), chi.RouteCtxKey, rCTX), + ) + + drivesDriveItemProvider. + EXPECT(). + GetShare(mock.Anything, mock.Anything). + Return(nil, nil). + Once() + + drivesDriveItemProvider. + EXPECT(). + GetShares(mock.Anything, mock.Anything, mock.Anything). Return(nil, errors.New("some error")). Once() @@ -587,7 +642,13 @@ var _ = Describe("DrivesDriveItemApi", func() { drivesDriveItemProvider. EXPECT(). - GetShareAndSiblings(mock.Anything, mock.Anything, mock.Anything). + GetShare(mock.Anything, mock.Anything). + Return(nil, nil). + Once() + + drivesDriveItemProvider. + EXPECT(). + GetShares(mock.Anything, mock.Anything, mock.Anything). Return(nil, nil). Once() @@ -622,7 +683,13 @@ var _ = Describe("DrivesDriveItemApi", func() { drivesDriveItemProvider. EXPECT(). - GetShareAndSiblings(mock.Anything, mock.Anything, mock.Anything). + GetShare(mock.Anything, mock.Anything). + Return(nil, nil). + Once() + + drivesDriveItemProvider. + EXPECT(). + GetShares(mock.Anything, mock.Anything, mock.Anything). Return([]*collaborationv1beta1.ReceivedShare{}, nil). Once() @@ -663,7 +730,13 @@ var _ = Describe("DrivesDriveItemApi", func() { drivesDriveItemProvider. EXPECT(). - GetShareAndSiblings(mock.Anything, mock.Anything, mock.Anything). + GetShare(mock.Anything, mock.Anything). + Return(nil, nil). + Once() + + drivesDriveItemProvider. + EXPECT(). + GetShares(mock.Anything, mock.Anything, mock.Anything). Return([]*collaborationv1beta1.ReceivedShare{share}, nil). Once()