enable restore path creation for sharepoint lists (#4922)
Enable restore path creation for sharepoint lists Changes previously approved in: https://github.com/alcionai/corso/pull/4855 #### Does this PR need a docs update or release note? - [x] ⛔ No #### Type of change <!--- Please check the type of change your PR introduces: ---> - [x] 🌻 Feature #### Issue(s) #4754 #### Test Plan <!-- How will this be tested prior to merging.--> - [x] 💪 Manual - [x] ⚡ Unit test - [x] 💚 E2E
This commit is contained in:
parent
d6e9a2112d
commit
98e8cac374
@ -142,7 +142,8 @@ func makeRestorePathsForEntry(
|
||||
// * OneDrive/SharePoint (needs drive information)
|
||||
switch true {
|
||||
case ent.Exchange != nil ||
|
||||
(ent.Groups != nil && ent.Groups.ItemType == details.GroupsChannelMessage):
|
||||
(ent.Groups != nil && ent.Groups.ItemType == details.GroupsChannelMessage) ||
|
||||
(ent.SharePoint != nil && ent.SharePoint.ItemType == details.SharePointList):
|
||||
// TODO(ashmrtn): Eventually make Events have it's own function to handle
|
||||
// setting the restore destination properly.
|
||||
res.RestorePath, err = basicLocationPath(repoRef, locRef)
|
||||
|
||||
@ -50,16 +50,19 @@ func (suite *RestorePathTransformerUnitSuite) TestGetPaths() {
|
||||
driveID = "some-drive-id"
|
||||
siteID = "some-site-id"
|
||||
extraItemName = "some-item"
|
||||
listName = "list1"
|
||||
SharePointRootItemPath = testdata.SharePointRootPath.MustAppend(extraItemName, true)
|
||||
SharePointListItemPath = testdata.SharePointListPath.MustAppend(listName, true)
|
||||
GroupsRootItemPath = testdata.GroupsRootPath.MustAppend(extraItemName, true)
|
||||
)
|
||||
|
||||
table := []struct {
|
||||
name string
|
||||
backupVersion int
|
||||
input []*details.Entry
|
||||
expectErr assert.ErrorAssertionFunc
|
||||
expected []expectPaths
|
||||
name string
|
||||
backupVersion int
|
||||
input []*details.Entry
|
||||
expectErr assert.ErrorAssertionFunc
|
||||
expected []expectPaths
|
||||
isSharepointList bool
|
||||
}{
|
||||
{
|
||||
name: "Groups List Errors v9",
|
||||
@ -157,13 +160,13 @@ func (suite *RestorePathTransformerUnitSuite) TestGetPaths() {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "SharePoint List Errors",
|
||||
name: "SharePoint List, item in root",
|
||||
// No version bump for the change so we always have to check for this.
|
||||
backupVersion: version.All8MigrateUserPNToID,
|
||||
input: []*details.Entry{
|
||||
{
|
||||
RepoRef: SharePointRootItemPath.RR.String(),
|
||||
LocationRef: SharePointRootItemPath.Loc.String(),
|
||||
RepoRef: SharePointListItemPath.RR.String(),
|
||||
LocationRef: SharePointListItemPath.Loc.String(),
|
||||
ItemInfo: details.ItemInfo{
|
||||
SharePoint: &details.SharePointInfo{
|
||||
ItemType: details.SharePointList,
|
||||
@ -171,7 +174,14 @@ func (suite *RestorePathTransformerUnitSuite) TestGetPaths() {
|
||||
},
|
||||
},
|
||||
},
|
||||
expectErr: assert.Error,
|
||||
expected: []expectPaths{
|
||||
{
|
||||
storage: SharePointListItemPath.RR.String(),
|
||||
restore: toRestore(SharePointListItemPath.RR),
|
||||
},
|
||||
},
|
||||
expectErr: assert.NoError,
|
||||
isSharepointList: true,
|
||||
},
|
||||
{
|
||||
name: "SharePoint Page Errors",
|
||||
@ -413,12 +423,23 @@ func (suite *RestorePathTransformerUnitSuite) TestGetPaths() {
|
||||
|
||||
for _, e := range test.expected {
|
||||
tmp := path.RestorePaths{}
|
||||
p, err := path.FromDataLayerPath(e.storage, true)
|
||||
var p path.Path
|
||||
var err error
|
||||
|
||||
if test.isSharepointList {
|
||||
p, err = path.PrefixOrPathFromDataLayerPath(e.storage, true)
|
||||
} else {
|
||||
p, err = path.FromDataLayerPath(e.storage, true)
|
||||
}
|
||||
require.NoError(t, err, "parsing expected storage path", clues.ToCore(err))
|
||||
|
||||
tmp.StoragePath = p
|
||||
|
||||
p, err = path.FromDataLayerPath(e.restore, false)
|
||||
if test.isSharepointList {
|
||||
p, err = path.PrefixOrPathFromDataLayerPath(e.restore, false)
|
||||
} else {
|
||||
p, err = path.FromDataLayerPath(e.restore, false)
|
||||
}
|
||||
require.NoError(t, err, "parsing expected restore path", clues.ToCore(err))
|
||||
|
||||
if e.isRestorePrefix {
|
||||
|
||||
57
src/pkg/backup/details/testdata/testdata.go
vendored
57
src/pkg/backup/details/testdata/testdata.go
vendored
@ -16,8 +16,16 @@ import (
|
||||
// mustParsePath takes a string representing a resource path and returns a path
|
||||
// instance. Panics if the path cannot be parsed. Useful for simple variable
|
||||
// assignments.
|
||||
func mustParsePath(ref string, isItem bool) path.Path {
|
||||
p, err := path.FromDataLayerPath(ref, isItem)
|
||||
func mustParsePath(ref string, isItem, isSharepointList bool) path.Path {
|
||||
var p path.Path
|
||||
var err error
|
||||
|
||||
if isSharepointList {
|
||||
p, err = path.PrefixOrPathFromDataLayerPath(ref, isItem)
|
||||
} else {
|
||||
p, err = path.FromDataLayerPath(ref, isItem)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -47,7 +55,7 @@ func locFromRepo(rr path.Path, isItem bool) *path.Builder {
|
||||
|
||||
if rr.Service() == path.GroupsService {
|
||||
loc = loc.PopFront().PopFront().PopFront()
|
||||
} else if rr.Service() == path.OneDriveService || rr.Category() == path.LibrariesCategory {
|
||||
} else if rr.Service() == path.OneDriveService || rr.Category() == path.LibrariesCategory || rr.Category() == path.ListsCategory {
|
||||
loc = loc.PopFront()
|
||||
}
|
||||
|
||||
@ -117,9 +125,12 @@ func (p repoRefAndLocRef) locationAsRepoRef() path.Path {
|
||||
return res
|
||||
}
|
||||
|
||||
func mustPathRep(ref string, isItem bool) repoRefAndLocRef {
|
||||
func mustPathRep(ref string, isItem, isSharepointList bool) repoRefAndLocRef {
|
||||
var rr path.Path
|
||||
var err error
|
||||
|
||||
res := repoRefAndLocRef{}
|
||||
tmp := mustParsePath(ref, isItem)
|
||||
tmp := mustParsePath(ref, isItem, isSharepointList)
|
||||
|
||||
// Now append stuff to the RepoRef elements so we have distinct LocationRef
|
||||
// and RepoRef elements to simulate using IDs in the path instead of display
|
||||
@ -133,12 +144,21 @@ func mustPathRep(ref string, isItem bool) repoRefAndLocRef {
|
||||
rrPB = rrPB.Append(tmp.Item() + fileSuffix)
|
||||
}
|
||||
|
||||
rr, err := rrPB.ToDataLayerPath(
|
||||
tmp.Tenant(),
|
||||
tmp.ProtectedResource(),
|
||||
tmp.Service(),
|
||||
tmp.Category(),
|
||||
isItem)
|
||||
if isSharepointList {
|
||||
rr, err = rrPB.ToDataLayerSharePointListPath(
|
||||
tmp.Tenant(),
|
||||
tmp.ProtectedResource(),
|
||||
tmp.Category(),
|
||||
isItem)
|
||||
} else {
|
||||
rr, err = rrPB.ToDataLayerPath(
|
||||
tmp.Tenant(),
|
||||
tmp.ProtectedResource(),
|
||||
tmp.Service(),
|
||||
tmp.Category(),
|
||||
isItem)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -166,7 +186,7 @@ var (
|
||||
Time3 = time.Date(2023, 9, 21, 10, 0, 0, 0, time.UTC)
|
||||
Time4 = time.Date(2023, 10, 21, 10, 0, 0, 0, time.UTC)
|
||||
|
||||
ExchangeEmailInboxPath = mustPathRep("tenant-id/exchange/user-id/email/Inbox", false)
|
||||
ExchangeEmailInboxPath = mustPathRep("tenant-id/exchange/user-id/email/Inbox", false, false)
|
||||
ExchangeEmailBasePath = ExchangeEmailInboxPath.MustAppend("subfolder", false)
|
||||
ExchangeEmailBasePath2 = ExchangeEmailInboxPath.MustAppend("othersubfolder/", false)
|
||||
ExchangeEmailBasePath3 = ExchangeEmailBasePath2.MustAppend("subsubfolder", false)
|
||||
@ -314,7 +334,7 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
ExchangeContactsRootPath = mustPathRep("tenant-id/exchange/user-id/contacts/contacts", false)
|
||||
ExchangeContactsRootPath = mustPathRep("tenant-id/exchange/user-id/contacts/contacts", false, false)
|
||||
ExchangeContactsBasePath = ExchangeContactsRootPath.MustAppend("contacts", false)
|
||||
ExchangeContactsBasePath2 = ExchangeContactsRootPath.MustAppend("morecontacts", false)
|
||||
ExchangeContactsItemPath1 = ExchangeContactsBasePath.MustAppend(ItemName1, true)
|
||||
@ -403,8 +423,8 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
ExchangeEventsBasePath = mustPathRep("tenant-id/exchange/user-id/events/holidays", false)
|
||||
ExchangeEventsBasePath2 = mustPathRep("tenant-id/exchange/user-id/events/moreholidays", false)
|
||||
ExchangeEventsBasePath = mustPathRep("tenant-id/exchange/user-id/events/holidays", false, false)
|
||||
ExchangeEventsBasePath2 = mustPathRep("tenant-id/exchange/user-id/events/moreholidays", false, false)
|
||||
ExchangeEventsItemPath1 = ExchangeEventsBasePath.MustAppend(ItemName1, true)
|
||||
ExchangeEventsItemPath2 = ExchangeEventsBasePath2.MustAppend(ItemName2, true)
|
||||
|
||||
@ -507,7 +527,7 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
OneDriveRootPath = mustPathRep("tenant-id/onedrive/user-id/files/drives/foo/root:", false)
|
||||
OneDriveRootPath = mustPathRep("tenant-id/onedrive/user-id/files/drives/foo/root:", false, false)
|
||||
OneDriveFolderPath = OneDriveRootPath.MustAppend("folder", false)
|
||||
OneDriveBasePath1 = OneDriveFolderPath.MustAppend("a", false)
|
||||
OneDriveBasePath2 = OneDriveFolderPath.MustAppend("b", false)
|
||||
@ -732,10 +752,11 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
GroupsRootPath = mustPathRep("tenant-id/groups/group-id/libraries/sites/site-id/drives/foo/root:", false)
|
||||
GroupsRootPath = mustPathRep("tenant-id/groups/group-id/libraries/sites/site-id/drives/foo/root:", false, false)
|
||||
|
||||
SharePointRootPath = mustPathRep("tenant-id/sharepoint/site-id/libraries/drives/foo/root:", false)
|
||||
SharePointRootPath = mustPathRep("tenant-id/sharepoint/site-id/libraries/drives/foo/root:", false, false)
|
||||
SharePointLibraryPath = SharePointRootPath.MustAppend("library", false)
|
||||
SharePointListPath = mustPathRep("tenant-id/sharepoint/site-id/lists", false, true)
|
||||
SharePointBasePath1 = SharePointLibraryPath.MustAppend("a", false)
|
||||
SharePointBasePath2 = SharePointLibraryPath.MustAppend("b", false)
|
||||
|
||||
|
||||
@ -355,6 +355,34 @@ func (pb Builder) ToDataLayerSharePointPath(
|
||||
return pb.ToDataLayerPath(tenant, site, SharePointService, category, isItem)
|
||||
}
|
||||
|
||||
func (pb Builder) ToDataLayerSharePointListPath(
|
||||
tenant, site string,
|
||||
category CategoryType,
|
||||
isItem bool,
|
||||
) (Path, error) {
|
||||
if err := ValidateServiceAndCategory(SharePointService, category); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := verifyInputValues(tenant, site); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prefixItems := []string{
|
||||
tenant,
|
||||
SharePointService.String(),
|
||||
site,
|
||||
category.String(),
|
||||
}
|
||||
|
||||
return &dataLayerResourcePath{
|
||||
Builder: *pb.withPrefix(prefixItems...),
|
||||
service: SharePointService,
|
||||
category: category,
|
||||
hasItem: isItem,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Stringers and PII Concealer Compliance
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user