lookup contact folder as fallback (#1174)
## Description In the event that a user only has a primary contact folder, and no subfolders, the contact folder legacy iter needs to fall back to checking for the contacts default folder in an isolated query, because that folder isn't provided as part of the contacts folders get request. ## Type of change - [x] 🐛 Bugfix ## Issue(s) * #1113 ## Test Plan - [x] 💪 Manual - [x] 💚 E2E
This commit is contained in:
parent
0963bbe364
commit
48cb751ee0
@ -291,6 +291,10 @@ func (suite *ExchangeServiceSuite) TestGraphQueryFunctions() {
|
|||||||
name: "GraphQuery: Get All ContactFolders",
|
name: "GraphQuery: Get All ContactFolders",
|
||||||
function: GetAllContactFolderNamesForUser,
|
function: GetAllContactFolderNamesForUser,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "GraphQuery: Get Default ContactFolder",
|
||||||
|
function: GetDefaultContactFolderForUser,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "GraphQuery: Get All Events for User",
|
name: "GraphQuery: Get All Events for User",
|
||||||
function: GetAllEventsForUser,
|
function: GetAllEventsForUser,
|
||||||
|
|||||||
@ -123,6 +123,12 @@ func (suite *ExchangeIteratorSuite) TestIterativeFunctions() {
|
|||||||
iterativeFunction: IterateFilterContainersForCollections,
|
iterativeFunction: IterateFilterContainersForCollections,
|
||||||
scope: contactScope[0],
|
scope: contactScope[0],
|
||||||
transformer: models.CreateContactFolderCollectionResponseFromDiscriminatorValue,
|
transformer: models.CreateContactFolderCollectionResponseFromDiscriminatorValue,
|
||||||
|
}, {
|
||||||
|
name: "Default Contacts Folder",
|
||||||
|
queryFunction: GetDefaultContactFolderForUser,
|
||||||
|
iterativeFunction: IterateSelectAllContactsForCollections,
|
||||||
|
scope: contactScope[0],
|
||||||
|
transformer: models.CreateContactFolderCollectionResponseFromDiscriminatorValue,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
|||||||
@ -6,8 +6,9 @@ import (
|
|||||||
msuser "github.com/microsoftgraph/msgraph-sdk-go/users"
|
msuser "github.com/microsoftgraph/msgraph-sdk-go/users"
|
||||||
mscalendars "github.com/microsoftgraph/msgraph-sdk-go/users/item/calendars"
|
mscalendars "github.com/microsoftgraph/msgraph-sdk-go/users/item/calendars"
|
||||||
mscontactfolder "github.com/microsoftgraph/msgraph-sdk-go/users/item/contactfolders"
|
mscontactfolder "github.com/microsoftgraph/msgraph-sdk-go/users/item/contactfolders"
|
||||||
mscontactbyid "github.com/microsoftgraph/msgraph-sdk-go/users/item/contactfolders/item"
|
mscontactfolderitem "github.com/microsoftgraph/msgraph-sdk-go/users/item/contactfolders/item"
|
||||||
mscontactfolderitem "github.com/microsoftgraph/msgraph-sdk-go/users/item/contactfolders/item/contacts"
|
mscontactfolderchild "github.com/microsoftgraph/msgraph-sdk-go/users/item/contactfolders/item/childfolders"
|
||||||
|
mscontactfolderitemcontact "github.com/microsoftgraph/msgraph-sdk-go/users/item/contactfolders/item/contacts"
|
||||||
mscontacts "github.com/microsoftgraph/msgraph-sdk-go/users/item/contacts"
|
mscontacts "github.com/microsoftgraph/msgraph-sdk-go/users/item/contacts"
|
||||||
msevents "github.com/microsoftgraph/msgraph-sdk-go/users/item/events"
|
msevents "github.com/microsoftgraph/msgraph-sdk-go/users/item/events"
|
||||||
msfolder "github.com/microsoftgraph/msgraph-sdk-go/users/item/mailfolders"
|
msfolder "github.com/microsoftgraph/msgraph-sdk-go/users/item/mailfolders"
|
||||||
@ -236,7 +237,7 @@ func optionsForContactFolders(moreOps []string) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
func optionsForContactFolderByID(moreOps []string) (
|
func optionsForContactFolderByID(moreOps []string) (
|
||||||
*mscontactbyid.ContactFolderItemRequestBuilderGetRequestConfiguration,
|
*mscontactfolderitem.ContactFolderItemRequestBuilderGetRequestConfiguration,
|
||||||
error,
|
error,
|
||||||
) {
|
) {
|
||||||
selecting, err := buildOptions(moreOps, folders)
|
selecting, err := buildOptions(moreOps, folders)
|
||||||
@ -244,10 +245,10 @@ func optionsForContactFolderByID(moreOps []string) (
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
requestParameters := &mscontactbyid.ContactFolderItemRequestBuilderGetQueryParameters{
|
requestParameters := &mscontactfolderitem.ContactFolderItemRequestBuilderGetQueryParameters{
|
||||||
Select: selecting,
|
Select: selecting,
|
||||||
}
|
}
|
||||||
options := &mscontactbyid.ContactFolderItemRequestBuilderGetRequestConfiguration{
|
options := &mscontactfolderitem.ContactFolderItemRequestBuilderGetRequestConfiguration{
|
||||||
QueryParameters: requestParameters,
|
QueryParameters: requestParameters,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,16 +299,16 @@ func optionsForMailFoldersItem(
|
|||||||
// TODO: Remove after Issue #828; requires updating msgraph to v0.34
|
// TODO: Remove after Issue #828; requires updating msgraph to v0.34
|
||||||
func optionsForContactFoldersItem(
|
func optionsForContactFoldersItem(
|
||||||
moreOps []string,
|
moreOps []string,
|
||||||
) (*mscontactfolderitem.ContactsRequestBuilderGetRequestConfiguration, error) {
|
) (*mscontactfolderitemcontact.ContactsRequestBuilderGetRequestConfiguration, error) {
|
||||||
selecting, err := buildOptions(moreOps, contacts)
|
selecting, err := buildOptions(moreOps, contacts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
requestParameters := &mscontactfolderitem.ContactsRequestBuilderGetQueryParameters{
|
requestParameters := &mscontactfolderitemcontact.ContactsRequestBuilderGetQueryParameters{
|
||||||
Select: selecting,
|
Select: selecting,
|
||||||
}
|
}
|
||||||
options := &mscontactfolderitem.ContactsRequestBuilderGetRequestConfiguration{
|
options := &mscontactfolderitemcontact.ContactsRequestBuilderGetRequestConfiguration{
|
||||||
QueryParameters: requestParameters,
|
QueryParameters: requestParameters,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,6 +333,25 @@ func optionsForEvents(moreOps []string) (*msevents.EventsRequestBuilderGetReques
|
|||||||
return options, nil
|
return options, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// optionsForContactChildFolders builds a contacts child folders request.
|
||||||
|
func optionsForContactChildFolders(
|
||||||
|
moreOps []string,
|
||||||
|
) (*mscontactfolderchild.ChildFoldersRequestBuilderGetRequestConfiguration, error) {
|
||||||
|
selecting, err := buildOptions(moreOps, contacts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
requestParameters := &mscontactfolderchild.ChildFoldersRequestBuilderGetQueryParameters{
|
||||||
|
Select: selecting,
|
||||||
|
}
|
||||||
|
options := &mscontactfolderchild.ChildFoldersRequestBuilderGetRequestConfiguration{
|
||||||
|
QueryParameters: requestParameters,
|
||||||
|
}
|
||||||
|
|
||||||
|
return options, nil
|
||||||
|
}
|
||||||
|
|
||||||
// optionsForContacts transforms options into select query for MailContacts
|
// optionsForContacts transforms options into select query for MailContacts
|
||||||
// @return is the first call in Contacts().GetWithRequestConfigurationAndResponseHandler(options, handler)
|
// @return is the first call in Contacts().GetWithRequestConfigurationAndResponseHandler(options, handler)
|
||||||
func optionsForContacts(moreOps []string) (*mscontacts.ContactsRequestBuilderGetRequestConfiguration, error) {
|
func optionsForContacts(moreOps []string) (*mscontacts.ContactsRequestBuilderGetRequestConfiguration, error) {
|
||||||
|
|||||||
@ -346,10 +346,12 @@ func GetContainerID(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetupExchangeCollectionVars is a helper function returns a sets
|
// SetupExchangeCollectionVars is a helper function returns a sets
|
||||||
// Exchange.Type specific functions based on scope
|
// Exchange.Type specific functions based on scope.
|
||||||
|
// The []GraphQuery slice provides fallback queries in the event that
|
||||||
|
// initial queries provide zero results.
|
||||||
func SetupExchangeCollectionVars(scope selectors.ExchangeScope) (
|
func SetupExchangeCollectionVars(scope selectors.ExchangeScope) (
|
||||||
absser.ParsableFactory,
|
absser.ParsableFactory,
|
||||||
GraphQuery,
|
[]GraphQuery,
|
||||||
GraphIterateFunc,
|
GraphIterateFunc,
|
||||||
error,
|
error,
|
||||||
) {
|
) {
|
||||||
@ -359,14 +361,14 @@ func SetupExchangeCollectionVars(scope selectors.ExchangeScope) (
|
|||||||
|
|
||||||
if scope.IncludesCategory(selectors.ExchangeContact) {
|
if scope.IncludesCategory(selectors.ExchangeContact) {
|
||||||
return models.CreateContactFolderCollectionResponseFromDiscriminatorValue,
|
return models.CreateContactFolderCollectionResponseFromDiscriminatorValue,
|
||||||
GetAllContactFolderNamesForUser,
|
[]GraphQuery{GetAllContactFolderNamesForUser, GetDefaultContactFolderForUser},
|
||||||
IterateSelectAllContactsForCollections,
|
IterateSelectAllContactsForCollections,
|
||||||
nil
|
nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if scope.IncludesCategory(selectors.ExchangeEvent) {
|
if scope.IncludesCategory(selectors.ExchangeEvent) {
|
||||||
return models.CreateCalendarCollectionResponseFromDiscriminatorValue,
|
return models.CreateCalendarCollectionResponseFromDiscriminatorValue,
|
||||||
GetAllCalendarNamesForUser,
|
[]GraphQuery{GetAllCalendarNamesForUser},
|
||||||
IterateSelectAllEventsFromCalendars,
|
IterateSelectAllEventsFromCalendars,
|
||||||
nil
|
nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,9 +51,25 @@ func GetAllCalendarNamesForUser(ctx context.Context, gs graph.Service, user stri
|
|||||||
return gs.Client().UsersById(user).Calendars().Get(ctx, options)
|
return gs.Client().UsersById(user).Calendars().Get(ctx, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDefaultContactFolderForUser is a GraphQuery function for getting the ContactFolderId
|
||||||
|
// and display names for the default "Contacts" folder.
|
||||||
|
// Only returns the default Contact Folder
|
||||||
|
func GetDefaultContactFolderForUser(ctx context.Context, gs graph.Service, user string) (absser.Parsable, error) {
|
||||||
|
options, err := optionsForContactChildFolders([]string{"displayName", "parentFolderId"})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gs.Client().
|
||||||
|
UsersById(user).
|
||||||
|
ContactFoldersById(rootFolderAlias).
|
||||||
|
ChildFolders().
|
||||||
|
Get(ctx, options)
|
||||||
|
}
|
||||||
|
|
||||||
// GetAllContactFolderNamesForUser is a GraphQuery function for getting ContactFolderId
|
// GetAllContactFolderNamesForUser is a GraphQuery function for getting ContactFolderId
|
||||||
// and display names for contacts. All other information is omitted.
|
// and display names for contacts. All other information is omitted.
|
||||||
// Does not return the primary Contact Folder
|
// Does not return the default Contact Folder
|
||||||
func GetAllContactFolderNamesForUser(ctx context.Context, gs graph.Service, user string) (absser.Parsable, error) {
|
func GetAllContactFolderNamesForUser(ctx context.Context, gs graph.Service, user string) (absser.Parsable, error) {
|
||||||
options, err := optionsForContactFolders([]string{"displayName", "parentFolderId"})
|
options, err := optionsForContactFolders([]string{"displayName", "parentFolderId"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -335,14 +335,20 @@ func (gc *GraphConnector) legacyFetchItems(
|
|||||||
) (map[string]*exchange.Collection, error) {
|
) (map[string]*exchange.Collection, error) {
|
||||||
var (
|
var (
|
||||||
errs error
|
errs error
|
||||||
|
errUpdater = func(id string, err error) {
|
||||||
|
errs = support.WrapAndAppend(id, err, errs)
|
||||||
|
}
|
||||||
collections = map[string]*exchange.Collection{}
|
collections = map[string]*exchange.Collection{}
|
||||||
)
|
)
|
||||||
|
|
||||||
transformer, query, gIter, err := exchange.SetupExchangeCollectionVars(scope)
|
transformer, queries, gIter, err := exchange.SetupExchangeCollectionVars(scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, support.WrapAndAppend(gc.Service().Adapter().GetBaseUrl(), err, nil)
|
return nil, support.WrapAndAppend(gc.Service().Adapter().GetBaseUrl(), err, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// queries is assumed to provide fallbacks in case of empty results. Any
|
||||||
|
// non-zero collection production will break out of the loop.
|
||||||
|
for _, query := range queries {
|
||||||
response, err := query(ctx, &gc.graphService, qp.User)
|
response, err := query(ctx, &gc.graphService, qp.User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(
|
return nil, errors.Wrapf(
|
||||||
@ -356,18 +362,18 @@ func (gc *GraphConnector) legacyFetchItems(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
errUpdater := func(id string, err error) {
|
|
||||||
errs = support.WrapAndAppend(id, err, errs)
|
|
||||||
}
|
|
||||||
|
|
||||||
// callbackFunc iterates through all M365 object target and fills exchange.Collection.jobs[]
|
// callbackFunc iterates through all M365 object target and fills exchange.Collection.jobs[]
|
||||||
// with corresponding item M365IDs. New collections are created for each directory.
|
// with corresponding item M365IDs. New collections are created for each directory.
|
||||||
// Each directory used the M365 Identifier. The use of ID stops collisions betweens users
|
// Each directory used the M365 Identifier. The use of ID stops collisions betweens users
|
||||||
callbackFunc := gIter(ctx, qp, errUpdater, collections, gc.UpdateStatus, resolver)
|
callbackFunc := gIter(ctx, qp, errUpdater, collections, gc.UpdateStatus, resolver)
|
||||||
iterateError := pageIterator.Iterate(ctx, callbackFunc)
|
|
||||||
|
|
||||||
if iterateError != nil {
|
if err := pageIterator.Iterate(ctx, callbackFunc); err != nil {
|
||||||
errs = support.WrapAndAppend(gc.graphService.adapter.GetBaseUrl(), iterateError, errs)
|
return nil, support.WrapAndAppend(gc.graphService.adapter.GetBaseUrl(), err, errs)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(collections) > 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return collections, errs
|
return collections, errs
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user