skips backup of non-recoverable list templates (#4940)
Skips backup of non-recoverable list templates. #### 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] 🧹 Tech Debt/Cleanup #### 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
c6b9615c7d
commit
66664b69e5
@ -154,7 +154,7 @@ func CollectLists(
|
|||||||
var (
|
var (
|
||||||
el = errs.Local()
|
el = errs.Local()
|
||||||
spcs = make([]data.BackupCollection, 0)
|
spcs = make([]data.BackupCollection, 0)
|
||||||
acc = api.CallConfig{Select: idAnd("displayName")}
|
acc = api.CallConfig{Select: idAnd("list")}
|
||||||
)
|
)
|
||||||
|
|
||||||
lists, err := bh.GetItems(ctx, acc)
|
lists, err := bh.GetItems(ctx, acc)
|
||||||
@ -167,6 +167,10 @@ func CollectLists(
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if api.SkipListTemplates.HasKey(ptr.Val(list.GetList().GetTemplate())) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
dir, err := path.Build(
|
dir, err := path.Build(
|
||||||
tenantID,
|
tenantID,
|
||||||
bpc.ProtectedResource.ID(),
|
bpc.ProtectedResource.ID(),
|
||||||
|
|||||||
@ -350,15 +350,9 @@ func (sc *Collection) handleListItems(
|
|||||||
metrics.Bytes += size
|
metrics.Bytes += size
|
||||||
metrics.Successes++
|
metrics.Successes++
|
||||||
|
|
||||||
template := ""
|
|
||||||
if list != nil && list.GetList() != nil {
|
|
||||||
template = ptr.Val(list.GetList().GetTemplate())
|
|
||||||
}
|
|
||||||
|
|
||||||
rc := io.NopCloser(bytes.NewReader(entryBytes))
|
rc := io.NopCloser(bytes.NewReader(entryBytes))
|
||||||
itemInfo := details.ItemInfo{
|
itemInfo := details.ItemInfo{
|
||||||
SharePoint: info,
|
SharePoint: info,
|
||||||
NotRecoverable: template == api.WebTemplateExtensionsListTemplateName,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
item, err := data.NewPrefetchedItemWithInfo(rc, listID, itemInfo)
|
item, err := data.NewPrefetchedItemWithInfo(rc, listID, itemInfo)
|
||||||
|
|||||||
@ -7,12 +7,10 @@ import (
|
|||||||
|
|
||||||
"github.com/alcionai/clues"
|
"github.com/alcionai/clues"
|
||||||
kioser "github.com/microsoft/kiota-serialization-json-go"
|
kioser "github.com/microsoft/kiota-serialization-json-go"
|
||||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
"github.com/alcionai/corso/src/internal/common/ptr"
|
|
||||||
"github.com/alcionai/corso/src/internal/data"
|
"github.com/alcionai/corso/src/internal/data"
|
||||||
"github.com/alcionai/corso/src/internal/m365/collection/site/mock"
|
"github.com/alcionai/corso/src/internal/m365/collection/site/mock"
|
||||||
betaAPI "github.com/alcionai/corso/src/internal/m365/service/sharepoint/api"
|
betaAPI "github.com/alcionai/corso/src/internal/m365/service/sharepoint/api"
|
||||||
@ -76,7 +74,6 @@ func (suite *SharePointCollectionSuite) TestCollection_Items() {
|
|||||||
|
|
||||||
tables := []struct {
|
tables := []struct {
|
||||||
name, itemName string
|
name, itemName string
|
||||||
notRecoverable bool
|
|
||||||
scope selectors.SharePointScope
|
scope selectors.SharePointScope
|
||||||
getter getItemByIDer
|
getter getItemByIDer
|
||||||
getDir func(t *testing.T) path.Path
|
getDir func(t *testing.T) path.Path
|
||||||
@ -123,53 +120,6 @@ func (suite *SharePointCollectionSuite) TestCollection_Items() {
|
|||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "List with wte template",
|
|
||||||
itemName: "MockListing",
|
|
||||||
notRecoverable: true,
|
|
||||||
scope: sel.Lists(selectors.Any())[0],
|
|
||||||
getter: &mock.ListHandler{},
|
|
||||||
getDir: func(t *testing.T) path.Path {
|
|
||||||
dir, err := path.Build(
|
|
||||||
tenant,
|
|
||||||
user,
|
|
||||||
path.SharePointService,
|
|
||||||
path.ListsCategory,
|
|
||||||
false,
|
|
||||||
dirRoot)
|
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
|
||||||
|
|
||||||
return dir
|
|
||||||
},
|
|
||||||
getItem: func(t *testing.T, name string) data.Item {
|
|
||||||
ow := kioser.NewJsonSerializationWriter()
|
|
||||||
|
|
||||||
listInfo := models.NewListInfo()
|
|
||||||
listInfo.SetTemplate(ptr.To("webTemplateExtensionsList"))
|
|
||||||
|
|
||||||
listing := spMock.ListDefault(name)
|
|
||||||
listing.SetDisplayName(&name)
|
|
||||||
listing.SetList(listInfo)
|
|
||||||
|
|
||||||
err := ow.WriteObjectValue("", listing)
|
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
|
||||||
|
|
||||||
byteArray, err := ow.GetSerializedContent()
|
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
|
||||||
|
|
||||||
info := &details.SharePointInfo{
|
|
||||||
ItemName: name,
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := data.NewPrefetchedItemWithInfo(
|
|
||||||
io.NopCloser(bytes.NewReader(byteArray)),
|
|
||||||
name,
|
|
||||||
details.ItemInfo{SharePoint: info, NotRecoverable: true})
|
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
|
||||||
|
|
||||||
return data
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "Pages",
|
name: "Pages",
|
||||||
itemName: "MockPages",
|
itemName: "MockPages",
|
||||||
@ -236,7 +186,6 @@ func (suite *SharePointCollectionSuite) TestCollection_Items() {
|
|||||||
assert.NotNil(t, info)
|
assert.NotNil(t, info)
|
||||||
assert.NotNil(t, info.SharePoint)
|
assert.NotNil(t, info.SharePoint)
|
||||||
assert.Equal(t, test.itemName, info.SharePoint.ItemName)
|
assert.Equal(t, test.itemName, info.SharePoint.ItemName)
|
||||||
assert.Equal(t, test.notRecoverable, info.NotRecoverable)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -211,7 +211,7 @@ func RestoreListCollection(
|
|||||||
restoreContainerName,
|
restoreContainerName,
|
||||||
errs)
|
errs)
|
||||||
if err != nil &&
|
if err != nil &&
|
||||||
errors.Is(err, api.ErrCannotCreateWebTemplateExtension) {
|
errors.Is(err, api.ErrSkippableListTemplate) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -105,7 +105,7 @@ func (suite *SharePointRestoreSuite) TestListCollection_Restore_invalidListTempl
|
|||||||
|
|
||||||
_, err := restoreListItem(ctx, lrh, mockData, suite.siteID, destName, fault.New(true))
|
_, err := restoreListItem(ctx, lrh, mockData, suite.siteID, destName, fault.New(true))
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
assert.Contains(t, err.Error(), api.ErrCannotCreateWebTemplateExtension.Error())
|
assert.Contains(t, err.Error(), api.ErrSkippableListTemplate.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteList(
|
func deleteList(
|
||||||
|
|||||||
@ -907,34 +907,6 @@ var pathItemsTable = []struct {
|
|||||||
expectRepoRefs: []string{"abcde", "12345", "foo.meta"},
|
expectRepoRefs: []string{"abcde", "12345", "foo.meta"},
|
||||||
expectLocationRefs: []string{"locationref", "locationref2", "locationref.dirmeta"},
|
expectLocationRefs: []string{"locationref", "locationref2", "locationref.dirmeta"},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "multiple entries with not recoverables",
|
|
||||||
ents: []Entry{
|
|
||||||
{
|
|
||||||
RepoRef: "abcde",
|
|
||||||
LocationRef: "locationref",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
RepoRef: "foo.meta",
|
|
||||||
LocationRef: "locationref.dirmeta",
|
|
||||||
ItemRef: "itemref.meta",
|
|
||||||
ItemInfo: ItemInfo{
|
|
||||||
SharePoint: &SharePointInfo{ItemType: SharePointList},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
RepoRef: "invalid-template-list-file",
|
|
||||||
LocationRef: "locationref-invalid-template-list-file",
|
|
||||||
ItemRef: "itemref-template-list-file",
|
|
||||||
ItemInfo: ItemInfo{
|
|
||||||
SharePoint: &SharePointInfo{ItemType: SharePointList},
|
|
||||||
NotRecoverable: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
expectRepoRefs: []string{"abcde", "foo.meta"},
|
|
||||||
expectLocationRefs: []string{"locationref", "locationref.dirmeta"},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *DetailsUnitSuite) TestDetailsModel_Path() {
|
func (suite *DetailsUnitSuite) TestDetailsModel_Path() {
|
||||||
|
|||||||
@ -75,7 +75,6 @@ type ItemInfo struct {
|
|||||||
Groups *GroupsInfo `json:"groups,omitempty"`
|
Groups *GroupsInfo `json:"groups,omitempty"`
|
||||||
// Optional item extension data
|
// Optional item extension data
|
||||||
Extension *ExtensionData `json:"extension,omitempty"`
|
Extension *ExtensionData `json:"extension,omitempty"`
|
||||||
NotRecoverable bool `json:"notRecoverable,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// typedInfo should get embedded in each sesrvice type to track
|
// typedInfo should get embedded in each sesrvice type to track
|
||||||
|
|||||||
@ -68,8 +68,7 @@ func (dm DetailsModel) Paths() []string {
|
|||||||
|
|
||||||
for _, ent := range dm.Entries {
|
for _, ent := range dm.Entries {
|
||||||
if ent.Folder != nil ||
|
if ent.Folder != nil ||
|
||||||
ent.isMetaFile() ||
|
ent.isMetaFile() {
|
||||||
ent.NotRecoverable {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,8 +87,7 @@ func (dm DetailsModel) Items() entrySet {
|
|||||||
for i := 0; i < len(dm.Entries); i++ {
|
for i := 0; i < len(dm.Entries); i++ {
|
||||||
ent := dm.Entries[i]
|
ent := dm.Entries[i]
|
||||||
if ent.Folder != nil ||
|
if ent.Folder != nil ||
|
||||||
ent.isMetaFile() ||
|
ent.isMetaFile() {
|
||||||
ent.NotRecoverable {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import (
|
|||||||
"github.com/alcionai/corso/src/pkg/services/m365/api/graph"
|
"github.com/alcionai/corso/src/pkg/services/m365/api/graph"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrCannotCreateWebTemplateExtension = clues.New("unable to create webTemplateExtension type lists")
|
var ErrSkippableListTemplate = clues.New("unable to create lists with skippable templates")
|
||||||
|
|
||||||
const (
|
const (
|
||||||
AttachmentsColumnName = "Attachments"
|
AttachmentsColumnName = "Attachments"
|
||||||
@ -83,6 +83,10 @@ var readOnlyFieldNames = keys.Set{
|
|||||||
ModifiedColumnName: {},
|
ModifiedColumnName: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var SkipListTemplates = keys.Set{
|
||||||
|
WebTemplateExtensionsListTemplateName: {},
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// controller
|
// controller
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -258,8 +262,8 @@ func (c Lists) PostList(
|
|||||||
|
|
||||||
if newList != nil &&
|
if newList != nil &&
|
||||||
newList.GetList() != nil &&
|
newList.GetList() != nil &&
|
||||||
ptr.Val(newList.GetList().GetTemplate()) == WebTemplateExtensionsListTemplateName {
|
SkipListTemplates.HasKey(ptr.Val(newList.GetList().GetTemplate())) {
|
||||||
return nil, clues.StackWC(ctx, ErrCannotCreateWebTemplateExtension)
|
return nil, clues.StackWC(ctx, ErrSkippableListTemplate)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore to List base to M365 back store
|
// Restore to List base to M365 back store
|
||||||
|
|||||||
@ -788,7 +788,7 @@ func (suite *ListsAPIIntgSuite) TestLists_PostList_invalidTemplate() {
|
|||||||
|
|
||||||
_, err = acl.PostList(ctx, siteID, listName, oldListByteArray, fault.New(true))
|
_, err = acl.PostList(ctx, siteID, listName, oldListByteArray, fault.New(true))
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
assert.Equal(t, ErrCannotCreateWebTemplateExtension.Error(), err.Error())
|
assert.Equal(t, ErrSkippableListTemplate.Error(), err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *ListsAPIIntgSuite) TestLists_DeleteList() {
|
func (suite *ListsAPIIntgSuite) TestLists_DeleteList() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user