standardizes the calendar resolver interface (#2162)
## Description Adds a little extra process into the calendar resolver so that it mimics the mail and contact resolvers. This will allow us to collapse the three resolvers into a more common handler or interface. We can take this change or drop it. I added the code in exploration of the event test failures, and figured I'd throw it out just in case. ## Does this PR need a docs update or release note? - [x] ⛔ No ## Type of change - [x] 🧹 Tech Debt/Cleanup ## Issue(s) * #2022 ## Test Plan - [x] 💚 E2E
This commit is contained in:
parent
0852de5d64
commit
8df00bd386
@ -58,6 +58,28 @@ func (c Events) DeleteCalendar(
|
|||||||
return c.stable.Client().UsersById(user).CalendarsById(calendarID).Delete(ctx, nil)
|
return c.stable.Client().UsersById(user).CalendarsById(calendarID).Delete(ctx, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c Events) GetContainerByID(
|
||||||
|
ctx context.Context,
|
||||||
|
userID, containerID string,
|
||||||
|
) (graph.Container, error) {
|
||||||
|
service, err := c.service()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ofc, err := optionsForCalendarsByID([]string{"name", "owner"})
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "options for event calendar")
|
||||||
|
}
|
||||||
|
|
||||||
|
cal, err := service.Client().UsersById(userID).CalendarsById(containerID).Get(ctx, ofc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return graph.CalendarDisplayable{Calendarable: cal}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetItem retrieves an Eventable item.
|
// GetItem retrieves an Eventable item.
|
||||||
func (c Events) GetItem(
|
func (c Events) GetItem(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
@ -183,14 +205,9 @@ func (c Events) GetAddedAndRemovedItemIDs(
|
|||||||
errs *multierror.Error
|
errs *multierror.Error
|
||||||
)
|
)
|
||||||
|
|
||||||
options, err := optionsForEventsByCalendarDelta([]string{"id"})
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, DeltaUpdate{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(oldDelta) > 0 {
|
if len(oldDelta) > 0 {
|
||||||
builder := users.NewItemCalendarsItemEventsDeltaRequestBuilder(oldDelta, service.Adapter())
|
builder := users.NewItemCalendarsItemEventsDeltaRequestBuilder(oldDelta, service.Adapter())
|
||||||
pgr := &eventPager{service, builder, options}
|
pgr := &eventPager{service, builder, nil}
|
||||||
|
|
||||||
added, removed, deltaURL, err := getItemsAddedAndRemovedFromContainer(ctx, pgr)
|
added, removed, deltaURL, err := getItemsAddedAndRemovedFromContainer(ctx, pgr)
|
||||||
// note: happy path, not the error condition
|
// note: happy path, not the error condition
|
||||||
@ -217,7 +234,7 @@ func (c Events) GetAddedAndRemovedItemIDs(
|
|||||||
// works as intended (until, at least, we want to _not_ call the beta anymore).
|
// works as intended (until, at least, we want to _not_ call the beta anymore).
|
||||||
rawURL := fmt.Sprintf(eventBetaDeltaURLTemplate, user, calendarID)
|
rawURL := fmt.Sprintf(eventBetaDeltaURLTemplate, user, calendarID)
|
||||||
builder := users.NewItemCalendarsItemEventsDeltaRequestBuilder(rawURL, service.Adapter())
|
builder := users.NewItemCalendarsItemEventsDeltaRequestBuilder(rawURL, service.Adapter())
|
||||||
pgr := &eventPager{service, builder, options}
|
pgr := &eventPager{service, builder, nil}
|
||||||
|
|
||||||
added, removed, deltaURL, err := getItemsAddedAndRemovedFromContainer(ctx, pgr)
|
added, removed, deltaURL, err := getItemsAddedAndRemovedFromContainer(ctx, pgr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -21,18 +21,6 @@ var (
|
|||||||
"owner": {},
|
"owner": {},
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldsForEvents = map[string]struct{}{
|
|
||||||
"calendar": {},
|
|
||||||
"end": {},
|
|
||||||
"id": {},
|
|
||||||
"isOnlineMeeting": {},
|
|
||||||
"isReminderOn": {},
|
|
||||||
"responseStatus": {},
|
|
||||||
"responseRequested": {},
|
|
||||||
"showAs": {},
|
|
||||||
"subject": {},
|
|
||||||
}
|
|
||||||
|
|
||||||
fieldsForFolders = map[string]struct{}{
|
fieldsForFolders = map[string]struct{}{
|
||||||
"childFolderCount": {},
|
"childFolderCount": {},
|
||||||
"displayName": {},
|
"displayName": {},
|
||||||
@ -112,6 +100,28 @@ func optionsForCalendars(moreOps []string) (
|
|||||||
return options, nil
|
return options, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// optionsForCalendarsByID places allowed options for exchange.Calendar object
|
||||||
|
// @param moreOps should reflect elements from fieldsForCalendars
|
||||||
|
// @return is first call in Calendars().GetWithRequestConfigurationAndResponseHandler
|
||||||
|
func optionsForCalendarsByID(moreOps []string) (
|
||||||
|
*users.ItemCalendarsCalendarItemRequestBuilderGetRequestConfiguration,
|
||||||
|
error,
|
||||||
|
) {
|
||||||
|
selecting, err := buildOptions(moreOps, fieldsForCalendars)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// should be a CalendarsRequestBuilderGetRequestConfiguration
|
||||||
|
requestParams := &users.ItemCalendarsCalendarItemRequestBuilderGetQueryParameters{
|
||||||
|
Select: selecting,
|
||||||
|
}
|
||||||
|
options := &users.ItemCalendarsCalendarItemRequestBuilderGetRequestConfiguration{
|
||||||
|
QueryParameters: requestParams,
|
||||||
|
}
|
||||||
|
|
||||||
|
return options, nil
|
||||||
|
}
|
||||||
|
|
||||||
// optionsForContactFolders places allowed options for exchange.ContactFolder object
|
// optionsForContactFolders places allowed options for exchange.ContactFolder object
|
||||||
// @return is first call in ContactFolders().GetWithRequestConfigurationAndResponseHandler
|
// @return is first call in ContactFolders().GetWithRequestConfigurationAndResponseHandler
|
||||||
func optionsForContactFolders(moreOps []string) (
|
func optionsForContactFolders(moreOps []string) (
|
||||||
@ -213,26 +223,6 @@ func optionsForContactFoldersItemDelta(
|
|||||||
return options, nil
|
return options, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// optionsForEvents ensures a valid option inputs for `exchange.Events` when selected from within a Calendar
|
|
||||||
func optionsForEventsByCalendarDelta(
|
|
||||||
moreOps []string,
|
|
||||||
) (*users.ItemCalendarsItemEventsDeltaRequestBuilderGetRequestConfiguration, error) {
|
|
||||||
selecting, err := buildOptions(moreOps, fieldsForEvents)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
requestParameters := &users.ItemCalendarsItemEventsDeltaRequestBuilderGetQueryParameters{
|
|
||||||
Select: selecting,
|
|
||||||
}
|
|
||||||
|
|
||||||
options := &users.ItemCalendarsItemEventsDeltaRequestBuilderGetRequestConfiguration{
|
|
||||||
QueryParameters: requestParameters,
|
|
||||||
}
|
|
||||||
|
|
||||||
return options, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// optionsForContactChildFolders builds a contacts child folders request.
|
// optionsForContactChildFolders builds a contacts child folders request.
|
||||||
func optionsForContactChildFolders(
|
func optionsForContactChildFolders(
|
||||||
moreOps []string,
|
moreOps []string,
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/alcionai/corso/src/internal/connector/graph"
|
"github.com/alcionai/corso/src/internal/connector/graph"
|
||||||
|
"github.com/alcionai/corso/src/internal/connector/support"
|
||||||
"github.com/alcionai/corso/src/pkg/path"
|
"github.com/alcionai/corso/src/pkg/path"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -14,9 +15,43 @@ var _ graph.ContainerResolver = &eventCalendarCache{}
|
|||||||
type eventCalendarCache struct {
|
type eventCalendarCache struct {
|
||||||
*containerResolver
|
*containerResolver
|
||||||
enumer containersEnumerator
|
enumer containersEnumerator
|
||||||
|
getter containerGetter
|
||||||
userID string
|
userID string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init ensures that the structure's fields are initialized.
|
||||||
|
// Fields Initialized when cache == nil:
|
||||||
|
// [mc.cache]
|
||||||
|
func (ecc *eventCalendarCache) init(
|
||||||
|
ctx context.Context,
|
||||||
|
) error {
|
||||||
|
if ecc.containerResolver == nil {
|
||||||
|
ecc.containerResolver = newContainerResolver()
|
||||||
|
}
|
||||||
|
|
||||||
|
return ecc.populateEventRoot(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// populateEventRoot manually fetches directories that are not returned during Graph for msgraph-sdk-go v. 40+
|
||||||
|
// DefaultCalendar is the traditional "Calendar".
|
||||||
|
// Action ensures that cache will stop at appropriate level.
|
||||||
|
// @error iff the struct is not properly instantiated
|
||||||
|
func (ecc *eventCalendarCache) populateEventRoot(ctx context.Context) error {
|
||||||
|
container := DefaultCalendar
|
||||||
|
|
||||||
|
f, err := ecc.getter.GetContainerByID(ctx, ecc.userID, container)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "fetching calendar "+support.ConnectorStackErrorTrace(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
temp := graph.NewCacheFolder(f, path.Builder{}.Append(container))
|
||||||
|
if err := ecc.addFolder(temp); err != nil {
|
||||||
|
return errors.Wrap(err, "initializing calendar resolver")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Populate utility function for populating eventCalendarCache.
|
// Populate utility function for populating eventCalendarCache.
|
||||||
// Executes 1 additional Graph Query
|
// Executes 1 additional Graph Query
|
||||||
// @param baseID: ignored. Present to conform to interface
|
// @param baseID: ignored. Present to conform to interface
|
||||||
@ -25,8 +60,8 @@ func (ecc *eventCalendarCache) Populate(
|
|||||||
baseID string,
|
baseID string,
|
||||||
baseContainerPath ...string,
|
baseContainerPath ...string,
|
||||||
) error {
|
) error {
|
||||||
if ecc.containerResolver == nil {
|
if err := ecc.init(ctx); err != nil {
|
||||||
ecc.containerResolver = newContainerResolver()
|
return errors.Wrap(err, "initializing")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := ecc.enumer.EnumerateContainers(ctx, ecc.userID, "", ecc.addFolder)
|
err := ecc.enumer.EnumerateContainers(ctx, ecc.userID, "", ecc.addFolder)
|
||||||
@ -34,6 +69,10 @@ func (ecc *eventCalendarCache) Populate(
|
|||||||
return errors.Wrap(err, "enumerating containers")
|
return errors.Wrap(err, "enumerating containers")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := ecc.populatePaths(ctx); err != nil {
|
||||||
|
return errors.Wrap(err, "establishing calendar paths")
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -51,6 +51,7 @@ func (suite *CacheResolverSuite) TestPopulate() {
|
|||||||
return &eventCalendarCache{
|
return &eventCalendarCache{
|
||||||
userID: tester.M365UserID(t),
|
userID: tester.M365UserID(t),
|
||||||
enumer: ac.Events(),
|
enumer: ac.Events(),
|
||||||
|
getter: ac.Events(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,14 +22,25 @@ type mailFolderCache struct {
|
|||||||
userID string
|
userID string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init ensures that the structure's fields are initialized.
|
||||||
|
// Fields Initialized when cache == nil:
|
||||||
|
// [mc.cache]
|
||||||
|
func (mc *mailFolderCache) init(
|
||||||
|
ctx context.Context,
|
||||||
|
) error {
|
||||||
|
if mc.containerResolver == nil {
|
||||||
|
mc.containerResolver = newContainerResolver()
|
||||||
|
}
|
||||||
|
|
||||||
|
return mc.populateMailRoot(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
// populateMailRoot manually fetches directories that are not returned during Graph for msgraph-sdk-go v. 40+
|
// populateMailRoot manually fetches directories that are not returned during Graph for msgraph-sdk-go v. 40+
|
||||||
// rootFolderAlias is the top-level directory for exchange.Mail.
|
// rootFolderAlias is the top-level directory for exchange.Mail.
|
||||||
// DefaultMailFolder is the traditional "Inbox" for exchange.Mail
|
// DefaultMailFolder is the traditional "Inbox" for exchange.Mail
|
||||||
// Action ensures that cache will stop at appropriate level.
|
// Action ensures that cache will stop at appropriate level.
|
||||||
// @error iff the struct is not properly instantiated
|
// @error iff the struct is not properly instantiated
|
||||||
func (mc *mailFolderCache) populateMailRoot(
|
func (mc *mailFolderCache) populateMailRoot(ctx context.Context) error {
|
||||||
ctx context.Context,
|
|
||||||
) error {
|
|
||||||
for _, fldr := range []string{rootFolderAlias, DefaultMailFolder} {
|
for _, fldr := range []string{rootFolderAlias, DefaultMailFolder} {
|
||||||
var directory string
|
var directory string
|
||||||
|
|
||||||
@ -76,16 +87,3 @@ func (mc *mailFolderCache) Populate(
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// init ensures that the structure's fields are initialized.
|
|
||||||
// Fields Initialized when cache == nil:
|
|
||||||
// [mc.cache]
|
|
||||||
func (mc *mailFolderCache) init(
|
|
||||||
ctx context.Context,
|
|
||||||
) error {
|
|
||||||
if mc.containerResolver == nil {
|
|
||||||
mc.containerResolver = newContainerResolver()
|
|
||||||
}
|
|
||||||
|
|
||||||
return mc.populateMailRoot(ctx)
|
|
||||||
}
|
|
||||||
|
|||||||
@ -66,9 +66,11 @@ func PopulateExchangeContainerResolver(
|
|||||||
cacheRoot = DefaultContactFolder
|
cacheRoot = DefaultContactFolder
|
||||||
|
|
||||||
case path.EventsCategory:
|
case path.EventsCategory:
|
||||||
|
ecc := ac.Events()
|
||||||
res = &eventCalendarCache{
|
res = &eventCalendarCache{
|
||||||
userID: qp.ResourceOwner,
|
userID: qp.ResourceOwner,
|
||||||
enumer: ac.Events(),
|
getter: ecc,
|
||||||
|
enumer: ecc,
|
||||||
}
|
}
|
||||||
cacheRoot = DefaultCalendar
|
cacheRoot = DefaultCalendar
|
||||||
|
|
||||||
|
|||||||
@ -507,9 +507,11 @@ func CreateContainerDestinaion(
|
|||||||
|
|
||||||
case path.EventsCategory:
|
case path.EventsCategory:
|
||||||
if directoryCache == nil {
|
if directoryCache == nil {
|
||||||
|
ace := ac.Events()
|
||||||
ecc := &eventCalendarCache{
|
ecc := &eventCalendarCache{
|
||||||
userID: user,
|
userID: user,
|
||||||
enumer: ac.Events(),
|
getter: ace,
|
||||||
|
enumer: ace,
|
||||||
}
|
}
|
||||||
caches[category] = ecc
|
caches[category] = ecc
|
||||||
newCache = true
|
newCache = true
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user