From dfceb79e0ad725041ff34384c53abd01c224ba59 Mon Sep 17 00:00:00 2001 From: ashmrtn Date: Mon, 27 Mar 2023 13:44:41 -0700 Subject: [PATCH] Update Exchange backup detail ParentPath when merging details (#2826) Exchange now holds a reference to the parent folder so be sure to update that if needed when merging backup details Calendar is the only thing that populates location ref right now so this alone doesn't completely solve the issue --- #### Does this PR need a docs update or release note? - [ ] :white_check_mark: Yes, it's included - [x] :clock1: Yes, but in a later PR - [ ] :no_entry: No #### Type of change - [ ] :sunflower: Feature - [x] :bug: Bugfix - [ ] :world_map: Documentation - [ ] :robot: Test - [ ] :computer: CI/Deployment - [ ] :broom: Tech Debt/Cleanup #### Issue(s) * #2819 #### Test Plan - [x] :muscle: Manual - [x] :zap: Unit test - [ ] :green_heart: E2E --- src/internal/operations/backup.go | 2 +- src/internal/operations/backup_test.go | 5 ++- src/pkg/backup/details/details.go | 23 +++++++++--- src/pkg/backup/details/details_test.go | 52 +++++++++++++++++++------- 4 files changed, 60 insertions(+), 22 deletions(-) diff --git a/src/internal/operations/backup.go b/src/internal/operations/backup.go index 40a74d089..c2111ed2e 100644 --- a/src/internal/operations/backup.go +++ b/src/internal/operations/backup.go @@ -577,7 +577,7 @@ func mergeDetails( // Fixup paths in the item. item := entry.ItemInfo - if err := details.UpdateItem(&item, newPath); err != nil { + if err := details.UpdateItem(&item, newPath, newLoc); err != nil { return clues.New("updating item details").WithClues(mctx) } diff --git a/src/internal/operations/backup_test.go b/src/internal/operations/backup_test.go index 127ac5483..b1cce45cb 100644 --- a/src/internal/operations/backup_test.go +++ b/src/internal/operations/backup_test.go @@ -290,8 +290,9 @@ func makeDetailsEntry( } res.Exchange = &details.ExchangeInfo{ - ItemType: details.ExchangeMail, - Size: int64(size), + ItemType: details.ExchangeMail, + Size: int64(size), + ParentPath: l.Folder(false), } case path.OneDriveService: diff --git a/src/pkg/backup/details/details.go b/src/pkg/backup/details/details.go index d71a5de72..1af96edcf 100644 --- a/src/pkg/backup/details/details.go +++ b/src/pkg/backup/details/details.go @@ -468,12 +468,14 @@ const ( FolderItem ItemType = 306 ) -func UpdateItem(item *ItemInfo, repoPath path.Path) error { +func UpdateItem(item *ItemInfo, repoPath, locPath path.Path) error { // Only OneDrive and SharePoint have information about parent folders // contained in them. - var updatePath func(path.Path) error + var updatePath func(repo path.Path, location path.Path) error switch item.infoType() { + case ExchangeContact, ExchangeEvent, ExchangeMail: + updatePath = item.Exchange.UpdateParentPath case SharePointLibrary: updatePath = item.SharePoint.UpdateParentPath case OneDriveItem: @@ -482,7 +484,7 @@ func UpdateItem(item *ItemInfo, repoPath path.Path) error { return nil } - return updatePath(repoPath) + return updatePath(repoPath, locPath) } // ItemInfo is a oneOf that contains service specific @@ -630,6 +632,17 @@ func (i ExchangeInfo) Values() []string { return []string{} } +func (i *ExchangeInfo) UpdateParentPath(_, locPath path.Path) error { + // Not all data types have this set yet. + if locPath == nil { + return nil + } + + i.ParentPath = locPath.Folder(true) + + return nil +} + // SharePointInfo describes a sharepoint item type SharePointInfo struct { Created time.Time `json:"created,omitempty"` @@ -664,7 +677,7 @@ func (i SharePointInfo) Values() []string { } } -func (i *SharePointInfo) UpdateParentPath(newPath path.Path) error { +func (i *SharePointInfo) UpdateParentPath(newPath, _ path.Path) error { newParent, err := path.GetDriveFolderPath(newPath) if err != nil { return clues.Wrap(err, "making sharePoint path").With("path", newPath) @@ -708,7 +721,7 @@ func (i OneDriveInfo) Values() []string { } } -func (i *OneDriveInfo) UpdateParentPath(newPath path.Path) error { +func (i *OneDriveInfo) UpdateParentPath(newPath, _ path.Path) error { newParent, err := path.GetDriveFolderPath(newPath) if err != nil { return clues.Wrap(err, "making oneDrive path").With("path", newPath) diff --git a/src/pkg/backup/details/details_test.go b/src/pkg/backup/details/details_test.go index 9de730f50..189f72a9f 100644 --- a/src/pkg/backup/details/details_test.go +++ b/src/pkg/backup/details/details_test.go @@ -860,6 +860,7 @@ func (suite *DetailsUnitSuite) TestUpdateItem() { driveID = "abcd" folder1 = "f1" folder2 = "f2" + folder3 = "f3" item = "hello.txt" ) @@ -879,6 +880,17 @@ func (suite *DetailsUnitSuite) TestUpdateItem() { item, }, ) + newExchangePath := makeItemPath( + suite.T(), + path.ExchangeService, + path.EmailCategory, + tenant, + resourceOwner, + []string{ + folder3, + item, + }, + ) badOneDrivePath := makeItemPath( suite.T(), path.OneDriveService, @@ -897,44 +909,56 @@ func (suite *DetailsUnitSuite) TestUpdateItem() { expectedItem ItemInfo }{ { - name: "ExchangeEventNoChange", + name: "ExchangeEvent", input: ItemInfo{ Exchange: &ExchangeInfo{ - ItemType: ExchangeEvent, + ItemType: ExchangeEvent, + ParentPath: folder1, }, }, + repoPath: newOneDrivePath, + locPath: newExchangePath, errCheck: assert.NoError, expectedItem: ItemInfo{ Exchange: &ExchangeInfo{ - ItemType: ExchangeEvent, + ItemType: ExchangeEvent, + ParentPath: folder3, }, }, }, { - name: "ExchangeContactNoChange", + name: "ExchangeContact", input: ItemInfo{ Exchange: &ExchangeInfo{ - ItemType: ExchangeContact, + ItemType: ExchangeContact, + ParentPath: folder1, }, }, + repoPath: newOneDrivePath, + locPath: newExchangePath, errCheck: assert.NoError, expectedItem: ItemInfo{ Exchange: &ExchangeInfo{ - ItemType: ExchangeContact, + ItemType: ExchangeContact, + ParentPath: folder3, }, }, }, { - name: "ExchangeMailNoChange", + name: "ExchangeMail", input: ItemInfo{ Exchange: &ExchangeInfo{ - ItemType: ExchangeMail, + ItemType: ExchangeMail, + ParentPath: folder1, }, }, + repoPath: newOneDrivePath, + locPath: newExchangePath, errCheck: assert.NoError, expectedItem: ItemInfo{ Exchange: &ExchangeInfo{ - ItemType: ExchangeMail, + ItemType: ExchangeMail, + ParentPath: folder3, }, }, }, @@ -947,7 +971,7 @@ func (suite *DetailsUnitSuite) TestUpdateItem() { }, }, repoPath: newOneDrivePath, - locPath: newOneDrivePath, + locPath: newExchangePath, errCheck: assert.NoError, expectedItem: ItemInfo{ OneDrive: &OneDriveInfo{ @@ -965,7 +989,7 @@ func (suite *DetailsUnitSuite) TestUpdateItem() { }, }, repoPath: newOneDrivePath, - locPath: newOneDrivePath, + locPath: newExchangePath, errCheck: assert.NoError, expectedItem: ItemInfo{ SharePoint: &SharePointInfo{ @@ -983,7 +1007,7 @@ func (suite *DetailsUnitSuite) TestUpdateItem() { }, }, repoPath: badOneDrivePath, - locPath: badOneDrivePath, + locPath: newExchangePath, errCheck: assert.Error, }, { @@ -995,7 +1019,7 @@ func (suite *DetailsUnitSuite) TestUpdateItem() { }, }, repoPath: badOneDrivePath, - locPath: badOneDrivePath, + locPath: newExchangePath, errCheck: assert.Error, }, } @@ -1005,7 +1029,7 @@ func (suite *DetailsUnitSuite) TestUpdateItem() { t := suite.T() item := test.input - err := UpdateItem(&item, test.repoPath) + err := UpdateItem(&item, test.repoPath, test.locPath) test.errCheck(t, err, clues.ToCore(err)) if err != nil {