Dedupe collection items for OneDrive (#2118)

## Description

Under some circumstances items can be returned multiple times when iterating through the endpoint. This dedupes items within a single collection.

It does not address the following:
* item being removed from the collection during iteration
* item appearing multiple times in different collections

## Does this PR need a docs update or release note?

- [ ]  Yes, it's included
- [ ] 🕐 Yes, but in a later PR
- [x]  No 

## Type of change

- [ ] 🌻 Feature
- [x] 🐛 Bugfix
- [ ] 🗺️ Documentation
- [ ] 🤖 Test
- [ ] 💻 CI/Deployment
- [x] 🧹 Tech Debt/Cleanup

## Issue(s)

* #1954 

## Test Plan

- [ ] 💪 Manual
- [x]  Unit test
- [ ] 💚 E2E
This commit is contained in:
ashmrtn 2023-01-11 16:00:41 -08:00 committed by GitHub
parent 53c5828caa
commit 32b11cdca8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 11 deletions

View File

@ -49,7 +49,7 @@ type Collection struct {
// represents
folderPath path.Path
// M365 IDs of file items within this collection
driveItems []models.DriveItemable
driveItems map[string]models.DriveItemable
// M365 ID of the drive this collection was created from
driveID string
source driveSource
@ -79,6 +79,7 @@ func NewCollection(
) *Collection {
c := &Collection{
folderPath: folderPath,
driveItems: map[string]models.DriveItemable{},
driveID: driveID,
source: source,
service: service,
@ -101,7 +102,7 @@ func NewCollection(
// Adds an itemID to the collection
// This will make it eligible to be populated
func (oc *Collection) Add(item models.DriveItemable) {
oc.driveItems = append(oc.driveItems, item)
oc.driveItems[*item.GetId()] = item
}
// Items() returns the channel containing M365 Exchange objects

View File

@ -61,14 +61,16 @@ func (suite *CollectionUnitTestSuite) TestCollection() {
)
table := []struct {
name string
source driveSource
itemReader itemReaderFunc
infoFrom func(*testing.T, details.ItemInfo) (string, string)
name string
numInstances int
source driveSource
itemReader itemReaderFunc
infoFrom func(*testing.T, details.ItemInfo) (string, string)
}{
{
name: "oneDrive",
source: OneDriveSource,
name: "oneDrive, no duplicates",
numInstances: 1,
source: OneDriveSource,
itemReader: func(context.Context, models.DriveItemable) (details.ItemInfo, io.ReadCloser, error) {
return details.ItemInfo{OneDrive: &details.OneDriveInfo{ItemName: testItemName}},
io.NopCloser(bytes.NewReader(testItemData)),
@ -80,8 +82,37 @@ func (suite *CollectionUnitTestSuite) TestCollection() {
},
},
{
name: "sharePoint",
source: SharePointSource,
name: "oneDrive, duplicates",
numInstances: 3,
source: OneDriveSource,
itemReader: func(context.Context, models.DriveItemable) (details.ItemInfo, io.ReadCloser, error) {
return details.ItemInfo{OneDrive: &details.OneDriveInfo{ItemName: testItemName}},
io.NopCloser(bytes.NewReader(testItemData)),
nil
},
infoFrom: func(t *testing.T, dii details.ItemInfo) (string, string) {
require.NotNil(t, dii.OneDrive)
return dii.OneDrive.ItemName, dii.OneDrive.ParentPath
},
},
{
name: "sharePoint, no duplicates",
numInstances: 1,
source: SharePointSource,
itemReader: func(context.Context, models.DriveItemable) (details.ItemInfo, io.ReadCloser, error) {
return details.ItemInfo{SharePoint: &details.SharePointInfo{ItemName: testItemName}},
io.NopCloser(bytes.NewReader(testItemData)),
nil
},
infoFrom: func(t *testing.T, dii details.ItemInfo) (string, string) {
require.NotNil(t, dii.SharePoint)
return dii.SharePoint.ItemName, dii.SharePoint.ParentPath
},
},
{
name: "sharePoint, duplicates",
numInstances: 3,
source: SharePointSource,
itemReader: func(context.Context, models.DriveItemable) (details.ItemInfo, io.ReadCloser, error) {
return details.ItemInfo{SharePoint: &details.SharePointInfo{ItemName: testItemName}},
io.NopCloser(bytes.NewReader(testItemData)),
@ -119,7 +150,11 @@ func (suite *CollectionUnitTestSuite) TestCollection() {
// Set a item reader, add an item and validate we get the item back
mockItem := models.NewDriveItem()
mockItem.SetId(&testItemID)
coll.Add(mockItem)
for i := 0; i < test.numInstances; i++ {
coll.Add(mockItem)
}
coll.itemReader = test.itemReader
// Read items from the collection