setting aside

This commit is contained in:
ryanfkeepers 2023-08-28 13:52:45 -06:00
parent b0eb3109dd
commit 7f6caf5fbe
22 changed files with 335 additions and 494 deletions

View File

@ -85,7 +85,7 @@ func collectItems(
invalidPrevDelta = true
newPaths = map[string]string{}
pager.Reset(ctx)
pager.Reset()
continue
}
@ -94,16 +94,11 @@ func collectItems(
return DeltaUpdate{}, nil, nil, graph.Wrap(ctx, err, "getting page")
}
vals, err := pager.ValuesIn(page)
if err != nil {
return DeltaUpdate{}, nil, nil, graph.Wrap(ctx, err, "extracting items from response")
}
err = collector(
ctx,
driveID,
driveName,
vals,
page.GetValue(),
oldPaths,
newPaths,
excluded,

View File

@ -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(ctx)
uc.itemPager.Reset()
_, _, _, err := collectItems(
ctx,

View File

@ -243,7 +243,7 @@ func populateCollections(
func collectItems(
ctx context.Context,
pager api.ChannelMessageDeltaEnumerator,
pager api.DeltaPager[models.ChatMessageable],
) ([]models.ChatMessageable, error) {
items := []models.ChatMessageable{}
@ -265,11 +265,7 @@ func collectItems(
// continue
// }
vals, err := pager.ValuesIn(page)
if err != nil {
return nil, graph.Wrap(ctx, err, "getting items in page")
}
vals := page.GetValue()
items = append(items, vals...)
nextLink, _ := api.NextAndDeltaLink(page)

View File

@ -16,7 +16,7 @@ type BackupHandler interface {
) (models.Channelable, error)
NewChannelsPager(
teamID string,
) api.ChannelDeltaEnumerator
) api.DeltaPager[models.Channelable]
GetMessageByID(
ctx context.Context,
@ -24,7 +24,7 @@ type BackupHandler interface {
) (models.ChatMessageable, error)
NewMessagePager(
teamID, channelID string,
) api.ChannelMessageDeltaEnumerator
) api.DeltaPager[models.ChatMessageable]
GetMessageReplies(
ctx context.Context,
@ -34,7 +34,7 @@ type BackupHandler interface {
type BackupMessagesHandler interface {
GetMessage(ctx context.Context, teamID, channelID, itemID string) (models.ChatMessageable, error)
NewMessagePager(teamID, channelID string) api.ChannelMessageDeltaEnumerator
NewMessagePager(teamID, channelID string) api.DeltaPager[models.ChatMessageable]
GetChannel(ctx context.Context, teamID, channelID string) (models.Channelable, error)
GetReply(ctx context.Context, teamID, channelID, messageID string) (serialization.Parsable, error)
}

View File

@ -90,7 +90,7 @@ func (c Contacts) EnumerateContainers(
// item pager
// ---------------------------------------------------------------------------
var _ itemPager[models.Contactable] = &contactsPageCtrl{}
var _ Pager[models.Contactable] = &contactsPageCtrl{}
type contactsPageCtrl struct {
gs graph.Servicer
@ -100,10 +100,11 @@ type contactsPageCtrl struct {
func (c Contacts) NewContactsPager(
userID, containerID string,
immutableIDs bool,
selectProps ...string,
) itemPager[models.Contactable] {
) Pager[models.Contactable] {
options := &users.ItemContactFoldersItemContactsRequestBuilderGetRequestConfiguration{
Headers: newPreferHeaders(preferPageSize(maxNonDeltaPageSize)),
Headers: newPreferHeaders(preferPageSize(c.options.DeltaPageSize), preferImmutableIDs(immutableIDs)),
QueryParameters: &users.ItemContactFoldersItemContactsRequestBuilderGetQueryParameters{},
// do NOT set Top. It limits the total items received.
}
@ -129,22 +130,98 @@ func (c Contacts) NewContactsPager(
return &contactsPageCtrl{c.Stable, builder, options}
}
//lint:ignore U1000 False Positive
func (p *contactsPageCtrl) getPage(ctx context.Context) (PageLinkValuer[models.Contactable], error) {
func (p *contactsPageCtrl) GetPage(ctx context.Context) (LinkValuer[models.Contactable], error) {
resp, err := p.builder.Get(ctx, p.options)
if err != nil {
return nil, graph.Stack(ctx, err)
}
return EmptyDeltaLinker[models.Contactable]{PageLinkValuer: resp}, nil
return EmptyDeltaLinker[models.Contactable]{LinkValuer: resp}, nil
}
//lint:ignore U1000 False Positive
func (p *contactsPageCtrl) setNext(nextLink string) {
func (p *contactsPageCtrl) SetNext(nextLink string) {
p.builder = users.NewItemContactFoldersItemContactsRequestBuilder(nextLink, p.gs.Adapter())
}
//lint:ignore U1000 False Positive
// ---------------------------------------------------------------------------
// delta pager
// ---------------------------------------------------------------------------
var _ DeltaPager[models.Contactable] = &contactDeltaPager{}
type contactDeltaPager struct {
gs graph.Servicer
userID string
containerID string
builder *users.ItemContactFoldersItemContactsDeltaRequestBuilder
options *users.ItemContactFoldersItemContactsDeltaRequestBuilderGetRequestConfiguration
}
func getContactDeltaBuilder(
ctx context.Context,
gs graph.Servicer,
userID, containerID string,
options *users.ItemContactFoldersItemContactsDeltaRequestBuilderGetRequestConfiguration,
) *users.ItemContactFoldersItemContactsDeltaRequestBuilder {
builder := gs.Client().
Users().
ByUserId(userID).
ContactFolders().
ByContactFolderId(containerID).
Contacts().
Delta()
return builder
}
func (c Contacts) NewContactsDeltaPager(
ctx context.Context,
userID, containerID, oldDelta string,
immutableIDs bool,
selectProps ...string,
) DeltaPager[getIDAndAddtler] {
options := &users.ItemContactFoldersItemContactsDeltaRequestBuilderGetRequestConfiguration{
Headers: newPreferHeaders(preferPageSize(c.options.DeltaPageSize), preferImmutableIDs(immutableIDs)),
QueryParameters: &users.ItemContactFoldersItemContactsDeltaRequestBuilderGetQueryParameters{
// do NOT set Top. It limits the total items received.
},
}
if len(selectProps) > 0 {
options.QueryParameters.Select = selectProps
}
var builder *users.ItemContactFoldersItemContactsDeltaRequestBuilder
if oldDelta != "" {
builder = users.NewItemContactFoldersItemContactsDeltaRequestBuilder(oldDelta, c.Stable.Adapter())
} else {
builder = getContactDeltaBuilder(ctx, c.Stable, userID, containerID, options)
}
return &contactDeltaPager{c.Stable, userID, containerID, builder, options}
}
func (p *contactDeltaPager) GetPage(ctx context.Context) (DeltaLinkValuer[models.Contactable], error) {
resp, err := p.builder.Get(ctx, p.options)
if err != nil {
return nil, graph.Stack(ctx, err)
}
return resp, nil
}
func (p *contactDeltaPager) SetNext(nextLink string) {
p.builder = users.NewItemContactFoldersItemContactsDeltaRequestBuilder(nextLink, p.gs.Adapter())
}
func (p *contactDeltaPager) Reset(ctx context.Context) {
p.builder = getContactDeltaBuilder(ctx, p.gs, p.userID, p.containerID, p.options)
}
// ---------------------------------------------------------------------------
// runners
// ---------------------------------------------------------------------------
func (c Contacts) GetItemsInContainerByCollisionKey(
ctx context.Context,
userID, containerID string,
@ -171,7 +248,7 @@ func (c Contacts) GetItemIDsInContainer(
userID, containerID string,
) (map[string]struct{}, error) {
ctx = clues.Add(ctx, "container_id", containerID)
pager := c.NewContactsPager(userID, containerID, "id")
pager := c.NewContactsPager(userID, containerID, false, "id")
items, err := enumerateItems(ctx, pager)
if err != nil {
@ -187,130 +264,6 @@ func (c Contacts) GetItemIDsInContainer(
return m, nil
}
// ---------------------------------------------------------------------------
// item ID pager
// ---------------------------------------------------------------------------
var _ DeltaPager[getIDAndAddtler] = &contactIDPager{}
type contactIDPager struct {
gs graph.Servicer
builder *users.ItemContactFoldersItemContactsRequestBuilder
options *users.ItemContactFoldersItemContactsRequestBuilderGetRequestConfiguration
}
func (c Contacts) NewContactIDsPager(
ctx context.Context,
userID, containerID string,
immutableIDs bool,
) DeltaPager[getIDAndAddtler] {
config := &users.ItemContactFoldersItemContactsRequestBuilderGetRequestConfiguration{
QueryParameters: &users.ItemContactFoldersItemContactsRequestBuilderGetQueryParameters{
Select: idAnd(parentFolderID),
// do NOT set Top. It limits the total items received.
},
Headers: newPreferHeaders(preferPageSize(maxNonDeltaPageSize), preferImmutableIDs(immutableIDs)),
}
builder := c.Stable.
Client().
Users().
ByUserId(userID).
ContactFolders().
ByContactFolderId(containerID).
Contacts()
return &contactIDPager{c.Stable, builder, config}
}
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)
}
return EmptyDeltaLinker[models.Contactable]{PageLinkValuer: resp}, nil
}
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) ValuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
return toValues[models.Contactable](pl)
}
// ---------------------------------------------------------------------------
// delta item ID pager
// ---------------------------------------------------------------------------
var _ DeltaPager[getIDAndAddtler] = &contactDeltaIDPager{}
type contactDeltaIDPager struct {
gs graph.Servicer
userID string
containerID string
builder *users.ItemContactFoldersItemContactsDeltaRequestBuilder
options *users.ItemContactFoldersItemContactsDeltaRequestBuilderGetRequestConfiguration
}
func getContactDeltaBuilder(
ctx context.Context,
gs graph.Servicer,
userID, containerID string,
options *users.ItemContactFoldersItemContactsDeltaRequestBuilderGetRequestConfiguration,
) *users.ItemContactFoldersItemContactsDeltaRequestBuilder {
builder := gs.Client().Users().ByUserId(userID).ContactFolders().ByContactFolderId(containerID).Contacts().Delta()
return builder
}
func (c Contacts) NewContactDeltaIDsPager(
ctx context.Context,
userID, containerID, oldDelta string,
immutableIDs bool,
) DeltaPager[getIDAndAddtler] {
options := &users.ItemContactFoldersItemContactsDeltaRequestBuilderGetRequestConfiguration{
QueryParameters: &users.ItemContactFoldersItemContactsDeltaRequestBuilderGetQueryParameters{
Select: idAnd(parentFolderID),
// do NOT set Top. It limits the total items received.
},
Headers: newPreferHeaders(preferPageSize(c.options.DeltaPageSize), preferImmutableIDs(immutableIDs)),
}
var builder *users.ItemContactFoldersItemContactsDeltaRequestBuilder
if oldDelta != "" {
builder = users.NewItemContactFoldersItemContactsDeltaRequestBuilder(oldDelta, c.Stable.Adapter())
} else {
builder = getContactDeltaBuilder(ctx, c.Stable, userID, containerID, options)
}
return &contactDeltaIDPager{c.Stable, userID, containerID, builder, options}
}
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)
}
return resp, nil
}
func (p *contactDeltaIDPager) SetNext(nextLink string) {
p.builder = users.NewItemContactFoldersItemContactsDeltaRequestBuilder(nextLink, p.gs.Adapter())
}
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) {
return toValues[models.Contactable](pl)
}
func (c Contacts) GetAddedAndRemovedItemIDs(
ctx context.Context,
userID, containerID, oldDelta string,
@ -322,8 +275,14 @@ func (c Contacts) GetAddedAndRemovedItemIDs(
"category", selectors.ExchangeContact,
"container_id", containerID)
pager := c.NewContactIDsPager(ctx, userID, containerID, immutableIDs)
deltaPager := c.NewContactDeltaIDsPager(ctx, userID, containerID, oldDelta, immutableIDs)
pager := c.NewContactsPager(userID, containerID, immutableIDs, idAnd(parentFolderID)...)
deltaPager := c.NewContactsDeltaPager(ctx, userID, containerID, oldDelta, immutableIDs, idAnd(parentFolderID)...)
return getAddedAndRemovedItemIDs(ctx, c.Stable, pager, deltaPager, oldDelta, canMakeDeltaQueries)
return getAddedAndRemovedItemIDs[models.Contactable](
ctx,
c.Stable,
pager,
deltaPager,
oldDelta,
canMakeDeltaQueries)
}

View File

@ -39,13 +39,13 @@ func (suite *ContactsPagerIntgSuite) TestContacts_GetItemsInContainerByCollision
ctx, flush := tester.NewContext(t)
defer flush()
container, err := ac.GetContainerByID(ctx, suite.its.userID, "contacts")
container, err := ac.GetContainerByID(ctx, suite.its.user.id, "contacts")
require.NoError(t, err, clues.ToCore(err))
conts, err := ac.Stable.
Client().
Users().
ByUserId(suite.its.userID).
ByUserId(suite.its.user.id).
ContactFolders().
ByContactFolderId(ptr.Val(container.GetId())).
Contacts().
@ -61,7 +61,7 @@ func (suite *ContactsPagerIntgSuite) TestContacts_GetItemsInContainerByCollision
expect := maps.Keys(expectM)
results, err := suite.its.ac.Contacts().GetItemsInContainerByCollisionKey(ctx, suite.its.userID, "contacts")
results, err := suite.its.ac.Contacts().GetItemsInContainerByCollisionKey(ctx, suite.its.user.id, "contacts")
require.NoError(t, err, clues.ToCore(err))
require.Less(t, 0, len(results), "requires at least one result")
@ -91,13 +91,13 @@ func (suite *ContactsPagerIntgSuite) TestContacts_GetItemsIDsInContainer() {
ctx, flush := tester.NewContext(t)
defer flush()
container, err := ac.GetContainerByID(ctx, suite.its.userID, api.DefaultContacts)
container, err := ac.GetContainerByID(ctx, suite.its.user.id, api.DefaultContacts)
require.NoError(t, err, clues.ToCore(err))
msgs, err := ac.Stable.
Client().
Users().
ByUserId(suite.its.userID).
ByUserId(suite.its.user.id).
ContactFolders().
ByContactFolderId(ptr.Val(container.GetId())).
Contacts().
@ -112,7 +112,7 @@ func (suite *ContactsPagerIntgSuite) TestContacts_GetItemsIDsInContainer() {
}
results, err := suite.its.ac.Contacts().
GetItemIDsInContainer(ctx, suite.its.userID, api.DefaultContacts)
GetItemIDsInContainer(ctx, suite.its.user.id, api.DefaultContacts)
require.NoError(t, err, clues.ToCore(err))
require.Less(t, 0, len(results), "requires at least one result")
require.Equal(t, len(expect), len(results), "must have same count of items")

View File

@ -141,7 +141,7 @@ func (suite *ContactsAPIIntgSuite) TestContacts_GetContainerByName() {
cc, err := suite.its.ac.Contacts().CreateContainer(
ctx,
suite.its.userID,
suite.its.user.id,
"",
rc.Location)
require.NoError(t, err, clues.ToCore(err))
@ -168,7 +168,7 @@ func (suite *ContactsAPIIntgSuite) TestContacts_GetContainerByName() {
_, err := suite.its.ac.
Contacts().
GetContainerByName(ctx, suite.its.userID, "", test.name)
GetContainerByName(ctx, suite.its.user.id, "", test.name)
test.expectErr(t, err, clues.ToCore(err))
})
}

View File

@ -2,7 +2,6 @@ package api
import (
"context"
"fmt"
"time"
"github.com/alcionai/clues"
@ -21,7 +20,7 @@ import (
// non-delta item pager
// ---------------------------------------------------------------------------
var _ itemPager[models.DriveItemable] = &driveItemPageCtrl{}
var _ Pager[models.DriveItemable] = &driveItemPageCtrl{}
type driveItemPageCtrl struct {
gs graph.Servicer
@ -32,7 +31,7 @@ type driveItemPageCtrl struct {
func (c Drives) NewDriveItemPager(
driveID, containerID string,
selectProps ...string,
) itemPager[models.DriveItemable] {
) Pager[models.DriveItemable] {
options := &drives.ItemItemsItemChildrenRequestBuilderGetRequestConfiguration{
QueryParameters: &drives.ItemItemsItemChildrenRequestBuilderGetQueryParameters{},
}
@ -53,17 +52,16 @@ func (c Drives) NewDriveItemPager(
}
//lint:ignore U1000 False Positive
func (p *driveItemPageCtrl) getPage(ctx context.Context) (PageLinkValuer[models.DriveItemable], error) {
func (p *driveItemPageCtrl) GetPage(ctx context.Context) (LinkValuer[models.DriveItemable], error) {
page, err := p.builder.Get(ctx, p.options)
if err != nil {
return nil, graph.Stack(ctx, err)
}
return EmptyDeltaLinker[models.DriveItemable]{PageLinkValuer: page}, nil
return EmptyDeltaLinker[models.DriveItemable]{LinkValuer: page}, nil
}
//lint:ignore U1000 False Positive
func (p *driveItemPageCtrl) setNext(nextLink string) {
func (p *driveItemPageCtrl) SetNext(nextLink string) {
p.builder = drives.NewItemItemsItemChildrenRequestBuilder(nextLink, p.gs.Adapter())
}
@ -105,7 +103,7 @@ func (c Drives) GetItemIDsInContainer(
items, err := enumerateItems(ctx, pager)
if err != nil {
return nil, graph.Wrap(ctx, err, "enumerating contacts")
return nil, graph.Wrap(ctx, err, "enumerating drive items")
}
m := map[string]DriveItemIDType{}
@ -171,25 +169,16 @@ func (c Drives) NewDriveItemDeltaPager(
return res
}
func (p *DriveItemDeltaPageCtrl) GetPage(ctx context.Context) (DeltaPageLinker, error) {
var (
resp DeltaPageLinker
err error
)
resp, err = p.builder.Get(ctx, p.options)
if err != nil {
return nil, graph.Stack(ctx, err)
}
return resp, nil
func (p *DriveItemDeltaPageCtrl) GetPage(ctx context.Context) (DeltaLinkValuer[models.DriveItemable], error) {
resp, err := p.builder.Get(ctx, p.options)
return resp, graph.Stack(ctx, err).OrNil()
}
func (p *DriveItemDeltaPageCtrl) SetNext(link string) {
p.builder = drives.NewItemItemsItemDeltaRequestBuilder(link, p.gs.Adapter())
}
func (p *DriveItemDeltaPageCtrl) Reset(context.Context) {
func (p *DriveItemDeltaPageCtrl) Reset() {
p.builder = p.gs.Client().
Drives().
ByDriveId(p.driveID).
@ -198,10 +187,6 @@ func (p *DriveItemDeltaPageCtrl) Reset(context.Context) {
Delta()
}
func (p *DriveItemDeltaPageCtrl) ValuesIn(l PageLinker) ([]models.DriveItemable, error) {
return getValues[models.DriveItemable](l)
}
// ---------------------------------------------------------------------------
// user's drives pager
// ---------------------------------------------------------------------------
@ -245,12 +230,11 @@ type nopUserDrivePageLinker struct {
func (nl nopUserDrivePageLinker) GetOdataNextLink() *string { return nil }
func (p *userDrivePager) GetPage(ctx context.Context) (PageLinker, error) {
var (
resp PageLinker
err error
)
func (nl nopUserDrivePageLinker) GetValue() []models.Driveable {
return []models.Driveable{nl.drive}
}
func (p *userDrivePager) GetPage(ctx context.Context) (LinkValuer[models.Driveable], error) {
d, err := p.gs.
Client().
Users().
@ -261,7 +245,7 @@ func (p *userDrivePager) GetPage(ctx context.Context) (PageLinker, error) {
return nil, graph.Stack(ctx, err)
}
resp = &nopUserDrivePageLinker{drive: d}
var resp LinkValuer[models.Driveable] = &nopUserDrivePageLinker{drive: d}
// TODO(keepers): turn back on when we can separate drive enumeration
// from default drive lookup.
@ -278,20 +262,6 @@ func (p *userDrivePager) SetNext(link string) {
p.builder = users.NewItemDrivesRequestBuilder(link, p.gs.Adapter())
}
func (p *userDrivePager) ValuesIn(l PageLinker) ([]models.Driveable, error) {
nl, ok := l.(*nopUserDrivePageLinker)
if !ok || nl == nil {
return nil, clues.New(fmt.Sprintf("improper page linker struct for user drives: %T", l))
}
// TODO(keepers): turn back on when we can separate drive enumeration
// from default drive lookup.
// return getValues[models.Driveable](l)
return []models.Driveable{nl.drive}, nil
}
// ---------------------------------------------------------------------------
// site's libraries pager
// ---------------------------------------------------------------------------
@ -332,28 +302,15 @@ func (c Drives) NewSiteDrivePager(
return res
}
func (p *siteDrivePager) GetPage(ctx context.Context) (PageLinker, error) {
var (
resp PageLinker
err error
)
resp, err = p.builder.Get(ctx, p.options)
if err != nil {
return nil, graph.Stack(ctx, err)
}
return resp, nil
func (p *siteDrivePager) GetPage(ctx context.Context) (LinkValuer[models.Driveable], error) {
resp, err := p.builder.Get(ctx, p.options)
return resp, graph.Stack(ctx, err).OrNil()
}
func (p *siteDrivePager) SetNext(link string) {
p.builder = sites.NewItemDrivesRequestBuilder(link, p.gs.Adapter())
}
func (p *siteDrivePager) ValuesIn(l PageLinker) ([]models.Driveable, error) {
return getValues[models.Driveable](l)
}
// ---------------------------------------------------------------------------
// drive pager
// ---------------------------------------------------------------------------
@ -374,8 +331,8 @@ func GetAllDrives(
// Loop through all pages returned by Graph API.
for {
var (
page LinkValuer[models.Driveable]
err error
page PageLinker
)
// Retry Loop for Drive retrieval. Request can timeout
@ -400,12 +357,8 @@ func GetAllDrives(
break
}
tmp, err := pager.ValuesIn(page)
if err != nil {
return nil, graph.Wrap(ctx, err, "extracting drives from response")
}
ds = append(ds, tmp...)
items := page.GetValue()
ds = append(ds, items...)
nextLink := ptr.Val(page.GetOdataNextLink())
if len(nextLink) == 0 {
@ -419,17 +372,3 @@ func GetAllDrives(
return ds, nil
}
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
func getValues[T any](l PageLinker) ([]T, error) {
page, ok := l.(interface{ GetValue() []T })
if !ok {
return nil, clues.New("page does not comply with GetValue() interface").
With("page_item_type", fmt.Sprintf("%T", l))
}
return page.GetValue(), nil
}

View File

@ -39,13 +39,13 @@ func (suite *DrivePagerIntgSuite) TestDrives_GetItemsInContainerByCollisionKey()
}{
{
name: "user drive",
driveID: suite.its.userDriveID,
rootFolderID: suite.its.userDriveRootFolderID,
driveID: suite.its.user.driveID,
rootFolderID: suite.its.user.driveRootFolderID,
},
{
name: "site drive",
driveID: suite.its.siteDriveID,
rootFolderID: suite.its.siteDriveRootFolderID,
driveID: suite.its.site.driveID,
rootFolderID: suite.its.site.driveRootFolderID,
},
}
for _, test := range table {
@ -75,7 +75,7 @@ func (suite *DrivePagerIntgSuite) TestDrives_GetItemsInContainerByCollisionKey()
t,
ims,
"need at least one item to compare in user %s drive %s folder %s",
suite.its.userID, test.driveID, test.rootFolderID)
suite.its.user.id, test.driveID, test.rootFolderID)
results, err := suite.its.ac.
Drives().
@ -113,13 +113,13 @@ func (suite *DrivePagerIntgSuite) TestDrives_GetItemIDsInContainer() {
}{
{
name: "user drive",
driveID: suite.its.userDriveID,
rootFolderID: suite.its.userDriveRootFolderID,
driveID: suite.its.user.driveID,
rootFolderID: suite.its.user.driveRootFolderID,
},
{
name: "site drive",
driveID: suite.its.siteDriveID,
rootFolderID: suite.its.siteDriveRootFolderID,
driveID: suite.its.site.driveID,
rootFolderID: suite.its.site.driveRootFolderID,
},
}
for _, test := range table {
@ -149,7 +149,7 @@ func (suite *DrivePagerIntgSuite) TestDrives_GetItemIDsInContainer() {
t,
igv,
"need at least one item to compare in user %s drive %s folder %s",
suite.its.userID, test.driveID, test.rootFolderID)
suite.its.user.id, test.driveID, test.rootFolderID)
for _, itm := range igv {
expect[ptr.Val(itm.GetId())] = api.DriveItemIDType{

View File

@ -76,8 +76,8 @@ func (suite *DriveAPIIntgSuite) TestDrives_PostItemInContainer() {
// generate a parent for the test data
parent, err := acd.PostItemInContainer(
ctx,
suite.its.userDriveID,
suite.its.userDriveRootFolderID,
suite.its.user.driveID,
suite.its.user.driveRootFolderID,
newItem(rc.Location, true),
control.Replace)
require.NoError(t, err, clues.ToCore(err))
@ -86,7 +86,7 @@ func (suite *DriveAPIIntgSuite) TestDrives_PostItemInContainer() {
folder := newItem("collision", true)
origFolder, err := acd.PostItemInContainer(
ctx,
suite.its.userDriveID,
suite.its.user.driveID,
ptr.Val(parent.GetId()),
folder,
control.Copy)
@ -96,7 +96,7 @@ func (suite *DriveAPIIntgSuite) TestDrives_PostItemInContainer() {
file := newItem("collision.txt", false)
origFile, err := acd.PostItemInContainer(
ctx,
suite.its.userDriveID,
suite.its.user.driveID,
ptr.Val(parent.GetId()),
file,
control.Copy)
@ -211,7 +211,7 @@ func (suite *DriveAPIIntgSuite) TestDrives_PostItemInContainer() {
t := suite.T()
i, err := acd.PostItemInContainer(
ctx,
suite.its.userDriveID,
suite.its.user.driveID,
ptr.Val(parent.GetId()),
test.postItem,
test.onCollision)
@ -239,8 +239,8 @@ func (suite *DriveAPIIntgSuite) TestDrives_PostItemInContainer_replaceFolderRegr
// generate a folder for the test data
folder, err := acd.PostItemInContainer(
ctx,
suite.its.userDriveID,
suite.its.userDriveRootFolderID,
suite.its.user.driveID,
suite.its.user.driveRootFolderID,
newItem(rc.Location, true),
// skip instead of replace here to get
// an ErrItemAlreadyExistsConflict, just in case.
@ -252,7 +252,7 @@ func (suite *DriveAPIIntgSuite) TestDrives_PostItemInContainer_replaceFolderRegr
file := newItem(fmt.Sprintf("collision_%d.txt", i), false)
f, err := acd.PostItemInContainer(
ctx,
suite.its.userDriveID,
suite.its.user.driveID,
ptr.Val(folder.GetId()),
file,
control.Copy)
@ -263,7 +263,7 @@ func (suite *DriveAPIIntgSuite) TestDrives_PostItemInContainer_replaceFolderRegr
resultFolder, err := acd.PostItemInContainer(
ctx,
suite.its.userDriveID,
suite.its.user.driveID,
ptr.Val(folder.GetParentReference().GetId()),
newItem(rc.Location, true),
control.Replace)
@ -274,7 +274,7 @@ func (suite *DriveAPIIntgSuite) TestDrives_PostItemInContainer_replaceFolderRegr
resultFileColl, err := acd.Stable.
Client().
Drives().
ByDriveId(suite.its.userDriveID).
ByDriveId(suite.its.user.driveID).
Items().
ByDriveItemId(ptr.Val(resultFolder.GetId())).
Children().

View File

@ -98,7 +98,7 @@ func (c Events) EnumerateContainers(
// item pager
// ---------------------------------------------------------------------------
var _ itemPager[models.Eventable] = &eventsPageCtrl{}
var _ Pager[models.Eventable] = &eventsPageCtrl{}
type eventsPageCtrl struct {
gs graph.Servicer
@ -109,7 +109,7 @@ type eventsPageCtrl struct {
func (c Events) NewEventsPager(
userID, containerID string,
selectProps ...string,
) itemPager[models.Eventable] {
) Pager[models.Eventable] {
options := &users.ItemCalendarsItemEventsRequestBuilderGetRequestConfiguration{
Headers: newPreferHeaders(preferPageSize(maxNonDeltaPageSize)),
QueryParameters: &users.ItemCalendarsItemEventsRequestBuilderGetQueryParameters{
@ -133,13 +133,11 @@ func (c Events) NewEventsPager(
}
//lint:ignore U1000 False Positive
func (p *eventsPageCtrl) getPage(ctx context.Context) (PageLinkValuer[models.Eventable], error) {
func (p *eventsPageCtrl) getPage(
ctx context.Context,
) (LinkValuer[models.Eventable], error) {
resp, err := p.builder.Get(ctx, p.options)
if err != nil {
return nil, graph.Stack(ctx, err)
}
return resp, nil
return resp, graph.Stack(ctx, err).OrNil()
}
//lint:ignore U1000 False Positive
@ -204,13 +202,11 @@ 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,
) (LinkValuer[models.Eventable], error) {
resp, err := p.builder.Get(ctx, p.options)
if err != nil {
return nil, graph.Stack(ctx, err)
}
return EmptyDeltaLinker[models.Eventable]{PageLinkValuer: resp}, nil
return EmptyDeltaLinker[models.Eventable]{LinkValuer: resp}, graph.Stack(ctx, err).OrNil()
}
func (p *eventIDPager) SetNext(nextLink string) {
@ -218,11 +214,7 @@ func (p *eventIDPager) SetNext(nextLink string) {
}
// non delta pagers don't need reset
func (p *eventIDPager) Reset(context.Context) {}
func (p *eventIDPager) ValuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
return toValues[models.Eventable](pl)
}
func (p *eventIDPager) Reset() {}
// ---------------------------------------------------------------------------
// delta item ID pager
@ -253,7 +245,7 @@ func (c Events) NewEventDeltaIDsPager(
var builder *users.ItemCalendarsItemEventsDeltaRequestBuilder
if oldDelta == "" {
builder = getEventDeltaBuilder(ctx, c.Stable, userID, containerID, options)
builder = getEventDeltaBuilder(c.Stable, userID, containerID, options)
} else {
builder = users.NewItemCalendarsItemEventsDeltaRequestBuilder(oldDelta, c.Stable.Adapter())
}
@ -262,7 +254,6 @@ func (c Events) NewEventDeltaIDsPager(
}
func getEventDeltaBuilder(
ctx context.Context,
gs graph.Servicer,
userID, containerID string,
options *users.ItemCalendarsItemEventsDeltaRequestBuilderGetRequestConfiguration,
@ -281,25 +272,19 @@ func getEventDeltaBuilder(
return builder
}
func (p *eventDeltaIDPager) GetPage(ctx context.Context) (DeltaPageLinker, error) {
func (p *eventDeltaIDPager) GetPage(
ctx context.Context,
) (DeltaLinkValuer[models.Eventable], error) {
resp, err := p.builder.Get(ctx, p.options)
if err != nil {
return nil, graph.Stack(ctx, err)
}
return resp, nil
return resp, graph.Stack(ctx, err).OrNil()
}
func (p *eventDeltaIDPager) SetNext(nextLink string) {
p.builder = users.NewItemCalendarsItemEventsDeltaRequestBuilder(nextLink, p.gs.Adapter())
}
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) {
return toValues[models.Eventable](pl)
func (p *eventDeltaIDPager) Reset() {
p.builder = getEventDeltaBuilder(p.gs, p.userID, p.containerID, p.options)
}
func (c Events) GetAddedAndRemovedItemIDs(

View File

@ -39,13 +39,13 @@ func (suite *EventsPagerIntgSuite) TestEvents_GetItemsInContainerByCollisionKey(
ctx, flush := tester.NewContext(t)
defer flush()
container, err := ac.GetContainerByID(ctx, suite.its.userID, "calendar")
container, err := ac.GetContainerByID(ctx, suite.its.user.id, "calendar")
require.NoError(t, err, clues.ToCore(err))
evts, err := ac.Stable.
Client().
Users().
ByUserId(suite.its.userID).
ByUserId(suite.its.user.id).
Calendars().
ByCalendarId(ptr.Val(container.GetId())).
Events().
@ -63,7 +63,7 @@ func (suite *EventsPagerIntgSuite) TestEvents_GetItemsInContainerByCollisionKey(
results, err := suite.its.ac.
Events().
GetItemsInContainerByCollisionKey(ctx, suite.its.userID, "calendar")
GetItemsInContainerByCollisionKey(ctx, suite.its.user.id, "calendar")
require.NoError(t, err, clues.ToCore(err))
require.Less(t, 0, len(results), "requires at least one result")

View File

@ -289,7 +289,7 @@ func (suite *EventsAPIIntgSuite) TestEvents_canFindNonStandardFolder() {
ac := suite.its.ac.Events()
rc := testdata.DefaultRestoreConfig("api_calendar_discovery")
cal, err := ac.CreateContainer(ctx, suite.its.userID, "", rc.Location)
cal, err := ac.CreateContainer(ctx, suite.its.user.id, "", rc.Location)
require.NoError(t, err, clues.ToCore(err))
var (
@ -306,7 +306,7 @@ func (suite *EventsAPIIntgSuite) TestEvents_canFindNonStandardFolder() {
err = ac.EnumerateContainers(
ctx,
suite.its.userID,
suite.its.user.id,
"Calendar",
findContainer,
fault.New(true))
@ -342,7 +342,7 @@ func (suite *EventsAPIIntgSuite) TestEvents_GetContainerByName() {
_, err := suite.its.ac.
Events().
GetContainerByName(ctx, suite.its.userID, "", test.name)
GetContainerByName(ctx, suite.its.user.id, "", test.name)
test.expectErr(t, err, clues.ToCore(err))
})
}

View File

@ -112,7 +112,7 @@ func (suite *GroupsIntgSuite) TestGetAll() {
func (suite *GroupsIntgSuite) TestGroups_GetByID() {
var (
groupID = suite.its.groupID
groupID = suite.its.group.id
groupsAPI = suite.its.ac.Groups()
)

View File

@ -74,16 +74,19 @@ func parseableToMap(t *testing.T, thing serialization.Parsable) map[string]any {
// Suite Setup
// ---------------------------------------------------------------------------
type ids struct {
id string
driveID string
driveRootFolderID string
testContainerID string
}
type intgTesterSetup struct {
ac api.Client
gockAC api.Client
userID string
userDriveID string
userDriveRootFolderID string
siteID string
siteDriveID string
siteDriveRootFolderID string
groupID string
ac api.Client
gockAC api.Client
user ids
site ids
group ids
}
func newIntegrationTesterSetup(t *testing.T) intgTesterSetup {
@ -106,42 +109,47 @@ func newIntegrationTesterSetup(t *testing.T) intgTesterSetup {
// user drive
its.userID = tconfig.M365UserID(t)
its.user.id = tconfig.M365UserID(t)
userDrive, err := its.ac.Users().GetDefaultDrive(ctx, its.userID)
userDrive, err := its.ac.Users().GetDefaultDrive(ctx, its.user.id)
require.NoError(t, err, clues.ToCore(err))
its.userDriveID = ptr.Val(userDrive.GetId())
its.user.driveID = ptr.Val(userDrive.GetId())
userDriveRootFolder, err := its.ac.Drives().GetRootFolder(ctx, its.userDriveID)
userDriveRootFolder, err := its.ac.Drives().GetRootFolder(ctx, its.user.driveID)
require.NoError(t, err, clues.ToCore(err))
its.userDriveRootFolderID = ptr.Val(userDriveRootFolder.GetId())
its.siteID = tconfig.M365SiteID(t)
its.user.driveRootFolderID = ptr.Val(userDriveRootFolder.GetId())
// site
siteDrive, err := its.ac.Sites().GetDefaultDrive(ctx, its.siteID)
its.site.id = tconfig.M365SiteID(t)
siteDrive, err := its.ac.Sites().GetDefaultDrive(ctx, its.site.id)
require.NoError(t, err, clues.ToCore(err))
its.siteDriveID = ptr.Val(siteDrive.GetId())
its.site.driveID = ptr.Val(siteDrive.GetId())
siteDriveRootFolder, err := its.ac.Drives().GetRootFolder(ctx, its.siteDriveID)
siteDriveRootFolder, err := its.ac.Drives().GetRootFolder(ctx, its.site.driveID)
require.NoError(t, err, clues.ToCore(err))
its.siteDriveRootFolderID = ptr.Val(siteDriveRootFolder.GetId())
its.site.driveRootFolderID = ptr.Val(siteDriveRootFolder.GetId())
// group
// groups/teams
// use of the TeamID is intentional here, so that we are assured
// the group has full usage of the teams api.
its.groupID = tconfig.M365TeamID(t)
its.group.id = tconfig.M365TeamID(t)
team, err := its.ac.Groups().GetByID(ctx, its.groupID)
channel, err := its.ac.Channels().
GetChannelByName(
ctx,
its.group.id,
"Test")
require.NoError(t, err, clues.ToCore(err))
require.Equal(t, "Test", ptr.Val(channel.GetDisplayName()))
its.groupID = ptr.Val(team.GetId())
its.group.testContainerID = ptr.Val(channel.GetId())
return its
}

View File

@ -17,46 +17,45 @@ import (
// ---------------------------------------------------------------------------
type DeltaPager[T any] interface {
DeltaGetPager
DeltaGetPager[T]
Resetter
SetNextLinker
ValuesInPageLinker[T]
}
type Pager[T any] interface {
GetPager
GetPager[T]
SetNextLinker
ValuesInPageLinker[T]
}
type DeltaGetPager interface {
GetPage(context.Context) (DeltaPageLinker, error)
type DeltaGetPager[T any] interface {
GetPage(context.Context) (DeltaLinkValuer[T], error)
}
type GetPager interface {
GetPage(context.Context) (PageLinker, error)
type GetPager[T any] interface {
GetPage(context.Context) (LinkValuer[T], error)
}
type Valuer[T any] interface {
GetValue() []T
}
type ValuesInPageLinker[T any] interface {
ValuesIn(PageLinker) ([]T, error)
}
type PageLinker interface {
type GetNextLinker interface {
GetOdataNextLink() *string
}
type DeltaPageLinker interface {
PageLinker
type GetDeltaLinker interface {
GetNextLinker
GetOdataDeltaLink() *string
}
type PageLinkValuer[T any] interface {
PageLinker
type LinkValuer[T any] interface {
Valuer[T]
GetNextLinker
}
type DeltaLinkValuer[T any] interface {
LinkValuer[T]
GetDeltaLinker
}
type SetNextLinker interface {
@ -64,7 +63,7 @@ type SetNextLinker interface {
}
type Resetter interface {
Reset(context.Context)
Reset()
}
// ---------------------------------------------------------------------------
@ -76,17 +75,17 @@ func IsNextLinkValid(next string) bool {
return !strings.Contains(next, `users//`)
}
func NextLink(pl PageLinker) string {
return ptr.Val(pl.GetOdataNextLink())
func NextLink(gnl GetNextLinker) string {
return ptr.Val(gnl.GetOdataNextLink())
}
func NextAndDeltaLink(pl DeltaPageLinker) (string, string) {
return NextLink(pl), ptr.Val(pl.GetOdataDeltaLink())
func NextAndDeltaLink(gdl GetDeltaLinker) (string, string) {
return NextLink(gdl), ptr.Val(gdl.GetOdataDeltaLink())
}
// EmptyDeltaLinker is used to convert PageLinker to DeltaPageLinker
type EmptyDeltaLinker[T any] struct {
PageLinkValuer[T]
LinkValuer[T]
}
func (EmptyDeltaLinker[T]) GetOdataDeltaLink() *string {
@ -94,23 +93,16 @@ func (EmptyDeltaLinker[T]) GetOdataDeltaLink() *string {
}
func (e EmptyDeltaLinker[T]) GetValue() []T {
return e.PageLinkValuer.GetValue()
return e.GetValue()
}
// ---------------------------------------------------------------------------
// generic handler for non-delta item paging in a container
// ---------------------------------------------------------------------------
type itemPager[T any] interface {
// getPage get a page with the specified options from graph
getPage(context.Context) (PageLinkValuer[T], error)
// setNext is used to pass in the next url got from graph
setNext(string)
}
func enumerateItems[T any](
ctx context.Context,
pager itemPager[T],
pager Pager[T],
) ([]T, error) {
var (
result = make([]T, 0)
@ -120,7 +112,7 @@ func enumerateItems[T any](
for len(nextLink) > 0 {
// 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, graph.Stack(ctx, err)
}
@ -128,7 +120,7 @@ func enumerateItems[T any](
result = append(result, resp.GetValue()...)
nextLink = NextLink(resp)
pager.setNext(nextLink)
pager.SetNext(nextLink)
}
logger.Ctx(ctx).Infow("completed enumeration", "count", len(result))
@ -137,9 +129,37 @@ func enumerateItems[T any](
}
// ---------------------------------------------------------------------------
// generic handler for delta-based ittem paging in a container
// generic handler for delta-based item paging in a container
// ---------------------------------------------------------------------------
func enumerateDeltaItems[T any](
ctx context.Context,
pager DeltaPager[T],
) ([]T, error) {
var (
result = make([]T, 0)
// stubbed initial value to ensure we enter the loop.
nextLink = "do-while"
)
for len(nextLink) > 0 {
// get the next page of data, check for standard errors
resp, err := pager.GetPage(ctx)
if err != nil {
return nil, graph.Stack(ctx, err)
}
result = append(result, resp.GetValue()...)
nextLink = NextLink(resp)
pager.SetNext(nextLink)
}
logger.Ctx(ctx).Infow("completed enumeration", "count", len(result))
return result, nil
}
// uses a models interface compliant with { GetValues() []T }
// to transform its results into a slice of getIDer interfaces.
// Generics used here to handle the variation of msoft interfaces
@ -173,16 +193,16 @@ type getIDAndAddtler interface {
GetAdditionalData() map[string]any
}
func getAddedAndRemovedItemIDs(
func getAddedAndRemovedItemIDs[T any](
ctx context.Context,
service graph.Servicer,
pager DeltaPager[getIDAndAddtler],
deltaPager DeltaPager[getIDAndAddtler],
pager DeltaPager[T],
deltaPager DeltaPager[T],
oldDelta string,
canMakeDeltaQueries bool,
) ([]string, []string, DeltaUpdate, error) {
var (
pgr DeltaPager[getIDAndAddtler]
pgr DeltaPager[T]
resetDelta bool
)
@ -211,7 +231,7 @@ func getAddedAndRemovedItemIDs(
}
// reset deltaPager
pgr.Reset(ctx)
pgr.Reset()
added, removed, deltaURL, err = getItemsAddedAndRemovedFromContainer(ctx, pgr)
if err != nil {
@ -222,9 +242,9 @@ func getAddedAndRemovedItemIDs(
}
// generic controller for retrieving all item ids in a container.
func getItemsAddedAndRemovedFromContainer(
func getItemsAddedAndRemovedFromContainer[T any](
ctx context.Context,
pager DeltaPager[getIDAndAddtler],
pager DeltaPager[T],
) ([]string, []string, string, error) {
var (
addedIDs = []string{}
@ -243,10 +263,7 @@ func getItemsAddedAndRemovedFromContainer(
// 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)
if err != nil {
return nil, nil, "", graph.Stack(ctx, err)
}
items := resp.GetValue()
itemCount += len(items)
page++

View File

@ -57,41 +57,39 @@ func (v testPagerValue) GetAdditionalData() map[string]any {
// mock page
type testPage struct {
values []any
type testPage[T any] struct {
values []T
}
func (p testPage) GetOdataNextLink() *string {
func (p testPage[T]) GetOdataNextLink() *string {
// no next, just one page
return ptr.To("")
}
func (p testPage) GetOdataDeltaLink() *string {
func (p testPage[T]) GetOdataDeltaLink() *string {
// delta is not tested here
return ptr.To("")
}
func (p testPage) GetValue() []any {
func (p testPage[T]) GetValue() []T {
return p.values
}
// mock item pager
var _ itemPager[any] = &testPager{}
var _ Pager[any] = &testPager{}
type testPager struct {
t *testing.T
pager testPage
pager testPage[any]
pageErr error
}
//lint:ignore U1000 False Positive
func (p *testPager) getPage(ctx context.Context) (PageLinkValuer[any], error) {
func (p *testPager) GetPage(ctx context.Context) (LinkValuer[any], error) {
return p.pager, p.pageErr
}
//lint:ignore U1000 False Positive
func (p *testPager) setNext(nextLink string) {}
func (p *testPager) SetNext(nextLink string) {}
// mock id pager
@ -105,7 +103,7 @@ type testIDsPager struct {
needsReset bool
}
func (p *testIDsPager) GetPage(ctx context.Context) (DeltaPageLinker, error) {
func (p *testIDsPager) GetPage(ctx context.Context) (DeltaLinkValuer[getIDAndAddtler], error) {
if p.errorCode != "" {
ierr := odataerrors.NewMainError()
ierr.SetCode(&p.errorCode)
@ -116,10 +114,10 @@ func (p *testIDsPager) GetPage(ctx context.Context) (DeltaPageLinker, error) {
return nil, err
}
return testPage{}, nil
return testPage[getIDAndAddtler]{}, nil
}
func (p *testIDsPager) SetNext(string) {}
func (p *testIDsPager) Reset(context.Context) {
func (p *testIDsPager) Reset() {
if !p.needsReset {
require.Fail(p.t, "reset should not be called")
}
@ -128,7 +126,7 @@ func (p *testIDsPager) Reset(context.Context) {
p.errorCode = ""
}
func (p *testIDsPager) ValuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
func (p *testIDsPager) ValuesIn(pl LinkValuer[getIDAndAddtler]) ([]getIDAndAddtler, error) {
items := []getIDAndAddtler{}
for _, id := range p.added {
@ -157,7 +155,7 @@ func TestItemPagerUnitSuite(t *testing.T) {
func (suite *ItemPagerUnitSuite) TestEnumerateItems() {
tests := []struct {
name string
getPager func(*testing.T, context.Context) itemPager[any]
getPager func(*testing.T, context.Context) Pager[any]
expect []any
expectErr require.ErrorAssertionFunc
}{
@ -166,10 +164,10 @@ func (suite *ItemPagerUnitSuite) TestEnumerateItems() {
getPager: func(
t *testing.T,
ctx context.Context,
) itemPager[any] {
) Pager[any] {
return &testPager{
t: t,
pager: testPage{[]any{"foo", "bar"}},
pager: testPage[any]{[]any{"foo", "bar"}},
}
},
expect: []any{"foo", "bar"},
@ -180,7 +178,7 @@ func (suite *ItemPagerUnitSuite) TestEnumerateItems() {
getPager: func(
t *testing.T,
ctx context.Context,
) itemPager[any] {
) Pager[any] {
return &testPager{
t: t,
pageErr: assert.AnError,

View File

@ -41,7 +41,7 @@ func (suite *ListsAPIIntgSuite) TestLists_PostDrive() {
var (
acl = suite.its.ac.Lists()
driveName = testdata.DefaultRestoreConfig("list_api_post_drive").Location
siteID = suite.its.siteID
siteID = suite.its.site.id
)
// first post, should have no errors

View File

@ -31,7 +31,7 @@ func (c Mail) NewMailFolderPager(userID string) mailFolderPager {
return mailFolderPager{c.Stable, builder}
}
func (p *mailFolderPager) getPage(ctx context.Context) (PageLinker, error) {
func (p *mailFolderPager) getPage(ctx context.Context) (LinkValuer[models.MailFolderable], error) {
page, err := p.builder.Get(ctx, nil)
if err != nil {
return nil, graph.Stack(ctx, err)
@ -44,7 +44,7 @@ func (p *mailFolderPager) setNext(nextLink string) {
p.builder = users.NewItemMailFoldersRequestBuilder(nextLink, p.service.Adapter())
}
func (p *mailFolderPager) valuesIn(pl PageLinker) ([]models.MailFolderable, error) {
func (p *mailFolderPager) valuesIn(pl LinkValuer[models.MailFolderable]) ([]models.MailFolderable, error) {
// Ideally this should be `users.ItemMailFoldersResponseable`, but
// that is not a thing as stable returns different result
page, ok := pl.(models.MailFolderCollectionResponseable)
@ -79,10 +79,7 @@ func (c Mail) EnumerateContainers(
return graph.Stack(ctx, err)
}
resp, err := pgr.valuesIn(page)
if err != nil {
return graph.Stack(ctx, err)
}
resp := page.GetValue()
for _, fold := range resp {
if el.Failure() != nil {
@ -121,7 +118,7 @@ func (c Mail) EnumerateContainers(
// item pager
// ---------------------------------------------------------------------------
var _ itemPager[models.Messageable] = &mailPageCtrl{}
var _ Pager[models.Messageable] = &mailPageCtrl{}
type mailPageCtrl struct {
gs graph.Servicer
@ -132,7 +129,7 @@ type mailPageCtrl struct {
func (c Mail) NewMailPager(
userID, containerID string,
selectProps ...string,
) itemPager[models.Messageable] {
) Pager[models.Messageable] {
options := &users.ItemMailFoldersItemMessagesRequestBuilderGetRequestConfiguration{
Headers: newPreferHeaders(preferPageSize(maxNonDeltaPageSize)),
QueryParameters: &users.ItemMailFoldersItemMessagesRequestBuilderGetQueryParameters{
@ -155,14 +152,11 @@ func (c Mail) NewMailPager(
return &mailPageCtrl{c.Stable, builder, options}
}
//lint:ignore U1000 False Positive
func (p *mailPageCtrl) getPage(ctx context.Context) (PageLinkValuer[models.Messageable], error) {
func (p *mailPageCtrl) GetPage(
ctx context.Context,
) (LinkValuer[models.Messageable], error) {
page, err := p.builder.Get(ctx, p.options)
if err != nil {
return nil, graph.Stack(ctx, err)
}
return EmptyDeltaLinker[models.Messageable]{PageLinkValuer: page}, nil
return EmptyDeltaLinker[models.Messageable]{LinkValuer: page}, graph.Stack(ctx, err).OrNil()
}
//lint:ignore U1000 False Positive
@ -206,13 +200,9 @@ 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) (DeltaLinkValuer[models.Messageable], error) {
page, err := p.builder.Get(ctx, p.options)
if err != nil {
return nil, graph.Stack(ctx, err)
}
return EmptyDeltaLinker[models.Messageable]{PageLinkValuer: page}, nil
return EmptyDeltaLinker[models.Messageable]{LinkValuer: page}, graph.Stack(ctx, err).OrNil()
}
func (p *mailIDPager) SetNext(nextLink string) {
@ -220,11 +210,7 @@ func (p *mailIDPager) SetNext(nextLink string) {
}
// non delta pagers don't have reset
func (p *mailIDPager) Reset(context.Context) {}
func (p *mailIDPager) ValuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
return toValues[models.Messageable](pl)
}
func (p *mailIDPager) Reset() {}
func (c Mail) GetItemsInContainerByCollisionKey(
ctx context.Context,
@ -256,7 +242,7 @@ func (c Mail) GetItemIDsInContainer(
items, err := enumerateItems(ctx, pager)
if err != nil {
return nil, graph.Wrap(ctx, err, "enumerating contacts")
return nil, graph.Wrap(ctx, err, "enumerating mail messages")
}
m := map[string]struct{}{}
@ -324,7 +310,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) (LinkValuer[models.Messageable], error) {
page, err := p.builder.Get(ctx, p.options)
if err != nil {
return nil, graph.Stack(ctx, err)
@ -337,7 +323,7 @@ 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() {
p.builder = p.gs.
Client().
Users().
@ -348,10 +334,6 @@ func (p *mailDeltaIDPager) Reset(ctx context.Context) {
Delta()
}
func (p *mailDeltaIDPager) ValuesIn(pl PageLinker) ([]getIDAndAddtler, error) {
return toValues[models.Messageable](pl)
}
func (c Mail) GetAddedAndRemovedItemIDs(
ctx context.Context,
userID, containerID, oldDelta string,

View File

@ -40,13 +40,13 @@ func (suite *MailPagerIntgSuite) TestMail_GetItemsInContainerByCollisionKey() {
ctx, flush := tester.NewContext(t)
defer flush()
container, err := ac.GetContainerByID(ctx, suite.its.userID, api.MailInbox)
container, err := ac.GetContainerByID(ctx, suite.its.user.id, api.MailInbox)
require.NoError(t, err, clues.ToCore(err))
msgs, err := ac.Stable.
Client().
Users().
ByUserId(suite.its.userID).
ByUserId(suite.its.user.id).
MailFolders().
ByMailFolderId(ptr.Val(container.GetId())).
Messages().
@ -62,7 +62,7 @@ func (suite *MailPagerIntgSuite) TestMail_GetItemsInContainerByCollisionKey() {
expect := maps.Keys(expectM)
results, err := suite.its.ac.Mail().GetItemsInContainerByCollisionKey(ctx, suite.its.userID, api.MailInbox)
results, err := suite.its.ac.Mail().GetItemsInContainerByCollisionKey(ctx, suite.its.user.id, api.MailInbox)
require.NoError(t, err, clues.ToCore(err))
require.Less(t, 0, len(results), "requires at least one result")
@ -101,7 +101,7 @@ func (suite *MailPagerIntgSuite) TestMail_GetItemsIDsInContainer() {
msgs, err := ac.Stable.
Client().
Users().
ByUserId(suite.its.userID).
ByUserId(suite.its.user.id).
MailFolders().
ByMailFolderId(api.MailInbox).
Messages().
@ -116,7 +116,7 @@ func (suite *MailPagerIntgSuite) TestMail_GetItemsIDsInContainer() {
}
results, err := suite.its.ac.Mail().
GetItemIDsInContainer(ctx, suite.its.userID, api.MailInbox)
GetItemIDsInContainer(ctx, suite.its.user.id, api.MailInbox)
require.NoError(t, err, clues.ToCore(err))
require.Less(t, 0, len(results), "requires at least one result")
require.Equal(t, len(expect), len(results), "must have same count of items")

View File

@ -414,7 +414,7 @@ func (suite *MailAPIIntgSuite) TestMail_GetContainerByName() {
ctx, flush := tester.NewContext(t)
defer flush()
parent, err := acm.CreateContainer(ctx, suite.its.userID, "msgfolderroot", rc.Location)
parent, err := acm.CreateContainer(ctx, suite.its.user.id, "msgfolderroot", rc.Location)
require.NoError(t, err, clues.ToCore(err))
table := []struct {
@ -448,7 +448,7 @@ func (suite *MailAPIIntgSuite) TestMail_GetContainerByName() {
ctx, flush := tester.NewContext(t)
defer flush()
_, err := acm.GetContainerByName(ctx, suite.its.userID, test.parentContainerID, test.name)
_, err := acm.GetContainerByName(ctx, suite.its.user.id, test.parentContainerID, test.name)
test.expectErr(t, err, clues.ToCore(err))
})
}
@ -460,10 +460,10 @@ func (suite *MailAPIIntgSuite) TestMail_GetContainerByName() {
ctx, flush := tester.NewContext(t)
defer flush()
child, err := acm.CreateContainer(ctx, suite.its.userID, pid, rc.Location)
child, err := acm.CreateContainer(ctx, suite.its.user.id, pid, rc.Location)
require.NoError(t, err, clues.ToCore(err))
result, err := acm.GetContainerByName(ctx, suite.its.userID, pid, rc.Location)
result, err := acm.GetContainerByName(ctx, suite.its.user.id, pid, rc.Location)
assert.NoError(t, err, clues.ToCore(err))
assert.Equal(t, ptr.Val(child.GetId()), ptr.Val(result.GetId()))
})

View File

@ -8,26 +8,25 @@ import (
"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
NextLink *string
Values []T
Err error
}
func (pr PagerResult[T]) GetValue() []T {
return pr.Values
}
func (pr PagerResult[T]) GetOdataNextLink() *string {
return pr.NextLink
}
func (pr PagerResult[T]) GetOdataDeltaLink() *string {
return pr.DeltaLink
}
// ---------------------------------------------------------------------------
// non-delta pager
// ---------------------------------------------------------------------------
@ -37,7 +36,7 @@ type Pager[T any] struct {
getIdx int
}
func (p *Pager[T]) GetPage(context.Context) (api.PageLinker, error) {
func (p *Pager[T]) GetPage(context.Context) (api.LinkValuer[T], error) {
if len(p.ToReturn) <= p.getIdx {
return nil, clues.New("index out of bounds").
With("index", p.getIdx, "values", p.ToReturn)
@ -46,28 +45,11 @@ func (p *Pager[T]) GetPage(context.Context) (api.PageLinker, error) {
idx := p.getIdx
p.getIdx++
link := DeltaNextLinks{Next: p.ToReturn[idx].NextLink}
return &link, p.ToReturn[idx].Err
return &p.ToReturn[idx], 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
// ---------------------------------------------------------------------------
@ -77,7 +59,7 @@ type DeltaPager[T any] struct {
getIdx int
}
func (p *DeltaPager[T]) GetPage(context.Context) (api.DeltaPageLinker, error) {
func (p *DeltaPager[T]) GetPage(context.Context) (api.DeltaLinkValuer[T], error) {
if len(p.ToReturn) <= p.getIdx {
return nil, clues.New("index out of bounds").
With("index", p.getIdx, "values", p.ToReturn)
@ -86,28 +68,8 @@ func (p *DeltaPager[T]) GetPage(context.Context) (api.DeltaPageLinker, error) {
idx := p.getIdx
p.getIdx++
link := DeltaNextLinks{
Next: p.ToReturn[idx].NextLink,
Delta: p.ToReturn[idx].DeltaLink,
}
return &link, p.ToReturn[idx].Err
return &p.ToReturn[idx], 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
}
func (p *DeltaPager[T]) SetNext(string) {}
func (p *DeltaPager[T]) Reset() {}