Use generic item in SharePoint lists/pages (#4367)

#### 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
- [ ] 🐛 Bugfix
- [ ] 🗺️ Documentation
- [ ] 🤖 Supportability/Tests
- [ ] 💻 CI/Deployment
- [x] 🧹 Tech Debt/Cleanup

#### Issue(s)

* #4191

#### Test Plan

- [ ] 💪 Manual
- [x]  Unit test
- [x] 💚 E2E
This commit is contained in:
ashmrtn 2023-09-28 22:17:11 -07:00 committed by GitHub
parent a806ab59bf
commit 1c520db3bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 97 deletions

View File

@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"context" "context"
"io" "io"
"time"
"github.com/alcionai/clues" "github.com/alcionai/clues"
"github.com/microsoft/kiota-abstractions-go/serialization" "github.com/microsoft/kiota-abstractions-go/serialization"
@ -40,12 +39,7 @@ const (
Pages DataCategory = 2 Pages DataCategory = 2
) )
var ( var _ data.BackupCollection = &Collection{}
_ data.BackupCollection = &Collection{}
_ data.Item = &Item{}
_ data.ItemInfo = &Item{}
_ data.ItemModTime = &Item{}
)
// Collection is the SharePoint.List implementation of data.Collection. SharePoint.Libraries collections are supported // Collection is the SharePoint.List implementation of data.Collection. SharePoint.Libraries collections are supported
// by the oneDrive.Collection as the calls are identical for populating the Collection // by the oneDrive.Collection as the calls are identical for populating the Collection
@ -120,43 +114,6 @@ func (sc *Collection) Items(
return sc.data return sc.data
} }
type Item struct {
id string
data io.ReadCloser
info *details.SharePointInfo
modTime time.Time
// true if the item was marked by graph as deleted.
deleted bool
}
func NewItem(name string, d io.ReadCloser) *Item {
return &Item{
id: name,
data: d,
}
}
func (sd *Item) ID() string {
return sd.id
}
func (sd *Item) ToReader() io.ReadCloser {
return sd.data
}
func (sd Item) Deleted() bool {
return sd.deleted
}
func (sd *Item) Info() (details.ItemInfo, error) {
return details.ItemInfo{SharePoint: sd.info}, nil
}
func (sd *Item) ModTime() time.Time {
return sd.modTime
}
func (sc *Collection) finishPopulation( func (sc *Collection) finishPopulation(
ctx context.Context, ctx context.Context,
metrics support.CollectionMetrics, metrics support.CollectionMetrics,
@ -251,20 +208,13 @@ func (sc *Collection) retrieveLists(
size := int64(len(byteArray)) size := int64(len(byteArray))
if size > 0 { if size > 0 {
t := time.Now()
if t1 := lst.GetLastModifiedDateTime(); t1 != nil {
t = *t1
}
metrics.Bytes += size metrics.Bytes += size
metrics.Successes++ metrics.Successes++
sc.data <- &Item{ sc.data <- data.NewPrefetchedItem(
id: ptr.Val(lst.GetId()), io.NopCloser(bytes.NewReader(byteArray)),
data: io.NopCloser(bytes.NewReader(byteArray)), ptr.Val(lst.GetId()),
info: ListToSPInfo(lst, size), details.ItemInfo{SharePoint: ListToSPInfo(lst, size)})
modTime: t,
}
progress <- struct{}{} progress <- struct{}{}
} }
@ -322,12 +272,10 @@ func (sc *Collection) retrievePages(
if size > 0 { if size > 0 {
metrics.Bytes += size metrics.Bytes += size
metrics.Successes++ metrics.Successes++
sc.data <- &Item{ sc.data <- data.NewPrefetchedItem(
id: ptr.Val(pg.GetId()), io.NopCloser(bytes.NewReader(byteArray)),
data: io.NopCloser(bytes.NewReader(byteArray)), ptr.Val(pg.GetId()),
info: pageToSPInfo(pg, root, size), details.ItemInfo{SharePoint: pageToSPInfo(pg, root, size)})
modTime: ptr.OrNow(pg.GetLastModifiedDateTime()),
}
progress <- struct{}{} progress <- struct{}{}
} }

View File

@ -19,6 +19,7 @@ import (
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/internal/tester/tconfig" "github.com/alcionai/corso/src/internal/tester/tconfig"
"github.com/alcionai/corso/src/pkg/account" "github.com/alcionai/corso/src/pkg/account"
"github.com/alcionai/corso/src/pkg/backup/details"
"github.com/alcionai/corso/src/pkg/control" "github.com/alcionai/corso/src/pkg/control"
"github.com/alcionai/corso/src/pkg/control/testdata" "github.com/alcionai/corso/src/pkg/control/testdata"
"github.com/alcionai/corso/src/pkg/fault" "github.com/alcionai/corso/src/pkg/fault"
@ -58,21 +59,6 @@ func TestSharePointCollectionSuite(t *testing.T) {
}) })
} }
func (suite *SharePointCollectionSuite) TestCollection_Item_Read() {
t := suite.T()
m := []byte("test message")
name := "aFile"
sc := &Item{
id: name,
data: io.NopCloser(bytes.NewReader(m)),
}
readData, err := io.ReadAll(sc.ToReader())
require.NoError(t, err, clues.ToCore(err))
assert.Equal(t, name, sc.id)
assert.Equal(t, readData, m)
}
// TestListCollection tests basic functionality to create // TestListCollection tests basic functionality to create
// SharePoint collection and to use the data stream channel. // SharePoint collection and to use the data stream channel.
func (suite *SharePointCollectionSuite) TestCollection_Items() { func (suite *SharePointCollectionSuite) TestCollection_Items() {
@ -88,7 +74,7 @@ func (suite *SharePointCollectionSuite) TestCollection_Items() {
name, itemName string name, itemName string
scope selectors.SharePointScope scope selectors.SharePointScope
getDir func(t *testing.T) path.Path getDir func(t *testing.T) path.Path
getItem func(t *testing.T, itemName string) *Item getItem func(t *testing.T, itemName string) data.Item
}{ }{
{ {
name: "List", name: "List",
@ -106,7 +92,7 @@ func (suite *SharePointCollectionSuite) TestCollection_Items() {
return dir return dir
}, },
getItem: func(t *testing.T, name string) *Item { getItem: func(t *testing.T, name string) data.Item {
ow := kioser.NewJsonSerializationWriter() ow := kioser.NewJsonSerializationWriter()
listing := spMock.ListDefault(name) listing := spMock.ListDefault(name)
listing.SetDisplayName(&name) listing.SetDisplayName(&name)
@ -117,11 +103,10 @@ func (suite *SharePointCollectionSuite) TestCollection_Items() {
byteArray, err := ow.GetSerializedContent() byteArray, err := ow.GetSerializedContent()
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
data := &Item{ data := data.NewPrefetchedItem(
id: name, io.NopCloser(bytes.NewReader(byteArray)),
data: io.NopCloser(bytes.NewReader(byteArray)), name,
info: ListToSPInfo(listing, int64(len(byteArray))), details.ItemInfo{SharePoint: ListToSPInfo(listing, int64(len(byteArray)))})
}
return data return data
}, },
@ -142,16 +127,15 @@ func (suite *SharePointCollectionSuite) TestCollection_Items() {
return dir return dir
}, },
getItem: func(t *testing.T, itemName string) *Item { getItem: func(t *testing.T, itemName string) data.Item {
byteArray := spMock.Page(itemName) byteArray := spMock.Page(itemName)
page, err := betaAPI.CreatePageFromBytes(byteArray) page, err := betaAPI.CreatePageFromBytes(byteArray)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
data := &Item{ data := data.NewPrefetchedItem(
id: itemName, io.NopCloser(bytes.NewReader(byteArray)),
data: io.NopCloser(bytes.NewReader(byteArray)), itemName,
info: betaAPI.PageInfo(page, int64(len(byteArray))), details.ItemInfo{SharePoint: betaAPI.PageInfo(page, int64(len(byteArray)))})
}
return data return data
}, },
@ -210,11 +194,10 @@ func (suite *SharePointCollectionSuite) TestListCollection_Restore() {
byteArray, err := service.Serialize(listing) byteArray, err := service.Serialize(listing)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
listData := &Item{ listData := data.NewPrefetchedItem(
id: testName, io.NopCloser(bytes.NewReader(byteArray)),
data: io.NopCloser(bytes.NewReader(byteArray)), testName,
info: ListToSPInfo(listing, int64(len(byteArray))), details.ItemInfo{SharePoint: ListToSPInfo(listing, int64(len(byteArray)))})
}
destName := testdata.DefaultRestoreConfig("").Location destName := testdata.DefaultRestoreConfig("").Location

View File

@ -4,13 +4,14 @@ import (
"bytes" "bytes"
"io" "io"
"testing" "testing"
"time"
"github.com/alcionai/clues" "github.com/alcionai/clues"
"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/m365/collection/site" "github.com/alcionai/corso/src/internal/data"
"github.com/alcionai/corso/src/internal/m365/graph" "github.com/alcionai/corso/src/internal/m365/graph"
"github.com/alcionai/corso/src/internal/m365/service/sharepoint/api" "github.com/alcionai/corso/src/internal/m365/service/sharepoint/api"
spMock "github.com/alcionai/corso/src/internal/m365/service/sharepoint/mock" spMock "github.com/alcionai/corso/src/internal/m365/service/sharepoint/mock"
@ -108,9 +109,10 @@ func (suite *SharePointPageSuite) TestRestoreSinglePage() {
//nolint:lll //nolint:lll
byteArray := spMock.Page("Byte Test") byteArray := spMock.Page("Byte Test")
pageData := site.NewItem( pageData := data.NewUnindexedPrefetchedItem(
io.NopCloser(bytes.NewReader(byteArray)),
testName, testName,
io.NopCloser(bytes.NewReader(byteArray))) time.Now())
info, err := api.RestoreSitePage( info, err := api.RestoreSitePage(
ctx, ctx,