github.com/cs3org/reva/v2@v2.27.7/pkg/share/manager/cs3/cs3_test.go (about) 1 // Copyright 2018-2022 CERN 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // In applying this license, CERN does not waive the privileges and immunities 16 // granted to it by virtue of its status as an Intergovernmental Organization 17 // or submit itself to any jurisdiction. 18 19 package cs3_test 20 21 import ( 22 "context" 23 "encoding/json" 24 "net/url" 25 "path" 26 "sync" 27 28 groupv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1" 29 userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" 30 collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" 31 provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" 32 ctxpkg "github.com/cs3org/reva/v2/pkg/ctx" 33 "github.com/cs3org/reva/v2/pkg/errtypes" 34 sharespkg "github.com/cs3org/reva/v2/pkg/share" 35 "github.com/cs3org/reva/v2/pkg/share/manager/cs3" 36 indexerpkg "github.com/cs3org/reva/v2/pkg/storage/utils/indexer" 37 indexermocks "github.com/cs3org/reva/v2/pkg/storage/utils/indexer/mocks" 38 storagemocks "github.com/cs3org/reva/v2/pkg/storage/utils/metadata/mocks" 39 "github.com/stretchr/testify/mock" 40 "google.golang.org/protobuf/testing/protocmp" 41 "google.golang.org/protobuf/types/known/fieldmaskpb" 42 43 . "github.com/onsi/ginkgo/v2" 44 . "github.com/onsi/gomega" 45 ) 46 47 var _ = Describe("Manager", func() { 48 var ( 49 storage *storagemocks.Storage 50 indexer *indexermocks.Indexer 51 user *userpb.User 52 grantee *userpb.User 53 share *collaboration.Share 54 share2 *collaboration.Share 55 groupShare *collaboration.Share 56 grant *collaboration.ShareGrant 57 ctx context.Context 58 granteeCtx context.Context 59 60 granteeFn string 61 groupFn string 62 ) 63 64 BeforeEach(func() { 65 storage = &storagemocks.Storage{} 66 storage.On("Init", mock.Anything, mock.Anything).Return(nil) 67 storage.On("MakeDirIfNotExist", mock.Anything, mock.Anything).Return(nil) 68 storage.On("SimpleUpload", mock.Anything, mock.Anything, mock.Anything).Return(nil) 69 indexer = &indexermocks.Indexer{} 70 indexer.On("AddIndex", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) 71 indexer.On("Add", mock.Anything).Return([]indexerpkg.IdxAddResult{}, nil) 72 indexer.On("Delete", mock.Anything).Return(nil) 73 74 user = &userpb.User{ 75 Id: &userpb.UserId{ 76 Idp: "localhost:1111", 77 OpaqueId: "1", 78 }, 79 } 80 grantee = &userpb.User{ 81 Id: &userpb.UserId{ 82 Idp: "localhost:1111", 83 OpaqueId: "2", 84 }, 85 Groups: []string{"users"}, 86 } 87 granteeFn = url.QueryEscape("user:" + grantee.Id.Idp + ":" + grantee.Id.OpaqueId) 88 groupFn = url.QueryEscape("group:users") 89 90 grant = &collaboration.ShareGrant{ 91 Grantee: &provider.Grantee{ 92 Type: provider.GranteeType_GRANTEE_TYPE_USER, 93 Id: &provider.Grantee_UserId{UserId: grantee.GetId()}, 94 }, 95 Permissions: &collaboration.SharePermissions{ 96 Permissions: &provider.ResourcePermissions{ 97 GetPath: true, 98 InitiateFileDownload: true, 99 ListFileVersions: true, 100 ListContainer: true, 101 Stat: true, 102 }, 103 }, 104 } 105 share = &collaboration.Share{ 106 Id: &collaboration.ShareId{OpaqueId: "1"}, 107 ResourceId: &provider.ResourceId{OpaqueId: "abcd"}, 108 Owner: user.GetId(), 109 Grantee: &provider.Grantee{ 110 Type: provider.GranteeType_GRANTEE_TYPE_USER, 111 Id: &provider.Grantee_UserId{UserId: grantee.GetId()}, 112 }, 113 Permissions: &collaboration.SharePermissions{ 114 Permissions: &provider.ResourcePermissions{ 115 GetPath: true, 116 InitiateFileDownload: true, 117 ListFileVersions: true, 118 ListContainer: true, 119 Stat: true, 120 }, 121 }, 122 } 123 share2 = &collaboration.Share{ 124 Id: &collaboration.ShareId{OpaqueId: "2"}, 125 ResourceId: &provider.ResourceId{OpaqueId: "efgh"}, 126 Owner: user.GetId(), 127 Grantee: &provider.Grantee{ 128 Type: provider.GranteeType_GRANTEE_TYPE_USER, 129 Id: &provider.Grantee_UserId{UserId: grantee.GetId()}, 130 }, 131 Permissions: &collaboration.SharePermissions{ 132 Permissions: &provider.ResourcePermissions{ 133 GetPath: true, 134 InitiateFileDownload: true, 135 ListFileVersions: true, 136 ListContainer: true, 137 Stat: true, 138 }, 139 }, 140 } 141 groupShare = &collaboration.Share{ 142 Id: &collaboration.ShareId{OpaqueId: "3"}, 143 ResourceId: &provider.ResourceId{OpaqueId: "ijkl"}, 144 Owner: user.GetId(), 145 Grantee: &provider.Grantee{ 146 Type: provider.GranteeType_GRANTEE_TYPE_GROUP, 147 Id: &provider.Grantee_GroupId{GroupId: &groupv1beta1.GroupId{ 148 Idp: "localhost:1111", 149 OpaqueId: "users", 150 }}, 151 }, 152 Permissions: &collaboration.SharePermissions{ 153 Permissions: &provider.ResourcePermissions{ 154 GetPath: true, 155 InitiateFileDownload: true, 156 ListFileVersions: true, 157 ListContainer: true, 158 Stat: true, 159 }, 160 }, 161 } 162 ctx = ctxpkg.ContextSetUser(context.Background(), user) 163 granteeCtx = ctxpkg.ContextSetUser(context.Background(), grantee) 164 }) 165 166 Describe("New", func() { 167 JustBeforeEach(func() { 168 m, err := cs3.New(nil, storage, indexer) 169 Expect(err).ToNot(HaveOccurred()) 170 Expect(m).ToNot(BeNil()) 171 }) 172 173 It("does not initialize the storage yet", func() { 174 storage.AssertNotCalled(GinkgoT(), "Init", mock.Anything, mock.Anything) 175 }) 176 }) 177 178 Describe("Load", func() { 179 It("loads shares including state and mountpoint information", func() { 180 m, err := cs3.New(nil, storage, indexer) 181 Expect(err).ToNot(HaveOccurred()) 182 183 sharesChan := make(chan *collaboration.Share) 184 receivedChan := make(chan sharespkg.ReceivedShareWithUser) 185 186 wg := sync.WaitGroup{} 187 wg.Add(2) 188 go func() { 189 err := m.Load(ctx, sharesChan, receivedChan) 190 Expect(err).ToNot(HaveOccurred()) 191 wg.Done() 192 }() 193 go func() { 194 sharesChan <- share 195 close(sharesChan) 196 close(receivedChan) 197 wg.Done() 198 }() 199 wg.Wait() 200 Eventually(sharesChan).Should(BeClosed()) 201 Eventually(receivedChan).Should(BeClosed()) 202 203 expectedPath := path.Join("shares", share.Id.OpaqueId) 204 storage.AssertCalled(GinkgoT(), "SimpleUpload", mock.Anything, expectedPath, mock.Anything) 205 }) 206 }) 207 208 Context("with a manager instance and a share", func() { 209 var ( 210 m *cs3.Manager 211 sharedResource = &provider.ResourceInfo{ 212 Id: &provider.ResourceId{ 213 StorageId: "storageid", 214 OpaqueId: "opaqueid", 215 }, 216 } 217 ) 218 219 JustBeforeEach(func() { 220 var err error 221 m, err = cs3.New(nil, storage, indexer) 222 Expect(err).ToNot(HaveOccurred()) 223 data, err := json.Marshal(share) 224 Expect(err).ToNot(HaveOccurred()) 225 storage.On("SimpleDownload", mock.Anything, path.Join("shares", share.Id.OpaqueId)).Return(data, nil) 226 data, err = json.Marshal(share2) 227 Expect(err).ToNot(HaveOccurred()) 228 storage.On("SimpleDownload", mock.Anything, path.Join("shares", share2.Id.OpaqueId)).Return(data, nil) 229 data, err = json.Marshal(groupShare) 230 Expect(err).ToNot(HaveOccurred()) 231 storage.On("SimpleDownload", mock.Anything, path.Join("shares", groupShare.Id.OpaqueId)).Return(data, nil) 232 data, err = json.Marshal(&cs3.ReceivedShareMetadata{ 233 State: collaboration.ShareState_SHARE_STATE_PENDING, 234 MountPoint: &provider.Reference{ 235 ResourceId: &provider.ResourceId{ 236 StorageId: "storageid", 237 OpaqueId: "opaqueid", 238 }, 239 Path: "path", 240 }, 241 }) 242 Expect(err).ToNot(HaveOccurred()) 243 storage.On("SimpleDownload", mock.Anything, path.Join("metadata", share2.Id.OpaqueId, granteeFn)). 244 Return(data, nil) 245 storage.On("SimpleDownload", mock.Anything, mock.Anything).Return(nil, errtypes.NotFound("")) 246 }) 247 248 Describe("Share", func() { 249 var ( 250 share *collaboration.Share 251 ) 252 253 JustBeforeEach(func() { 254 var err error 255 share, err = m.Share(ctx, sharedResource, grant) 256 Expect(err).ToNot(HaveOccurred()) 257 }) 258 259 It("returns a share holding the share information", func() { 260 Expect(share).ToNot(BeNil()) 261 Expect(share.ResourceId).To(Equal(sharedResource.Id)) 262 Expect(share.Creator).To(Equal(user.Id)) 263 Expect(share.Grantee).To(Equal(grant.Grantee)) 264 Expect(share.Permissions).To(Equal(grant.Permissions)) 265 }) 266 267 It("stores the share in the storage using the id as the filename", func() { 268 expectedPath := path.Join("shares", share.Id.OpaqueId) 269 storage.AssertCalled(GinkgoT(), "SimpleUpload", mock.Anything, expectedPath, mock.Anything) 270 }) 271 272 It("indexes the share", func() { 273 indexer.AssertCalled(GinkgoT(), "Add", mock.AnythingOfType("*collaborationv1beta1.Share")) 274 }) 275 }) 276 277 Describe("Unshare", func() { 278 It("deletes the share", func() { 279 storage.On("Delete", mock.Anything, mock.Anything).Return(nil) 280 err := m.Unshare(ctx, &collaboration.ShareReference{Spec: &collaboration.ShareReference_Id{Id: share.Id}}) 281 Expect(err).ToNot(HaveOccurred()) 282 expectedPath := path.Join("shares", share.Id.OpaqueId) 283 storage.AssertCalled(GinkgoT(), "Delete", mock.Anything, expectedPath) 284 }) 285 286 It("removes the share from the index", func() { 287 storage.On("Delete", mock.Anything, mock.Anything).Return(nil) 288 err := m.Unshare(ctx, &collaboration.ShareReference{Spec: &collaboration.ShareReference_Id{Id: share.Id}}) 289 Expect(err).ToNot(HaveOccurred()) 290 indexer.AssertCalled(GinkgoT(), "Delete", mock.AnythingOfType("*collaborationv1beta1.Share")) 291 }) 292 293 It("still tries to delete the share from the index when the share couldn't be found", func() { 294 storage.On("Delete", mock.Anything, mock.Anything).Return(errtypes.NotFound("")) 295 err := m.Unshare(ctx, &collaboration.ShareReference{Spec: &collaboration.ShareReference_Id{Id: share.Id}}) 296 Expect(err).ToNot(HaveOccurred()) 297 indexer.AssertCalled(GinkgoT(), "Delete", mock.AnythingOfType("*collaborationv1beta1.Share")) 298 }) 299 }) 300 301 Describe("UpdateShare", func() { 302 It("updates the share", func() { 303 Expect(share.Permissions.Permissions.AddGrant).To(BeFalse()) 304 s, err := m.UpdateShare(ctx, 305 &collaboration.ShareReference{Spec: &collaboration.ShareReference_Id{Id: share.Id}}, 306 &collaboration.SharePermissions{Permissions: &provider.ResourcePermissions{AddGrant: true}}, nil, nil) 307 Expect(err).ToNot(HaveOccurred()) 308 Expect(s).ToNot(BeNil()) 309 Expect(s.Permissions.Permissions.AddGrant).To(BeTrue()) 310 }) 311 }) 312 Describe("GetShare", func() { 313 Context("when the share is a user share ", func() { 314 Context("when requesting the share by id", func() { 315 It("returns NotFound", func() { 316 returnedShare, err := m.GetShare(ctx, &collaboration.ShareReference{ 317 Spec: &collaboration.ShareReference_Id{Id: &collaboration.ShareId{OpaqueId: "1000"}}, 318 }) 319 Expect(err).To(HaveOccurred()) 320 Expect(returnedShare).To(BeNil()) 321 }) 322 323 It("returns the share", func() { 324 returnedShare, err := m.GetShare(ctx, &collaboration.ShareReference{ 325 Spec: &collaboration.ShareReference_Id{Id: &collaboration.ShareId{OpaqueId: "1"}}, 326 }) 327 Expect(err).ToNot(HaveOccurred()) 328 Expect(returnedShare).ToNot(BeNil()) 329 Expect(returnedShare.Id.OpaqueId).To(Equal(share.Id.OpaqueId)) 330 Expect(returnedShare.Owner).To(BeComparableTo(share.Owner, protocmp.Transform())) 331 Expect(returnedShare.Grantee).To(BeComparableTo(share.Grantee, protocmp.Transform())) 332 Expect(returnedShare.Permissions).To(BeComparableTo(share.Permissions, protocmp.Transform())) 333 }) 334 }) 335 336 Context("when requesting the share by key", func() { 337 It("returns NotFound", func() { 338 indexer.On("FindBy", mock.Anything, 339 indexerpkg.NewField("OwnerId", url.QueryEscape(share.Owner.Idp+":"+share.Owner.OpaqueId)), 340 ). 341 Return([]string{share.Id.OpaqueId, share2.Id.OpaqueId}, nil) 342 indexer.On("FindBy", mock.Anything, 343 indexerpkg.NewField("GranteeId", url.QueryEscape("user:"+grantee.Id.Idp+":"+grantee.Id.OpaqueId)), 344 ). 345 Return([]string{}, nil) 346 returnedShare, err := m.GetShare(ctx, &collaboration.ShareReference{ 347 Spec: &collaboration.ShareReference_Key{ 348 Key: &collaboration.ShareKey{ 349 Owner: share2.Owner, 350 ResourceId: share2.ResourceId, 351 Grantee: share2.Grantee, 352 }, 353 }, 354 }) 355 Expect(err).To(HaveOccurred()) 356 Expect(returnedShare).To(BeNil()) 357 }) 358 It("gets the share", func() { 359 indexer.On("FindBy", mock.Anything, 360 indexerpkg.NewField("OwnerId", url.QueryEscape(share.Owner.Idp+":"+share.Owner.OpaqueId)), 361 ). 362 Return([]string{share.Id.OpaqueId, share2.Id.OpaqueId}, nil) 363 indexer.On("FindBy", mock.Anything, 364 indexerpkg.NewField("GranteeId", url.QueryEscape("user:"+grantee.Id.Idp+":"+grantee.Id.OpaqueId)), 365 ). 366 Return([]string{share2.Id.OpaqueId}, nil) 367 returnedShare, err := m.GetShare(ctx, &collaboration.ShareReference{ 368 Spec: &collaboration.ShareReference_Key{ 369 Key: &collaboration.ShareKey{ 370 Owner: share2.Owner, 371 ResourceId: share2.ResourceId, 372 Grantee: share2.Grantee, 373 }, 374 }, 375 }) 376 Expect(err).ToNot(HaveOccurred()) 377 Expect(returnedShare).ToNot(BeNil()) 378 Expect(returnedShare.Id.OpaqueId).To(Equal(share2.Id.OpaqueId)) 379 Expect(returnedShare.Owner).To(BeComparableTo(share2.Owner, protocmp.Transform())) 380 Expect(returnedShare.Grantee).To(BeComparableTo(share2.Grantee, protocmp.Transform())) 381 Expect(returnedShare.Permissions).To(BeComparableTo(share2.Permissions, protocmp.Transform())) 382 }) 383 }) 384 }) 385 386 Context("when the share is a group share ", func() { 387 BeforeEach(func() { 388 share.Grantee = &provider.Grantee{ 389 Type: provider.GranteeType_GRANTEE_TYPE_GROUP, 390 Id: &provider.Grantee_GroupId{ 391 GroupId: &groupv1beta1.GroupId{OpaqueId: "1000"}, 392 }, 393 } 394 }) 395 396 It("returns a group share", func() { 397 returnedShare, err := m.GetShare(ctx, &collaboration.ShareReference{ 398 Spec: &collaboration.ShareReference_Id{Id: &collaboration.ShareId{OpaqueId: "1"}}, 399 }) 400 Expect(err).ToNot(HaveOccurred()) 401 Expect(returnedShare).ToNot(BeNil()) 402 Expect(returnedShare.Id.OpaqueId).To(Equal(share.Id.OpaqueId)) 403 Expect(returnedShare.Owner).To(BeComparableTo(share.Owner, protocmp.Transform())) 404 Expect(returnedShare.Grantee).To(BeComparableTo(share.Grantee, protocmp.Transform())) 405 Expect(returnedShare.Permissions).To(Equal(share.Permissions)) 406 }) 407 }) 408 }) 409 410 Describe("ListShares", func() { 411 JustBeforeEach(func() { 412 indexer.On("FindBy", mock.Anything, 413 mock.MatchedBy(func(input indexerpkg.Field) bool { 414 return input.Name == "OwnerId" 415 }), 416 mock.MatchedBy(func(input indexerpkg.Field) bool { 417 return input.Name == "CreatorId" 418 }), 419 ).Return([]string{share.Id.OpaqueId, share2.Id.OpaqueId}, nil) 420 indexer.On("FindBy", mock.Anything, 421 mock.MatchedBy(func(input indexerpkg.Field) bool { 422 return input.Name == "ResourceId" && input.Value == "!abcd" 423 }), 424 ).Return([]string{share.Id.OpaqueId}, nil) 425 }) 426 It("uses the index to get the owned shares", func() { 427 shares, err := m.ListShares(ctx, []*collaboration.Filter{}) 428 Expect(err).ToNot(HaveOccurred()) 429 Expect(len(shares)).To(Equal(2)) 430 Expect(shares[0].Id.OpaqueId).To(Equal("1")) 431 Expect(shares[1].Id.OpaqueId).To(Equal("2")) 432 }) 433 434 It("applies resource id filters", func() { 435 shares, err := m.ListShares(ctx, []*collaboration.Filter{ 436 { 437 Type: collaboration.Filter_TYPE_RESOURCE_ID, 438 Term: &collaboration.Filter_ResourceId{ 439 ResourceId: share.ResourceId, 440 }, 441 }, 442 }) 443 Expect(err).ToNot(HaveOccurred()) 444 Expect(len(shares)).To(Equal(1)) 445 Expect(shares[0].Id.OpaqueId).To(Equal("1")) 446 }) 447 }) 448 449 Describe("ListReceivedShares", func() { 450 Context("with a received user share", func() { 451 BeforeEach(func() { 452 indexer.On("FindBy", mock.Anything, 453 mock.MatchedBy(func(input indexerpkg.Field) bool { 454 return input.Name == "GranteeId" && input.Value == granteeFn 455 }), 456 ). 457 Return([]string{share2.Id.OpaqueId}, nil) 458 indexer.On("FindBy", mock.Anything, 459 mock.MatchedBy(func(input indexerpkg.Field) bool { 460 return input.Name == "GranteeId" 461 }), 462 ). 463 Return([]string{}, nil) 464 }) 465 466 It("list the user shares", func() { 467 rshares, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{}, nil) 468 Expect(err).ToNot(HaveOccurred()) 469 Expect(rshares).ToNot(BeNil()) 470 Expect(len(rshares)).To(Equal(1)) 471 472 rshare := rshares[0] 473 Expect(rshare.State).To(Equal(collaboration.ShareState_SHARE_STATE_PENDING)) 474 Expect(rshare.MountPoint.ResourceId.StorageId).To(Equal("storageid")) 475 Expect(rshare.MountPoint.ResourceId.OpaqueId).To(Equal("opaqueid")) 476 Expect(rshare.MountPoint.Path).To(Equal("path")) 477 }) 478 }) 479 480 Context("with a received group share", func() { 481 BeforeEach(func() { 482 indexer.On("FindBy", mock.Anything, 483 mock.MatchedBy(func(input indexerpkg.Field) bool { 484 return input.Name == "GranteeId" && input.Value == groupFn 485 }), 486 ). 487 Return([]string{share2.Id.OpaqueId}, nil) 488 indexer.On("FindBy", mock.Anything, 489 mock.MatchedBy(func(input indexerpkg.Field) bool { 490 return input.Name == "GranteeId" 491 }), 492 ). 493 Return([]string{}, nil) 494 }) 495 496 It("list the group share", func() { 497 rshares, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{}, nil) 498 Expect(err).ToNot(HaveOccurred()) 499 Expect(rshares).ToNot(BeNil()) 500 Expect(len(rshares)).To(Equal(1)) 501 502 rshare := rshares[0] 503 Expect(rshare.State).To(Equal(collaboration.ShareState_SHARE_STATE_PENDING)) 504 Expect(rshare.MountPoint.ResourceId.StorageId).To(Equal("storageid")) 505 Expect(rshare.MountPoint.ResourceId.OpaqueId).To(Equal("opaqueid")) 506 Expect(rshare.MountPoint.Path).To(Equal("path")) 507 }) 508 }) 509 510 Context("with a received user and group share", func() { 511 BeforeEach(func() { 512 indexer.On("FindBy", mock.Anything, 513 mock.MatchedBy(func(input indexerpkg.Field) bool { 514 return input.Name == "GranteeId" && input.Value == granteeFn 515 }), 516 ). 517 Return([]string{share.Id.OpaqueId}, nil) 518 519 indexer.On("FindBy", mock.Anything, 520 mock.MatchedBy(func(input indexerpkg.Field) bool { 521 return input.Name == "GranteeId" && input.Value == groupFn 522 }), 523 ). 524 Return([]string{groupShare.Id.OpaqueId}, nil) 525 526 indexer.On("FindBy", mock.Anything, 527 mock.MatchedBy(func(input indexerpkg.Field) bool { 528 return input.Name == "GranteeId" 529 }), 530 ). 531 Return([]string{}, nil) 532 }) 533 534 It("list the user and shares", func() { 535 rshares, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{}, nil) 536 Expect(err).ToNot(HaveOccurred()) 537 Expect(rshares).ToNot(BeNil()) 538 Expect(len(rshares)).To(Equal(2)) 539 }) 540 541 It("list only the user when user filter is given ", func() { 542 rshares, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{ 543 { 544 Type: collaboration.Filter_TYPE_GRANTEE_TYPE, 545 Term: &collaboration.Filter_GranteeType{ 546 GranteeType: provider.GranteeType_GRANTEE_TYPE_USER, 547 }, 548 }, 549 }, nil) 550 Expect(err).ToNot(HaveOccurred()) 551 Expect(rshares).ToNot(BeNil()) 552 Expect(len(rshares)).To(Equal(1)) 553 Expect(rshares[0].Share.Grantee.Type).To(Equal(provider.GranteeType_GRANTEE_TYPE_USER)) 554 }) 555 556 It("list only the group when group filter is given ", func() { 557 rshares, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{ 558 { 559 Type: collaboration.Filter_TYPE_GRANTEE_TYPE, 560 Term: &collaboration.Filter_GranteeType{ 561 GranteeType: provider.GranteeType_GRANTEE_TYPE_GROUP, 562 }, 563 }, 564 }, nil) 565 Expect(err).ToNot(HaveOccurred()) 566 Expect(rshares).ToNot(BeNil()) 567 Expect(len(rshares)).To(Equal(1)) 568 Expect(rshares[0].Share.Grantee.Type).To(Equal(provider.GranteeType_GRANTEE_TYPE_GROUP)) 569 }) 570 }) 571 }) 572 573 Describe("GetReceivedShare", func() { 574 Context("when the share is a user share ", func() { 575 Context("when requesting the share by id", func() { 576 It("returns NotFound", func() { 577 rshare, err := m.GetReceivedShare(granteeCtx, &collaboration.ShareReference{ 578 Spec: &collaboration.ShareReference_Id{Id: &collaboration.ShareId{OpaqueId: "1000"}}, 579 }) 580 Expect(err).To(HaveOccurred()) 581 Expect(rshare).To(BeNil()) 582 }) 583 584 It("returns the share", func() { 585 rshare, err := m.GetReceivedShare(granteeCtx, &collaboration.ShareReference{ 586 Spec: &collaboration.ShareReference_Id{Id: &collaboration.ShareId{OpaqueId: share2.Id.OpaqueId}}, 587 }) 588 Expect(err).ToNot(HaveOccurred()) 589 Expect(rshare).ToNot(BeNil()) 590 Expect(rshare.Share.Id.OpaqueId).To(Equal(share2.Id.OpaqueId)) 591 Expect(rshare.Share.Owner).To(BeComparableTo(share2.Owner, protocmp.Transform())) 592 Expect(rshare.Share.Grantee).To(BeComparableTo(share2.Grantee, protocmp.Transform())) 593 Expect(rshare.Share.Permissions).To(BeComparableTo(share2.Permissions, protocmp.Transform())) 594 Expect(rshare.State).To(Equal(collaboration.ShareState_SHARE_STATE_PENDING)) 595 Expect(rshare.MountPoint.ResourceId.StorageId).To(Equal("storageid")) 596 Expect(rshare.MountPoint.ResourceId.OpaqueId).To(Equal("opaqueid")) 597 Expect(rshare.MountPoint.Path).To(Equal("path")) 598 }) 599 }) 600 }) 601 }) 602 603 Describe("UpdateReceivedShare", func() { 604 It("updates the share", func() { 605 rs, err := m.GetReceivedShare(granteeCtx, &collaboration.ShareReference{Spec: &collaboration.ShareReference_Id{Id: share2.Id}}) 606 Expect(err).ToNot(HaveOccurred()) 607 608 Expect(rs.State).To(Equal(collaboration.ShareState_SHARE_STATE_PENDING)) 609 rs.State = collaboration.ShareState_SHARE_STATE_ACCEPTED 610 rs.MountPoint.Path = "newPath/" 611 612 rrs, err := m.UpdateReceivedShare(granteeCtx, 613 rs, &fieldmaskpb.FieldMask{Paths: []string{"state", "mount_point"}}, nil) 614 Expect(err).ToNot(HaveOccurred()) 615 Expect(rrs).ToNot(BeNil()) 616 Expect(rrs.Share.ResourceId).ToNot(BeNil()) 617 storage.AssertCalled(GinkgoT(), "SimpleUpload", mock.Anything, "metadata/2/"+granteeFn, mock.MatchedBy(func(data []byte) bool { 618 meta := cs3.ReceivedShareMetadata{} 619 err := json.Unmarshal(data, &meta) 620 Expect(err).ToNot(HaveOccurred()) 621 return meta.MountPoint != nil && meta.State == collaboration.ShareState_SHARE_STATE_ACCEPTED && meta.MountPoint.Path == "newPath/" 622 })) 623 }) 624 625 It("does not update fields that aren't part of the fieldmask", func() { 626 rs, err := m.GetReceivedShare(granteeCtx, &collaboration.ShareReference{Spec: &collaboration.ShareReference_Id{Id: share2.Id}}) 627 Expect(err).ToNot(HaveOccurred()) 628 629 Expect(rs.State).To(Equal(collaboration.ShareState_SHARE_STATE_PENDING)) 630 rs.State = collaboration.ShareState_SHARE_STATE_ACCEPTED 631 rs.MountPoint.Path = "newPath/" 632 633 rrs, err := m.UpdateReceivedShare(granteeCtx, 634 rs, &fieldmaskpb.FieldMask{Paths: []string{"mount_point"}}, nil) 635 Expect(err).ToNot(HaveOccurred()) 636 Expect(rrs).ToNot(BeNil()) 637 Expect(rrs.Share.ResourceId).ToNot(BeNil()) 638 storage.AssertCalled(GinkgoT(), "SimpleUpload", mock.Anything, "metadata/2/"+granteeFn, mock.MatchedBy(func(data []byte) bool { 639 meta := cs3.ReceivedShareMetadata{} 640 err := json.Unmarshal(data, &meta) 641 Expect(err).ToNot(HaveOccurred()) 642 return meta.MountPoint != nil && meta.State == collaboration.ShareState_SHARE_STATE_PENDING && meta.MountPoint.Path == "newPath/" 643 })) 644 }) 645 }) 646 }) 647 })