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)
}
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() {
var (
tenant = "a-tenant"
@ -1283,7 +1226,7 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
table := []struct {
name string
drives []models.Driveable
items map[string][]deltaPagerResult
items map[string][]apiMock.PagerResult[models.DriveItemable]
canUsePreviousBackup bool
errCheck assert.ErrorAssertionFunc
prevFolderPaths map[string]map[string]string
@ -1302,14 +1245,14 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{
name: "OneDrive_OneItemPage_DelFileOnly_NoFolders_NoErrors",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"), // will be present, not needed
delItem("file", driveBasePath1, "root", true, false, false),
},
deltaLink: &delta,
DeltaLink: &delta,
},
},
},
@ -1334,14 +1277,14 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{
name: "OneDrive_OneItemPage_NoFolderDeltas_NoErrors",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
driveItem("file", "file", driveBasePath1, "root", true, false, false),
},
deltaLink: &delta,
DeltaLink: &delta,
},
},
},
@ -1366,15 +1309,15 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{
name: "OneDrive_OneItemPage_NoErrors",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, 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",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", 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",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", driveBasePath1+"/folder", "folder", 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",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, 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",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false),
},
nextLink: &next,
NextLink: &next,
},
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file2", "file2", driveBasePath1+"/folder", "folder", true, false, false),
},
deltaLink: &delta,
DeltaLink: &delta,
},
},
},
@ -1568,25 +1511,25 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
drive1,
drive2,
},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false),
},
deltaLink: &delta,
DeltaLink: &delta,
},
},
driveID2: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root2"),
driveItem("folder2", "folder", driveBasePath2, "root2", false, true, false),
driveItem("file2", "file", driveBasePath2+"/folder", "folder2", true, false, false),
},
deltaLink: &delta2,
DeltaLink: &delta2,
},
},
},
@ -1630,25 +1573,25 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
drive1,
drive2,
},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false),
},
deltaLink: &delta,
DeltaLink: &delta,
},
},
driveID2: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
driveItem("folder", "folder", driveBasePath2, "root", false, true, 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",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
err: assert.AnError,
Err: assert.AnError,
},
},
},
@ -1709,17 +1652,17 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{
name: "OneDrive_OneItemPage_DeltaError",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
err: getDeltaError(),
Err: getDeltaError(),
},
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
driveItem("file", "file", driveBasePath1, "root", true, false, false),
},
deltaLink: &delta,
DeltaLink: &delta,
},
},
},
@ -1744,25 +1687,25 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{
name: "OneDrive_TwoItemPage_DeltaError",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
err: getDeltaError(),
Err: getDeltaError(),
},
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
driveItem("file", "file", driveBasePath1, "root", true, false, false),
},
nextLink: &next,
NextLink: &next,
},
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, 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",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
driveItem("file", "file", driveBasePath1, "root", true, false, false),
},
nextLink: &next,
NextLink: &next,
},
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, 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",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
err: getDeltaError(),
Err: getDeltaError(),
},
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
driveItem("folder2", "folder2", driveBasePath1, "root", false, true, 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",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
err: getDeltaError(),
Err: getDeltaError(),
},
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
driveItem("folder2", "folder", driveBasePath1, "root", false, true, 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",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", 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"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file2", "file2", 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",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
err: getDeltaError(),
Err: getDeltaError(),
},
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false),
driveItem("folder2", "folder2", driveBasePath1, "root", false, true, false),
driveItem("file2", "file2", driveBasePath1+"/folder2", "folder2", true, false, false),
},
nextLink: &next,
NextLink: &next,
},
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
delItem("folder2", driveBasePath1, "root", false, true, 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",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
err: getDeltaError(),
Err: getDeltaError(),
},
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
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",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
err: getDeltaError(),
Err: getDeltaError(),
},
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
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",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false),
},
nextLink: &next,
NextLink: &next,
},
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
delItem("folder", driveBasePath1, "root", false, true, 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",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
driveItem("folder", "folder", driveBasePath1, "root", false, true, false),
driveItem("file", "file", driveBasePath1+"/folder", "folder", true, false, false),
},
nextLink: &next,
NextLink: &next,
},
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
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",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
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",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"),
delItem("file", driveBasePath1, "root", true, false, false),
},
deltaLink: &delta,
DeltaLink: &delta,
},
},
},
@ -2285,13 +2228,13 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
{
name: "TwoPriorDrives_OneTombstoned",
drives: []models.Driveable{drive1},
items: map[string][]deltaPagerResult{
items: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID1: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
driveRootItem("root"), // will be present
},
deltaLink: &delta,
DeltaLink: &delta,
},
},
},
@ -2322,17 +2265,17 @@ func (suite *OneDriveCollectionsUnitSuite) TestGet() {
ctx, flush := tester.NewContext(t)
defer flush()
mockDrivePager := &apiMock.DrivePager{
ToReturn: []apiMock.PagerResult{
{Drives: test.drives},
mockDrivePager := &apiMock.Pager[models.Driveable]{
ToReturn: []apiMock.PagerResult[models.Driveable]{
{Values: test.drives},
},
}
itemPagers := map[string]api.DriveItemDeltaEnumerator{}
itemPagers := map[string]api.DeltaPager[models.DriveItemable]{}
for driveID := range test.items {
itemPagers[driveID] = &mockItemPager{
toReturn: test.items[driveID],
itemPagers[driveID] = &apiMock.DeltaPager[models.DriveItemable]{
ToReturn: test.items[driveID],
}
}
@ -2583,7 +2526,7 @@ func (suite *OneDriveCollectionsUnitSuite) TestCollectItems() {
table := []struct {
name string
items []deltaPagerResult
items []apiMock.PagerResult[models.DriveItemable]
deltaURL string
prevDeltaSuccess bool
prevDelta string
@ -2592,8 +2535,8 @@ func (suite *OneDriveCollectionsUnitSuite) TestCollectItems() {
{
name: "delta on first run",
deltaURL: delta,
items: []deltaPagerResult{
{deltaLink: &delta},
items: []apiMock.PagerResult[models.DriveItemable]{
{DeltaLink: &delta},
},
prevDeltaSuccess: true,
prevDelta: prevDelta,
@ -2601,8 +2544,8 @@ func (suite *OneDriveCollectionsUnitSuite) TestCollectItems() {
{
name: "empty prev delta",
deltaURL: delta,
items: []deltaPagerResult{
{deltaLink: &delta},
items: []apiMock.PagerResult[models.DriveItemable]{
{DeltaLink: &delta},
},
prevDeltaSuccess: false,
prevDelta: "",
@ -2610,9 +2553,9 @@ func (suite *OneDriveCollectionsUnitSuite) TestCollectItems() {
{
name: "next then delta",
deltaURL: delta,
items: []deltaPagerResult{
{nextLink: &next},
{deltaLink: &delta},
items: []apiMock.PagerResult[models.DriveItemable]{
{NextLink: &next},
{DeltaLink: &delta},
},
prevDeltaSuccess: true,
prevDelta: prevDelta,
@ -2620,18 +2563,18 @@ func (suite *OneDriveCollectionsUnitSuite) TestCollectItems() {
{
name: "invalid prev delta",
deltaURL: delta,
items: []deltaPagerResult{
{err: getDeltaError()},
{deltaLink: &delta}, // works on retry
items: []apiMock.PagerResult[models.DriveItemable]{
{Err: getDeltaError()},
{DeltaLink: &delta}, // works on retry
},
prevDelta: prevDelta,
prevDeltaSuccess: false,
},
{
name: "fail a normal delta query",
items: []deltaPagerResult{
{nextLink: &next},
{err: assert.AnError},
items: []apiMock.PagerResult[models.DriveItemable]{
{NextLink: &next},
{Err: assert.AnError},
},
prevDelta: prevDelta,
prevDeltaSuccess: true,
@ -2645,8 +2588,8 @@ func (suite *OneDriveCollectionsUnitSuite) TestCollectItems() {
ctx, flush := tester.NewContext(t)
defer flush()
itemPager := &mockItemPager{
toReturn: test.items,
itemPager := &apiMock.DeltaPager[models.DriveItemable]{
ToReturn: test.items,
}
collectorFunc := func(
@ -2687,7 +2630,7 @@ func (suite *OneDriveCollectionsUnitSuite) TestAddURLCacheToDriveCollections() {
table := []struct {
name string
items []deltaPagerResult
items []apiMock.PagerResult[any]
deltaURL string
prevDeltaSuccess bool
prevDelta string
@ -2704,8 +2647,8 @@ func (suite *OneDriveCollectionsUnitSuite) TestAddURLCacheToDriveCollections() {
ctx, flush := tester.NewContext(t)
defer flush()
itemPagers := map[string]api.DriveItemDeltaEnumerator{}
itemPagers[driveID] = &mockItemPager{}
itemPagers := map[string]api.DeltaPager[models.DriveItemable]{}
itemPagers[driveID] = &apiMock.DeltaPager[models.DriveItemable]{}
mbh := mock.DefaultOneDriveBH()
mbh.ItemPagerV = itemPagers

View File

@ -50,7 +50,7 @@ type BackupHandler interface {
// ServiceCat returns the service and category used by this implementation.
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
// provided path.
FormatDisplayPath(driveName string, parentPath *path.Builder) string
@ -62,7 +62,7 @@ type BackupHandler interface {
}
type NewDrivePagerer interface {
NewDrivePager(resourceOwner string, fields []string) api.DrivePager
NewDrivePager(resourceOwner string, fields []string) api.Pager[models.Driveable]
}
type GetItemPermissioner interface {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,6 +24,7 @@ import (
"github.com/alcionai/corso/src/pkg/control/testdata"
"github.com/alcionai/corso/src/pkg/fault"
"github.com/alcionai/corso/src/pkg/services/m365/api"
apiMock "github.com/alcionai/corso/src/pkg/services/m365/api/mock"
)
type URLCacheIntegrationSuite struct {
@ -209,20 +210,20 @@ func (suite *URLCacheUnitSuite) TestGetItemProperties() {
table := []struct {
name string
pagerResult map[string][]deltaPagerResult
pagerResult map[string][]apiMock.PagerResult[models.DriveItemable]
expectedItemProps map[string]itemProps
expectedErr require.ErrorAssertionFunc
cacheAssert func(*urlCache, time.Time)
}{
{
name: "single item in cache",
pagerResult: map[string][]deltaPagerResult{
pagerResult: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
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",
pagerResult: map[string][]deltaPagerResult{
pagerResult: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
fileItem("1", "file1", "root", "root", "https://dummy1.com", false),
fileItem("2", "file2", "root", "root", "https://dummy2.com", false),
fileItem("3", "file3", "root", "root", "https://dummy3.com", false),
fileItem("4", "file4", "root", "root", "https://dummy4.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",
pagerResult: map[string][]deltaPagerResult{
pagerResult: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
fileItem("1", "file1", "root", "root", "https://dummy1.com", false),
fileItem("2", "file2", "root", "root", "https://dummy2.com", false),
fileItem("3", "file3", "root", "root", "https://dummy3.com", false),
fileItem("1", "file1", "root", "root", "https://test1.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",
pagerResult: map[string][]deltaPagerResult{
pagerResult: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
fileItem("1", "file1", "root", "root", "https://dummy1.com", false),
fileItem("2", "file2", "root", "root", "https://dummy2.com", false),
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",
pagerResult: map[string][]deltaPagerResult{
pagerResult: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
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",
pagerResult: map[string][]deltaPagerResult{
pagerResult: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
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),
},
deltaLink: &deltaString,
err: errors.New("delta query error"),
DeltaLink: &deltaString,
Err: errors.New("delta query error"),
},
},
},
@ -407,14 +408,14 @@ func (suite *URLCacheUnitSuite) TestGetItemProperties() {
{
name: "folder item",
pagerResult: map[string][]deltaPagerResult{
pagerResult: map[string][]apiMock.PagerResult[models.DriveItemable]{
driveID: {
{
items: []models.DriveItemable{
Values: []models.DriveItemable{
fileItem("1", "file1", "root", "root", "https://dummy1.com", 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)
defer flush()
itemPager := &mockItemPager{
toReturn: test.pagerResult[driveID],
itemPager := &apiMock.DeltaPager[models.DriveItemable]{
ToReturn: test.pagerResult[driveID],
}
cache, err := newURLCache(
@ -487,7 +488,7 @@ func (suite *URLCacheUnitSuite) TestNeedsRefresh() {
driveID,
"",
refreshInterval,
&mockItemPager{},
&apiMock.DeltaPager[models.DriveItemable]{},
fault.New(true))
require.NoError(t, err, clues.ToCore(err))
@ -516,7 +517,7 @@ func (suite *URLCacheUnitSuite) TestNewURLCache() {
name string
driveID string
refreshInt time.Duration
itemPager api.DriveItemDeltaEnumerator
itemPager api.DeltaPager[models.DriveItemable]
errors *fault.Bus
expectedErr require.ErrorAssertionFunc
}{
@ -524,7 +525,7 @@ func (suite *URLCacheUnitSuite) TestNewURLCache() {
name: "invalid driveID",
driveID: "",
refreshInt: 1 * time.Hour,
itemPager: &mockItemPager{},
itemPager: &apiMock.DeltaPager[models.DriveItemable]{},
errors: fault.New(true),
expectedErr: require.Error,
},
@ -532,7 +533,7 @@ func (suite *URLCacheUnitSuite) TestNewURLCache() {
name: "invalid refresh interval",
driveID: "drive1",
refreshInt: 100 * time.Millisecond,
itemPager: &mockItemPager{},
itemPager: &apiMock.DeltaPager[models.DriveItemable]{},
errors: fault.New(true),
expectedErr: require.Error,
},
@ -548,7 +549,7 @@ func (suite *URLCacheUnitSuite) TestNewURLCache() {
name: "valid",
driveID: "drive1",
refreshInt: 1 * time.Hour,
itemPager: &mockItemPager{},
itemPager: &apiMock.DeltaPager[models.DriveItemable]{},
errors: fault.New(true),
expectedErr: require.NoError,
},

View File

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

View File

@ -82,13 +82,10 @@ func (c Contacts) DeleteContainer(
return nil
}
// prefer GetContainerByID where possible.
// use this only in cases where the models.ContactFolderable
// is required.
func (c Contacts) GetFolder(
func (c Contacts) GetContainerByID(
ctx context.Context,
userID, containerID string,
) (models.ContactFolderable, error) {
) (graph.Container, error) {
config := &users.ItemContactFoldersContactFolderItemRequestBuilderGetRequestConfiguration{
QueryParameters: &users.ItemContactFoldersContactFolderItemRequestBuilderGetQueryParameters{
Select: idAnd(displayName, parentFolderID),
@ -109,14 +106,6 @@ func (c Contacts) GetFolder(
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
func (c Contacts) GetContainerByName(
ctx context.Context,

View File

@ -191,7 +191,7 @@ func (c Contacts) GetItemIDsInContainer(
// item ID pager
// ---------------------------------------------------------------------------
var _ itemIDPager = &contactIDPager{}
var _ DeltaPager[getIDAndAddtler] = &contactIDPager{}
type contactIDPager struct {
gs graph.Servicer
@ -203,7 +203,7 @@ func (c Contacts) NewContactIDsPager(
ctx context.Context,
userID, containerID string,
immutableIDs bool,
) itemIDPager {
) DeltaPager[getIDAndAddtler] {
config := &users.ItemContactFoldersItemContactsRequestBuilderGetRequestConfiguration{
QueryParameters: &users.ItemContactFoldersItemContactsRequestBuilderGetQueryParameters{
Select: idAnd(parentFolderID),
@ -223,7 +223,7 @@ func (c Contacts) NewContactIDsPager(
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)
if err != nil {
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
}
func (p *contactIDPager) setNext(nextLink string) {
func (p *contactIDPager) SetNext(nextLink string) {
p.builder = users.NewItemContactFoldersItemContactsRequestBuilder(nextLink, p.gs.Adapter())
}
// 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)
}
@ -247,7 +247,7 @@ func (p *contactIDPager) valuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
// delta item ID pager
// ---------------------------------------------------------------------------
var _ itemIDPager = &contactDeltaIDPager{}
var _ DeltaPager[getIDAndAddtler] = &contactDeltaIDPager{}
type contactDeltaIDPager struct {
gs graph.Servicer
@ -271,7 +271,7 @@ func (c Contacts) NewContactDeltaIDsPager(
ctx context.Context,
userID, containerID, oldDelta string,
immutableIDs bool,
) itemIDPager {
) DeltaPager[getIDAndAddtler] {
options := &users.ItemContactFoldersItemContactsDeltaRequestBuilderGetRequestConfiguration{
QueryParameters: &users.ItemContactFoldersItemContactsDeltaRequestBuilderGetQueryParameters{
Select: idAnd(parentFolderID),
@ -290,7 +290,7 @@ func (c Contacts) NewContactDeltaIDsPager(
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)
if err != nil {
return nil, graph.Stack(ctx, err)
@ -299,15 +299,15 @@ func (p *contactDeltaIDPager) getPage(ctx context.Context) (DeltaPageLinker, err
return resp, nil
}
func (p *contactDeltaIDPager) setNext(nextLink string) {
func (p *contactDeltaIDPager) SetNext(nextLink string) {
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)
}
func (p *contactDeltaIDPager) valuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
func (p *contactDeltaIDPager) ValuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
return toValues[models.Contactable](pl)
}

View File

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

View File

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

View File

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

View File

@ -16,11 +16,31 @@ import (
// 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 {
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 {
ValuesIn(PageLinker) ([]T, error)
}
@ -34,10 +54,19 @@ type DeltaPageLinker interface {
GetOdataDeltaLink() *string
}
type PageLinkValuer[T any] interface {
PageLinker
Valuer[T]
}
type SetNextLinker interface {
SetNext(nextLink string)
}
type Resetter interface {
Reset(context.Context)
}
// ---------------------------------------------------------------------------
// common funcs
// ---------------------------------------------------------------------------
@ -55,15 +84,6 @@ func NextAndDeltaLink(pl DeltaPageLinker) (string, string) {
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
type EmptyDeltaLinker[T any] struct {
PageLinkValuer[T]
@ -148,19 +168,6 @@ func toValues[T any](a any) ([]getIDAndAddtler, error) {
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 {
GetId() *string
GetAdditionalData() map[string]any
@ -169,13 +176,13 @@ type getIDAndAddtler interface {
func getAddedAndRemovedItemIDs(
ctx context.Context,
service graph.Servicer,
pager itemIDPager,
deltaPager itemIDPager,
pager DeltaPager[getIDAndAddtler],
deltaPager DeltaPager[getIDAndAddtler],
oldDelta string,
canMakeDeltaQueries bool,
) ([]string, []string, DeltaUpdate, error) {
var (
pgr itemIDPager
pgr DeltaPager[getIDAndAddtler]
resetDelta bool
)
@ -204,7 +211,7 @@ func getAddedAndRemovedItemIDs(
}
// reset deltaPager
pgr.reset(ctx)
pgr.Reset(ctx)
added, removed, deltaURL, err = getItemsAddedAndRemovedFromContainer(ctx, pgr)
if err != nil {
@ -217,7 +224,7 @@ func getAddedAndRemovedItemIDs(
// generic controller for retrieving all item ids in a container.
func getItemsAddedAndRemovedFromContainer(
ctx context.Context,
pager itemIDPager,
pager DeltaPager[getIDAndAddtler],
) ([]string, []string, string, error) {
var (
addedIDs = []string{}
@ -229,14 +236,14 @@ func getItemsAddedAndRemovedFromContainer(
for {
// get the next page of data, check for standard errors
resp, err := pager.getPage(ctx)
resp, err := pager.GetPage(ctx)
if err != nil {
return nil, nil, deltaURL, graph.Stack(ctx, err)
}
// each category type responds with a different interface, but all
// 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 {
return nil, nil, "", graph.Stack(ctx, err)
}
@ -278,7 +285,7 @@ func getItemsAddedAndRemovedFromContainer(
break
}
pager.setNext(nextLink)
pager.SetNext(nextLink)
}
logger.Ctx(ctx).Infow("completed enumeration", "count", itemCount)

View File

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

View File

@ -41,46 +41,6 @@ type Mail struct {
// 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(
ctx context.Context,
userID, parentContainerID, containerName string,
@ -131,13 +91,10 @@ func (c Mail) DeleteContainer(
return nil
}
// prefer GetContainerByID where possible.
// use this only in cases where the models.MailFolderable
// is required.
func (c Mail) GetFolder(
func (c Mail) GetContainerByID(
ctx context.Context,
userID, containerID string,
) (models.MailFolderable, error) {
) (graph.Container, error) {
config := &users.ItemMailFoldersMailFolderItemRequestBuilderGetRequestConfiguration{
QueryParameters: &users.ItemMailFoldersMailFolderItemRequestBuilderGetQueryParameters{
Select: idAnd(displayName, parentFolderID),
@ -158,14 +115,6 @@ func (c Mail) GetFolder(
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
func (c Mail) GetContainerByName(
ctx context.Context,

View File

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

View File

@ -383,7 +383,7 @@ func (suite *MailAPIIntgSuite) TestMail_RestoreLargeAttachment() {
folderName := testdata.DefaultRestoreConfig("maillargeattachmenttest").Location
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))
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
}