add scope category to path cat type func (#1344)
## Description Builds a scope.Category() -> path.CategoryType trans- former func into scopes to standardize the relationship between the two properties. ## Type of change - [x] 🌻 Feature ## Issue(s) * #1133 ## Test Plan - [x] ⚡ Unit test
This commit is contained in:
parent
8559c0530b
commit
77c703cee9
@ -225,7 +225,7 @@ func GetContainers(
|
|||||||
qp graph.QueryParams,
|
qp graph.QueryParams,
|
||||||
gs graph.Service,
|
gs graph.Service,
|
||||||
) ([]graph.CachedContainer, error) {
|
) ([]graph.CachedContainer, error) {
|
||||||
category := graph.ScopeToPathCategory(qp.Scope)
|
category := qp.Scope.Category().PathType()
|
||||||
|
|
||||||
switch category {
|
switch category {
|
||||||
case path.ContactsCategory:
|
case path.ContactsCategory:
|
||||||
|
|||||||
@ -28,7 +28,7 @@ func FilterContainersAndFillCollections(
|
|||||||
resolver graph.ContainerResolver,
|
resolver graph.ContainerResolver,
|
||||||
) error {
|
) error {
|
||||||
var (
|
var (
|
||||||
category = graph.ScopeToPathCategory(qp.Scope)
|
category = qp.Scope.Category().PathType()
|
||||||
collectionType = CategoryToOptionIdentifier(category)
|
collectionType = CategoryToOptionIdentifier(category)
|
||||||
errs error
|
errs error
|
||||||
)
|
)
|
||||||
|
|||||||
@ -17,7 +17,6 @@ import (
|
|||||||
|
|
||||||
"github.com/alcionai/corso/src/pkg/logger"
|
"github.com/alcionai/corso/src/pkg/logger"
|
||||||
"github.com/alcionai/corso/src/pkg/path"
|
"github.com/alcionai/corso/src/pkg/path"
|
||||||
"github.com/alcionai/corso/src/pkg/selectors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -70,23 +69,6 @@ func (handler *LoggingMiddleware) Intercept(
|
|||||||
return pipeline.Next(req, middlewareIndex)
|
return pipeline.Next(req, middlewareIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScopeToPathCategory helper function that maps selectors.ExchangeScope to path.CategoryType
|
|
||||||
func ScopeToPathCategory(scope selectors.ExchangeScope) path.CategoryType {
|
|
||||||
if scope.IncludesCategory(selectors.ExchangeMail) {
|
|
||||||
return path.EmailCategory
|
|
||||||
}
|
|
||||||
|
|
||||||
if scope.IncludesCategory(selectors.ExchangeContact) {
|
|
||||||
return path.ContactsCategory
|
|
||||||
}
|
|
||||||
|
|
||||||
if scope.IncludesCategory(selectors.ExchangeEvent) {
|
|
||||||
return path.EventsCategory
|
|
||||||
}
|
|
||||||
|
|
||||||
return path.UnknownCategory
|
|
||||||
}
|
|
||||||
|
|
||||||
func StringToPathCategory(input string) path.CategoryType {
|
func StringToPathCategory(input string) path.CategoryType {
|
||||||
param := strings.ToLower(input)
|
param := strings.ToLower(input)
|
||||||
|
|
||||||
|
|||||||
@ -298,7 +298,7 @@ func (gc *GraphConnector) createCollections(
|
|||||||
Credentials: gc.credentials,
|
Credentials: gc.credentials,
|
||||||
}
|
}
|
||||||
|
|
||||||
itemCategory := graph.ScopeToPathCategory(qp.Scope)
|
itemCategory := qp.Scope.Category().PathType()
|
||||||
|
|
||||||
foldersComplete, closer := observe.MessageWithCompletion(fmt.Sprintf("∙ %s - %s:", itemCategory.String(), user))
|
foldersComplete, closer := observe.MessageWithCompletion(fmt.Sprintf("∙ %s - %s:", itemCategory.String(), user))
|
||||||
defer closer()
|
defer closer()
|
||||||
@ -307,7 +307,7 @@ func (gc *GraphConnector) createCollections(
|
|||||||
resolver, err := exchange.PopulateExchangeContainerResolver(
|
resolver, err := exchange.PopulateExchangeContainerResolver(
|
||||||
ctx,
|
ctx,
|
||||||
qp,
|
qp,
|
||||||
graph.ScopeToPathCategory(qp.Scope),
|
qp.Scope.Category().PathType(),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "getting folder cache")
|
return nil, errors.Wrap(err, "getting folder cache")
|
||||||
|
|||||||
@ -466,14 +466,24 @@ const (
|
|||||||
// append new filter cats here
|
// append new filter cats here
|
||||||
)
|
)
|
||||||
|
|
||||||
// exchangePathSet describes the category type keys used in Exchange paths.
|
// exchangeLeafProperties describes common metadata of the leaf categories
|
||||||
// The order of each slice is important, and should match the order in which
|
var exchangeLeafProperties = map[categorizer]leafProperty{
|
||||||
// these types appear in the canonical Path for each type.
|
ExchangeContact: {
|
||||||
var exchangePathSet = map[categorizer][]categorizer{
|
pathKeys: []categorizer{ExchangeUser, ExchangeContactFolder, ExchangeContact},
|
||||||
ExchangeContact: {ExchangeUser, ExchangeContactFolder, ExchangeContact},
|
pathType: path.ContactsCategory,
|
||||||
ExchangeEvent: {ExchangeUser, ExchangeEventCalendar, ExchangeEvent},
|
},
|
||||||
ExchangeMail: {ExchangeUser, ExchangeMailFolder, ExchangeMail},
|
ExchangeEvent: {
|
||||||
ExchangeUser: {ExchangeUser}, // the root category must be represented
|
pathKeys: []categorizer{ExchangeUser, ExchangeEventCalendar, ExchangeEvent},
|
||||||
|
pathType: path.EventsCategory,
|
||||||
|
},
|
||||||
|
ExchangeMail: {
|
||||||
|
pathKeys: []categorizer{ExchangeUser, ExchangeMailFolder, ExchangeMail},
|
||||||
|
pathType: path.EmailCategory,
|
||||||
|
},
|
||||||
|
ExchangeUser: { // the root category must be represented, even though it isn't a leaf
|
||||||
|
pathKeys: []categorizer{ExchangeUser},
|
||||||
|
pathType: path.UnknownCategory,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec exchangeCategory) String() string {
|
func (ec exchangeCategory) String() string {
|
||||||
@ -551,7 +561,12 @@ func (ec exchangeCategory) pathValues(p path.Path) map[categorizer]string {
|
|||||||
|
|
||||||
// pathKeys returns the path keys recognized by the receiver's leaf type.
|
// pathKeys returns the path keys recognized by the receiver's leaf type.
|
||||||
func (ec exchangeCategory) pathKeys() []categorizer {
|
func (ec exchangeCategory) pathKeys() []categorizer {
|
||||||
return exchangePathSet[ec.leafCat()]
|
return exchangeLeafProperties[ec.leafCat()].pathKeys
|
||||||
|
}
|
||||||
|
|
||||||
|
// PathType converts the category's leaf type into the matching path.CategoryType.
|
||||||
|
func (ec exchangeCategory) PathType() path.CategoryType {
|
||||||
|
return exchangeLeafProperties[ec.leafCat()].pathType
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
@ -1394,3 +1394,34 @@ func (suite *ExchangeSelectorSuite) TestCategoryFromItemType() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *ExchangeSelectorSuite) TestCategory_PathType() {
|
||||||
|
table := []struct {
|
||||||
|
cat exchangeCategory
|
||||||
|
pathType path.CategoryType
|
||||||
|
}{
|
||||||
|
{ExchangeCategoryUnknown, path.UnknownCategory},
|
||||||
|
{ExchangeContact, path.ContactsCategory},
|
||||||
|
{ExchangeContactFolder, path.ContactsCategory},
|
||||||
|
{ExchangeEvent, path.EventsCategory},
|
||||||
|
{ExchangeEventCalendar, path.EventsCategory},
|
||||||
|
{ExchangeMail, path.EmailCategory},
|
||||||
|
{ExchangeMailFolder, path.EmailCategory},
|
||||||
|
{ExchangeUser, path.UnknownCategory},
|
||||||
|
{ExchangeFilterMailSender, path.EmailCategory},
|
||||||
|
{ExchangeFilterMailSubject, path.EmailCategory},
|
||||||
|
{ExchangeFilterMailReceivedAfter, path.EmailCategory},
|
||||||
|
{ExchangeFilterMailReceivedBefore, path.EmailCategory},
|
||||||
|
{ExchangeFilterContactName, path.ContactsCategory},
|
||||||
|
{ExchangeFilterEventOrganizer, path.EventsCategory},
|
||||||
|
{ExchangeFilterEventRecurs, path.EventsCategory},
|
||||||
|
{ExchangeFilterEventStartsAfter, path.EventsCategory},
|
||||||
|
{ExchangeFilterEventStartsBefore, path.EventsCategory},
|
||||||
|
{ExchangeFilterEventSubject, path.EventsCategory},
|
||||||
|
}
|
||||||
|
for _, test := range table {
|
||||||
|
suite.T().Run(test.cat.String(), func(t *testing.T) {
|
||||||
|
assert.Equal(t, test.pathType, test.cat.PathType())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -62,6 +62,15 @@ func (mc mockCategorizer) pathKeys() []categorizer {
|
|||||||
return []categorizer{rootCatStub, leafCatStub}
|
return []categorizer{rootCatStub, leafCatStub}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mc mockCategorizer) PathType() path.CategoryType {
|
||||||
|
switch mc {
|
||||||
|
case leafCatStub:
|
||||||
|
return path.EventsCategory
|
||||||
|
default:
|
||||||
|
return path.UnknownCategory
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func stubPathValues() map[categorizer]string {
|
func stubPathValues() map[categorizer]string {
|
||||||
return map[categorizer]string{
|
return map[categorizer]string{
|
||||||
rootCatStub: rootCatStub.String(),
|
rootCatStub: rootCatStub.String(),
|
||||||
|
|||||||
@ -288,12 +288,16 @@ const (
|
|||||||
FileFilterModifiedBefore oneDriveCategory = "FileFilterModifiedBefore"
|
FileFilterModifiedBefore oneDriveCategory = "FileFilterModifiedBefore"
|
||||||
)
|
)
|
||||||
|
|
||||||
// oneDrivePathSet describes the category type keys used in OneDrive paths.
|
// oneDriveLeafProperties describes common metadata of the leaf categories
|
||||||
// The order of each slice is important, and should match the order in which
|
var oneDriveLeafProperties = map[categorizer]leafProperty{
|
||||||
// these types appear in the canonical Path for each type.
|
OneDriveItem: {
|
||||||
var oneDrivePathSet = map[categorizer][]categorizer{
|
pathKeys: []categorizer{OneDriveUser, OneDriveFolder, OneDriveItem},
|
||||||
OneDriveItem: {OneDriveUser, OneDriveFolder, OneDriveItem},
|
pathType: path.FilesCategory,
|
||||||
OneDriveUser: {OneDriveUser}, // the root category must be represented
|
},
|
||||||
|
OneDriveUser: { // the root category must be represented, even though it isn't a leaf
|
||||||
|
pathKeys: []categorizer{OneDriveUser},
|
||||||
|
pathType: path.UnknownCategory,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c oneDriveCategory) String() string {
|
func (c oneDriveCategory) String() string {
|
||||||
@ -350,7 +354,12 @@ func (c oneDriveCategory) pathValues(p path.Path) map[categorizer]string {
|
|||||||
|
|
||||||
// pathKeys returns the path keys recognized by the receiver's leaf type.
|
// pathKeys returns the path keys recognized by the receiver's leaf type.
|
||||||
func (c oneDriveCategory) pathKeys() []categorizer {
|
func (c oneDriveCategory) pathKeys() []categorizer {
|
||||||
return oneDrivePathSet[c.leafCat()]
|
return oneDriveLeafProperties[c.leafCat()].pathKeys
|
||||||
|
}
|
||||||
|
|
||||||
|
// PathType converts the category's leaf type into the matching path.CategoryType.
|
||||||
|
func (c oneDriveCategory) PathType() path.CategoryType {
|
||||||
|
return oneDriveLeafProperties[c.leafCat()].pathType
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
@ -336,3 +336,24 @@ func (suite *OneDriveSelectorSuite) TestOneDriveScope_MatchesInfo() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *OneDriveSelectorSuite) TestCategory_PathType() {
|
||||||
|
table := []struct {
|
||||||
|
cat oneDriveCategory
|
||||||
|
pathType path.CategoryType
|
||||||
|
}{
|
||||||
|
{OneDriveCategoryUnknown, path.UnknownCategory},
|
||||||
|
{OneDriveUser, path.UnknownCategory},
|
||||||
|
{OneDriveItem, path.FilesCategory},
|
||||||
|
{OneDriveFolder, path.FilesCategory},
|
||||||
|
{FileFilterCreatedAfter, path.FilesCategory},
|
||||||
|
{FileFilterCreatedBefore, path.FilesCategory},
|
||||||
|
{FileFilterModifiedAfter, path.FilesCategory},
|
||||||
|
{FileFilterModifiedBefore, path.FilesCategory},
|
||||||
|
}
|
||||||
|
for _, test := range table {
|
||||||
|
suite.T().Run(test.cat.String(), func(t *testing.T) {
|
||||||
|
assert.Equal(t, test.pathType, test.cat.PathType())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -11,9 +11,29 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// interfaces
|
// types & interfaces
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// leafProperty describes metadata associated with a leaf categorizer
|
||||||
|
type leafProperty struct {
|
||||||
|
// pathKeys describes the categorizer keys used to map scope type to a value
|
||||||
|
// extracted from a path.Path.
|
||||||
|
// The order of the slice is important, and should match the order in which
|
||||||
|
// these types appear in the path.Path for each type.
|
||||||
|
// Ex: given: exchangeMail
|
||||||
|
// categoryPath => [ExchangeUser, ExchangeMailFolder, ExchangeMail]
|
||||||
|
// suggests that scopes involving exchange mail will need to match a user,
|
||||||
|
// mailFolder, and mail; appearing in the path in that order.
|
||||||
|
pathKeys []categorizer
|
||||||
|
|
||||||
|
// pathType produces the path.CategoryType representing this leafType.
|
||||||
|
// This allows the scope to type to be compared using the more commonly recognized
|
||||||
|
// path category consts.
|
||||||
|
// Ex: given: exchangeMail
|
||||||
|
// pathType => path.EmailCategory
|
||||||
|
pathType path.CategoryType
|
||||||
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
// categorizer recognizes service specific item categories.
|
// categorizer recognizes service specific item categories.
|
||||||
categorizer interface {
|
categorizer interface {
|
||||||
@ -54,6 +74,10 @@ type (
|
|||||||
// ids in a path with the same keys that it uses to retrieve those values from a scope,
|
// ids in a path with the same keys that it uses to retrieve those values from a scope,
|
||||||
// so that the two can be compared.
|
// so that the two can be compared.
|
||||||
pathKeys() []categorizer
|
pathKeys() []categorizer
|
||||||
|
|
||||||
|
// PathType converts the category's leaf type into the matching path.CategoryType.
|
||||||
|
// Exported due to common use by consuming packages.
|
||||||
|
PathType() path.CategoryType
|
||||||
}
|
}
|
||||||
// categoryT is the generic type interface of a categorizer
|
// categoryT is the generic type interface of a categorizer
|
||||||
categoryT interface {
|
categoryT interface {
|
||||||
@ -84,7 +108,7 @@ type (
|
|||||||
scope map[string]filters.Filter
|
scope map[string]filters.Filter
|
||||||
|
|
||||||
// scoper describes the minimum necessary interface that a soundly built scope should
|
// scoper describes the minimum necessary interface that a soundly built scope should
|
||||||
// comply with.
|
// comply with to be usable by selector generics.
|
||||||
scoper interface {
|
scoper interface {
|
||||||
// Every scope is expected to contain a reference to its category. This allows users
|
// Every scope is expected to contain a reference to its category. This allows users
|
||||||
// to evaluate structs with a call to myscope.Category(). Category() is expected to
|
// to evaluate structs with a call to myscope.Category(). Category() is expected to
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user