unify api pager interfaces (#4088)

We have multitple different pager interfaces that all utilize the same (effective) set of functions.  This change reduces those to two different interfaces: a delta- and non-delta- pair of pagers.

---

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

- [x]  No

#### Type of change

- [x] 🧹 Tech Debt/Cleanup

#### Issue(s)

* #3989

#### Test Plan

- [x]  Unit test
- [x] 💚 E2E
This commit is contained in:
Keepers 2023-08-28 11:24:46 -06:00 committed by GitHub
parent d1f098b398
commit ee321863ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 440 additions and 520 deletions

View File

@ -1179,63 +1179,6 @@ func (suite *OneDriveCollectionsUnitSuite) TestDeserializeMetadata_ReadFailure()
require.False(t, canUsePreviousBackup) require.False(t, canUsePreviousBackup)
} }
type mockDeltaPageLinker struct {
link *string
delta *string
}
func (pl *mockDeltaPageLinker) GetOdataNextLink() *string {
return pl.link
}
func (pl *mockDeltaPageLinker) GetOdataDeltaLink() *string {
return pl.delta
}
type deltaPagerResult struct {
items []models.DriveItemable
nextLink *string
deltaLink *string
err error
}
type mockItemPager struct {
// DriveID -> set of return values for queries for that drive.
toReturn []deltaPagerResult
getIdx int
}
func (p *mockItemPager) GetPage(context.Context) (api.DeltaPageLinker, error) {
if len(p.toReturn) <= p.getIdx {
return nil, assert.AnError
}
idx := p.getIdx
p.getIdx++
return &mockDeltaPageLinker{
p.toReturn[idx].nextLink,
p.toReturn[idx].deltaLink,
}, p.toReturn[idx].err
}
func (p *mockItemPager) SetNext(string) {}
func (p *mockItemPager) Reset() {}
func (p *mockItemPager) ValuesIn(api.DeltaPageLinker) ([]models.DriveItemable, error) {
idx := p.getIdx
if idx > 0 {
// Return values lag by one since we increment in GetPage().
idx--
}
if len(p.toReturn) <= idx {
return nil, assert.AnError
}
return p.toReturn[idx].items, nil
}
func (suite *OneDriveCollectionsUnitSuite) TestGet() { func (suite *OneDriveCollectionsUnitSuite) TestGet() {
var ( var (
tenant = "a-tenant" tenant = "a-tenant"
@ -1283,7 +1226,7 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
table := []struct { table := []struct {
name string name string
drives []models.Driveable drives []models.Driveable
items map[string][]deltaPagerResult items map[string][]apiMock.PagerResult[models.DriveItemable]
canUsePreviousBackup bool canUsePreviousBackup bool
errCheck assert.ErrorAssertionFunc errCheck assert.ErrorAssertionFunc
prevFolderPaths map[string]map[string]string prevFolderPaths map[string]map[string]string
@ -1302,14 +1245,14 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "OneDrive_OneItemPage_DelFileOnly_NoFolders_NoErrors", name: "OneDrive_OneItemPage_DelFileOnly_NoFolders_NoErrors",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), // will be present, not needed driveRootItem("root"), // will be present, not needed
delItem("file", driveBasePath1, "root", true, false, false), delItem("file", driveBasePath1, "root", true, false, false),
}, },
deltaLink: &delta, DeltaLink: &delta,
}, },
}, },
}, },
@ -1334,14 +1277,14 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "OneDrive_OneItemPage_NoFolderDeltas_NoErrors", name: "OneDrive_OneItemPage_NoFolderDeltas_NoErrors",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("file", "file", driveBasePath1, "root", true, false, false), driveItem("file", "file", driveBasePath1, "root", true, false, false),
}, },
deltaLink: &delta, DeltaLink: &delta,
}, },
}, },
}, },
@ -1366,15 +1309,15 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "OneDrive_OneItemPage_NoErrors", name: "OneDrive_OneItemPage_NoErrors",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false), driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false), driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false),
}, },
deltaLink: &delta, DeltaLink: &delta,
}, },
}, },
}, },
@ -1403,16 +1346,16 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "OneDrive_OneItemPage_NoErrors_FileRenamedMultiple", name: "OneDrive_OneItemPage_NoErrors_FileRenamedMultiple",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false), driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false), driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false),
driveItem("file", "file2", driveBasePath1+"/folder", "folder", true, false, false), driveItem("file", "file2", driveBasePath1+"/folder", "folder", true, false, false),
}, },
deltaLink: &delta, DeltaLink: &delta,
}, },
}, },
}, },
@ -1441,16 +1384,16 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "OneDrive_OneItemPage_NoErrors_FileMovedMultiple", name: "OneDrive_OneItemPage_NoErrors_FileMovedMultiple",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false), driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false), driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false),
driveItem("file", "file2", driveBasePath1, "root", true, false, false), driveItem("file", "file2", driveBasePath1, "root", true, false, false),
}, },
deltaLink: &delta, DeltaLink: &delta,
}, },
}, },
}, },
@ -1481,15 +1424,15 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "OneDrive_OneItemPage_EmptyDelta_NoErrors", name: "OneDrive_OneItemPage_EmptyDelta_NoErrors",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false), driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false), driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false),
}, },
deltaLink: &empty, // probably will never happen with graph DeltaLink: &empty, // probably will never happen with graph
}, },
}, },
}, },
@ -1518,23 +1461,23 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "OneDrive_TwoItemPages_NoErrors", name: "OneDrive_TwoItemPages_NoErrors",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false), driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false), driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false),
}, },
nextLink: &next, NextLink: &next,
}, },
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false), driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file2", "file2", driveBasePath1+"/folder", "folder", true, false, false), driveItem("file2", "file2", driveBasePath1+"/folder", "folder", true, false, false),
}, },
deltaLink: &delta, DeltaLink: &delta,
}, },
}, },
}, },
@ -1568,25 +1511,25 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
drive1, drive1,
drive2, drive2,
}, },
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false), driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false), driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false),
}, },
deltaLink: &delta, DeltaLink: &delta,
}, },
}, },
driveID2: { driveID2: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root2"), driveRootItem("root2"),
driveItem("folder2", "folder", driveBasePath2, "root2", false, true, false), driveItem("folder2", "folder", driveBasePath2, "root2", false, true, false),
driveItem("file2", "file", driveBasePath2+"/folder", "folder2", true, false, false), driveItem("file2", "file", driveBasePath2+"/folder", "folder2", true, false, false),
}, },
deltaLink: &delta2, DeltaLink: &delta2,
}, },
}, },
}, },
@ -1630,25 +1573,25 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
drive1, drive1,
drive2, drive2,
}, },
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false), driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false), driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false),
}, },
deltaLink: &delta, DeltaLink: &delta,
}, },
}, },
driveID2: { driveID2: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("folder", "folder", driveBasePath2, "root", false, true, false), driveItem("folder", "folder", driveBasePath2, "root", false, true, false),
driveItem("file2", "file", driveBasePath2+"/folder", "folder", true, false, false), driveItem("file2", "file", driveBasePath2+"/folder", "folder", true, false, false),
}, },
deltaLink: &delta2, DeltaLink: &delta2,
}, },
}, },
}, },
@ -1689,10 +1632,10 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "OneDrive_OneItemPage_Errors", name: "OneDrive_OneItemPage_Errors",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
err: assert.AnError, Err: assert.AnError,
}, },
}, },
}, },
@ -1709,17 +1652,17 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "OneDrive_OneItemPage_DeltaError", name: "OneDrive_OneItemPage_DeltaError",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
err: getDeltaError(), Err: getDeltaError(),
}, },
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("file", "file", driveBasePath1, "root", true, false, false), driveItem("file", "file", driveBasePath1, "root", true, false, false),
}, },
deltaLink: &delta, DeltaLink: &delta,
}, },
}, },
}, },
@ -1744,25 +1687,25 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "OneDrive_TwoItemPage_DeltaError", name: "OneDrive_TwoItemPage_DeltaError",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
err: getDeltaError(), Err: getDeltaError(),
}, },
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("file", "file", driveBasePath1, "root", true, false, false), driveItem("file", "file", driveBasePath1, "root", true, false, false),
}, },
nextLink: &next, NextLink: &next,
}, },
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false), driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file2", "file", driveBasePath1+"/folder", "folder", true, false, false), driveItem("file2", "file", driveBasePath1+"/folder", "folder", true, false, false),
}, },
deltaLink: &delta, DeltaLink: &delta,
}, },
}, },
}, },
@ -1790,22 +1733,22 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "OneDrive_TwoItemPage_NoDeltaError", name: "OneDrive_TwoItemPage_NoDeltaError",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("file", "file", driveBasePath1, "root", true, false, false), driveItem("file", "file", driveBasePath1, "root", true, false, false),
}, },
nextLink: &next, NextLink: &next,
}, },
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false), driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file2", "file", driveBasePath1+"/folder", "folder", true, false, false), driveItem("file2", "file", driveBasePath1+"/folder", "folder", true, false, false),
}, },
deltaLink: &delta, DeltaLink: &delta,
}, },
}, },
}, },
@ -1837,18 +1780,18 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "OneDrive_OneItemPage_InvalidPrevDelta_DeleteNonExistentFolder", name: "OneDrive_OneItemPage_InvalidPrevDelta_DeleteNonExistentFolder",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
err: getDeltaError(), Err: getDeltaError(),
}, },
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("folder2", "folder2", driveBasePath1, "root", false, true, false), driveItem("folder2", "folder2", driveBasePath1, "root", false, true, false),
driveItem("file", "file", driveBasePath1+"/folder2", "folder2", true, false, false), driveItem("file", "file", driveBasePath1+"/folder2", "folder2", true, false, false),
}, },
deltaLink: &delta, DeltaLink: &delta,
}, },
}, },
}, },
@ -1884,18 +1827,18 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "OneDrive_OneItemPage_InvalidPrevDelta_AnotherFolderAtDeletedLocation", name: "OneDrive_OneItemPage_InvalidPrevDelta_AnotherFolderAtDeletedLocation",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
err: getDeltaError(), Err: getDeltaError(),
}, },
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("folder2", "folder", driveBasePath1, "root", false, true, false), driveItem("folder2", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", driveBasePath1+"/folder", "folder2", true, false, false), driveItem("file", "file", driveBasePath1+"/folder", "folder2", true, false, false),
}, },
deltaLink: &delta, DeltaLink: &delta,
}, },
}, },
}, },
@ -1934,25 +1877,25 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "OneDrive Two Item Pages with Malware", name: "OneDrive Two Item Pages with Malware",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false), driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false), driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false),
malwareItem("malware", "malware", driveBasePath1+"/folder", "folder", true, false, false), malwareItem("malware", "malware", driveBasePath1+"/folder", "folder", true, false, false),
}, },
nextLink: &next, NextLink: &next,
}, },
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false), driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file2", "file2", driveBasePath1+"/folder", "folder", true, false, false), driveItem("file2", "file2", driveBasePath1+"/folder", "folder", true, false, false),
malwareItem("malware2", "malware2", driveBasePath1+"/folder", "folder", true, false, false), malwareItem("malware2", "malware2", driveBasePath1+"/folder", "folder", true, false, false),
}, },
deltaLink: &delta, DeltaLink: &delta,
}, },
}, },
}, },
@ -1984,28 +1927,28 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "One Drive Delta Error Deleted Folder In New Results", name: "One Drive Delta Error Deleted Folder In New Results",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
err: getDeltaError(), Err: getDeltaError(),
}, },
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false), driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false), driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false),
driveItem("folder2", "folder2", driveBasePath1, "root", false, true, false), driveItem("folder2", "folder2", driveBasePath1, "root", false, true, false),
driveItem("file2", "file2", driveBasePath1+"/folder2", "folder2", true, false, false), driveItem("file2", "file2", driveBasePath1+"/folder2", "folder2", true, false, false),
}, },
nextLink: &next, NextLink: &next,
}, },
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
delItem("folder2", driveBasePath1, "root", false, true, false), delItem("folder2", driveBasePath1, "root", false, true, false),
delItem("file2", driveBasePath1, "root", true, false, false), delItem("file2", driveBasePath1, "root", true, false, false),
}, },
deltaLink: &delta2, DeltaLink: &delta2,
}, },
}, },
}, },
@ -2042,17 +1985,17 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "One Drive Delta Error Random Folder Delete", name: "One Drive Delta Error Random Folder Delete",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
err: getDeltaError(), Err: getDeltaError(),
}, },
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
delItem("folder", driveBasePath1, "root", false, true, false), delItem("folder", driveBasePath1, "root", false, true, false),
}, },
deltaLink: &delta, DeltaLink: &delta,
}, },
}, },
}, },
@ -2085,17 +2028,17 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "One Drive Delta Error Random Item Delete", name: "One Drive Delta Error Random Item Delete",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
err: getDeltaError(), Err: getDeltaError(),
}, },
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
delItem("file", driveBasePath1, "root", true, false, false), delItem("file", driveBasePath1, "root", true, false, false),
}, },
deltaLink: &delta, DeltaLink: &delta,
}, },
}, },
}, },
@ -2125,23 +2068,23 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "One Drive Folder Made And Deleted", name: "One Drive Folder Made And Deleted",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false), driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false), driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false),
}, },
nextLink: &next, NextLink: &next,
}, },
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
delItem("folder", driveBasePath1, "root", false, true, false), delItem("folder", driveBasePath1, "root", false, true, false),
delItem("file", driveBasePath1, "root", true, false, false), delItem("file", driveBasePath1, "root", true, false, false),
}, },
deltaLink: &delta2, DeltaLink: &delta2,
}, },
}, },
}, },
@ -2169,22 +2112,22 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "One Drive Item Made And Deleted", name: "One Drive Item Made And Deleted",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false), driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false), driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false),
}, },
nextLink: &next, NextLink: &next,
}, },
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
delItem("file", driveBasePath1, "root", true, false, false), delItem("file", driveBasePath1, "root", true, false, false),
}, },
deltaLink: &delta, DeltaLink: &delta,
}, },
}, },
}, },
@ -2215,14 +2158,14 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "One Drive Random Folder Delete", name: "One Drive Random Folder Delete",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
delItem("folder", driveBasePath1, "root", false, true, false), delItem("folder", driveBasePath1, "root", false, true, false),
}, },
deltaLink: &delta, DeltaLink: &delta,
}, },
}, },
}, },
@ -2250,14 +2193,14 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "One Drive Random Item Delete", name: "One Drive Random Item Delete",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), driveRootItem("root"),
delItem("file", driveBasePath1, "root", true, false, false), delItem("file", driveBasePath1, "root", true, false, false),
}, },
deltaLink: &delta, DeltaLink: &delta,
}, },
}, },
}, },
@ -2285,13 +2228,13 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{ {
name: "TwoPriorDrives_OneTombstoned", name: "TwoPriorDrives_OneTombstoned",
drives: []models.Driveable{drive1}, drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{ items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: { driveID1: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
driveRootItem("root"), // will be present driveRootItem("root"), // will be present
}, },
deltaLink: &delta, DeltaLink: &delta,
}, },
}, },
}, },
@ -2322,17 +2265,17 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
mockDrivePager := &apiMock.DrivePager{ mockDrivePager := &apiMock.Pager[models.Driveable]{
ToReturn: []apiMock.PagerResult{ ToReturn: []apiMock.PagerResult[models.Driveable]{
{Drives: test.drives}, {Values: test.drives},
}, },
} }
itemPagers := map[string]api.DriveItemDeltaEnumerator{} itemPagers := map[string]api.DeltaPager[models.DriveItemable]{}
for driveID := range test.items { for driveID := range test.items {
itemPagers[driveID] = &mockItemPager{ itemPagers[driveID] = &apiMock.DeltaPager[models.DriveItemable]{
toReturn: test.items[driveID], ToReturn: test.items[driveID],
} }
} }
@ -2583,7 +2526,7 @@ func (suite *OneDriveCollectionsUnitSuite) TestCollectItems() {
table := []struct { table := []struct {
name string name string
items []deltaPagerResult items []apiMock.PagerResult[models.DriveItemable]
deltaURL string deltaURL string
prevDeltaSuccess bool prevDeltaSuccess bool
prevDelta string prevDelta string
@ -2592,8 +2535,8 @@ func (suite *OneDriveCollectionsUnitSuite) TestCollectItems() {
{ {
name: "delta on first run", name: "delta on first run",
deltaURL: delta, deltaURL: delta,
items: []deltaPagerResult{ items: []apiMock.PagerResult[models.DriveItemable]{
{deltaLink: &delta}, {DeltaLink: &delta},
}, },
prevDeltaSuccess: true, prevDeltaSuccess: true,
prevDelta: prevDelta, prevDelta: prevDelta,
@ -2601,8 +2544,8 @@ func (suite *OneDriveCollectionsUnitSuite) TestCollectItems() {
{ {
name: "empty prev delta", name: "empty prev delta",
deltaURL: delta, deltaURL: delta,
items: []deltaPagerResult{ items: []apiMock.PagerResult[models.DriveItemable]{
{deltaLink: &delta}, {DeltaLink: &delta},
}, },
prevDeltaSuccess: false, prevDeltaSuccess: false,
prevDelta: "", prevDelta: "",
@ -2610,9 +2553,9 @@ func (suite *OneDriveCollectionsUnitSuite) TestCollectItems() {
{ {
name: "next then delta", name: "next then delta",
deltaURL: delta, deltaURL: delta,
items: []deltaPagerResult{ items: []apiMock.PagerResult[models.DriveItemable]{
{nextLink: &next}, {NextLink: &next},
{deltaLink: &delta}, {DeltaLink: &delta},
}, },
prevDeltaSuccess: true, prevDeltaSuccess: true,
prevDelta: prevDelta, prevDelta: prevDelta,
@ -2620,18 +2563,18 @@ func (suite *OneDriveCollectionsUnitSuite) TestCollectItems() {
{ {
name: "invalid prev delta", name: "invalid prev delta",
deltaURL: delta, deltaURL: delta,
items: []deltaPagerResult{ items: []apiMock.PagerResult[models.DriveItemable]{
{err: getDeltaError()}, {Err: getDeltaError()},
{deltaLink: &delta}, // works on retry {DeltaLink: &delta}, // works on retry
}, },
prevDelta: prevDelta, prevDelta: prevDelta,
prevDeltaSuccess: false, prevDeltaSuccess: false,
}, },
{ {
name: "fail a normal delta query", name: "fail a normal delta query",
items: []deltaPagerResult{ items: []apiMock.PagerResult[models.DriveItemable]{
{nextLink: &next}, {NextLink: &next},
{err: assert.AnError}, {Err: assert.AnError},
}, },
prevDelta: prevDelta, prevDelta: prevDelta,
prevDeltaSuccess: true, prevDeltaSuccess: true,
@ -2645,8 +2588,8 @@ func (suite *OneDriveCollectionsUnitSuite) TestCollectItems() {
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
itemPager := &mockItemPager{ itemPager := &apiMock.DeltaPager[models.DriveItemable]{
toReturn: test.items, ToReturn: test.items,
} }
collectorFunc := func( collectorFunc := func(
@ -2687,7 +2630,7 @@ func (suite *OneDriveCollectionsUnitSuite) TestAddURLCacheToDriveCollections() {
table := []struct { table := []struct {
name string name string
items []deltaPagerResult items []apiMock.PagerResult[any]
deltaURL string deltaURL string
prevDeltaSuccess bool prevDeltaSuccess bool
prevDelta string prevDelta string
@ -2704,8 +2647,8 @@ func (suite *OneDriveCollectionsUnitSuite) TestAddURLCacheToDriveCollections() {
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
itemPagers := map[string]api.DriveItemDeltaEnumerator{} itemPagers := map[string]api.DeltaPager[models.DriveItemable]{}
itemPagers[driveID] = &mockItemPager{} itemPagers[driveID] = &apiMock.DeltaPager[models.DriveItemable]{}
mbh := mock.DefaultOneDriveBH() mbh := mock.DefaultOneDriveBH()
mbh.ItemPagerV = itemPagers mbh.ItemPagerV = itemPagers

View File

@ -50,7 +50,7 @@ type BackupHandler interface {
// ServiceCat returns the service and category used by this implementation. // ServiceCat returns the service and category used by this implementation.
ServiceCat() (path.ServiceType, path.CategoryType) ServiceCat() (path.ServiceType, path.CategoryType)
NewItemPager(driveID, link string, fields []string) api.DriveItemDeltaEnumerator NewItemPager(driveID, link string, fields []string) api.DeltaPager[models.DriveItemable]
// FormatDisplayPath creates a human-readable string to represent the // FormatDisplayPath creates a human-readable string to represent the
// provided path. // provided path.
FormatDisplayPath(driveName string, parentPath *path.Builder) string FormatDisplayPath(driveName string, parentPath *path.Builder) string
@ -62,7 +62,7 @@ type BackupHandler interface {
} }
type NewDrivePagerer interface { type NewDrivePagerer interface {
NewDrivePager(resourceOwner string, fields []string) api.DrivePager NewDrivePager(resourceOwner string, fields []string) api.Pager[models.Driveable]
} }
type GetItemPermissioner interface { type GetItemPermissioner interface {

View File

@ -42,7 +42,7 @@ type itemCollector func(
// provided `collector` method // provided `collector` method
func collectItems( func collectItems(
ctx context.Context, ctx context.Context,
pager api.DriveItemDeltaEnumerator, pager api.DeltaPager[models.DriveItemable],
driveID, driveName string, driveID, driveName string,
collector itemCollector, collector itemCollector,
oldPaths map[string]string, oldPaths map[string]string,
@ -85,7 +85,7 @@ func collectItems(
invalidPrevDelta = true invalidPrevDelta = true
newPaths = map[string]string{} newPaths = map[string]string{}
pager.Reset() pager.Reset(ctx)
continue continue
} }

View File

@ -72,26 +72,26 @@ func (suite *ItemCollectorUnitSuite) TestDrives() {
resultDrives = append(resultDrives, d) resultDrives = append(resultDrives, d)
} }
tooManyRetries := make([]mock.PagerResult, 0, maxDrivesRetries+1) tooManyRetries := make([]mock.PagerResult[models.Driveable], 0, maxDrivesRetries+1)
for i := 0; i < maxDrivesRetries+1; i++ { for i := 0; i < maxDrivesRetries+1; i++ {
tooManyRetries = append(tooManyRetries, mock.PagerResult{ tooManyRetries = append(tooManyRetries, mock.PagerResult[models.Driveable]{
Err: context.DeadlineExceeded, Err: context.DeadlineExceeded,
}) })
} }
table := []struct { table := []struct {
name string name string
pagerResults []mock.PagerResult pagerResults []mock.PagerResult[models.Driveable]
retry bool retry bool
expectedErr assert.ErrorAssertionFunc expectedErr assert.ErrorAssertionFunc
expectedResults []models.Driveable expectedResults []models.Driveable
}{ }{
{ {
name: "AllOneResultNilNextLink", name: "AllOneResultNilNextLink",
pagerResults: []mock.PagerResult{ pagerResults: []mock.PagerResult[models.Driveable]{
{ {
Drives: resultDrives, Values: resultDrives,
NextLink: nil, NextLink: nil,
Err: nil, Err: nil,
}, },
@ -102,9 +102,9 @@ func (suite *ItemCollectorUnitSuite) TestDrives() {
}, },
{ {
name: "AllOneResultEmptyNextLink", name: "AllOneResultEmptyNextLink",
pagerResults: []mock.PagerResult{ pagerResults: []mock.PagerResult[models.Driveable]{
{ {
Drives: resultDrives, Values: resultDrives,
NextLink: &emptyLink, NextLink: &emptyLink,
Err: nil, Err: nil,
}, },
@ -115,14 +115,14 @@ func (suite *ItemCollectorUnitSuite) TestDrives() {
}, },
{ {
name: "SplitResultsNilNextLink", name: "SplitResultsNilNextLink",
pagerResults: []mock.PagerResult{ pagerResults: []mock.PagerResult[models.Driveable]{
{ {
Drives: resultDrives[:numDriveResults/2], Values: resultDrives[:numDriveResults/2],
NextLink: &link, NextLink: &link,
Err: nil, Err: nil,
}, },
{ {
Drives: resultDrives[numDriveResults/2:], Values: resultDrives[numDriveResults/2:],
NextLink: nil, NextLink: nil,
Err: nil, Err: nil,
}, },
@ -133,14 +133,14 @@ func (suite *ItemCollectorUnitSuite) TestDrives() {
}, },
{ {
name: "SplitResultsEmptyNextLink", name: "SplitResultsEmptyNextLink",
pagerResults: []mock.PagerResult{ pagerResults: []mock.PagerResult[models.Driveable]{
{ {
Drives: resultDrives[:numDriveResults/2], Values: resultDrives[:numDriveResults/2],
NextLink: &link, NextLink: &link,
Err: nil, Err: nil,
}, },
{ {
Drives: resultDrives[numDriveResults/2:], Values: resultDrives[numDriveResults/2:],
NextLink: &emptyLink, NextLink: &emptyLink,
Err: nil, Err: nil,
}, },
@ -151,14 +151,14 @@ func (suite *ItemCollectorUnitSuite) TestDrives() {
}, },
{ {
name: "NonRetryableError", name: "NonRetryableError",
pagerResults: []mock.PagerResult{ pagerResults: []mock.PagerResult[models.Driveable]{
{ {
Drives: resultDrives, Values: resultDrives,
NextLink: &link, NextLink: &link,
Err: nil, Err: nil,
}, },
{ {
Drives: nil, Values: nil,
NextLink: nil, NextLink: nil,
Err: assert.AnError, Err: assert.AnError,
}, },
@ -169,9 +169,9 @@ func (suite *ItemCollectorUnitSuite) TestDrives() {
}, },
{ {
name: "MySiteURLNotFound", name: "MySiteURLNotFound",
pagerResults: []mock.PagerResult{ pagerResults: []mock.PagerResult[models.Driveable]{
{ {
Drives: nil, Values: nil,
NextLink: nil, NextLink: nil,
Err: graph.Stack(ctx, mySiteURLNotFound), Err: graph.Stack(ctx, mySiteURLNotFound),
}, },
@ -182,9 +182,9 @@ func (suite *ItemCollectorUnitSuite) TestDrives() {
}, },
{ {
name: "MySiteNotFound", name: "MySiteNotFound",
pagerResults: []mock.PagerResult{ pagerResults: []mock.PagerResult[models.Driveable]{
{ {
Drives: nil, Values: nil,
NextLink: nil, NextLink: nil,
Err: graph.Stack(ctx, mySiteNotFound), Err: graph.Stack(ctx, mySiteNotFound),
}, },
@ -195,19 +195,19 @@ func (suite *ItemCollectorUnitSuite) TestDrives() {
}, },
{ {
name: "SplitResultsContextTimeoutWithRetries", name: "SplitResultsContextTimeoutWithRetries",
pagerResults: []mock.PagerResult{ pagerResults: []mock.PagerResult[models.Driveable]{
{ {
Drives: resultDrives[:numDriveResults/2], Values: resultDrives[:numDriveResults/2],
NextLink: &link, NextLink: &link,
Err: nil, Err: nil,
}, },
{ {
Drives: nil, Values: nil,
NextLink: nil, NextLink: nil,
Err: context.DeadlineExceeded, Err: context.DeadlineExceeded,
}, },
{ {
Drives: resultDrives[numDriveResults/2:], Values: resultDrives[numDriveResults/2:],
NextLink: &emptyLink, NextLink: &emptyLink,
Err: nil, Err: nil,
}, },
@ -218,19 +218,19 @@ func (suite *ItemCollectorUnitSuite) TestDrives() {
}, },
{ {
name: "SplitResultsContextTimeoutNoRetries", name: "SplitResultsContextTimeoutNoRetries",
pagerResults: []mock.PagerResult{ pagerResults: []mock.PagerResult[models.Driveable]{
{ {
Drives: resultDrives[:numDriveResults/2], Values: resultDrives[:numDriveResults/2],
NextLink: &link, NextLink: &link,
Err: nil, Err: nil,
}, },
{ {
Drives: nil, Values: nil,
NextLink: nil, NextLink: nil,
Err: context.DeadlineExceeded, Err: context.DeadlineExceeded,
}, },
{ {
Drives: resultDrives[numDriveResults/2:], Values: resultDrives[numDriveResults/2:],
NextLink: &emptyLink, NextLink: &emptyLink,
Err: nil, Err: nil,
}, },
@ -242,9 +242,9 @@ func (suite *ItemCollectorUnitSuite) TestDrives() {
{ {
name: "TooManyRetries", name: "TooManyRetries",
pagerResults: append( pagerResults: append(
[]mock.PagerResult{ []mock.PagerResult[models.Driveable]{
{ {
Drives: resultDrives[:numDriveResults/2], Values: resultDrives[:numDriveResults/2],
NextLink: &link, NextLink: &link,
Err: nil, Err: nil,
}, },
@ -263,7 +263,7 @@ func (suite *ItemCollectorUnitSuite) TestDrives() {
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
pager := &mock.DrivePager{ pager := &mock.Pager[models.Driveable]{
ToReturn: test.pagerResults, ToReturn: test.pagerResults,
} }

View File

@ -66,14 +66,14 @@ func (h itemBackupHandler) ServiceCat() (path.ServiceType, path.CategoryType) {
func (h itemBackupHandler) NewDrivePager( func (h itemBackupHandler) NewDrivePager(
resourceOwner string, fields []string, resourceOwner string, fields []string,
) api.DrivePager { ) api.Pager[models.Driveable] {
return h.ac.NewUserDrivePager(resourceOwner, fields) return h.ac.NewUserDrivePager(resourceOwner, fields)
} }
func (h itemBackupHandler) NewItemPager( func (h itemBackupHandler) NewItemPager(
driveID, link string, driveID, link string,
fields []string, fields []string,
) api.DriveItemDeltaEnumerator { ) api.DeltaPager[models.DriveItemable] {
return h.ac.NewDriveItemDeltaPager(driveID, link, fields) return h.ac.NewDriveItemDeltaPager(driveID, link, fields)
} }
@ -145,7 +145,7 @@ func (h itemRestoreHandler) PostDrive(
func (h itemRestoreHandler) NewDrivePager( func (h itemRestoreHandler) NewDrivePager(
resourceOwner string, fields []string, resourceOwner string, fields []string,
) api.DrivePager { ) api.Pager[models.Driveable] {
return h.ac.NewUserDrivePager(resourceOwner, fields) return h.ac.NewUserDrivePager(resourceOwner, fields)
} }

View File

@ -69,14 +69,14 @@ func (h libraryBackupHandler) ServiceCat() (path.ServiceType, path.CategoryType)
func (h libraryBackupHandler) NewDrivePager( func (h libraryBackupHandler) NewDrivePager(
resourceOwner string, resourceOwner string,
fields []string, fields []string,
) api.DrivePager { ) api.Pager[models.Driveable] {
return h.ac.NewSiteDrivePager(resourceOwner, fields) return h.ac.NewSiteDrivePager(resourceOwner, fields)
} }
func (h libraryBackupHandler) NewItemPager( func (h libraryBackupHandler) NewItemPager(
driveID, link string, driveID, link string,
fields []string, fields []string,
) api.DriveItemDeltaEnumerator { ) api.DeltaPager[models.DriveItemable] {
return h.ac.NewDriveItemDeltaPager(driveID, link, fields) return h.ac.NewDriveItemDeltaPager(driveID, link, fields)
} }
@ -184,7 +184,7 @@ func (h libraryRestoreHandler) PostDrive(
func (h libraryRestoreHandler) NewDrivePager( func (h libraryRestoreHandler) NewDrivePager(
resourceOwner string, resourceOwner string,
fields []string, fields []string,
) api.DrivePager { ) api.Pager[models.Driveable] {
return h.ac.Drives().NewSiteDrivePager(resourceOwner, fields) return h.ac.Drives().NewSiteDrivePager(resourceOwner, fields)
} }

View File

@ -408,7 +408,7 @@ func (suite *RestoreUnitSuite) TestRestoreCaches_AddDrive() {
type mockGDPARF struct { type mockGDPARF struct {
err error err error
rootFolder models.DriveItemable rootFolder models.DriveItemable
pager *apiMock.DrivePager pager *apiMock.Pager[models.Driveable]
} }
func (m *mockGDPARF) GetRootFolder( func (m *mockGDPARF) GetRootFolder(
@ -421,7 +421,7 @@ func (m *mockGDPARF) GetRootFolder(
func (m *mockGDPARF) NewDrivePager( func (m *mockGDPARF) NewDrivePager(
string, string,
[]string, []string,
) api.DrivePager { ) api.Pager[models.Driveable] {
return m.pager return m.pager
} }
@ -439,16 +439,16 @@ func (suite *RestoreUnitSuite) TestRestoreCaches_Populate() {
table := []struct { table := []struct {
name string name string
mock *apiMock.DrivePager mock *apiMock.Pager[models.Driveable]
expectErr require.ErrorAssertionFunc expectErr require.ErrorAssertionFunc
expectLen int expectLen int
checkValues bool checkValues bool
}{ }{
{ {
name: "no results", name: "no results",
mock: &apiMock.DrivePager{ mock: &apiMock.Pager[models.Driveable]{
ToReturn: []apiMock.PagerResult{ ToReturn: []apiMock.PagerResult[models.Driveable]{
{Drives: []models.Driveable{}}, {Values: []models.Driveable{}},
}, },
}, },
expectErr: require.NoError, expectErr: require.NoError,
@ -456,9 +456,9 @@ func (suite *RestoreUnitSuite) TestRestoreCaches_Populate() {
}, },
{ {
name: "one result", name: "one result",
mock: &apiMock.DrivePager{ mock: &apiMock.Pager[models.Driveable]{
ToReturn: []apiMock.PagerResult{ ToReturn: []apiMock.PagerResult[models.Driveable]{
{Drives: []models.Driveable{md}}, {Values: []models.Driveable{md}},
}, },
}, },
expectErr: require.NoError, expectErr: require.NoError,
@ -467,8 +467,8 @@ func (suite *RestoreUnitSuite) TestRestoreCaches_Populate() {
}, },
{ {
name: "error", name: "error",
mock: &apiMock.DrivePager{ mock: &apiMock.Pager[models.Driveable]{
ToReturn: []apiMock.PagerResult{ ToReturn: []apiMock.PagerResult[models.Driveable]{
{Err: assert.AnError}, {Err: assert.AnError},
}, },
}, },

View File

@ -47,7 +47,7 @@ type urlCache struct {
refreshMu sync.Mutex refreshMu sync.Mutex
deltaQueryCount int deltaQueryCount int
itemPager api.DriveItemDeltaEnumerator itemPager api.DeltaPager[models.DriveItemable]
errs *fault.Bus errs *fault.Bus
} }
@ -56,7 +56,7 @@ type urlCache struct {
func newURLCache( func newURLCache(
driveID, prevDelta string, driveID, prevDelta string,
refreshInterval time.Duration, refreshInterval time.Duration,
itemPager api.DriveItemDeltaEnumerator, itemPager api.DeltaPager[models.DriveItemable],
errs *fault.Bus, errs *fault.Bus,
) (*urlCache, error) { ) (*urlCache, error) {
err := validateCacheParams( err := validateCacheParams(
@ -83,7 +83,7 @@ func newURLCache(
func validateCacheParams( func validateCacheParams(
driveID string, driveID string,
refreshInterval time.Duration, refreshInterval time.Duration,
itemPager api.DriveItemDeltaEnumerator, itemPager api.DeltaPager[models.DriveItemable],
) error { ) error {
if len(driveID) == 0 { if len(driveID) == 0 {
return clues.New("drive id is empty") return clues.New("drive id is empty")
@ -182,7 +182,7 @@ func (uc *urlCache) deltaQuery(
) error { ) error {
logger.Ctx(ctx).Debug("starting delta query") logger.Ctx(ctx).Debug("starting delta query")
// Reset item pager to remove any previous state // Reset item pager to remove any previous state
uc.itemPager.Reset() uc.itemPager.Reset(ctx)
_, _, _, err := collectItems( _, _, _, err := collectItems(
ctx, ctx,

View File

@ -24,6 +24,7 @@ import (
"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"
"github.com/alcionai/corso/src/pkg/services/m365/api" "github.com/alcionai/corso/src/pkg/services/m365/api"
apiMock "github.com/alcionai/corso/src/pkg/services/m365/api/mock"
) )
type URLCacheIntegrationSuite struct { type URLCacheIntegrationSuite struct {
@ -209,20 +210,20 @@ func (suite *URLCacheUnitSuite) TestGetItemProperties() {
table := []struct { table := []struct {
name string name string
pagerResult map[string][]deltaPagerResult pagerResult map[string][]apiMock.PagerResult[models.DriveItemable]
expectedItemProps map[string]itemProps expectedItemProps map[string]itemProps
expectedErr require.ErrorAssertionFunc expectedErr require.ErrorAssertionFunc
cacheAssert func(*urlCache, time.Time) cacheAssert func(*urlCache, time.Time)
}{ }{
{ {
name: "single item in cache", name: "single item in cache",
pagerResult: map[string][]deltaPagerResult{ pagerResult: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID: { driveID: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
fileItem("1", "file1", "root", "root", "https://dummy1.com", false), fileItem("1", "file1", "root", "root", "https://dummy1.com", false),
}, },
deltaLink: &deltaString, DeltaLink: &deltaString,
}, },
}, },
}, },
@ -241,17 +242,17 @@ func (suite *URLCacheUnitSuite) TestGetItemProperties() {
}, },
{ {
name: "multiple items in cache", name: "multiple items in cache",
pagerResult: map[string][]deltaPagerResult{ pagerResult: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID: { driveID: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
fileItem("1", "file1", "root", "root", "https://dummy1.com", false), fileItem("1", "file1", "root", "root", "https://dummy1.com", false),
fileItem("2", "file2", "root", "root", "https://dummy2.com", false), fileItem("2", "file2", "root", "root", "https://dummy2.com", false),
fileItem("3", "file3", "root", "root", "https://dummy3.com", false), fileItem("3", "file3", "root", "root", "https://dummy3.com", false),
fileItem("4", "file4", "root", "root", "https://dummy4.com", false), fileItem("4", "file4", "root", "root", "https://dummy4.com", false),
fileItem("5", "file5", "root", "root", "https://dummy5.com", false), fileItem("5", "file5", "root", "root", "https://dummy5.com", false),
}, },
deltaLink: &deltaString, DeltaLink: &deltaString,
}, },
}, },
}, },
@ -286,17 +287,17 @@ func (suite *URLCacheUnitSuite) TestGetItemProperties() {
}, },
{ {
name: "duplicate items with potentially new urls", name: "duplicate items with potentially new urls",
pagerResult: map[string][]deltaPagerResult{ pagerResult: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID: { driveID: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
fileItem("1", "file1", "root", "root", "https://dummy1.com", false), fileItem("1", "file1", "root", "root", "https://dummy1.com", false),
fileItem("2", "file2", "root", "root", "https://dummy2.com", false), fileItem("2", "file2", "root", "root", "https://dummy2.com", false),
fileItem("3", "file3", "root", "root", "https://dummy3.com", false), fileItem("3", "file3", "root", "root", "https://dummy3.com", false),
fileItem("1", "file1", "root", "root", "https://test1.com", false), fileItem("1", "file1", "root", "root", "https://test1.com", false),
fileItem("2", "file2", "root", "root", "https://test2.com", false), fileItem("2", "file2", "root", "root", "https://test2.com", false),
}, },
deltaLink: &deltaString, DeltaLink: &deltaString,
}, },
}, },
}, },
@ -323,15 +324,15 @@ func (suite *URLCacheUnitSuite) TestGetItemProperties() {
}, },
{ {
name: "deleted items", name: "deleted items",
pagerResult: map[string][]deltaPagerResult{ pagerResult: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID: { driveID: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
fileItem("1", "file1", "root", "root", "https://dummy1.com", false), fileItem("1", "file1", "root", "root", "https://dummy1.com", false),
fileItem("2", "file2", "root", "root", "https://dummy2.com", false), fileItem("2", "file2", "root", "root", "https://dummy2.com", false),
fileItem("1", "file1", "root", "root", "https://dummy1.com", true), fileItem("1", "file1", "root", "root", "https://dummy1.com", true),
}, },
deltaLink: &deltaString, DeltaLink: &deltaString,
}, },
}, },
}, },
@ -354,13 +355,13 @@ func (suite *URLCacheUnitSuite) TestGetItemProperties() {
}, },
{ {
name: "item not found in cache", name: "item not found in cache",
pagerResult: map[string][]deltaPagerResult{ pagerResult: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID: { driveID: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
fileItem("1", "file1", "root", "root", "https://dummy1.com", false), fileItem("1", "file1", "root", "root", "https://dummy1.com", false),
}, },
deltaLink: &deltaString, DeltaLink: &deltaString,
}, },
}, },
}, },
@ -376,20 +377,20 @@ func (suite *URLCacheUnitSuite) TestGetItemProperties() {
}, },
{ {
name: "multi-page delta query error", name: "multi-page delta query error",
pagerResult: map[string][]deltaPagerResult{ pagerResult: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID: { driveID: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
fileItem("1", "file1", "root", "root", "https://dummy1.com", false), fileItem("1", "file1", "root", "root", "https://dummy1.com", false),
}, },
nextLink: &next, NextLink: &next,
}, },
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
fileItem("2", "file2", "root", "root", "https://dummy2.com", false), fileItem("2", "file2", "root", "root", "https://dummy2.com", false),
}, },
deltaLink: &deltaString, DeltaLink: &deltaString,
err: errors.New("delta query error"), Err: errors.New("delta query error"),
}, },
}, },
}, },
@ -407,14 +408,14 @@ func (suite *URLCacheUnitSuite) TestGetItemProperties() {
{ {
name: "folder item", name: "folder item",
pagerResult: map[string][]deltaPagerResult{ pagerResult: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID: { driveID: {
{ {
items: []models.DriveItemable{ Values: []models.DriveItemable{
fileItem("1", "file1", "root", "root", "https://dummy1.com", false), fileItem("1", "file1", "root", "root", "https://dummy1.com", false),
driveItem("2", "folder2", "root", "root", false, true, false), driveItem("2", "folder2", "root", "root", false, true, false),
}, },
deltaLink: &deltaString, DeltaLink: &deltaString,
}, },
}, },
}, },
@ -436,8 +437,8 @@ func (suite *URLCacheUnitSuite) TestGetItemProperties() {
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
itemPager := &mockItemPager{ itemPager := &apiMock.DeltaPager[models.DriveItemable]{
toReturn: test.pagerResult[driveID], ToReturn: test.pagerResult[driveID],
} }
cache, err := newURLCache( cache, err := newURLCache(
@ -487,7 +488,7 @@ func (suite *URLCacheUnitSuite) TestNeedsRefresh() {
driveID, driveID,
"", "",
refreshInterval, refreshInterval,
&mockItemPager{}, &apiMock.DeltaPager[models.DriveItemable]{},
fault.New(true)) fault.New(true))
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
@ -516,7 +517,7 @@ func (suite *URLCacheUnitSuite) TestNewURLCache() {
name string name string
driveID string driveID string
refreshInt time.Duration refreshInt time.Duration
itemPager api.DriveItemDeltaEnumerator itemPager api.DeltaPager[models.DriveItemable]
errors *fault.Bus errors *fault.Bus
expectedErr require.ErrorAssertionFunc expectedErr require.ErrorAssertionFunc
}{ }{
@ -524,7 +525,7 @@ func (suite *URLCacheUnitSuite) TestNewURLCache() {
name: "invalid driveID", name: "invalid driveID",
driveID: "", driveID: "",
refreshInt: 1 * time.Hour, refreshInt: 1 * time.Hour,
itemPager: &mockItemPager{}, itemPager: &apiMock.DeltaPager[models.DriveItemable]{},
errors: fault.New(true), errors: fault.New(true),
expectedErr: require.Error, expectedErr: require.Error,
}, },
@ -532,7 +533,7 @@ func (suite *URLCacheUnitSuite) TestNewURLCache() {
name: "invalid refresh interval", name: "invalid refresh interval",
driveID: "drive1", driveID: "drive1",
refreshInt: 100 * time.Millisecond, refreshInt: 100 * time.Millisecond,
itemPager: &mockItemPager{}, itemPager: &apiMock.DeltaPager[models.DriveItemable]{},
errors: fault.New(true), errors: fault.New(true),
expectedErr: require.Error, expectedErr: require.Error,
}, },
@ -548,7 +549,7 @@ func (suite *URLCacheUnitSuite) TestNewURLCache() {
name: "valid", name: "valid",
driveID: "drive1", driveID: "drive1",
refreshInt: 1 * time.Hour, refreshInt: 1 * time.Hour,
itemPager: &mockItemPager{}, itemPager: &apiMock.DeltaPager[models.DriveItemable]{},
errors: fault.New(true), errors: fault.New(true),
expectedErr: require.NoError, expectedErr: require.NoError,
}, },

View File

@ -34,9 +34,9 @@ type BackupHandler struct {
Service path.ServiceType Service path.ServiceType
Category path.CategoryType Category path.CategoryType
DrivePagerV api.DrivePager DrivePagerV api.Pager[models.Driveable]
// driveID -> itemPager // driveID -> itemPager
ItemPagerV map[string]api.DriveItemDeltaEnumerator ItemPagerV map[string]api.DeltaPager[models.DriveItemable]
LocationIDFn locationIDer LocationIDFn locationIDer
@ -103,11 +103,11 @@ func (h BackupHandler) ServiceCat() (path.ServiceType, path.CategoryType) {
return h.Service, h.Category return h.Service, h.Category
} }
func (h BackupHandler) NewDrivePager(string, []string) api.DrivePager { func (h BackupHandler) NewDrivePager(string, []string) api.Pager[models.Driveable] {
return h.DrivePagerV return h.DrivePagerV
} }
func (h BackupHandler) NewItemPager(driveID string, _ string, _ []string) api.DriveItemDeltaEnumerator { func (h BackupHandler) NewItemPager(driveID string, _ string, _ []string) api.DeltaPager[models.DriveItemable] {
return h.ItemPagerV[driveID] return h.ItemPagerV[driveID]
} }
@ -249,7 +249,7 @@ type RestoreHandler struct {
PostItemResp models.DriveItemable PostItemResp models.DriveItemable
PostItemErr error PostItemErr error
DrivePagerV api.DrivePager DrivePagerV api.Pager[models.Driveable]
PostDriveResp models.Driveable PostDriveResp models.Driveable
PostDriveErr error PostDriveErr error
@ -264,7 +264,7 @@ func (h RestoreHandler) PostDrive(
return h.PostDriveResp, h.PostDriveErr return h.PostDriveResp, h.PostDriveErr
} }
func (h RestoreHandler) NewDrivePager(string, []string) api.DrivePager { func (h RestoreHandler) NewDrivePager(string, []string) api.Pager[models.Driveable] {
return h.DrivePagerV return h.DrivePagerV
} }

View File

@ -82,13 +82,10 @@ func (c Contacts) DeleteContainer(
return nil return nil
} }
// prefer GetContainerByID where possible. func (c Contacts) GetContainerByID(
// use this only in cases where the models.ContactFolderable
// is required.
func (c Contacts) GetFolder(
ctx context.Context, ctx context.Context,
userID, containerID string, userID, containerID string,
) (models.ContactFolderable, error) { ) (graph.Container, error) {
config := &users.ItemContactFoldersContactFolderItemRequestBuilderGetRequestConfiguration{ config := &users.ItemContactFoldersContactFolderItemRequestBuilderGetRequestConfiguration{
QueryParameters: &users.ItemContactFoldersContactFolderItemRequestBuilderGetQueryParameters{ QueryParameters: &users.ItemContactFoldersContactFolderItemRequestBuilderGetQueryParameters{
Select: idAnd(displayName, parentFolderID), Select: idAnd(displayName, parentFolderID),
@ -109,14 +106,6 @@ func (c Contacts) GetFolder(
return resp, nil return resp, nil
} }
// interface-compliant wrapper of GetFolder
func (c Contacts) GetContainerByID(
ctx context.Context,
userID, containerID string,
) (graph.Container, error) {
return c.GetFolder(ctx, userID, containerID)
}
// GetContainerByName fetches a folder by name // GetContainerByName fetches a folder by name
func (c Contacts) GetContainerByName( func (c Contacts) GetContainerByName(
ctx context.Context, ctx context.Context,

View File

@ -191,7 +191,7 @@ func (c Contacts) GetItemIDsInContainer(
// item ID pager // item ID pager
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
var _ itemIDPager = &contactIDPager{} var _ DeltaPager[getIDAndAddtler] = &contactIDPager{}
type contactIDPager struct { type contactIDPager struct {
gs graph.Servicer gs graph.Servicer
@ -203,7 +203,7 @@ func (c Contacts) NewContactIDsPager(
ctx context.Context, ctx context.Context,
userID, containerID string, userID, containerID string,
immutableIDs bool, immutableIDs bool,
) itemIDPager { ) DeltaPager[getIDAndAddtler] {
config := &users.ItemContactFoldersItemContactsRequestBuilderGetRequestConfiguration{ config := &users.ItemContactFoldersItemContactsRequestBuilderGetRequestConfiguration{
QueryParameters: &users.ItemContactFoldersItemContactsRequestBuilderGetQueryParameters{ QueryParameters: &users.ItemContactFoldersItemContactsRequestBuilderGetQueryParameters{
Select: idAnd(parentFolderID), Select: idAnd(parentFolderID),
@ -223,7 +223,7 @@ func (c Contacts) NewContactIDsPager(
return &contactIDPager{c.Stable, builder, config} return &contactIDPager{c.Stable, builder, config}
} }
func (p *contactIDPager) getPage(ctx context.Context) (DeltaPageLinker, error) { func (p *contactIDPager) GetPage(ctx context.Context) (DeltaPageLinker, error) {
resp, err := p.builder.Get(ctx, p.options) resp, err := p.builder.Get(ctx, p.options)
if err != nil { if err != nil {
return nil, graph.Stack(ctx, err) return nil, graph.Stack(ctx, err)
@ -232,14 +232,14 @@ func (p *contactIDPager) getPage(ctx context.Context) (DeltaPageLinker, error) {
return EmptyDeltaLinker[models.Contactable]{PageLinkValuer: resp}, nil return EmptyDeltaLinker[models.Contactable]{PageLinkValuer: resp}, nil
} }
func (p *contactIDPager) setNext(nextLink string) { func (p *contactIDPager) SetNext(nextLink string) {
p.builder = users.NewItemContactFoldersItemContactsRequestBuilder(nextLink, p.gs.Adapter()) p.builder = users.NewItemContactFoldersItemContactsRequestBuilder(nextLink, p.gs.Adapter())
} }
// non delta pagers don't need reset // non delta pagers don't need reset
func (p *contactIDPager) reset(context.Context) {} func (p *contactIDPager) Reset(context.Context) {}
func (p *contactIDPager) valuesIn(pl PageLinker) ([]getIDAndAddtler, error) { func (p *contactIDPager) ValuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
return toValues[models.Contactable](pl) return toValues[models.Contactable](pl)
} }
@ -247,7 +247,7 @@ func (p *contactIDPager) valuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
// delta item ID pager // delta item ID pager
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
var _ itemIDPager = &contactDeltaIDPager{} var _ DeltaPager[getIDAndAddtler] = &contactDeltaIDPager{}
type contactDeltaIDPager struct { type contactDeltaIDPager struct {
gs graph.Servicer gs graph.Servicer
@ -271,7 +271,7 @@ func (c Contacts) NewContactDeltaIDsPager(
ctx context.Context, ctx context.Context,
userID, containerID, oldDelta string, userID, containerID, oldDelta string,
immutableIDs bool, immutableIDs bool,
) itemIDPager { ) DeltaPager[getIDAndAddtler] {
options := &users.ItemContactFoldersItemContactsDeltaRequestBuilderGetRequestConfiguration{ options := &users.ItemContactFoldersItemContactsDeltaRequestBuilderGetRequestConfiguration{
QueryParameters: &users.ItemContactFoldersItemContactsDeltaRequestBuilderGetQueryParameters{ QueryParameters: &users.ItemContactFoldersItemContactsDeltaRequestBuilderGetQueryParameters{
Select: idAnd(parentFolderID), Select: idAnd(parentFolderID),
@ -290,7 +290,7 @@ func (c Contacts) NewContactDeltaIDsPager(
return &contactDeltaIDPager{c.Stable, userID, containerID, builder, options} return &contactDeltaIDPager{c.Stable, userID, containerID, builder, options}
} }
func (p *contactDeltaIDPager) getPage(ctx context.Context) (DeltaPageLinker, error) { func (p *contactDeltaIDPager) GetPage(ctx context.Context) (DeltaPageLinker, error) {
resp, err := p.builder.Get(ctx, p.options) resp, err := p.builder.Get(ctx, p.options)
if err != nil { if err != nil {
return nil, graph.Stack(ctx, err) return nil, graph.Stack(ctx, err)
@ -299,15 +299,15 @@ func (p *contactDeltaIDPager) getPage(ctx context.Context) (DeltaPageLinker, err
return resp, nil return resp, nil
} }
func (p *contactDeltaIDPager) setNext(nextLink string) { func (p *contactDeltaIDPager) SetNext(nextLink string) {
p.builder = users.NewItemContactFoldersItemContactsDeltaRequestBuilder(nextLink, p.gs.Adapter()) p.builder = users.NewItemContactFoldersItemContactsDeltaRequestBuilder(nextLink, p.gs.Adapter())
} }
func (p *contactDeltaIDPager) reset(ctx context.Context) { func (p *contactDeltaIDPager) Reset(ctx context.Context) {
p.builder = getContactDeltaBuilder(ctx, p.gs, p.userID, p.containerID, p.options) p.builder = getContactDeltaBuilder(ctx, p.gs, p.userID, p.containerID, p.options)
} }
func (p *contactDeltaIDPager) valuesIn(pl PageLinker) ([]getIDAndAddtler, error) { func (p *contactDeltaIDPager) ValuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
return toValues[models.Contactable](pl) return toValues[models.Contactable](pl)
} }

View File

@ -120,20 +120,11 @@ func (c Drives) GetItemIDsInContainer(
return m, nil return m, nil
} }
// ---------------------------------------------------------------------------
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// delta item pager // delta item pager
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
type DriveItemDeltaEnumerator interface { var _ DeltaPager[models.DriveItemable] = &DriveItemDeltaPageCtrl{}
GetPage(context.Context) (DeltaPageLinker, error)
SetNext(nextLink string)
Reset()
ValuesIn(DeltaPageLinker) ([]models.DriveItemable, error)
}
var _ DriveItemDeltaEnumerator = &DriveItemDeltaPageCtrl{}
type DriveItemDeltaPageCtrl struct { type DriveItemDeltaPageCtrl struct {
gs graph.Servicer gs graph.Servicer
@ -198,7 +189,7 @@ func (p *DriveItemDeltaPageCtrl) SetNext(link string) {
p.builder = drives.NewItemItemsItemDeltaRequestBuilder(link, p.gs.Adapter()) p.builder = drives.NewItemItemsItemDeltaRequestBuilder(link, p.gs.Adapter())
} }
func (p *DriveItemDeltaPageCtrl) Reset() { func (p *DriveItemDeltaPageCtrl) Reset(context.Context) {
p.builder = p.gs.Client(). p.builder = p.gs.Client().
Drives(). Drives().
ByDriveId(p.driveID). ByDriveId(p.driveID).
@ -207,7 +198,7 @@ func (p *DriveItemDeltaPageCtrl) Reset() {
Delta() Delta()
} }
func (p *DriveItemDeltaPageCtrl) ValuesIn(l DeltaPageLinker) ([]models.DriveItemable, error) { func (p *DriveItemDeltaPageCtrl) ValuesIn(l PageLinker) ([]models.DriveItemable, error) {
return getValues[models.DriveItemable](l) return getValues[models.DriveItemable](l)
} }
@ -215,7 +206,7 @@ func (p *DriveItemDeltaPageCtrl) ValuesIn(l DeltaPageLinker) ([]models.DriveItem
// user's drives pager // user's drives pager
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
var _ DrivePager = &userDrivePager{} var _ Pager[models.Driveable] = &userDrivePager{}
type userDrivePager struct { type userDrivePager struct {
userID string userID string
@ -305,7 +296,7 @@ func (p *userDrivePager) ValuesIn(l PageLinker) ([]models.Driveable, error) {
// site's libraries pager // site's libraries pager
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
var _ DrivePager = &siteDrivePager{} var _ Pager[models.Driveable] = &siteDrivePager{}
type siteDrivePager struct { type siteDrivePager struct {
gs graph.Servicer gs graph.Servicer
@ -367,17 +358,10 @@ func (p *siteDrivePager) ValuesIn(l PageLinker) ([]models.Driveable, error) {
// drive pager // drive pager
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// DrivePager pages through different types of drive owners
type DrivePager interface {
GetPage(context.Context) (PageLinker, error)
SetNext(nextLink string)
ValuesIn(PageLinker) ([]models.Driveable, error)
}
// GetAllDrives fetches all drives for the given pager // GetAllDrives fetches all drives for the given pager
func GetAllDrives( func GetAllDrives(
ctx context.Context, ctx context.Context,
pager DrivePager, pager Pager[models.Driveable],
retry bool, retry bool,
maxRetryCount int, maxRetryCount int,
) ([]models.Driveable, error) { ) ([]models.Driveable, error) {

View File

@ -91,13 +91,10 @@ func (c Events) DeleteContainer(
return nil return nil
} }
// prefer GetContainerByID where possible. func (c Events) GetContainerByID(
// use this only in cases where the models.Calendarable
// is required.
func (c Events) GetCalendar(
ctx context.Context, ctx context.Context,
userID, containerID string, userID, containerID string,
) (models.Calendarable, error) { ) (graph.Container, error) {
config := &users.ItemCalendarsCalendarItemRequestBuilderGetRequestConfiguration{ config := &users.ItemCalendarsCalendarItemRequestBuilderGetRequestConfiguration{
QueryParameters: &users.ItemCalendarsCalendarItemRequestBuilderGetQueryParameters{ QueryParameters: &users.ItemCalendarsCalendarItemRequestBuilderGetQueryParameters{
Select: idAnd("name", "owner"), Select: idAnd("name", "owner"),
@ -115,20 +112,7 @@ func (c Events) GetCalendar(
return nil, graph.Stack(ctx, err) return nil, graph.Stack(ctx, err)
} }
return resp, nil return graph.CalendarDisplayable{Calendarable: resp}, nil
}
// interface-compliant wrapper of GetCalendar
func (c Events) GetContainerByID(
ctx context.Context,
userID, containerID string,
) (graph.Container, error) {
cal, err := c.GetCalendar(ctx, userID, containerID)
if err != nil {
return nil, err
}
return graph.CalendarDisplayable{Calendarable: cal}, nil
} }
// GetContainerByName fetches a calendar by name // GetContainerByName fetches a calendar by name

View File

@ -173,7 +173,7 @@ func (c Events) GetItemsInContainerByCollisionKey(
// item ID pager // item ID pager
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
var _ itemIDPager = &eventIDPager{} var _ DeltaPager[getIDAndAddtler] = &eventIDPager{}
type eventIDPager struct { type eventIDPager struct {
gs graph.Servicer gs graph.Servicer
@ -185,7 +185,7 @@ func (c Events) NewEventIDsPager(
ctx context.Context, ctx context.Context,
userID, containerID string, userID, containerID string,
immutableIDs bool, immutableIDs bool,
) (itemIDPager, error) { ) (DeltaPager[getIDAndAddtler], error) {
options := &users.ItemCalendarsItemEventsRequestBuilderGetRequestConfiguration{ options := &users.ItemCalendarsItemEventsRequestBuilderGetRequestConfiguration{
Headers: newPreferHeaders(preferPageSize(maxNonDeltaPageSize), preferImmutableIDs(immutableIDs)), Headers: newPreferHeaders(preferPageSize(maxNonDeltaPageSize), preferImmutableIDs(immutableIDs)),
QueryParameters: &users.ItemCalendarsItemEventsRequestBuilderGetQueryParameters{ QueryParameters: &users.ItemCalendarsItemEventsRequestBuilderGetQueryParameters{
@ -204,7 +204,7 @@ func (c Events) NewEventIDsPager(
return &eventIDPager{c.Stable, builder, options}, nil return &eventIDPager{c.Stable, builder, options}, nil
} }
func (p *eventIDPager) getPage(ctx context.Context) (DeltaPageLinker, error) { func (p *eventIDPager) GetPage(ctx context.Context) (DeltaPageLinker, error) {
resp, err := p.builder.Get(ctx, p.options) resp, err := p.builder.Get(ctx, p.options)
if err != nil { if err != nil {
return nil, graph.Stack(ctx, err) return nil, graph.Stack(ctx, err)
@ -213,14 +213,14 @@ func (p *eventIDPager) getPage(ctx context.Context) (DeltaPageLinker, error) {
return EmptyDeltaLinker[models.Eventable]{PageLinkValuer: resp}, nil return EmptyDeltaLinker[models.Eventable]{PageLinkValuer: resp}, nil
} }
func (p *eventIDPager) setNext(nextLink string) { func (p *eventIDPager) SetNext(nextLink string) {
p.builder = users.NewItemCalendarsItemEventsRequestBuilder(nextLink, p.gs.Adapter()) p.builder = users.NewItemCalendarsItemEventsRequestBuilder(nextLink, p.gs.Adapter())
} }
// non delta pagers don't need reset // non delta pagers don't need reset
func (p *eventIDPager) reset(context.Context) {} func (p *eventIDPager) Reset(context.Context) {}
func (p *eventIDPager) valuesIn(pl PageLinker) ([]getIDAndAddtler, error) { func (p *eventIDPager) ValuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
return toValues[models.Eventable](pl) return toValues[models.Eventable](pl)
} }
@ -228,7 +228,7 @@ func (p *eventIDPager) valuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
// delta item ID pager // delta item ID pager
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
var _ itemIDPager = &eventDeltaIDPager{} var _ DeltaPager[getIDAndAddtler] = &eventDeltaIDPager{}
type eventDeltaIDPager struct { type eventDeltaIDPager struct {
gs graph.Servicer gs graph.Servicer
@ -242,7 +242,7 @@ func (c Events) NewEventDeltaIDsPager(
ctx context.Context, ctx context.Context,
userID, containerID, oldDelta string, userID, containerID, oldDelta string,
immutableIDs bool, immutableIDs bool,
) (itemIDPager, error) { ) (DeltaPager[getIDAndAddtler], error) {
options := &users.ItemCalendarsItemEventsDeltaRequestBuilderGetRequestConfiguration{ options := &users.ItemCalendarsItemEventsDeltaRequestBuilderGetRequestConfiguration{
Headers: newPreferHeaders(preferPageSize(c.options.DeltaPageSize), preferImmutableIDs(immutableIDs)), Headers: newPreferHeaders(preferPageSize(c.options.DeltaPageSize), preferImmutableIDs(immutableIDs)),
QueryParameters: &users.ItemCalendarsItemEventsDeltaRequestBuilderGetQueryParameters{ QueryParameters: &users.ItemCalendarsItemEventsDeltaRequestBuilderGetQueryParameters{
@ -281,7 +281,7 @@ func getEventDeltaBuilder(
return builder return builder
} }
func (p *eventDeltaIDPager) getPage(ctx context.Context) (DeltaPageLinker, error) { func (p *eventDeltaIDPager) GetPage(ctx context.Context) (DeltaPageLinker, error) {
resp, err := p.builder.Get(ctx, p.options) resp, err := p.builder.Get(ctx, p.options)
if err != nil { if err != nil {
return nil, graph.Stack(ctx, err) return nil, graph.Stack(ctx, err)
@ -290,15 +290,15 @@ func (p *eventDeltaIDPager) getPage(ctx context.Context) (DeltaPageLinker, error
return resp, nil return resp, nil
} }
func (p *eventDeltaIDPager) setNext(nextLink string) { func (p *eventDeltaIDPager) SetNext(nextLink string) {
p.builder = users.NewItemCalendarsItemEventsDeltaRequestBuilder(nextLink, p.gs.Adapter()) p.builder = users.NewItemCalendarsItemEventsDeltaRequestBuilder(nextLink, p.gs.Adapter())
} }
func (p *eventDeltaIDPager) reset(ctx context.Context) { func (p *eventDeltaIDPager) Reset(ctx context.Context) {
p.builder = getEventDeltaBuilder(ctx, p.gs, p.userID, p.containerID, p.options) p.builder = getEventDeltaBuilder(ctx, p.gs, p.userID, p.containerID, p.options)
} }
func (p *eventDeltaIDPager) valuesIn(pl PageLinker) ([]getIDAndAddtler, error) { func (p *eventDeltaIDPager) ValuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
return toValues[models.Eventable](pl) return toValues[models.Eventable](pl)
} }

View File

@ -16,11 +16,31 @@ import (
// common interfaces // common interfaces
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// TODO(keepers): replace all matching uses of GetPage with this. type DeltaPager[T any] interface {
DeltaGetPager
Resetter
SetNextLinker
ValuesInPageLinker[T]
}
type Pager[T any] interface {
GetPager
SetNextLinker
ValuesInPageLinker[T]
}
type DeltaGetPager interface { type DeltaGetPager interface {
GetPage(context.Context) (DeltaPageLinker, error) GetPage(context.Context) (DeltaPageLinker, error)
} }
type GetPager interface {
GetPage(context.Context) (PageLinker, error)
}
type Valuer[T any] interface {
GetValue() []T
}
type ValuesInPageLinker[T any] interface { type ValuesInPageLinker[T any] interface {
ValuesIn(PageLinker) ([]T, error) ValuesIn(PageLinker) ([]T, error)
} }
@ -34,10 +54,19 @@ type DeltaPageLinker interface {
GetOdataDeltaLink() *string GetOdataDeltaLink() *string
} }
type PageLinkValuer[T any] interface {
PageLinker
Valuer[T]
}
type SetNextLinker interface { type SetNextLinker interface {
SetNext(nextLink string) SetNext(nextLink string)
} }
type Resetter interface {
Reset(context.Context)
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// common funcs // common funcs
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -55,15 +84,6 @@ func NextAndDeltaLink(pl DeltaPageLinker) (string, string) {
return NextLink(pl), ptr.Val(pl.GetOdataDeltaLink()) return NextLink(pl), ptr.Val(pl.GetOdataDeltaLink())
} }
type Valuer[T any] interface {
GetValue() []T
}
type PageLinkValuer[T any] interface {
PageLinker
Valuer[T]
}
// EmptyDeltaLinker is used to convert PageLinker to DeltaPageLinker // EmptyDeltaLinker is used to convert PageLinker to DeltaPageLinker
type EmptyDeltaLinker[T any] struct { type EmptyDeltaLinker[T any] struct {
PageLinkValuer[T] PageLinkValuer[T]
@ -148,19 +168,6 @@ func toValues[T any](a any) ([]getIDAndAddtler, error) {
return r, nil return r, nil
} }
type itemIDPager interface {
// getPage get a page with the specified options from graph
getPage(context.Context) (DeltaPageLinker, error)
// setNext is used to pass in the next url got from graph
setNext(string)
// reset is used to clear delta url in delta pagers. When
// reset is called, we reset the state(delta url) that we
// currently have and start a new delta query without the token.
reset(context.Context)
// valuesIn gets us the values in a page
valuesIn(PageLinker) ([]getIDAndAddtler, error)
}
type getIDAndAddtler interface { type getIDAndAddtler interface {
GetId() *string GetId() *string
GetAdditionalData() map[string]any GetAdditionalData() map[string]any
@ -169,13 +176,13 @@ type getIDAndAddtler interface {
func getAddedAndRemovedItemIDs( func getAddedAndRemovedItemIDs(
ctx context.Context, ctx context.Context,
service graph.Servicer, service graph.Servicer,
pager itemIDPager, pager DeltaPager[getIDAndAddtler],
deltaPager itemIDPager, deltaPager DeltaPager[getIDAndAddtler],
oldDelta string, oldDelta string,
canMakeDeltaQueries bool, canMakeDeltaQueries bool,
) ([]string, []string, DeltaUpdate, error) { ) ([]string, []string, DeltaUpdate, error) {
var ( var (
pgr itemIDPager pgr DeltaPager[getIDAndAddtler]
resetDelta bool resetDelta bool
) )
@ -204,7 +211,7 @@ func getAddedAndRemovedItemIDs(
} }
// reset deltaPager // reset deltaPager
pgr.reset(ctx) pgr.Reset(ctx)
added, removed, deltaURL, err = getItemsAddedAndRemovedFromContainer(ctx, pgr) added, removed, deltaURL, err = getItemsAddedAndRemovedFromContainer(ctx, pgr)
if err != nil { if err != nil {
@ -217,7 +224,7 @@ func getAddedAndRemovedItemIDs(
// generic controller for retrieving all item ids in a container. // generic controller for retrieving all item ids in a container.
func getItemsAddedAndRemovedFromContainer( func getItemsAddedAndRemovedFromContainer(
ctx context.Context, ctx context.Context,
pager itemIDPager, pager DeltaPager[getIDAndAddtler],
) ([]string, []string, string, error) { ) ([]string, []string, string, error) {
var ( var (
addedIDs = []string{} addedIDs = []string{}
@ -229,14 +236,14 @@ func getItemsAddedAndRemovedFromContainer(
for { for {
// get the next page of data, check for standard errors // get the next page of data, check for standard errors
resp, err := pager.getPage(ctx) resp, err := pager.GetPage(ctx)
if err != nil { if err != nil {
return nil, nil, deltaURL, graph.Stack(ctx, err) return nil, nil, deltaURL, graph.Stack(ctx, err)
} }
// each category type responds with a different interface, but all // each category type responds with a different interface, but all
// of them comply with GetValue, which is where we'll get our item data. // of them comply with GetValue, which is where we'll get our item data.
items, err := pager.valuesIn(resp) items, err := pager.ValuesIn(resp)
if err != nil { if err != nil {
return nil, nil, "", graph.Stack(ctx, err) return nil, nil, "", graph.Stack(ctx, err)
} }
@ -278,7 +285,7 @@ func getItemsAddedAndRemovedFromContainer(
break break
} }
pager.setNext(nextLink) pager.SetNext(nextLink)
} }
logger.Ctx(ctx).Infow("completed enumeration", "count", itemCount) logger.Ctx(ctx).Infow("completed enumeration", "count", itemCount)

View File

@ -95,7 +95,7 @@ func (p *testPager) setNext(nextLink string) {}
// mock id pager // mock id pager
var _ itemIDPager = &testIDsPager{} var _ DeltaPager[getIDAndAddtler] = &testIDsPager{}
type testIDsPager struct { type testIDsPager struct {
t *testing.T t *testing.T
@ -105,7 +105,7 @@ type testIDsPager struct {
needsReset bool needsReset bool
} }
func (p *testIDsPager) getPage(ctx context.Context) (DeltaPageLinker, error) { func (p *testIDsPager) GetPage(ctx context.Context) (DeltaPageLinker, error) {
if p.errorCode != "" { if p.errorCode != "" {
ierr := odataerrors.NewMainError() ierr := odataerrors.NewMainError()
ierr.SetCode(&p.errorCode) ierr.SetCode(&p.errorCode)
@ -118,8 +118,8 @@ func (p *testIDsPager) getPage(ctx context.Context) (DeltaPageLinker, error) {
return testPage{}, nil return testPage{}, nil
} }
func (p *testIDsPager) setNext(string) {} func (p *testIDsPager) SetNext(string) {}
func (p *testIDsPager) reset(context.Context) { func (p *testIDsPager) Reset(context.Context) {
if !p.needsReset { if !p.needsReset {
require.Fail(p.t, "reset should not be called") require.Fail(p.t, "reset should not be called")
} }
@ -128,7 +128,7 @@ func (p *testIDsPager) reset(context.Context) {
p.errorCode = "" p.errorCode = ""
} }
func (p *testIDsPager) valuesIn(pl PageLinker) ([]getIDAndAddtler, error) { func (p *testIDsPager) ValuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
items := []getIDAndAddtler{} items := []getIDAndAddtler{}
for _, id := range p.added { for _, id := range p.added {
@ -208,15 +208,21 @@ func (suite *ItemPagerUnitSuite) TestEnumerateItems() {
func (suite *ItemPagerUnitSuite) TestGetAddedAndRemovedItemIDs() { func (suite *ItemPagerUnitSuite) TestGetAddedAndRemovedItemIDs() {
tests := []struct { tests := []struct {
name string name string
pagerGetter func(*testing.T, context.Context, graph.Servicer, string, string, bool) (itemIDPager, error) pagerGetter func(
*testing.T,
context.Context,
graph.Servicer,
string, string,
bool,
) (DeltaPager[getIDAndAddtler], error)
deltaPagerGetter func( deltaPagerGetter func(
*testing.T, *testing.T,
context.Context, context.Context,
graph.Servicer, graph.Servicer,
string, string, string, string, string, string,
bool, bool,
) (itemIDPager, error) ) (DeltaPager[getIDAndAddtler], error)
added []string added []string
removed []string removed []string
deltaUpdate DeltaUpdate deltaUpdate DeltaUpdate
@ -232,7 +238,7 @@ func (suite *ItemPagerUnitSuite) TestGetAddedAndRemovedItemIDs() {
user string, user string,
directory string, directory string,
immutableIDs bool, immutableIDs bool,
) (itemIDPager, error) { ) (DeltaPager[getIDAndAddtler], error) {
// this should not be called // this should not be called
return nil, assert.AnError return nil, assert.AnError
}, },
@ -244,7 +250,7 @@ func (suite *ItemPagerUnitSuite) TestGetAddedAndRemovedItemIDs() {
directory string, directory string,
delta string, delta string,
immutableIDs bool, immutableIDs bool,
) (itemIDPager, error) { ) (DeltaPager[getIDAndAddtler], error) {
return &testIDsPager{ return &testIDsPager{
t: t, t: t,
added: []string{"uno", "dos"}, added: []string{"uno", "dos"},
@ -265,7 +271,7 @@ func (suite *ItemPagerUnitSuite) TestGetAddedAndRemovedItemIDs() {
user string, user string,
directory string, directory string,
immutableIDs bool, immutableIDs bool,
) (itemIDPager, error) { ) (DeltaPager[getIDAndAddtler], error) {
// this should not be called // this should not be called
return nil, assert.AnError return nil, assert.AnError
}, },
@ -277,7 +283,7 @@ func (suite *ItemPagerUnitSuite) TestGetAddedAndRemovedItemIDs() {
directory string, directory string,
delta string, delta string,
immutableIDs bool, immutableIDs bool,
) (itemIDPager, error) { ) (DeltaPager[getIDAndAddtler], error) {
return &testIDsPager{ return &testIDsPager{
t: t, t: t,
added: []string{"uno", "dos"}, added: []string{"uno", "dos"},
@ -299,7 +305,7 @@ func (suite *ItemPagerUnitSuite) TestGetAddedAndRemovedItemIDs() {
user string, user string,
directory string, directory string,
immutableIDs bool, immutableIDs bool,
) (itemIDPager, error) { ) (DeltaPager[getIDAndAddtler], error) {
// this should not be called // this should not be called
return nil, assert.AnError return nil, assert.AnError
}, },
@ -311,7 +317,7 @@ func (suite *ItemPagerUnitSuite) TestGetAddedAndRemovedItemIDs() {
directory string, directory string,
delta string, delta string,
immutableIDs bool, immutableIDs bool,
) (itemIDPager, error) { ) (DeltaPager[getIDAndAddtler], error) {
return &testIDsPager{ return &testIDsPager{
t: t, t: t,
added: []string{"uno", "dos"}, added: []string{"uno", "dos"},
@ -335,7 +341,7 @@ func (suite *ItemPagerUnitSuite) TestGetAddedAndRemovedItemIDs() {
user string, user string,
directory string, directory string,
immutableIDs bool, immutableIDs bool,
) (itemIDPager, error) { ) (DeltaPager[getIDAndAddtler], error) {
return &testIDsPager{ return &testIDsPager{
t: t, t: t,
added: []string{"uno", "dos"}, added: []string{"uno", "dos"},
@ -350,7 +356,7 @@ func (suite *ItemPagerUnitSuite) TestGetAddedAndRemovedItemIDs() {
directory string, directory string,
delta string, delta string,
immutableIDs bool, immutableIDs bool,
) (itemIDPager, error) { ) (DeltaPager[getIDAndAddtler], error) {
return &testIDsPager{errorCode: "ErrorQuotaExceeded"}, nil return &testIDsPager{errorCode: "ErrorQuotaExceeded"}, nil
}, },
added: []string{"uno", "dos"}, added: []string{"uno", "dos"},

View File

@ -41,46 +41,6 @@ type Mail struct {
// containers // containers
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// CreateMailFolder makes a mail folder iff a folder of the same name does not exist
// Reference: https://docs.microsoft.com/en-us/graph/api/user-post-mailfolders?view=graph-rest-1.0&tabs=http
func (c Mail) CreateMailFolder(
ctx context.Context,
userID, containerName string,
) (models.MailFolderable, error) {
isHidden := false
body := models.NewMailFolder()
body.SetDisplayName(&containerName)
body.SetIsHidden(&isHidden)
mdl, err := c.Stable.Client().
Users().
ByUserId(userID).
MailFolders().
Post(ctx, body, nil)
if err != nil {
return nil, graph.Wrap(ctx, err, "creating mail folder")
}
return mdl, nil
}
func (c Mail) DeleteMailFolder(
ctx context.Context,
userID, id string,
) error {
err := c.Stable.Client().
Users().
ByUserId(userID).
MailFolders().
ByMailFolderId(id).
Delete(ctx, nil)
if err != nil {
return graph.Wrap(ctx, err, "deleting mail folder")
}
return nil
}
func (c Mail) CreateContainer( func (c Mail) CreateContainer(
ctx context.Context, ctx context.Context,
userID, parentContainerID, containerName string, userID, parentContainerID, containerName string,
@ -131,13 +91,10 @@ func (c Mail) DeleteContainer(
return nil return nil
} }
// prefer GetContainerByID where possible. func (c Mail) GetContainerByID(
// use this only in cases where the models.MailFolderable
// is required.
func (c Mail) GetFolder(
ctx context.Context, ctx context.Context,
userID, containerID string, userID, containerID string,
) (models.MailFolderable, error) { ) (graph.Container, error) {
config := &users.ItemMailFoldersMailFolderItemRequestBuilderGetRequestConfiguration{ config := &users.ItemMailFoldersMailFolderItemRequestBuilderGetRequestConfiguration{
QueryParameters: &users.ItemMailFoldersMailFolderItemRequestBuilderGetQueryParameters{ QueryParameters: &users.ItemMailFoldersMailFolderItemRequestBuilderGetQueryParameters{
Select: idAnd(displayName, parentFolderID), Select: idAnd(displayName, parentFolderID),
@ -158,14 +115,6 @@ func (c Mail) GetFolder(
return resp, nil return resp, nil
} }
// interface-compliant wrapper of GetFolder
func (c Mail) GetContainerByID(
ctx context.Context,
userID, containerID string,
) (graph.Container, error) {
return c.GetFolder(ctx, userID, containerID)
}
// GetContainerByName fetches a folder by name // GetContainerByName fetches a folder by name
func (c Mail) GetContainerByName( func (c Mail) GetContainerByName(
ctx context.Context, ctx context.Context,

View File

@ -174,7 +174,7 @@ func (p *mailPageCtrl) setNext(nextLink string) {
// item ID pager // item ID pager
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
var _ itemIDPager = &mailIDPager{} var _ DeltaPager[getIDAndAddtler] = &mailIDPager{}
type mailIDPager struct { type mailIDPager struct {
gs graph.Servicer gs graph.Servicer
@ -186,7 +186,7 @@ func (c Mail) NewMailIDsPager(
ctx context.Context, ctx context.Context,
userID, containerID string, userID, containerID string,
immutableIDs bool, immutableIDs bool,
) itemIDPager { ) DeltaPager[getIDAndAddtler] {
config := &users.ItemMailFoldersItemMessagesRequestBuilderGetRequestConfiguration{ config := &users.ItemMailFoldersItemMessagesRequestBuilderGetRequestConfiguration{
QueryParameters: &users.ItemMailFoldersItemMessagesRequestBuilderGetQueryParameters{ QueryParameters: &users.ItemMailFoldersItemMessagesRequestBuilderGetQueryParameters{
Select: idAnd("isRead"), Select: idAnd("isRead"),
@ -206,7 +206,7 @@ func (c Mail) NewMailIDsPager(
return &mailIDPager{c.Stable, builder, config} return &mailIDPager{c.Stable, builder, config}
} }
func (p *mailIDPager) getPage(ctx context.Context) (DeltaPageLinker, error) { func (p *mailIDPager) GetPage(ctx context.Context) (DeltaPageLinker, error) {
page, err := p.builder.Get(ctx, p.options) page, err := p.builder.Get(ctx, p.options)
if err != nil { if err != nil {
return nil, graph.Stack(ctx, err) return nil, graph.Stack(ctx, err)
@ -215,14 +215,14 @@ func (p *mailIDPager) getPage(ctx context.Context) (DeltaPageLinker, error) {
return EmptyDeltaLinker[models.Messageable]{PageLinkValuer: page}, nil return EmptyDeltaLinker[models.Messageable]{PageLinkValuer: page}, nil
} }
func (p *mailIDPager) setNext(nextLink string) { func (p *mailIDPager) SetNext(nextLink string) {
p.builder = users.NewItemMailFoldersItemMessagesRequestBuilder(nextLink, p.gs.Adapter()) p.builder = users.NewItemMailFoldersItemMessagesRequestBuilder(nextLink, p.gs.Adapter())
} }
// non delta pagers don't have reset // non delta pagers don't have reset
func (p *mailIDPager) reset(context.Context) {} func (p *mailIDPager) Reset(context.Context) {}
func (p *mailIDPager) valuesIn(pl PageLinker) ([]getIDAndAddtler, error) { func (p *mailIDPager) ValuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
return toValues[models.Messageable](pl) return toValues[models.Messageable](pl)
} }
@ -272,7 +272,7 @@ func (c Mail) GetItemIDsInContainer(
// delta item ID pager // delta item ID pager
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
var _ itemIDPager = &mailDeltaIDPager{} var _ DeltaPager[getIDAndAddtler] = &mailDeltaIDPager{}
type mailDeltaIDPager struct { type mailDeltaIDPager struct {
gs graph.Servicer gs graph.Servicer
@ -304,7 +304,7 @@ func (c Mail) NewMailDeltaIDsPager(
ctx context.Context, ctx context.Context,
userID, containerID, oldDelta string, userID, containerID, oldDelta string,
immutableIDs bool, immutableIDs bool,
) itemIDPager { ) DeltaPager[getIDAndAddtler] {
config := &users.ItemMailFoldersItemMessagesDeltaRequestBuilderGetRequestConfiguration{ config := &users.ItemMailFoldersItemMessagesDeltaRequestBuilderGetRequestConfiguration{
QueryParameters: &users.ItemMailFoldersItemMessagesDeltaRequestBuilderGetQueryParameters{ QueryParameters: &users.ItemMailFoldersItemMessagesDeltaRequestBuilderGetQueryParameters{
Select: idAnd("isRead"), Select: idAnd("isRead"),
@ -324,7 +324,7 @@ func (c Mail) NewMailDeltaIDsPager(
return &mailDeltaIDPager{c.Stable, userID, containerID, builder, config} return &mailDeltaIDPager{c.Stable, userID, containerID, builder, config}
} }
func (p *mailDeltaIDPager) getPage(ctx context.Context) (DeltaPageLinker, error) { func (p *mailDeltaIDPager) GetPage(ctx context.Context) (DeltaPageLinker, error) {
page, err := p.builder.Get(ctx, p.options) page, err := p.builder.Get(ctx, p.options)
if err != nil { if err != nil {
return nil, graph.Stack(ctx, err) return nil, graph.Stack(ctx, err)
@ -333,11 +333,11 @@ func (p *mailDeltaIDPager) getPage(ctx context.Context) (DeltaPageLinker, error)
return page, nil return page, nil
} }
func (p *mailDeltaIDPager) setNext(nextLink string) { func (p *mailDeltaIDPager) SetNext(nextLink string) {
p.builder = users.NewItemMailFoldersItemMessagesDeltaRequestBuilder(nextLink, p.gs.Adapter()) p.builder = users.NewItemMailFoldersItemMessagesDeltaRequestBuilder(nextLink, p.gs.Adapter())
} }
func (p *mailDeltaIDPager) reset(ctx context.Context) { func (p *mailDeltaIDPager) Reset(ctx context.Context) {
p.builder = p.gs. p.builder = p.gs.
Client(). Client().
Users(). Users().
@ -348,7 +348,7 @@ func (p *mailDeltaIDPager) reset(ctx context.Context) {
Delta() Delta()
} }
func (p *mailDeltaIDPager) valuesIn(pl PageLinker) ([]getIDAndAddtler, error) { func (p *mailDeltaIDPager) ValuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
return toValues[models.Messageable](pl) return toValues[models.Messageable](pl)
} }

View File

@ -383,7 +383,7 @@ func (suite *MailAPIIntgSuite) TestMail_RestoreLargeAttachment() {
folderName := testdata.DefaultRestoreConfig("maillargeattachmenttest").Location folderName := testdata.DefaultRestoreConfig("maillargeattachmenttest").Location
msgs := suite.its.ac.Mail() msgs := suite.its.ac.Mail()
mailfolder, err := msgs.CreateMailFolder(ctx, userID, folderName) mailfolder, err := msgs.CreateContainer(ctx, userID, api.MsgFolderRoot, folderName)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
msg := models.NewMessage() msg := models.NewMessage()

View File

@ -1,56 +0,0 @@
package mock
import (
"context"
"github.com/alcionai/clues"
"github.com/microsoftgraph/msgraph-sdk-go/models"
"github.com/alcionai/corso/src/pkg/services/m365/api"
)
type PageLink struct {
Link *string
}
func (pl *PageLink) GetOdataNextLink() *string {
return pl.Link
}
type PagerResult struct {
Drives []models.Driveable
NextLink *string
Err error
}
type DrivePager struct {
ToReturn []PagerResult
GetIdx int
}
func (p *DrivePager) GetPage(context.Context) (api.PageLinker, error) {
if len(p.ToReturn) <= p.GetIdx {
return nil, clues.New("ToReturn index out of bounds")
}
idx := p.GetIdx
p.GetIdx++
return &PageLink{p.ToReturn[idx].NextLink}, p.ToReturn[idx].Err
}
func (p *DrivePager) SetNext(string) {}
func (p *DrivePager) ValuesIn(api.PageLinker) ([]models.Driveable, error) {
idx := p.GetIdx
if idx > 0 {
// Return values lag by one since we increment in GetPage().
idx--
}
if len(p.ToReturn) <= idx {
return nil, clues.New("ToReturn index out of bounds")
}
return p.ToReturn[idx].Drives, nil
}

View File

@ -0,0 +1,113 @@
package mock
import (
"context"
"github.com/alcionai/clues"
"github.com/alcionai/corso/src/pkg/services/m365/api"
)
type DeltaNextLinks struct {
Next *string
Delta *string
}
func (dnl *DeltaNextLinks) GetOdataNextLink() *string {
return dnl.Next
}
func (dnl *DeltaNextLinks) GetOdataDeltaLink() *string {
return dnl.Delta
}
type PagerResult[T any] struct {
Values []T
NextLink *string
DeltaLink *string
Err error
}
// ---------------------------------------------------------------------------
// non-delta pager
// ---------------------------------------------------------------------------
type Pager[T any] struct {
ToReturn []PagerResult[T]
getIdx int
}
func (p *Pager[T]) GetPage(context.Context) (api.PageLinker, error) {
if len(p.ToReturn) <= p.getIdx {
return nil, clues.New("index out of bounds").
With("index", p.getIdx, "values", p.ToReturn)
}
idx := p.getIdx
p.getIdx++
link := DeltaNextLinks{Next: p.ToReturn[idx].NextLink}
return &link, p.ToReturn[idx].Err
}
func (p *Pager[T]) SetNext(string) {}
func (p *Pager[T]) ValuesIn(api.PageLinker) ([]T, error) {
idx := p.getIdx
if idx > 0 {
// Return values lag by one since we increment in GetPage().
idx--
}
if len(p.ToReturn) <= idx {
return nil, clues.New("index out of bounds").
With("index", idx, "values", p.ToReturn)
}
return p.ToReturn[idx].Values, nil
}
// ---------------------------------------------------------------------------
// delta pager
// ---------------------------------------------------------------------------
type DeltaPager[T any] struct {
ToReturn []PagerResult[T]
getIdx int
}
func (p *DeltaPager[T]) GetPage(context.Context) (api.DeltaPageLinker, error) {
if len(p.ToReturn) <= p.getIdx {
return nil, clues.New("index out of bounds").
With("index", p.getIdx, "values", p.ToReturn)
}
idx := p.getIdx
p.getIdx++
link := DeltaNextLinks{
Next: p.ToReturn[idx].NextLink,
Delta: p.ToReturn[idx].DeltaLink,
}
return &link, p.ToReturn[idx].Err
}
func (p *DeltaPager[T]) SetNext(string) {}
func (p *DeltaPager[T]) Reset(context.Context) {}
func (p *DeltaPager[T]) ValuesIn(api.PageLinker) ([]T, error) {
idx := p.getIdx
if idx > 0 {
// Return values lag by one since we increment in GetPage().
idx--
}
if len(p.ToReturn) <= idx {
return nil, clues.New("index out of bounds").
With("index", idx, "values", p.ToReturn)
}
return p.ToReturn[idx].Values, nil
}